Ich werde an diesem einen Stich nehmen, wie ich glaube, ich habe genug mit Ihrem Code getestet, um zu verstehen, was los ist .
Beginnen wir damit, wie Excel die verschiedenen benannten Bereiche behandelt, wenn die von Ihnen festgelegten Aktionen ausgeführt werden. Sie können sehen, dass nach der Einstellung copyRange
auf die MERGE_THEN_NAME
Konstante, und mit .Copy
(für Testzwecke) auf der neu definierten copyRange
, die A2
Zelle hat die beweglichen gestrichelten Linien um es herum.
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

da der definierte Bereich als =wsPasteTest!$A$2
im Namen Manager lesen ist dies erwartet wird.

Diese Definition des Bereichs bedeutet, dass, wenn Excel den benannten Bereich erneut besucht Wert zu extrahieren, es tut dies, indem Sie die Adresse wörtlich zu interpretieren, dh sie berücksichtigt nur den Zellenwert von A2 seit the merged cells' value is defined in the "top left" Zelladresse selbst. Diese Logik kann durch das korrekte Verfahren zum Zurückgeben des Werts einer verbundenen Zelle durch VBA-Prozeduren (die in dem obigen Hyperlink adressiert sind) bestätigt werden, indem etwas wie Range("A2:E2").Cells(1).Value
anstelle von einfach Range("A2:E2").Value
verwendet werden muss. Die letztere Option gibt ein Array zurück, da es den Wert jeder einzelnen Zelle im Bereich berücksichtigt.
Der nächste Teil ist hier, warum es gefährlich sein kann .Select
oder .Activate
durch den ganzen Code zu verwenden, sondern zeigt auch, wie das Verhalten bekommen Sie möchten. Wir können sehen, wenn wir .Select
die copyCell
, dass es wählt die gesamte verbundene Zelle im Vergleich zu nur A2
in der .Copy
-Methode (die imitiert, wie ein Benutzer mit dem Bereich in der Kalkulationstabelle selbst interagiert). Wenn wir jetzt copyCell
auswählen und dann Selection.Copy
verwenden, wird die gesamte verbundene Zelle kopiert und nicht nur A2
, da Excel angewiesen wurde, den gesamten Array-Bereich zu erfassen. Excel hat auch gezeigt, wie wichtig die Auswahl eines Elements und die anschließende Verwendung der Auswahl ist, um die Interpretation eines Bereichs drastisch zu ändern, anstatt explizit mit dem Bereich zu arbeiten.
Der Code in PerformTests()
und TestNames()
zu Ihnen identisch ist, wurde die folgende Unter geändert:
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
Hier ist das Ergebnis der copyCell
ausgewählt wird, dann kopiert.

Hier ist das Ergebnis der pasteCell
ausgewählt wird, dann in eingefügt. Dies zeigt das gewünschte Ergebnis bei der Verwendung von Merge_Then_Name
.

Letztlich kann man sehen, dass, wenn Sie einen Namen Bereich siehe ausdrücklich, dass nach Verschmelzung definiert wurde, interpretiert er die Adresse des benannten Bereich buchstäblich (eine einzelne Zelle Wert mit Single geben Zellformatierung), die mit der vorgeschlagenen Kleistermethode nicht eindeutig in die gewünschte Flächengröße eingefügt werden kann. Wenn Sie Ihre Einfügemethode auf xlPasteValues
ändern, können Sie vermeiden, .Select
zu verwenden. Der Grund dafür ist, dass die Definition von Paste_Merge_Then_Name
als =wsPasteTest!$A$8
beibehalten werden kann und gleichzeitig der Wert in einen einzelnen Zellenbereich übertragen werden kann. Diese Methode behält die Formatierung der Zielzelle bei und ersetzt nur den Wert. Es ist nicht genau das, was deine beabsichtigte Paste war, aber ziemlich nah.
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

Der Name_Then_Merge
Bereich arbeitet sowohl mit einzelner Zelle und die benannten Bereich Pasten für einen Hauptgrund; Wie viele Platzhalter enthält es für Werte.Wenn Sie die .Copy
Methode von Name_Then_Merge
tun, wählt es die gesamte verbundene Zelle aus, weil es nach seiner Definition angewiesen wird=wsPasteTest!$A$5:$E$5
. Das ist gut, weil das Einfügen in einen gleichnamigen benannten Bereich funktioniert, weil sie übereinstimmen, und das Einfügen in eine einzelne Zelle würde funktionieren, weil es einen einzelnen, nicht leeren Wert gibt.
Zusammenfassung: Die benannten Bereiche sind durch ihre anfänglichen Zellenwerte definiert und enthalten die Anzahl der "Orte", selbst nachdem die Zellen zusammengeführt wurden. Wenn Sie also einen Bereich benennen, verweist er auf die Werte der einzelnen Zellen in einem Bereich (in diesem Fall 5 Werte), und das Zusammenführen der Zelle ändert nicht die Definition des benannten Bereichs (ändert jedoch alle Werte des Arrays nach dem ersten) Zelle zu "" als Platzhalter). Wenn Sie Zellen zusammenführen und dann den Bereich benennen, wird der Wert in der oberen linken Zelle des zusammengeführten Bereichs gespeichert und wird daher als Definition der verbundenen Zelle für den benannten Bereich verwendet. In diesem Fall wird Excel verwirrt, wenn Sie versuchen, nur .Paste
oder xlPasteAll
dies in eine verbundene Zelle, weil es den Wert der Quelle als einzelne Zelle Bereich kopiert und versuchen, es in das Ziel, das eine fünfzellige Bereich ist einfügen.
Lösen Sie dies, indem Sie sicherstellen, dass Sie den gesamten Bereich des benannten Bereichs kopieren, indem Sie ihn auswählen oder indem Sie eine andere Pastenmethode verwenden aber seien Sie vorsichtig, was diese Pastenmethoden produzieren. Z.B. xlPasteAllUsingSourceTheme
wird die Zielzellen auflösen, erfüllt jedoch immer noch die angegebene Bereichsdefinition.
Ich beschuldige [Joel] (http://stackoverflow.com/users/4/joel-spolsky). – Raystafarian
Was ist die Einfügemethode, wenn Sie den Fehler 1004 erhalten? Ich habe Probleme beim Replizieren des Fehlers – Dan
@Dan den Testcode hinzugefügt – Kaz