Knowledge Base KB0070

Warum reagiert mein Excel-Makro so langsam, wenn think-cell aktiviert ist?

Eine häufige Ursache für Leistungsprobleme von VBA-Makros besteht in der Verwendung der .Select-Funktion. Jedes Mal, wenn in Excel eine Zelle markiert wird, werden sämtliche Excel-Add-Ins (einschließlich think-cell) über die Änderung der Markierung benachrichtigt, wodurch das jeweilige Makro deutlich ausgebremst wird. Vor allem Makros, die durch Makroaufzeichnung erstellt wurden, sind für dieses Problem anfällig.

Microsoft empfiehlt, die SELECT-Anweisung im VBA-Code zur Leistungssteigerung zu vermeiden:

Beispiel: Umgehung der .Select-Funktion

Betrachten wir das folgende einfache Makro AutoFillTable:

Sub AutoFillTable()
    Dim iRange As Excel.Range
    Set iRange = Application.InputBox(prompt:="Enter range", Type:=8)
    Dim nCount As Integer
    nCount = iRange.Cells.Count
    For i = 1 To nCount
        Selection.Copy
        If iRange.Cells.Item(i).Value = "" Then
            iRange.Cells.Item(i).Range("A1").Select
            ActiveSheet.Paste
        Else
            iRange.Cells.Item(i).Range("A1").Select
        End If
    Next
End Sub

Diese Funktion öffnet ein Eingabefeld an, das den Benutzer dazu auffordert, einen Zellbereich anzugeben. Die Funktion durchläuft alle Zellen dieses Bereichs. Trifft sie dabei auf eine Zelle, die nicht leer ist, kopiert sie den Inhalt der Zelle in die Zwischenablage. Die Funktion fügt den Inhalt der Zwischenablage in jede nachfolgende leere Zelle ein.

AutoFillTable verwendet die Zwischenablage, um den Zellinhalt zu kopieren. Daher muss die Funktion jede zu bearbeitende Zelle markieren, um Excel zu signalisieren, welche Zelle kopiert und in welche Zelle der Inhalt eingefügt werden soll. Die folgende Funktion AutoFillTable2 zeigt die empfohlene Lösung:

Sub AutoFillTable2()
    Dim iRange As Excel.Range
    Set iRange = Application.InputBox(prompt:="Enter range", Type:=8)
    Dim iCellMaster As Excel.Range
    For Each iCell In iRange.Cells
        If iCell.Value = "" Then
            If Not iCellMaster Is Nothing Then
                iCellMaster.Copy (iCell)
            End If
        Else
            Set iCellMaster = iCell
        End If
    Next iCell
End Sub

AutoFillTable2 unterscheidet sich in zwei wichtigen Punkten von ihrem Vorgänger:

  1. Vor allem kommt sie ohne das Markieren von Zellen aus. Wenn eine Zelle gefunden wird, die nicht leer ist, wird ihr Inhalt stattdessen in der Variable iCellMaster gespeichert. Wird anschließend eine leere Zelle gefunden, wird der gesamte Inhalt von iCellMaster in iCell kopiert.
  2. Dabei wird die Sprachfunktion For Each … Next von Visual Basic verwendet, um jede Zelle im Bereich zu besuchen. Dies verbessert bereits die Lesbarkeit.

Teilen