周日,08 2017十月
  0 回复
  3.2K访问
0
投票
解开
我的工作簿中有一个包含 400 多行、8 列和 160 个合并范围的工作表,我弄乱了它的外观。 我在互联网上搜索了 VBA Autofit Merged Cells。 这些 URL 都没有多大用处。 本网站上的宏在正确的轨道上,但是:-
1) 我必须手动识别并输入 160 个合并范围。
我添加了对合并单元格范围的搜索。
2)它使用第一行进行合并单元格计算(单元格 ZZ1)。 我在单元格 A1(标题)上使用了更大的字体,这导致计算所需的合并自动调整高度时出错。
我在数据下方使用 1 列右侧和 1 行的单元格。 (Ctrl+Shift+End,没有找到这个单元格)
3)它重新计算所有合并的单元格,因此它减少了包含合并单元格和正常单元格的两行的高度,使正常单元格不可读。
仅当所需的合并高度超过现有高度时,我才更改行高。
4) 将合并范围内的数据复制到ZZ1单元格的方法不正确,仅基于合并范围内的文本,而没有考虑各个合并单元格中不同的字体大小。
我更正了复制方法。
5)宏很慢:我的工作表上大约 15 秒以上。
在宏结束时关闭屏幕刷新并重新打开可将此时间缩短到 2 秒。

我设法找到了另一个恼人的错误。 自动调整工作表(在更正合并范围之前)并且它扭曲了几行。 一些设置为换行的“普通”单元格的高度增加了,并显示为一行(或两行)文本,文本下方有一个空白行。 互联网搜索表明这是由 Excel 更改显示以适应打印机字体引起的。 找到了一个“解决方法”,我添加到宏中:
将列宽增加一小部分。
自动调整工作表上的所有行。
对行高进行更正以适应合并的范围。
将列宽恢复为原始大小。
修复了它,现在不再出现空白行!

以为现在一切都是正确的,但后来我发现了另一个问题。 如果我关闭工作簿并重新打开它,空白行又回来了。 查看了文件/选项,我在 Internet 上搜索了一种防止工作簿在关闭/打开工作簿时更新屏幕显示但没有成功的方法。 我必须在“ThisWorkbook”选项卡上添加 Private Sub Workbook_Open(),并在打开工作簿时调用运行宏。


选项显式

子 Look4Merged()
将 WSN 调暗为字符串'工作表名称
Dim sht As Worksheet 'Used by "Set"
Dim LastRow As Long '所有数据列的最后一行
Dim LastRowCC As Long '当前列的最后一行有数据
Dim LastColumn As Integer '所有数据行中最后一列的个数
Dim CurrCol As Integer '当前列数
Dim Letter As String '将 CurrCol 数字转换为字符串
Dim ILetter As String '最后一列右侧的索引列
Dim ICell As String '单元格右侧一列和向下一排 frpm 数据区域。 用于计算所需的合并高度
Dim CRow As Long '当前行号
Dim TwN As Long '错误处理
Dim TwD As String '错误处理
Dim Mgd As Boolean 'True/False 测试单元格是否合并
Dim MgdCellAddr As String '包含合并范围作为字符串
Dim MgdCellStart As String '合并单元格范围的起始字母 用于例如检查 B 列的合并单元格,忽略从 A 列开始延伸到 B 列的任何合并单元格(已评估)
Dim MgdCellStart1 As String '用于计算 MgdCellStart
Dim MgdCellStart2 As String '用于计算 MgdCellStart
Dim OldHeight As Single '合并范围内所有行的现有高度
Dim P1 As Integer '循环计数/指针
Dim OldWidth As Single '合并范围内单元格的现有宽度
Dim NewHeight As Single '合并范围内所有行的所需高度。 如果超过 OldHeight,则按比例更新各个行
Dim C1 As Integer '循环列数
Dim R1 As Long '循环行数/指针
Dim Tweak As Single '小幅增加列宽以克服空白行问题
将橙色调暗为范围
出错时转到 TomsHandler

Application.ScreenUpdating = False '如果屏幕更新仅 15 秒关闭,则快 2 秒。
Tweak = 1.04 '在自动调整所有行之前将列宽增加 4%。
WSN = ActiveSheet.名称
Columns("A:A").EntireRow.Hidden = False

'在带有数据的整个工作表中查找最后一个活动行和列
使用 ActiveSheet.UsedRange
LastColumn = Range(Range("A1"), Cells(Rows.Count, Columns.Count)).Find(What:="*", LookIn:=xlValues, _
SearchOrder:=xlByColumns、SearchDirection:=xlPrevious).Column
LastRow = Range(Range("A1"), Cells(Rows.Count, Columns.Count)).Find(What:="*", LookIn:=xlValues, _
SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
结束
CurrCol = LastColumn + 1 '即到最后一列的右侧
如果 CurrCol < 27 那么
ILetter = Chr$(CurrCol + 64) '索引列
其他
ILetter = Chr$(Int((CurrCol - 1) / 26) + 64)
ILetter = ILetter & Chr$(CurrCol - Int((CurrCol - 1) / 26) * 26 + 64) '如果是两位数的索引列。没有打扰三个字母
结束如果

'Icell 位于数据的右下方。 单元格用于计算适合合并范围所需的高度
ICell = ILetter & LastRow + 1

'少量增加列宽以解决空白行换行错误。
Range("A" & LastRow + 1).Select
对于 C1 = 1 到 LastColumn
ActiveCell.ColumnWidth = ActiveCell.ColumnWidth * Tweak '小幅增加列宽以解决bug
ActiveCell.Offset(0, 1).Range("A1").Select ' 向右移动一个单元格
下一页

'自动调整行(忽略合并的行),列宽增加 4%,以防止某些包装行出现空白行错误
单元格.选择
选择.行.自动调整
Set sht = Worksheets(WSN) '需要在数据列中找到最后一个条目

对于 CurrCol = 1 到 LastColumn
'将当前列号转换为字母(单字母或双字母)
如果 CurrCol < 27 那么
字母 = Chr$(CurrCol + 64)
其他
字母 = Chr$(Int((CurrCol - 1) / 26) + 64)
字母 = 字母 & Chr$(CurrCol - Int((CurrCol - 1) / 26) * 26 + 64)
结束如果
LastRowCC = sht.Cells(sht.Rows.Count, Letter).End(xlUp).Row '查找当前列的最后一行

对于 CRow = 1 到 LastRowCC
范围(字母和 CRow)。选择
Mgd = ActiveCell.MergeCells '是合并范围内的单元格
If Mgd = True Then '如果为真,则为
'什么是合并的范围地址? 提取单个/两位数作为范围的开始
MgdCellAddr = ActiveCell.MergeArea.Address
MgdCellStart1 = Mid(MgdCellAddr, 2, 1)
MgdCellStart2 = Mid(MgdCellAddr, 3, 1)
如果 MgdCellStart2 = "$" 那么
MgdCellStart = MgdCellStart1
其他
MgdCellStart = MgdCellStart1 & MgdCellStart2
结束如果
If MgdCellStart = Letter Then '合并单元格第一列等于当前列
带表(WSN)
旧宽度 = 0
Set oRange = Range(MgdCellAddr) '将 oRange 设置为检测到的合并范围
对于 C1 = 1 到 oRange.Columns.Count
OldWidth = OldWidth + .Cells(1, oRange.Column + C1 - 1).ColumnWidth '累积单元格范围的列宽(添加4%)
下一页
旧高度 = 0
对于 R1 = 1 到 oRange.Rows.Count
OldHeight = OldHeight + .Cells(CRow, oRange.Row + R1 - 1).RowHeight '累积单元格范围的现有行高
下一页
oRange.MergeCells = 假
.Range(Letter & CRow).Copy Destination:=Range(ICell) '复制文本和字体大小,而不仅仅是值
.Range(ICell).WrapText = True '换行 ICell
.Columns(ILetter).ColumnWidth = OldWidth '更改包含 ICell 的列的宽度以模仿现有范围
.Rows(LastRow + 1).EntireRow.AutoFit '自动调整ICell行,准备测量所需的合并高度
oRange.MergeCells = True '将合并的范围重置为合并的
oRange.WrapText = True '和换行
'测量合并范围所需的高度
新高度 = .Rows(LastRow + 1).RowHeight
'新要求的高度是否超过旧的现有高度
如果 NewHeight > OldHeight 则
对于 R1 = CRow 到 CRow + oRange.Rows.Count - 1
'按比例增加范围内的每一行
Range(ILetter & R1).RowHeight = Range(ILetter & R1).RowHeight * NewHeight / OldHeight
下一页
其他
'合并单元格中有足够的空间
结束如果
CRow = CRow + oRange.Rows.Count - 1 'else 在多行范围内,将下降到范围的第二行并在到达“下一个”时重复计算
.Range(ICell).Clear 'Zap ICell 准备好进行下一次计算
.Range(ICell).ColumnWidth = 8.1 '整理列宽
结束
结束如果
结束如果
下一页
下一页

'重置列宽删除 4% 添加(需要解决换行错误)
Range("A" & LastRow + 1).Select
对于 C1 = 1 到 LastColumn
ActiveCell.ColumnWidth = ActiveCell.ColumnWidth / Tweak '将列宽减小到原始
ActiveCell.Offset(0, 1).Range("A1").Select ' 右一个单元格
下一页
范围(“A1”)。选择

Application.ScreenUpdating = True '重新开启更新
退出小组

汤姆斯处理程序:
Application.ScreenUpdating = True '重新开启更新
TwN = 错误编号
TwD = 错误描述
MsgBox "需要处理错误" & TwN & " " & TwD
Stop 停止
简历
END SUB

是否可以防止 Excel 在关闭/重新打开工作簿时更改屏幕显示外观?
目前还没有回复。