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
- 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) = 20ist exakt gleichbedeutend mit drei separaten Zeilen; For i = 1 To 5 ... Next idurchlä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 & ... & vbNewLinebaut eine wachsende Zeichenkette zeilenweise auf –vbNewLineist 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 = "" Thenentscheidet, welche der beidenMsgBox-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
- Kopieren Sie
CheckStockLevelsin Ihre Arbeitsmappe und führen Sie es aus. Überprüfen Sie, ob die Meldung mit dem Screenshot übereinstimmt. - Ä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.
- 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. - Herausforderung: Schreiben Sie die Schleife
For i = 1 To 5stattdessen mitFor Eachüber ein Variant-Array um — funktioniert die Logik weiterhin?
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) auf25geändert werden — Produktname und Mindestbestand bleiben unverändert. - Überlege vor dem Ausführen, welcher
Casegreifen sollte: Ist 25 ≤ 30 (der Mindestbestand)? Vergleiche dies speziell mit der ZeileCase 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.
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
Danke für Ihr Feedback!
Fragen Sie AI
Fragen Sie AI
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
- 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) = 20ist exakt gleichbedeutend mit drei separaten Zeilen; For i = 1 To 5 ... Next idurchlä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 & ... & vbNewLinebaut eine wachsende Zeichenkette zeilenweise auf –vbNewLineist 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 = "" Thenentscheidet, welche der beidenMsgBox-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
- Kopieren Sie
CheckStockLevelsin Ihre Arbeitsmappe und führen Sie es aus. Überprüfen Sie, ob die Meldung mit dem Screenshot übereinstimmt. - Ä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.
- 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. - Herausforderung: Schreiben Sie die Schleife
For i = 1 To 5stattdessen mitFor Eachüber ein Variant-Array um — funktioniert die Logik weiterhin?
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) auf25geändert werden — Produktname und Mindestbestand bleiben unverändert. - Überlege vor dem Ausführen, welcher
Casegreifen sollte: Ist 25 ≤ 30 (der Mindestbestand)? Vergleiche dies speziell mit der ZeileCase 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.
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
Danke für Ihr Feedback!