Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lernen Schleifen | VBA Fundamentals
Excel VBA für Geschäftsautomatisierung

Schleifen

Swipe um das Menü anzuzeigen

Bisherige Techniken arbeiteten immer nur mit einem Wert gleichzeitig. Schleifen ermöglichen es, dieselbe Logik auf viele Werte hintereinander anzuwenden – fünf Produkte, fünfhundert Bestellungen, beliebig viele Zeilen einer Tabelle – ohne denselben Codeblock immer wieder kopieren zu müssen.

For...Next

Wiederholt einen Codeblock eine feste, bekannte Anzahl von Malen:

Dim i As Long
For i = 1 To 5
    Debug.Print "Row " & i
Next i
 
' Step lets you skip or count backward
For i = 10 To 1 Step -1
    Debug.Print i
Next i

Im ersten Durchlauf beginnt i bei 1, der Code im Block wird einmal mit diesem Wert ausgeführt, dann erhöht sich i automatisch um 1 und der gesamte Block läuft erneut – dies wiederholt sich, bis i den Wert 5 überschreitet, woraufhin die Schleife einfach endet und die Ausführung nach Next fortgesetzt wird. Step ändert die Schrittweite: Step -1 zählt rückwärts statt standardmäßig vorwärts in Einerschritten, und Step 2 würde in Zweierschritten zählen. Die Schleifenvariable i ist keine besondere Syntax – sie ist einfach eine gewöhnliche Long-Variable, die VBA bei jedem Durchlauf automatisch aktualisiert.

For Each

Durchläuft jedes Element einer Sammlung direkt, ohne dass Sie wissen müssen, wie viele Elemente es gibt oder einen Zähler verwalten müssen:

Dim cell As Range
For Each cell In ThisWorkbook.Worksheets("Products").Range("B2:B6")
    Debug.Print cell.Value
Next cell

Hier nimmt cell nacheinander jeden einzelnen Wert im Bereich B2:B6 an, und Sie lesen den jeweiligen Inhalt mit .Value aus. Im Vergleich zu For...Next: Bei For...Next zählen Sie Zahlen durch und verwenden diese Zahl, um etwas nachzuschlagen; bei For Each gehen Sie direkt durch die Elemente selbst, was natürlicher wirkt, sobald Sie mit Zellbereichen arbeiten.

Do While

Wiederholt sich, solange eine Bedingung True bleibt – die Schleife weiß im Voraus nicht, wie oft sie ausgeführt wird, was sie von For...Next unterscheidet:

Dim stock As Integer
stock = 134
Do While stock > 0
    stock = stock - 30    ' simulate selling in batches of 30
Loop
Debug.Print stock   ' whatever's left after the loop stops

VBA prüft stock > 0 vor jedem einzelnen Durchlauf der Schleife, auch beim allerersten Mal. Verfolgen Sie es Schritt für Schritt: 134 → 104 → 74 → 44 → 14, dann wird die Bedingung erneut geprüft – 14 ist immer noch größer als 0, also läuft die Schleife noch einmal und landet bei -16. Erst dann ergibt stock > 0 den Wert False, und die Schleife endet mit stock bei -16, nicht exakt bei 0 oder 14. Dies sollte man beim ersten Mal genau nachvollziehen, da es eine häufige Quelle für Off-by-one-Fehler ist: Eine Do While-Schleife läuft so lange weiter, wie die Bedingung zum Prüfzeitpunkt erfüllt ist, auch wenn die Aktion im Inneren der Schleife über das gewünschte Ziel hinausschießt.

Do Until

Es gibt auch Do Until, das das Spiegelbild von Do While ist – es wiederholt sich, solange eine Bedingung False ist, und stoppt in dem Moment, in dem die Bedingung True wird, also genau umgekehrt. Welche Variante sich natürlicher liest, hängt davon ab, wie Sie die Geschäftsregel formulieren würden: „solange weitermachen, wie Bestand vorhanden ist“ spricht für Do While; „weitermachen, bis der Bestand aufgebraucht ist“ spricht für Do Until – beide können identisches Verhalten erzeugen, nur unterschiedlich formuliert.

Exit-Anweisungen

Ermöglichen das vorzeitige Verlassen einer Schleife, bevor die eigentliche Endbedingung erreicht ist:

For i = 1 To 100
    If i = 10 Then Exit For   ' stop the loop immediately
    Debug.Print i
Next i

Diese Schleife ist darauf ausgelegt, bis 100 zu zählen, aber sobald i den Wert 10 erreicht, beendet Exit For sie sofort – alles nach Exit For wird nicht mehr ausgeführt, und die Ausführung springt direkt zur Zeile nach Next i. Dieses Muster wird verwendet, um eine Liste zu durchsuchen und sofort zu stoppen, sobald das Gesuchte gefunden wurde, anstatt unnötig alle verbleibenden Elemente weiter zu prüfen.

Zusammenspiel der Techniken

Alle Techniken aus diesem Kapitel – Variablen, Operatoren, Funktionen, bedingte Logik und jetzt Schleifen – werden in der Prozedur kombiniert, auf die dieses Kapitel hingearbeitet hat:

Option Explicit
 
Sub CheckStockLevels()
 
    ' Sample data standing in for the Products table
    Dim products(1 To 5) As String
    Dim stockLevels(1 To 5) As Integer
    Dim reorderLevels(1 To 5) As Integer
    Dim i As Long
    Dim alertMessage As String
 
    products(1) = "Laptop Stand": stockLevels(1) = 58: reorderLevels(1) = 20
    products(2) = "Wireless Mouse": stockLevels(2) = 134: reorderLevels(2) = 30
    products(3) = "USB-C Hub": stockLevels(3) = 44: reorderLevels(3) = 15
    products(4) = "Monitor Arm": stockLevels(4) = 18: reorderLevels(4) = 10
    products(5) = "Keyboard": stockLevels(5) = 61: reorderLevels(5) = 20
 
    alertMessage = ""
 
    For i = 1 To 5
        Select Case stockLevels(i)
            Case Is <= reorderLevels(i)
                alertMessage = alertMessage & products(i) & _
                    " — REORDER NOW" & vbNewLine
            Case Is <= reorderLevels(i) + 10
                alertMessage = alertMessage & products(i) & _
                    " — watch closely" & vbNewLine
        End Select
    Next i
 
    If alertMessage = "" Then
        MsgBox "All products are adequately stocked."
    Else
        MsgBox "Stock Alerts:" & vbNewLine & alertMessage
    End If
End Sub
Zeile für Zeile durchgehen
expand arrow
  • Dim products(1 To 5) As String und die beiden ähnlichen Zeilen darunter deklarieren Arrays – jeweils eine nummerierte Reihe von fünf Feldern statt eines einzelnen Feldes, sodass products(1) der Name des ersten Produkts ist, products(2) das zweite usw.;
  • Die fünf Zeilen mit Doppelpunkt (:) zwischen den Anweisungen fassen mehrere Zuweisungen aus Gründen der Lesbarkeit auf eine Zeile zusammen – products(1) = "Laptop Stand": stockLevels(1) = 58: reorderLevels(1) = 20 ist exakt gleichbedeutend mit drei separaten Zeilen;
  • For i = 1 To 5 ... Next i durchläuft alle fünf Produkte nacheinander, wobei i sowohl als Schleifenzähler als auch als Index für jedes Array dient;
  • Select Case stockLevels(i) wiederholt die gleiche bereichsbasierte Entscheidung aus Abschnitt 2.4, jetzt aber mit echten Arraydaten statt einer einzelnen fest codierten Zahl;
  • Case Is <= reorderLevels(i) erfasst jedes Produkt, dessen Bestand auf oder unter seinen eigenen Nachbestellwert gefallen ist – beachten Sie, dass reorderLevels(i) selbst eine Variable ist, keine feste Zahl, sodass jedes Produkt an seinem eigenen Schwellenwert gemessen wird und nicht alle an einem gemeinsamen;
  • alertMessage = alertMessage & ... & vbNewLine baut eine wachsende Zeichenkette zeilenweise auf – vbNewLine ist eine eingebaute Konstante, die einen Zeilenumbruch einfügt, sodass jedes markierte Produkt in der endgültigen Nachricht in einer eigenen Zeile erscheint;
  • Die abschließende Prüfung If alertMessage = "" Then entscheidet, welche der beiden MsgBox-Varianten der Benutzer tatsächlich sieht – ein leerer String bedeutet, dass die Schleife nichts zum Markieren gefunden hat.

Führen Sie dies aus und Sie sollten sehen, dass der Monitorarm als "genau beobachten" markiert wird (18 Einheiten gegenüber einem Mindestbestand von 10) — verfolgen Sie die Schleife für i = 4 von Hand, wenn Sie genau nachvollziehen möchten, warum nur dieses Element vom zweiten Case und nicht vom ersten erfasst wird. Diese Prozedur verwendet Arrays, eine Schleife, eine Select Case-Anweisung und Zeichenkettenaufbau, die alle zusammenarbeiten. Das ist bereits sehr nah an produktionsreifer Logik, nur dass sie mit Beispieldaten arbeitet, die direkt in den Code eingegeben wurden, anstatt mit einem echten Arbeitsblatt.

Aufgabe

  1. Kopieren Sie CheckStockLevels in Ihre Arbeitsmappe und führen Sie es aus. Überprüfen Sie, ob die Meldung mit dem Screenshot übereinstimmt.
  2. Ändern Sie den Lagerbestand der Wireless Mouse auf 25 und führen Sie das Makro erneut aus — sie sollte jetzt ebenfalls als "genau beobachten" angezeigt werden.
  3. Fügen Sie darunter eine Do While-Schleife ein, die simuliert, dass jeweils 15 Einheiten des Laptopständers verkauft werden, bis der Bestand auf 20 oder weniger fällt. Geben Sie nach jedem Verkauf den aktuellen Bestand im Direktfenster aus.
  4. Herausforderung: Schreiben Sie die Schleife For i = 1 To 5 stattdessen mit For Each über ein Variant-Array um — funktioniert die Logik weiterhin?
Hinweis
expand arrow

2. Ändern des Lagerbestands der Wireless Mouse

  • Suche die Zeile, die die Daten der Wireless Mouse festlegt: products(2) = "Wireless Mouse": stockLevels(2) = 134: reorderLevels(2) = 30.
  • Es muss nur die mittlere Zahl (134) auf 25 geändert werden — Produktname und Mindestbestand bleiben unverändert.
  • Überlege vor dem Ausführen, welcher Case greifen sollte: Ist 25 ≤ 30 (der Mindestbestand)? Vergleiche dies speziell mit der Zeile Case Is <= reorderLevels(i), nicht mit der zweiten.

3. Simulation von Sammelverkäufen mit Do While

  • Es wird eine Variable benötigt, die den aktuellen Lagerbestand des Laptop Stand hält — starte sie mit dem Wert, der bereits in stockLevels(1) (58) steht, damit keine neue Zahl eingegeben wird, die vom Rest des Makros abweichen könnte.
  • Die Schleifenbedingung soll prüfen, ob der Bestand noch über 20 liegt — sobald geprüft wird und der Bestand 20 oder weniger beträgt, soll die Schleife enden.
  • Ziehe bei jedem Durchlauf 15 ab und gib den neuen Wert direkt nach dem Abziehen aus — nicht davor —, damit jede ausgegebene Zahl einen abgeschlossenen Verkauf widerspiegelt.
  • Zeichne es zuerst auf Papier nach: 58 → 43 → 28 → 13. Beachte, dass der letzte Wert unter 20 fällt und nicht genau darauf landet — das ist das gleiche Do While-Überschreitungsverhalten, das im Schleifendiagramm des Kapitels zuvor erläutert wurde, kein Fehler.
Lösung
expand arrow

Punkt 2 — innerhalb von CheckStockLevels einfach eine Zahl ändern:

products(2) = "Wireless Mouse": stockLevels(2) = 25: reorderLevels(2) = 30

Führe das Sub erneut aus.

Punkt 3 — füge dies unterhalb des bestehenden Codes ein, weiterhin innerhalb von CheckStockLevels (vor End Sub):

    ' --- Simulate selling Laptop Stand in batches of 15 ---
    Dim laptopStandStock As Integer
    laptopStandStock = stockLevels(1)

    Do While laptopStandStock > 20
        laptopStandStock = laptopStandStock - 15
        Debug.Print laptopStandStock
    Loop
War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 2. Kapitel 5

Fragen Sie AI

expand

Fragen Sie AI

ChatGPT

Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen

Schleifen

Bisherige Techniken arbeiteten immer nur mit einem Wert gleichzeitig. Schleifen ermöglichen es, dieselbe Logik auf viele Werte hintereinander anzuwenden – fünf Produkte, fünfhundert Bestellungen, beliebig viele Zeilen einer Tabelle – ohne denselben Codeblock immer wieder kopieren zu müssen.

For...Next

Wiederholt einen Codeblock eine feste, bekannte Anzahl von Malen:

Dim i As Long
For i = 1 To 5
    Debug.Print "Row " & i
Next i
 
' Step lets you skip or count backward
For i = 10 To 1 Step -1
    Debug.Print i
Next i

Im ersten Durchlauf beginnt i bei 1, der Code im Block wird einmal mit diesem Wert ausgeführt, dann erhöht sich i automatisch um 1 und der gesamte Block läuft erneut – dies wiederholt sich, bis i den Wert 5 überschreitet, woraufhin die Schleife einfach endet und die Ausführung nach Next fortgesetzt wird. Step ändert die Schrittweite: Step -1 zählt rückwärts statt standardmäßig vorwärts in Einerschritten, und Step 2 würde in Zweierschritten zählen. Die Schleifenvariable i ist keine besondere Syntax – sie ist einfach eine gewöhnliche Long-Variable, die VBA bei jedem Durchlauf automatisch aktualisiert.

For Each

Durchläuft jedes Element einer Sammlung direkt, ohne dass Sie wissen müssen, wie viele Elemente es gibt oder einen Zähler verwalten müssen:

Dim cell As Range
For Each cell In ThisWorkbook.Worksheets("Products").Range("B2:B6")
    Debug.Print cell.Value
Next cell

Hier nimmt cell nacheinander jeden einzelnen Wert im Bereich B2:B6 an, und Sie lesen den jeweiligen Inhalt mit .Value aus. Im Vergleich zu For...Next: Bei For...Next zählen Sie Zahlen durch und verwenden diese Zahl, um etwas nachzuschlagen; bei For Each gehen Sie direkt durch die Elemente selbst, was natürlicher wirkt, sobald Sie mit Zellbereichen arbeiten.

Do While

Wiederholt sich, solange eine Bedingung True bleibt – die Schleife weiß im Voraus nicht, wie oft sie ausgeführt wird, was sie von For...Next unterscheidet:

Dim stock As Integer
stock = 134
Do While stock > 0
    stock = stock - 30    ' simulate selling in batches of 30
Loop
Debug.Print stock   ' whatever's left after the loop stops

VBA prüft stock > 0 vor jedem einzelnen Durchlauf der Schleife, auch beim allerersten Mal. Verfolgen Sie es Schritt für Schritt: 134 → 104 → 74 → 44 → 14, dann wird die Bedingung erneut geprüft – 14 ist immer noch größer als 0, also läuft die Schleife noch einmal und landet bei -16. Erst dann ergibt stock > 0 den Wert False, und die Schleife endet mit stock bei -16, nicht exakt bei 0 oder 14. Dies sollte man beim ersten Mal genau nachvollziehen, da es eine häufige Quelle für Off-by-one-Fehler ist: Eine Do While-Schleife läuft so lange weiter, wie die Bedingung zum Prüfzeitpunkt erfüllt ist, auch wenn die Aktion im Inneren der Schleife über das gewünschte Ziel hinausschießt.

Do Until

Es gibt auch Do Until, das das Spiegelbild von Do While ist – es wiederholt sich, solange eine Bedingung False ist, und stoppt in dem Moment, in dem die Bedingung True wird, also genau umgekehrt. Welche Variante sich natürlicher liest, hängt davon ab, wie Sie die Geschäftsregel formulieren würden: „solange weitermachen, wie Bestand vorhanden ist“ spricht für Do While; „weitermachen, bis der Bestand aufgebraucht ist“ spricht für Do Until – beide können identisches Verhalten erzeugen, nur unterschiedlich formuliert.

Exit-Anweisungen

Ermöglichen das vorzeitige Verlassen einer Schleife, bevor die eigentliche Endbedingung erreicht ist:

For i = 1 To 100
    If i = 10 Then Exit For   ' stop the loop immediately
    Debug.Print i
Next i

Diese Schleife ist darauf ausgelegt, bis 100 zu zählen, aber sobald i den Wert 10 erreicht, beendet Exit For sie sofort – alles nach Exit For wird nicht mehr ausgeführt, und die Ausführung springt direkt zur Zeile nach Next i. Dieses Muster wird verwendet, um eine Liste zu durchsuchen und sofort zu stoppen, sobald das Gesuchte gefunden wurde, anstatt unnötig alle verbleibenden Elemente weiter zu prüfen.

Zusammenspiel der Techniken

Alle Techniken aus diesem Kapitel – Variablen, Operatoren, Funktionen, bedingte Logik und jetzt Schleifen – werden in der Prozedur kombiniert, auf die dieses Kapitel hingearbeitet hat:

Option Explicit
 
Sub CheckStockLevels()
 
    ' Sample data standing in for the Products table
    Dim products(1 To 5) As String
    Dim stockLevels(1 To 5) As Integer
    Dim reorderLevels(1 To 5) As Integer
    Dim i As Long
    Dim alertMessage As String
 
    products(1) = "Laptop Stand": stockLevels(1) = 58: reorderLevels(1) = 20
    products(2) = "Wireless Mouse": stockLevels(2) = 134: reorderLevels(2) = 30
    products(3) = "USB-C Hub": stockLevels(3) = 44: reorderLevels(3) = 15
    products(4) = "Monitor Arm": stockLevels(4) = 18: reorderLevels(4) = 10
    products(5) = "Keyboard": stockLevels(5) = 61: reorderLevels(5) = 20
 
    alertMessage = ""
 
    For i = 1 To 5
        Select Case stockLevels(i)
            Case Is <= reorderLevels(i)
                alertMessage = alertMessage & products(i) & _
                    " — REORDER NOW" & vbNewLine
            Case Is <= reorderLevels(i) + 10
                alertMessage = alertMessage & products(i) & _
                    " — watch closely" & vbNewLine
        End Select
    Next i
 
    If alertMessage = "" Then
        MsgBox "All products are adequately stocked."
    Else
        MsgBox "Stock Alerts:" & vbNewLine & alertMessage
    End If
End Sub
Zeile für Zeile durchgehen
expand arrow
  • Dim products(1 To 5) As String und die beiden ähnlichen Zeilen darunter deklarieren Arrays – jeweils eine nummerierte Reihe von fünf Feldern statt eines einzelnen Feldes, sodass products(1) der Name des ersten Produkts ist, products(2) das zweite usw.;
  • Die fünf Zeilen mit Doppelpunkt (:) zwischen den Anweisungen fassen mehrere Zuweisungen aus Gründen der Lesbarkeit auf eine Zeile zusammen – products(1) = "Laptop Stand": stockLevels(1) = 58: reorderLevels(1) = 20 ist exakt gleichbedeutend mit drei separaten Zeilen;
  • For i = 1 To 5 ... Next i durchläuft alle fünf Produkte nacheinander, wobei i sowohl als Schleifenzähler als auch als Index für jedes Array dient;
  • Select Case stockLevels(i) wiederholt die gleiche bereichsbasierte Entscheidung aus Abschnitt 2.4, jetzt aber mit echten Arraydaten statt einer einzelnen fest codierten Zahl;
  • Case Is <= reorderLevels(i) erfasst jedes Produkt, dessen Bestand auf oder unter seinen eigenen Nachbestellwert gefallen ist – beachten Sie, dass reorderLevels(i) selbst eine Variable ist, keine feste Zahl, sodass jedes Produkt an seinem eigenen Schwellenwert gemessen wird und nicht alle an einem gemeinsamen;
  • alertMessage = alertMessage & ... & vbNewLine baut eine wachsende Zeichenkette zeilenweise auf – vbNewLine ist eine eingebaute Konstante, die einen Zeilenumbruch einfügt, sodass jedes markierte Produkt in der endgültigen Nachricht in einer eigenen Zeile erscheint;
  • Die abschließende Prüfung If alertMessage = "" Then entscheidet, welche der beiden MsgBox-Varianten der Benutzer tatsächlich sieht – ein leerer String bedeutet, dass die Schleife nichts zum Markieren gefunden hat.

Führen Sie dies aus und Sie sollten sehen, dass der Monitorarm als "genau beobachten" markiert wird (18 Einheiten gegenüber einem Mindestbestand von 10) — verfolgen Sie die Schleife für i = 4 von Hand, wenn Sie genau nachvollziehen möchten, warum nur dieses Element vom zweiten Case und nicht vom ersten erfasst wird. Diese Prozedur verwendet Arrays, eine Schleife, eine Select Case-Anweisung und Zeichenkettenaufbau, die alle zusammenarbeiten. Das ist bereits sehr nah an produktionsreifer Logik, nur dass sie mit Beispieldaten arbeitet, die direkt in den Code eingegeben wurden, anstatt mit einem echten Arbeitsblatt.

Aufgabe

  1. Kopieren Sie CheckStockLevels in Ihre Arbeitsmappe und führen Sie es aus. Überprüfen Sie, ob die Meldung mit dem Screenshot übereinstimmt.
  2. Ändern Sie den Lagerbestand der Wireless Mouse auf 25 und führen Sie das Makro erneut aus — sie sollte jetzt ebenfalls als "genau beobachten" angezeigt werden.
  3. Fügen Sie darunter eine Do While-Schleife ein, die simuliert, dass jeweils 15 Einheiten des Laptopständers verkauft werden, bis der Bestand auf 20 oder weniger fällt. Geben Sie nach jedem Verkauf den aktuellen Bestand im Direktfenster aus.
  4. Herausforderung: Schreiben Sie die Schleife For i = 1 To 5 stattdessen mit For Each über ein Variant-Array um — funktioniert die Logik weiterhin?
Hinweis
expand arrow

2. Ändern des Lagerbestands der Wireless Mouse

  • Suche die Zeile, die die Daten der Wireless Mouse festlegt: products(2) = "Wireless Mouse": stockLevels(2) = 134: reorderLevels(2) = 30.
  • Es muss nur die mittlere Zahl (134) auf 25 geändert werden — Produktname und Mindestbestand bleiben unverändert.
  • Überlege vor dem Ausführen, welcher Case greifen sollte: Ist 25 ≤ 30 (der Mindestbestand)? Vergleiche dies speziell mit der Zeile Case Is <= reorderLevels(i), nicht mit der zweiten.

3. Simulation von Sammelverkäufen mit Do While

  • Es wird eine Variable benötigt, die den aktuellen Lagerbestand des Laptop Stand hält — starte sie mit dem Wert, der bereits in stockLevels(1) (58) steht, damit keine neue Zahl eingegeben wird, die vom Rest des Makros abweichen könnte.
  • Die Schleifenbedingung soll prüfen, ob der Bestand noch über 20 liegt — sobald geprüft wird und der Bestand 20 oder weniger beträgt, soll die Schleife enden.
  • Ziehe bei jedem Durchlauf 15 ab und gib den neuen Wert direkt nach dem Abziehen aus — nicht davor —, damit jede ausgegebene Zahl einen abgeschlossenen Verkauf widerspiegelt.
  • Zeichne es zuerst auf Papier nach: 58 → 43 → 28 → 13. Beachte, dass der letzte Wert unter 20 fällt und nicht genau darauf landet — das ist das gleiche Do While-Überschreitungsverhalten, das im Schleifendiagramm des Kapitels zuvor erläutert wurde, kein Fehler.
Lösung
expand arrow

Punkt 2 — innerhalb von CheckStockLevels einfach eine Zahl ändern:

products(2) = "Wireless Mouse": stockLevels(2) = 25: reorderLevels(2) = 30

Führe das Sub erneut aus.

Punkt 3 — füge dies unterhalb des bestehenden Codes ein, weiterhin innerhalb von CheckStockLevels (vor End Sub):

    ' --- Simulate selling Laptop Stand in batches of 15 ---
    Dim laptopStandStock As Integer
    laptopStandStock = stockLevels(1)

    Do While laptopStandStock > 20
        laptopStandStock = laptopStandStock - 15
        Debug.Print laptopStandStock
    Loop
War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 2. Kapitel 5
some-alt