Suche…


Qualifizierende Referenzen

Wenn Sie sich auf ein worksheet , einen range oder einzelne cells beziehen, ist es wichtig, die Referenz vollständig zu qualifizieren.

Zum Beispiel:

ThisWorkbook.Worksheets("Sheet1").Range(Cells(1, 2), Cells(2, 3)).Copy

Ist nicht vollständig qualifiziert: Den Cells sind keine Arbeitsmappe und kein Arbeitsblatt zugeordnet. Ohne explizite Referenz verweist Cells standardmäßig auf das ActiveSheet . Daher Sheet1 dieser Code fehl (falsche Ergebnisse), wenn ein anderes Arbeitsblatt als Sheet1 das aktuelle ActiveSheet .

Die einfachste Möglichkeit, dies zu korrigieren, besteht darin, eine With Anweisung wie folgt zu verwenden:

With ThisWorkbook.Worksheets("Sheet1")
    .Range(.Cells(1, 2), .Cells(2, 3)).Copy
End With

Alternativ können Sie eine Arbeitsblattvariable verwenden. (Diese Methode wird höchstwahrscheinlich bevorzugt, wenn Ihr Code auf mehrere Arbeitsblätter verweisen muss, z. B. das Kopieren von Daten von einem Arbeitsblatt auf ein anderes.)

Dim ws1 As Worksheet
Set ws1 = ThisWorkbook.Worksheets("Sheet1")
ws1.Range(ws1.Cells(1, 2), ws1.Cells(2, 3)).Copy

Ein weiteres häufiges Problem besteht darin, auf die Worksheets-Auflistung zu verweisen, ohne die Arbeitsmappe zu qualifizieren. Zum Beispiel:

Worksheets("Sheet1").Copy

Das Arbeitsblatt Sheet1 ist nicht vollständig qualifiziert und es fehlt eine Arbeitsmappe. Dies kann fehlschlagen, wenn auf mehrere Arbeitsmappen im Code verwiesen wird. Verwenden Sie stattdessen eine der folgenden Möglichkeiten:

ThisWorkbook.Worksheets("Sheet1")       '<--ThisWorkbook refers to the workbook containing 
                                        'the running VBA code
Workbooks("Book1").Worksheets("Sheet1") '<--Where Book1 is the workbook containing Sheet1

Vermeiden Sie jedoch Folgendes:

ActiveWorkbook.Worksheets("Sheet1")     '<--Valid, but if another workbook is activated
                                        'the reference will be changed

Ähnliches gilt für range Objekte, wenn nicht ausdrücklich qualifiziert, der range wird auf das aktuell aktive Blatt verweisen:

Range("a1")

Ist das gleiche wie:

ActiveSheet.Range("a1")

Zeilen oder Spalten in einer Schleife löschen

Wenn Sie Zeilen (oder Spalten) in einer Schleife löschen möchten, sollten Sie die Schleife immer am Ende des Bereichs beginnen und in jedem Schritt zurückgehen. Bei Verwendung des Codes:

Dim i As Long
With Workbooks("Book1").Worksheets("Sheet1")
    For i = 1 To 4
        If IsEmpty(.Cells(i, 1)) Then .Rows(i).Delete
    Next i
End With

Sie werden einige Reihen vermissen. Wenn der Code beispielsweise Zeile 3 löscht, wird Zeile 4 zu Zeile 3. Die Variable i ändert sich jedoch zu 4. In diesem Fall wird der Code eine Zeile übersehen und eine andere Zeile überprüfen, die zuvor nicht in Reichweite war.

Der richtige Code wäre

Dim i As Long
With Workbooks("Book1").Worksheets("Sheet1")
    For i = 4 To 1 Step -1
        If IsEmpty(.Cells(i, 1)) Then .Rows(i).Delete
    Next i
End With

ActiveWorkbook vs. ThisWorkbook

ActiveWorkbook und ThisWorkbook werden von neuen VBA-Benutzern manchmal austauschbar verwendet, ohne zu ThisWorkbook , worauf sich jedes Objekt bezieht. Beide Objekte gehören zum Anwendungsobjekt


Das ActiveWorkbook Objekt verweist auf die Arbeitsmappe, die sich zum Zeitpunkt der Ausführung derzeit in der obersten Ansicht des Excel-Anwendungsobjekts befindet. (zB die Arbeitsmappe, mit der Sie an dem Punkt sehen und interagieren können, an dem auf dieses Objekt verwiesen wird)

Sub ActiveWorkbookExample()

'// Let's assume that 'Other Workbook.xlsx' has "Bar" written in A1.

    ActiveWorkbook.ActiveSheet.Range("A1").Value = "Foo"
    Debug.Print ActiveWorkbook.ActiveSheet.Range("A1").Value '// Prints "Foo"

    Workbooks.Open("C:\Users\BloggsJ\Other Workbook.xlsx")
    Debug.Print ActiveWorkbook.ActiveSheet.Range("A1").Value '// Prints "Bar"

    Workbooks.Add 1
    Debug.Print ActiveWorkbook.ActiveSheet.Range("A1").Value '// Prints nothing

End Sub

Das ThisWorkbook Objekt verweist auf die Arbeitsmappe, zu der der Code zum Zeitpunkt der Ausführung gehört.

Sub ThisWorkbookExample()

'// Let's assume to begin that this code is in the same workbook that is currently active

    ActiveWorkbook.Sheet1.Range("A1").Value = "Foo"
    Workbooks.Add 1
    ActiveWorkbook.ActiveSheet.Range("A1").Value = "Bar"

    Debug.Print ActiveWorkbook.ActiveSheet.Range("A1").Value '// Prints "Bar"
    Debug.Print ThisWorkbook.Sheet1.Range("A1").Value '// Prints "Foo"

End Sub

Schnittstelle für ein Dokument vs. mehrere Dokumentschnittstellen

Beachten Sie, dass Microsoft Excel 2013 (und höher) Single Document Interface (SDI) und Excel 2010 (und darunter) Multiple Document Interfaces (MDI) verwenden.

Dies impliziert, dass für Excel 2013 (SDI) jede Arbeitsmappe in einer einzelnen Instanz von Excel eine eigene Menübandoberfläche enthält:

Geben Sie hier die Bildbeschreibung ein

Im Gegensatz dazu wurde für Excel 2010 für jede Arbeitsmappe in einer einzelnen Instanz von Excel eine gemeinsame Ribbon-Benutzeroberfläche (MDI) verwendet: Geben Sie hier die Bildbeschreibung ein

Dies wirft einige wichtige Probleme auf, wenn Sie einen VBA-Code (2010 <-> 2013) migrieren möchten, der mit der Multifunktionsleiste interagiert.

Es muss eine Prozedur erstellt werden, um die Ribbon-UI-Steuerelemente in allen Arbeitsmappen für Excel 2013 und höher im gleichen Status zu aktualisieren.

Beachten Sie, dass :

  1. Alle Fenstermethoden, Ereignisse und Eigenschaften auf Excel-Anwendungsebene bleiben davon unberührt. ( Application.ActiveWindow , Application.Windows ...)
  2. In Excel 2013 und höher (SDI) werden jetzt alle Methoden, Ereignisse und Eigenschaften der Arbeitsmappen auf Fenstern der obersten Ebene ausgeführt. Das Handle dieses obersten Fensters kann mit Application.Hwnd abgerufen werden

Weitere Informationen finden Sie in der Quelle dieses Beispiels: MSDN .

Dies verursacht auch einige Probleme mit modelllosen Benutzerformularen. Hier finden Sie eine Lösung.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow