In diesem Beitrag möchte ich Ihnen einen Überblick über verschiedene Arten von VBA-Schleifen und den daraus resultierenden Durchlaufgeschwindigkeiten geben.
Die Testdatei enthält dazu in Spalte A 2000 Zahlen und die gleiche Menge in Spalte B. Ziel der Testumgebung ist, Duplikate, also gleiche Ziffern von Spalte A in Spalte B zu finden und über den Befehl debug.print im Direktfenster der VBA-Umgebung auszugeben.
Die folgende Abbildung zeigt die ersten Zeilen der Testdatei mit den entsprechenden Ergebnissen.
Der Geschwindigkeitstest untersucht drei verschiedene For-Next-Schleifendurchläufe, welche im Folgenden kurz erläutert werden:
Variante 1: For-Next-Schleife mit direktem Verweis auf die Spalten- und Zeilennummern
Diese Variante verwendet die direkte Referenzierung der Zeilennummern, indem in der For-Next-Schleife die Start- und End-Zeilennummer angegeben wurde, siehe entsprechenden VBA-Code:
Sub for_next_Zellen()
'** doppelte Werte über for-Next-Schleife ermitteln
Set wsakt = ThisWorkbook.Sheets(1)
wsakt.Range("D3").Value = Time
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
For a = 1 To 2000
'** Wert aus Spalte 1 auslesen
wert1 = wsakt.Cells(a, 1).Value
For b = 1 To 2000
'** Prüfen, ob wert aus Spalte 1 mit dem Wert aus Spalte 2 übereinstimmt und ausgeben
If wsakt.Cells(b, 2).Value = wert1 Then
Debug.Print wert1
End If
Next b
Next a
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
wsakt.Range("D4").Value = Time
End Sub
Variante 2: For-Each-Next-Schleife mit direktem Verweis auf die Spalten- und Zeilennummern
Die zweite Variante verwendet anstatt der direkten Zeilenreferenzierung zwei Bereichsnamen, welche zuvor definiert wurden. Dem Namen bereich1 wurde der Zellbereich A1:A2000 und dem Namen bereich2 der Zellbezug B1:B2000 zugewiesen. Um die Bereichsnamen zu durchlaufen kommt das Konstrukt der For-Each-Next-Schleife zum Einsatz, siehe folgenden VBA-Code:
Sub for_each_Bereich()
'** doppelte Werte über for-Next-Schleife mit Bereichsnamen ermitteln
Set wsakt = ThisWorkbook.Sheets(1)
wsakt.Range("D11").Value = Time
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
For Each zelle1 In Range("bereich1")
'** Wert aus Spalte 1 auslesen
wert1 = wsakt.Cells(zelle1, 1).Value
For Each zelle2 In Range("bereich2")
'** Prüfen, ob wert aus Spalte 1 mit dem Wert aus Spalte 2 übereinstimmt und ausgeben
If wsakt.Cells(zelle2, 2).Value = wert1 Then
Debug.Print wert1
End If
Next zelle2
Next zelle1
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
wsakt.Range("D12").Value = Time
End Sub
Variante 3: For-Next-Schleife unter Verwendung von Array-Variablen
In der dritten Variante wurden die Werte aus dem Bereich A1:A2000 und B1:B2000 zunächst in eine 2-dimensionalte Array-Variable eingelesen. Mit Hilfe der For-Next-Schleife wurde dann der Inhalt der 1. Dimension mit dem Inhalt der 2. Dimension der Array-Variable verglichen und auf diese Weise die Duplikate ermittelt, siehe folgenden VBA-Code:
Sub for_next_Array()
'** doppelte Werte über for-Next-Schleife mit Array-Variable ermitteln
Set wsakt = ThisWorkbook.Sheets(1)
Dim wert(2000, 2)
wsakt.Range("D19").Value = Time
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
For a = 1 To 2000
wert(a, 1) = wsakt.Cells(a, 1).Value
wert(a, 2) = wsakt.Cells(a, 2).Value
Next a
For a = 1 To 2000
For b = 1 To 2000
'** Prüfen, ob wert aus Spalte 1 mit dem Wert aus Spalte 2 übereinstimmt und ausgeben
If wert(a, 1) = wert(b, 2) Then
Debug.Print wert(a, 1)
End If
Next b
Next a
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
wsakt.Range("D20").Value = Time
End Sub
Testergebnisse
Die folgende Tabelle zeigt die Programmlaufzeiten der drei Varianten:
Variane | Laufzeit in Sekunden |
Variante 1 | 33 Sekunden |
Variante 2 | 44 Sekunden |
Variante 3 | < 1 Sekunde |
Wie nicht anders zu erwarten war, ist die Variante mit Verwendung der Array-Variablen die schnellst. Dass der Vergleich aber in nur einem kleinen Bruchteil der notwendigen Zeit der anderen Varianten erfolgt, war dann doch etwas überraschend.
Wie dieser Test zeigt, empfiehlt sich gerade beim Durchlaufen vieler Zellen der Einsatz von Array-Variablen. Wie vielleicht vermutet bringt der Einsatz von Bereichsnamen in diesem Zusammenhang keinen Geschwindigkeitsvorteil, das Gegenteil ist der Fall.
Die Beispieldatei mit den drei verschiednen Test-Durchläufen können Sie über den nachfolgenden Link herunterladen.