Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Leer Lussen | VBA Fundamentals
Excel VBA voor Bedrijfsautomatisering

Lussen

Veeg om het menu te tonen

Elke techniek tot nu toe werkte met één waarde tegelijk. Lussen zijn de manier om dezelfde logica toe te passen op meerdere waarden achter elkaar — vijf producten, vijfhonderd bestellingen, of hoeveel rijen een tabel ook bevat — zonder steeds hetzelfde codeblok te kopiëren en plakken.

For...Next

Herhaalt een codeblok een vast, bekend aantal keren:

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

In de eerste lus begint i bij 1, de code binnenin draait één keer met die waarde, daarna verhoogt i automatisch met 1 en het hele blok draait opnieuw — dit herhaalt tot i voorbij 5 is, waarna de lus stopt en de uitvoering verdergaat na Next. Step verandert de stapgrootte: Step -1 telt omlaag in plaats van standaard omhoog met 1, en Step 2 telt met stappen van twee. De lusvariabele i is geen speciale syntaxis — het is gewoon een gewone Long-variabele die VBA bij elke herhaling voor je bijwerkt.

For Each

Doorloopt direct elk item in een collectie, zonder dat je hoeft te weten hoeveel items er zijn of zelf een teller hoeft bij te houden:

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

Hier neemt cell telkens één individuele cel in het bereik B2:B6 aan, en je leest de inhoud uit met .Value. Vergelijk dit met For...Next: bij For...Next tel je door getallen en gebruik je dat getal om iets op te zoeken; bij For Each loop je direct door de items zelf, wat natuurlijker leest zodra je met werkbladbereiken werkt.

Do While

Herhaalt zolang een conditie True blijft — de lus weet vooraf niet hoe vaak hij zal draaien, wat verschilt van For...Next:

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 controleert stock > 0 voor elke herhaling van de lus, ook de allereerste keer. Volg het stap voor stap: 134 → 104 → 74 → 44 → 14, en dan wordt de conditie opnieuw gecontroleerd — 14 is nog steeds groter dan 0, dus de lus draait nog een keer en komt uit op -16. Pas dan wordt stock > 0 eindelijk False, en stopt de lus met stock op -16, niet netjes op 0 of 14. Dit is de moeite waard om goed na te lopen, want het is een veelvoorkomende bron van off-by-one verrassingen: een Do While-lus blijft draaien zolang de conditie geldt op het moment dat hij wordt gecontroleerd, zelfs als de actie binnen de lus voorbij de grens schiet die je in gedachten had.

Do Until

Er is ook Do Until, het spiegelbeeld van Do While — deze herhaalt zolang een conditie False is en stopt zodra die conditie True wordt, in plaats van andersom. Welke natuurlijker leest hangt af van hoe je de bedrijfsregel hardop zou formuleren: "doorgaan zolang er voorraad is" suggereert Do While; "doorgaan tot de voorraad op is" suggereert Do Until — ze kunnen identiek gedrag opleveren, alleen anders geformuleerd.

Exit Statements

Hiermee kun je een lus vroegtijdig verlaten, voordat de natuurlijke eindconditie is bereikt:

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

Deze lus is opgezet om tot 100 te tellen, maar zodra i de waarde 10 bereikt, stopt Exit For hem direct — niets na Exit For wordt uitgevoerd, en de uitvoering springt meteen naar de regel na Next i. Dit patroon gebruik je om een lijst te doorzoeken en te stoppen zodra je gevonden hebt wat je zoekt, in plaats van onnodig alle resterende items te blijven controleren.

Alles samenbrengen

Elke techniek uit dit hoofdstuk — variabelen, operatoren, functies, conditionele logica en nu lussen — komt samen in de procedure waar dit hoofdstuk naartoe heeft gewerkt:

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
Regel voor regel doorlopen
expand arrow
  • Dim products(1 To 5) As String en de twee vergelijkbare regels eronder declareren arrays — elk een genummerde rij van vijf vakjes in plaats van één vakje, dus products(1) is de naam van het eerste product, products(2) het tweede, enzovoort;
  • De vijf regels met een dubbele punt (:) tussen statements plaatsen meerdere toewijzingen op één regel puur voor de leesbaarheid — products(1) = "Laptop Stand": stockLevels(1) = 58: reorderLevels(1) = 20 is exact gelijk aan het schrijven van deze als drie aparte regels;
  • For i = 1 To 5 ... Next i loopt alle vijf producten één voor één door, waarbij i zowel als lus-teller als index in elke array wordt gebruikt;
  • Select Case stockLevels(i) voert dezelfde bereik-gebaseerde beslissing uit als in sectie 2.4, maar nu op echte arraydata in plaats van één hardgecodeerd getal;
  • Case Is <= reorderLevels(i) vangt elk product waarvan de voorraad op of onder het eigen bestelniveau is gekomen — let op, reorderLevels(i) is zelf een variabele, geen vast getal, dus elk product wordt beoordeeld op zijn eigen drempel in plaats van één drempel voor iedereen;
  • alertMessage = alertMessage & ... & vbNewLine bouwt een groeiende string op, regel voor regel — vbNewLine is een ingebouwde constante die een regeleinde invoegt, zodat elk gemarkeerd product op een eigen regel in het eindbericht verschijnt;
  • De laatste If alertMessage = "" Then-controle bepaalt welke van de twee MsgBox-varianten de gebruiker daadwerkelijk ziet — een lege string betekent dat de lus niets heeft gevonden dat gemarkeerd moest worden.

Voer dit uit en je zou moeten zien dat de Monitor Arm wordt gemarkeerd als "nauwlettend volgen" (18 stuks tegenover een herbestelniveau van 10) — loop handmatig door de lus voor i = 4 als je precies wilt bevestigen waarom dit de enige is die door de tweede Case wordt opgepikt en niet door de eerste. Deze procedure gebruikt arrays, een lus, een Select Case en stringopbouw, die allemaal samenwerken. Dit benadert al productieklare logica, alleen wordt er nu gewerkt met voorbeeldgegevens die direct in de code zijn getypt in plaats van een echt werkblad.

Taak

  1. Kopieer CheckStockLevels naar je werkmap en voer het uit. Bevestig dat het bericht overeenkomt met de schermafbeelding.
  2. Verander de voorraad van de Wireless Mouse naar 25 en voer opnieuw uit — deze zou nu ook als "nauwlettend volgen" moeten verschijnen.
  3. Voeg daaronder een Do While-lus toe die simuleert dat er telkens 15 stuks van de Laptop Stand worden verkocht totdat de voorraad 20 of lager is, waarbij het lopende totaal na elke verkoop naar het Immediate Window wordt geprint.
  4. Uitdaging: schrijf de For i = 1 To 5-lus om met For Each over een Variant-array — werkt de logica nog steeds?
Hint
expand arrow

2. De voorraad van de Wireless Mouse aanpassen

  • Zoek de regel die de gegevens van de Wireless Mouse instelt: products(2) = "Wireless Mouse": stockLevels(2) = 134: reorderLevels(2) = 30.
  • Alleen het middelste getal (134) wijzigen naar 25 — laat de productnaam en het herbestelniveau ongemoeid.
  • Bedenk vooraf handmatig welke Case dit zal opvangen: is 25 ≤ 30 (het herbestelniveau)? Vergelijk dit specifiek met de regel Case Is <= reorderLevels(i), niet met de tweede regel.

3. Batchverkopen simuleren met Do While

  • Een variabele nodig om de lopende voorraad van de Laptop Stand bij te houden — begin met dezelfde waarde als in stockLevels(1) (58), zodat je geen nieuw getal hoeft in te voeren dat uit de pas kan lopen met de rest van de macro.
  • De voorwaarde van de lus moet controleren of de voorraad nog boven 20 is — zodra de controle uitwijst dat de voorraad 20 of lager is, stopt de lus.
  • Trek per ronde 15 af en print de nieuwe waarde direct na het aftrekken — niet ervoor — zodat elk getoond getal een voltooide verkoop weergeeft.
  • Werk het eerst op papier uit: 58 → 43 → 28 → 13. Merk op dat de laatste waarde onder de 20 uitkomt in plaats van er precies op — dat is hetzelfde Do While-overschietgedrag als in het lusdiagram eerder in het hoofdstuk, geen fout.
Oplossing
expand arrow

Punt 2 — binnen CheckStockLevels slechts één getal aanpassen:

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

Voer de Sub opnieuw uit.

Punt 3 — voeg dit toe onder de bestaande code, nog steeds binnen CheckStockLevels (voor 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
Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 2. Hoofdstuk 5

Vraag AI

expand

Vraag AI

ChatGPT

Vraag wat u wilt of probeer een van de voorgestelde vragen om onze chat te starten.

Lussen

Elke techniek tot nu toe werkte met één waarde tegelijk. Lussen zijn de manier om dezelfde logica toe te passen op meerdere waarden achter elkaar — vijf producten, vijfhonderd bestellingen, of hoeveel rijen een tabel ook bevat — zonder steeds hetzelfde codeblok te kopiëren en plakken.

For...Next

Herhaalt een codeblok een vast, bekend aantal keren:

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

In de eerste lus begint i bij 1, de code binnenin draait één keer met die waarde, daarna verhoogt i automatisch met 1 en het hele blok draait opnieuw — dit herhaalt tot i voorbij 5 is, waarna de lus stopt en de uitvoering verdergaat na Next. Step verandert de stapgrootte: Step -1 telt omlaag in plaats van standaard omhoog met 1, en Step 2 telt met stappen van twee. De lusvariabele i is geen speciale syntaxis — het is gewoon een gewone Long-variabele die VBA bij elke herhaling voor je bijwerkt.

For Each

Doorloopt direct elk item in een collectie, zonder dat je hoeft te weten hoeveel items er zijn of zelf een teller hoeft bij te houden:

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

Hier neemt cell telkens één individuele cel in het bereik B2:B6 aan, en je leest de inhoud uit met .Value. Vergelijk dit met For...Next: bij For...Next tel je door getallen en gebruik je dat getal om iets op te zoeken; bij For Each loop je direct door de items zelf, wat natuurlijker leest zodra je met werkbladbereiken werkt.

Do While

Herhaalt zolang een conditie True blijft — de lus weet vooraf niet hoe vaak hij zal draaien, wat verschilt van For...Next:

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 controleert stock > 0 voor elke herhaling van de lus, ook de allereerste keer. Volg het stap voor stap: 134 → 104 → 74 → 44 → 14, en dan wordt de conditie opnieuw gecontroleerd — 14 is nog steeds groter dan 0, dus de lus draait nog een keer en komt uit op -16. Pas dan wordt stock > 0 eindelijk False, en stopt de lus met stock op -16, niet netjes op 0 of 14. Dit is de moeite waard om goed na te lopen, want het is een veelvoorkomende bron van off-by-one verrassingen: een Do While-lus blijft draaien zolang de conditie geldt op het moment dat hij wordt gecontroleerd, zelfs als de actie binnen de lus voorbij de grens schiet die je in gedachten had.

Do Until

Er is ook Do Until, het spiegelbeeld van Do While — deze herhaalt zolang een conditie False is en stopt zodra die conditie True wordt, in plaats van andersom. Welke natuurlijker leest hangt af van hoe je de bedrijfsregel hardop zou formuleren: "doorgaan zolang er voorraad is" suggereert Do While; "doorgaan tot de voorraad op is" suggereert Do Until — ze kunnen identiek gedrag opleveren, alleen anders geformuleerd.

Exit Statements

Hiermee kun je een lus vroegtijdig verlaten, voordat de natuurlijke eindconditie is bereikt:

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

Deze lus is opgezet om tot 100 te tellen, maar zodra i de waarde 10 bereikt, stopt Exit For hem direct — niets na Exit For wordt uitgevoerd, en de uitvoering springt meteen naar de regel na Next i. Dit patroon gebruik je om een lijst te doorzoeken en te stoppen zodra je gevonden hebt wat je zoekt, in plaats van onnodig alle resterende items te blijven controleren.

Alles samenbrengen

Elke techniek uit dit hoofdstuk — variabelen, operatoren, functies, conditionele logica en nu lussen — komt samen in de procedure waar dit hoofdstuk naartoe heeft gewerkt:

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
Regel voor regel doorlopen
expand arrow
  • Dim products(1 To 5) As String en de twee vergelijkbare regels eronder declareren arrays — elk een genummerde rij van vijf vakjes in plaats van één vakje, dus products(1) is de naam van het eerste product, products(2) het tweede, enzovoort;
  • De vijf regels met een dubbele punt (:) tussen statements plaatsen meerdere toewijzingen op één regel puur voor de leesbaarheid — products(1) = "Laptop Stand": stockLevels(1) = 58: reorderLevels(1) = 20 is exact gelijk aan het schrijven van deze als drie aparte regels;
  • For i = 1 To 5 ... Next i loopt alle vijf producten één voor één door, waarbij i zowel als lus-teller als index in elke array wordt gebruikt;
  • Select Case stockLevels(i) voert dezelfde bereik-gebaseerde beslissing uit als in sectie 2.4, maar nu op echte arraydata in plaats van één hardgecodeerd getal;
  • Case Is <= reorderLevels(i) vangt elk product waarvan de voorraad op of onder het eigen bestelniveau is gekomen — let op, reorderLevels(i) is zelf een variabele, geen vast getal, dus elk product wordt beoordeeld op zijn eigen drempel in plaats van één drempel voor iedereen;
  • alertMessage = alertMessage & ... & vbNewLine bouwt een groeiende string op, regel voor regel — vbNewLine is een ingebouwde constante die een regeleinde invoegt, zodat elk gemarkeerd product op een eigen regel in het eindbericht verschijnt;
  • De laatste If alertMessage = "" Then-controle bepaalt welke van de twee MsgBox-varianten de gebruiker daadwerkelijk ziet — een lege string betekent dat de lus niets heeft gevonden dat gemarkeerd moest worden.

Voer dit uit en je zou moeten zien dat de Monitor Arm wordt gemarkeerd als "nauwlettend volgen" (18 stuks tegenover een herbestelniveau van 10) — loop handmatig door de lus voor i = 4 als je precies wilt bevestigen waarom dit de enige is die door de tweede Case wordt opgepikt en niet door de eerste. Deze procedure gebruikt arrays, een lus, een Select Case en stringopbouw, die allemaal samenwerken. Dit benadert al productieklare logica, alleen wordt er nu gewerkt met voorbeeldgegevens die direct in de code zijn getypt in plaats van een echt werkblad.

Taak

  1. Kopieer CheckStockLevels naar je werkmap en voer het uit. Bevestig dat het bericht overeenkomt met de schermafbeelding.
  2. Verander de voorraad van de Wireless Mouse naar 25 en voer opnieuw uit — deze zou nu ook als "nauwlettend volgen" moeten verschijnen.
  3. Voeg daaronder een Do While-lus toe die simuleert dat er telkens 15 stuks van de Laptop Stand worden verkocht totdat de voorraad 20 of lager is, waarbij het lopende totaal na elke verkoop naar het Immediate Window wordt geprint.
  4. Uitdaging: schrijf de For i = 1 To 5-lus om met For Each over een Variant-array — werkt de logica nog steeds?
Hint
expand arrow

2. De voorraad van de Wireless Mouse aanpassen

  • Zoek de regel die de gegevens van de Wireless Mouse instelt: products(2) = "Wireless Mouse": stockLevels(2) = 134: reorderLevels(2) = 30.
  • Alleen het middelste getal (134) wijzigen naar 25 — laat de productnaam en het herbestelniveau ongemoeid.
  • Bedenk vooraf handmatig welke Case dit zal opvangen: is 25 ≤ 30 (het herbestelniveau)? Vergelijk dit specifiek met de regel Case Is <= reorderLevels(i), niet met de tweede regel.

3. Batchverkopen simuleren met Do While

  • Een variabele nodig om de lopende voorraad van de Laptop Stand bij te houden — begin met dezelfde waarde als in stockLevels(1) (58), zodat je geen nieuw getal hoeft in te voeren dat uit de pas kan lopen met de rest van de macro.
  • De voorwaarde van de lus moet controleren of de voorraad nog boven 20 is — zodra de controle uitwijst dat de voorraad 20 of lager is, stopt de lus.
  • Trek per ronde 15 af en print de nieuwe waarde direct na het aftrekken — niet ervoor — zodat elk getoond getal een voltooide verkoop weergeeft.
  • Werk het eerst op papier uit: 58 → 43 → 28 → 13. Merk op dat de laatste waarde onder de 20 uitkomt in plaats van er precies op — dat is hetzelfde Do While-overschietgedrag als in het lusdiagram eerder in het hoofdstuk, geen fout.
Oplossing
expand arrow

Punt 2 — binnen CheckStockLevels slechts één getal aanpassen:

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

Voer de Sub opnieuw uit.

Punt 3 — voeg dit toe onder de bestaande code, nog steeds binnen CheckStockLevels (voor 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
Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 2. Hoofdstuk 5
some-alt