Excel – 为什么命名合并范围不同于合并范围然后命名?

我知道,我知道,合并范围是可怕的工作。 但不pipe怎么说:

我发现了一些有趣的行为,我可以复制/粘贴一些合并范围,而不是其他人。 所以我尝试了一下。

build立:

在这里输入图像说明

在这里输入图像说明

已经很明显,这些范围不是一回事。 合并后命名的范围只包含topLeftCell引用,而命名后合并的范围则保留对所有单元格的引用。


编辑:testing代码

Option Explicit Public Sub PerformTests() Const NAME_THEN_MERGE As String = "Name_Then_Merge" Const MERGE_THEN_NAME As String = "Merge_Then_Name" Const PASTE_NAME_THEN_MERGE As String = "Paste_Name_Then_Merge" Const PASTE_MERGE_THEN_NAME As String = "Paste_Merge_Then_Name" TestNames MERGE_THEN_NAME, PASTE_NAME_THEN_MERGE '/ Result: Error 1004, cannot do that to a merged cell End Sub Public Sub TestNames(ByVal copyName As String, ByVal pasteName As String) wsPasteTest.Activate Dim copyRange As Range, pasteRange As Range Set copyRange = wsPasteTest.Range(copyName) Set pasteRange = wsPasteTest.Range(pasteName) CopyPasteCell copyRange, pasteRange End Sub Public Sub CopyPasteCell(ByRef copyCell As Range, ByRef pasteCell As Range, Optional ByVal pasteRowHeights As Boolean = False) copyCell.Copy pasteCell.PasteSpecial xlPasteAll If pasteRowHeights Then Dim sourceRowHeight As Long sourceRowHeight = copyCell.rowHeight pasteCell.rowHeight = sourceRowHeight End If End Sub 

广泛的testing后,这似乎是结论:

如果您命名一个单元格范围,然后将它们合并,则名称为“范围”将保留对所有单元格的引用。 如果您先合并,则命名范围仅指向topLeftCell。

如果您尝试复制已命名的范围,则将其视为与其参考大小相同。 因此,将5个单元格的集合(命名和合并)复制到另一个相同大小的合并单元格或单个单元格是可行的。

但是,(合并命名)范围只能复制到单个单元格。 试图复制到一组5个合并单元格将导致1004错误。


为什么? 怎样处理导致这种差异的合并单元格和命名范围?


作为参考,这是Office 365,Excel版本15.0.4805.1003

我会试穿这个,因为我认为我已经testing了足够的代码,以了解发生了什么事情。

让我们从执行您指定的操作时Excel如何处理各种命名范围开始。 在将copyRange设置为MERGE_THEN_NAME常量并在新定义的copyRange使用.Copy (用于testing目的)之后,您可以看到A2单元格周围有移动的虚线。

 Option Explicit Public Sub PerformTests() Const NAME_THEN_MERGE As String = "Name_Then_Merge" Const MERGE_THEN_NAME As String = "Merge_Then_Name" Const PASTE_NAME_THEN_MERGE As String = "Paste_Name_Then_Merge" Const PASTE_MERGE_THEN_NAME As String = "Paste_Merge_Then_Name" TestNames MERGE_THEN_NAME, PASTE_MERGE_THEN_NAME '/ Result: Error 1004, cannot do that to a merged cell End Sub Public Sub TestNames(ByVal copyName As String, ByVal pasteName As String) Sheets("wsPasteTest").Activate Dim copyRange As Range, pasteRange As Range Set copyRange = Sheets("wsPasteTest").Range(copyName) copyRange.Copy 'This is the last step executed before error Set pasteRange = Sheets("wsPasteTest").Range(pasteName) CopyPasteCell copyRange, pasteRange End Sub 

在这里输入图像说明

这是预期的,因为定义的范围在名称pipe理器中被读作=wsPasteTest!$A$2

名称管理器说明

该范围的定义意味着,当Excel重新访问指定的范围来提取一个值时,它通过逐字地解释地址来实现,也就是说,它只考虑A2的单元格值,因为合并单元格的值在“左上”本身的单元地址。 这个逻辑可以通过使用类似于Range("A2:E2").Cells(1).Value东西,通过VBA程序返回一个合并单元格的值的正确方法来确认(这在上面的超链接中得到了解决Range("A2:E2").Cells(1).Value而不是简单的Range("A2:E2").Value 。 后一个选项返回一个数组,因为它正在考虑范围内的每个单元格的值。


接下来的部分就是为什么使用它可能会很危险。select或者通过你的整个代码.Activate ,也显示如何得到你想要的行为。 我们可以看到什么时候。selectcopyCell它select整个合并单元格相比,在.Copy方法(模仿如何用户与电子表格本身的范围交互)只是A2 。 所以现在,如果我们selectcopyCell ,然后使用Selection.Copy ,整个合并的单元格被复制,而不是A2因为Excel已经被指示抓取整个数组区域。 Excel也显示了select项目的重要性,然后使用select可以彻底改变对范围的解释,而不是明确地处理范围。

PerformTests()TestNames()的代码与您的代码相同,修改了以下PerformTests()

 Public Sub CopyPasteCell(ByRef copyCell As Range, ByRef pasteCell As Range, Optional ByVal pasteRowHeights As Boolean = False) copyCell.Select Selection.Copy 'this step is shown in the first screenshot below pasteCell.Select Selection.PasteSpecial xlPasteAll 'this step is shown in the second screentshot below If pasteRowHeights Then Dim sourceRowHeight As Long sourceRowHeight = copyCell.RowHeight pasteCell.RowHeight = sourceRowHeight End If End Sub 

这是copyCell被选中,然后复制的结果。

Selection.Copy结果

这是pasteCell被选中的结果,然后粘贴到。 这显示了使用Merge_Then_Name范围时所需的结果。

选择。特别的结果


最终,您可以看到,当您合并明确引用已命名的范围时,它会逐字地解释命名的范围的地址(给出单个单元格格式的单元格值),显然无法将其粘贴到所需的区域大小build议的粘贴方法。 如果您将粘贴方法更改为xlPasteValues ,则可以避免使用.Select 。 原因是因为它允许Paste_Merge_Then_Name的定义保持为=wsPasteTest!$A$8同时也允许将值传递到单个单元区域。 此方法保持目标单元格的格式相同,而只是replace值。 这不完全是你想要的粘贴,但非常接近。

 Public Sub CopyPasteCell(ByRef copyCell As Range, ByRef pasteCell As Range, Optional ByVal pasteRowHeights As Boolean = False) copyCell.Copy pasteCell.PasteSpecial xlPasteValues If pasteRowHeights Then Dim sourceRowHeight As Long sourceRowHeight = copyCell.RowHeight pasteCell.RowHeight = sourceRowHeight End If End Sub 

粘贴特殊结果


由于一个主要原因, Name_Then_Merge范围同时适用于单个单元格和命名的范围粘贴; 它包含多less个占位符值。 当您执行.Copy方法时,它会select整个合并的单元格, 因为它的定义是 =wsPasteTest!$A$5:$E$5 。 这是很好的,因为将它粘贴到一个相同大小的命名范围中是可行的,因为它们匹配,并且粘贴到单个单元格中会起作用,因为有一个非空值。


总结:命名的范围是由它们的初始单元格值定义的,即使在单元格合并之后也保留了这个“位置”的数目。 所以,如果你命名一个范围,它引用一个范围内的每个单元格的值(在这种情况下是5个值),并且合并单元格不会改变命名范围的定义(但会改变第一个单元格为“”作为占位符)。 如果合并单元格并命名范围,则该值将保留在合并区域的左上angular单元格中,因此将用作命名范围的合并单元格的定义。 在这种情况下,如果您试图.Paste xlPasteAllxlPasteAll .Paste到合并的单元格中,Excel会感到困惑,因为它会将源的值复制为单个单元格区域,并尝试将其粘贴到五个单元格区域。

解决这个问题的方法是确保通过select或使用不同的粘贴方法来复制命名范围的整个区域, 但要小心这些粘贴方法产生的内容 。 例如xlPasteAllUsingSourceTheme将取消合并目标单元格,但仍然满足指定的范围定义。