Løkker
Sveip for å vise menyen
Hver teknikk så langt har jobbet med én verdi om gangen. Løkker er måten du bruker samme logikk på mange verdier etter hverandre — fem produkter, fem hundre ordre, eller så mange rader som en tabell måtte inneholde — uten å måtte kopiere og lime inn samme kodeblokk om og om igjen.
For...Next
Gjentar en kodeblokk et fast, kjent antall ganger:
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
I den første løkken starter i på 1, koden inni kjører én gang med den verdien, så økes i automatisk med 1 og hele blokken kjøres igjen — dette gjentas til i passerer 5, da stopper løkken og kjøringen fortsetter etter Next. Step endrer inkrementet: Step -1 teller nedover i stedet for standarden oppover med én, og Step 2 ville telt med to om gangen. Løkkevariabelen i er ikke spesiell syntaks — det er bare en vanlig Long-variabel som VBA oppdaterer for deg hver gang gjennom løkken.
For Each
Løkker gjennom hvert element i en samling direkte, uten at du trenger å vite hvor mange elementer det er eller holde styr på en teller selv:
Dim cell As Range
For Each cell In ThisWorkbook.Worksheets("Products").Range("B2:B6")
Debug.Print cell.Value
Next cell
Her tar cell verdien til hver enkelt celle i området B2:B6 etter tur, og du leser innholdet med .Value. Sammenlign dette med For...Next: med For...Next teller du gjennom tall og bruker det tallet til å slå opp noe; med For Each går du direkte gjennom elementene selv, noe som ofte er mer naturlig når du jobber med områder i regnearket.
Do While
Gjentar så lenge en betingelse er True — løkken vet ikke på forhånd hvor mange ganger den vil kjøre, noe som skiller seg fra 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 sjekker stock > 0 før hver eneste gjennomgang av løkken, inkludert den aller første. Følg det for hånd: 134 → 104 → 74 → 44 → 14, og så sjekkes betingelsen igjen — 14 er fortsatt større enn 0, så løkken kjører én gang til og lander på -16. Først da blir stock > 0 usann, og løkken stopper med stock på -16, ikke pent på 0 eller 14. Dette er verdt å følge nøye første gang, fordi det ofte fører til "off-by-one"-feil: en Do While-løkke fortsetter så lenge betingelsen stemmer i det øyeblikket den sjekkes, selv om handlingen inni løkken går forbi grensen du hadde sett for deg.
Do Until
Det finnes også Do Until, som er speilbildet av Do While — den gjentar mens en betingelse er False og stopper i det øyeblikket betingelsen blir True, altså motsatt vei. Hvilken som føles mest naturlig avhenger av hvordan du ville formulert forretningsregelen muntlig: "fortsett så lenge det er varer igjen" tilsier Do While; "fortsett til varene er tomme" tilsier Do Until — de kan gi identisk oppførsel, bare formulert fra hver sin retning.
Exit-setninger
Lar deg bryte ut av en løkke tidlig, før den naturlige sluttbetingelsen er nådd:
For i = 1 To 100
If i = 10 Then Exit For ' stop the loop immediately
Debug.Print i
Next i
Denne løkken er satt opp til å telle helt til 100, men i det øyeblikket i når 10, stopper Exit For den — ingenting etter Exit For kjøres, og kjøringen hopper rett til linjen etter Next i. Dette er mønsteret du bruker for å søke gjennom en liste og stoppe så snart du har funnet det du leter etter, i stedet for å fortsette å sjekke resten av elementene unødvendig.
Sette det sammen
Alle teknikkene fra dette kapittelet — variabler, operatorer, funksjoner, betinget logikk og nå løkker — kombineres i prosedyren dette kapittelet har bygget opp mot:
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 og de to lignende linjene under erklærer arrayer — hver av dem er en nummerert rad med fem bokser i stedet for én boks, så products(1) er navnet på det første produktet, products(2) det andre, og så videre;
- De fem linjene som bruker kolon (
:) mellom setningene, samler flere tildelinger på én linje kun for lesbarhet her —products(1) = "Laptop Stand": stockLevels(1) = 58: reorderLevels(1) = 20er nøyaktig det samme som å skrive dem som tre separate linjer; For i = 1 To 5 ... Next igår gjennom alle fem produktene ett om gangen, og bruker i både som løkketeller og som indeks i hver array;Select Case stockLevels(i)kjører samme områdebaserte avgjørelse fra seksjon 2.4, men nå mot ekte array-data i stedet for et enkelt hardkodet tall;- Case Is <= reorderLevels(i) fanger opp ethvert produkt der lageret har falt til eller under sitt eget bestillingsnivå — merk at reorderLevels(i) selv er en variabel, ikke et fast tall, så hvert produkt vurderes mot sin egen terskel i stedet for én felles terskel for alle;
alertMessage = alertMessage & ... & vbNewLinebygger opp en voksende streng én linje om gangen —vbNewLineer en innebygd konstant som legger inn linjeskift, slik at hvert flagget produkt vises på egen linje i den endelige meldingen;- Den siste
If alertMessage = "" Then-sjekken avgjør hvilken av de toMsgBox-variantene brukeren faktisk ser — en tom streng betyr at løkken aldri fant noe som burde flagges.
Kjør dette, og du skal se at Monitor Arm blir flagget som "følg nøye med" (18 enheter mot et bestillingsnivå på 10) — gå gjennom løkken manuelt for i = 4 hvis du vil bekrefte nøyaktig hvorfor det er den eneste som fanges opp av den andre Case og ikke den første. Denne prosedyren bruker matriser, en løkke, en Select Case og strengbygging, alt som jobber sammen. Dette er faktisk nær produksjonsklar logikk allerede, bare kjørt mot eksempeldata skrevet direkte inn i koden i stedet for et ekte regneark.
Oppgave
- Kopier
CheckStockLevelsinn i arbeidsboken din og kjør den. Bekreft at meldingen samsvarer med skjermbildet. - Endre lagerbeholdningen for Wireless Mouse til 25 og kjør på nytt — den skal nå også vises som "følg nøye med".
- Legg til en
Do While-løkke under som simulerer salg av 15 enheter Laptop Stand om gangen til lageret faller til 20 eller lavere, og skriv ut løpende total til Immediate Window etter hvert salg. - Utfordring: skriv om
For i = 1 To 5-løkka ved å brukeFor Eachover en Variant-matrise i stedet — fungerer logikken fortsatt?
2. Endre lagerbeholdningen for Wireless Mouse
- Finn linjen som setter opp dataene for Wireless Mouse:
products(2) = "Wireless Mouse": stockLevels(2) = 134: reorderLevels(2) = 30. - Du trenger bare å endre det midterste tallet (
134) til25— la produktnavnet og bestillingsnivået være uendret. - Før du kjører det, regn ut for hånd hvilken
Casesom skal fange det: er 25 ≤ 30 (bestillingsnivået)? Sammenlign dette spesielt med linjenCase Is <= reorderLevels(i), ikke den andre.
3. Simulere partisalgs med Do While
- Du trenger en variabel for å holde styr på løpende lager for Laptop Stand — start den med samme verdi som allerede står i
stockLevels(1)(58), slik at du ikke skriver inn et nytt tall som kan komme ut av synk med resten av makroen. - Løkkens betingelse skal sjekke om lageret fortsatt er over 20 — i det øyeblikket den sjekker og finner lageret på 20 eller lavere, skal den stoppe.
- Trekk fra 15 én gang per gjennomgang, og skriv ut den nye verdien rett etter at du har trukket fra — ikke før — slik at hvert utskrevne tall gjenspeiler et fullført salg.
- Gå gjennom det på papir først: 58 → 43 → 28 → 13. Merk at den siste verdien faller under 20 i stedet for å lande nøyaktig på det — dette er samme
Do While-overskridelsesatferd som løkkediagrammet tidligere i kapitlet viste, ikke en feil.
Punkt 2 — inne i CheckStockLevels, endre bare ett tall:
products(2) = "Wireless Mouse": stockLevels(2) = 25: reorderLevels(2) = 30
Kjør Sub på nytt.
Punkt 3 — legg til dette under eksisterende kode, fortsatt inne i CheckStockLevels (før 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
Takk for tilbakemeldingene dine!
Spør AI
Spør AI
Spør om hva du vil, eller prøv ett av de foreslåtte spørsmålene for å starte chatten vår
Løkker
Hver teknikk så langt har jobbet med én verdi om gangen. Løkker er måten du bruker samme logikk på mange verdier etter hverandre — fem produkter, fem hundre ordre, eller så mange rader som en tabell måtte inneholde — uten å måtte kopiere og lime inn samme kodeblokk om og om igjen.
For...Next
Gjentar en kodeblokk et fast, kjent antall ganger:
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
I den første løkken starter i på 1, koden inni kjører én gang med den verdien, så økes i automatisk med 1 og hele blokken kjøres igjen — dette gjentas til i passerer 5, da stopper løkken og kjøringen fortsetter etter Next. Step endrer inkrementet: Step -1 teller nedover i stedet for standarden oppover med én, og Step 2 ville telt med to om gangen. Løkkevariabelen i er ikke spesiell syntaks — det er bare en vanlig Long-variabel som VBA oppdaterer for deg hver gang gjennom løkken.
For Each
Løkker gjennom hvert element i en samling direkte, uten at du trenger å vite hvor mange elementer det er eller holde styr på en teller selv:
Dim cell As Range
For Each cell In ThisWorkbook.Worksheets("Products").Range("B2:B6")
Debug.Print cell.Value
Next cell
Her tar cell verdien til hver enkelt celle i området B2:B6 etter tur, og du leser innholdet med .Value. Sammenlign dette med For...Next: med For...Next teller du gjennom tall og bruker det tallet til å slå opp noe; med For Each går du direkte gjennom elementene selv, noe som ofte er mer naturlig når du jobber med områder i regnearket.
Do While
Gjentar så lenge en betingelse er True — løkken vet ikke på forhånd hvor mange ganger den vil kjøre, noe som skiller seg fra 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 sjekker stock > 0 før hver eneste gjennomgang av løkken, inkludert den aller første. Følg det for hånd: 134 → 104 → 74 → 44 → 14, og så sjekkes betingelsen igjen — 14 er fortsatt større enn 0, så løkken kjører én gang til og lander på -16. Først da blir stock > 0 usann, og løkken stopper med stock på -16, ikke pent på 0 eller 14. Dette er verdt å følge nøye første gang, fordi det ofte fører til "off-by-one"-feil: en Do While-løkke fortsetter så lenge betingelsen stemmer i det øyeblikket den sjekkes, selv om handlingen inni løkken går forbi grensen du hadde sett for deg.
Do Until
Det finnes også Do Until, som er speilbildet av Do While — den gjentar mens en betingelse er False og stopper i det øyeblikket betingelsen blir True, altså motsatt vei. Hvilken som føles mest naturlig avhenger av hvordan du ville formulert forretningsregelen muntlig: "fortsett så lenge det er varer igjen" tilsier Do While; "fortsett til varene er tomme" tilsier Do Until — de kan gi identisk oppførsel, bare formulert fra hver sin retning.
Exit-setninger
Lar deg bryte ut av en løkke tidlig, før den naturlige sluttbetingelsen er nådd:
For i = 1 To 100
If i = 10 Then Exit For ' stop the loop immediately
Debug.Print i
Next i
Denne løkken er satt opp til å telle helt til 100, men i det øyeblikket i når 10, stopper Exit For den — ingenting etter Exit For kjøres, og kjøringen hopper rett til linjen etter Next i. Dette er mønsteret du bruker for å søke gjennom en liste og stoppe så snart du har funnet det du leter etter, i stedet for å fortsette å sjekke resten av elementene unødvendig.
Sette det sammen
Alle teknikkene fra dette kapittelet — variabler, operatorer, funksjoner, betinget logikk og nå løkker — kombineres i prosedyren dette kapittelet har bygget opp mot:
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 og de to lignende linjene under erklærer arrayer — hver av dem er en nummerert rad med fem bokser i stedet for én boks, så products(1) er navnet på det første produktet, products(2) det andre, og så videre;
- De fem linjene som bruker kolon (
:) mellom setningene, samler flere tildelinger på én linje kun for lesbarhet her —products(1) = "Laptop Stand": stockLevels(1) = 58: reorderLevels(1) = 20er nøyaktig det samme som å skrive dem som tre separate linjer; For i = 1 To 5 ... Next igår gjennom alle fem produktene ett om gangen, og bruker i både som løkketeller og som indeks i hver array;Select Case stockLevels(i)kjører samme områdebaserte avgjørelse fra seksjon 2.4, men nå mot ekte array-data i stedet for et enkelt hardkodet tall;- Case Is <= reorderLevels(i) fanger opp ethvert produkt der lageret har falt til eller under sitt eget bestillingsnivå — merk at reorderLevels(i) selv er en variabel, ikke et fast tall, så hvert produkt vurderes mot sin egen terskel i stedet for én felles terskel for alle;
alertMessage = alertMessage & ... & vbNewLinebygger opp en voksende streng én linje om gangen —vbNewLineer en innebygd konstant som legger inn linjeskift, slik at hvert flagget produkt vises på egen linje i den endelige meldingen;- Den siste
If alertMessage = "" Then-sjekken avgjør hvilken av de toMsgBox-variantene brukeren faktisk ser — en tom streng betyr at løkken aldri fant noe som burde flagges.
Kjør dette, og du skal se at Monitor Arm blir flagget som "følg nøye med" (18 enheter mot et bestillingsnivå på 10) — gå gjennom løkken manuelt for i = 4 hvis du vil bekrefte nøyaktig hvorfor det er den eneste som fanges opp av den andre Case og ikke den første. Denne prosedyren bruker matriser, en løkke, en Select Case og strengbygging, alt som jobber sammen. Dette er faktisk nær produksjonsklar logikk allerede, bare kjørt mot eksempeldata skrevet direkte inn i koden i stedet for et ekte regneark.
Oppgave
- Kopier
CheckStockLevelsinn i arbeidsboken din og kjør den. Bekreft at meldingen samsvarer med skjermbildet. - Endre lagerbeholdningen for Wireless Mouse til 25 og kjør på nytt — den skal nå også vises som "følg nøye med".
- Legg til en
Do While-løkke under som simulerer salg av 15 enheter Laptop Stand om gangen til lageret faller til 20 eller lavere, og skriv ut løpende total til Immediate Window etter hvert salg. - Utfordring: skriv om
For i = 1 To 5-løkka ved å brukeFor Eachover en Variant-matrise i stedet — fungerer logikken fortsatt?
2. Endre lagerbeholdningen for Wireless Mouse
- Finn linjen som setter opp dataene for Wireless Mouse:
products(2) = "Wireless Mouse": stockLevels(2) = 134: reorderLevels(2) = 30. - Du trenger bare å endre det midterste tallet (
134) til25— la produktnavnet og bestillingsnivået være uendret. - Før du kjører det, regn ut for hånd hvilken
Casesom skal fange det: er 25 ≤ 30 (bestillingsnivået)? Sammenlign dette spesielt med linjenCase Is <= reorderLevels(i), ikke den andre.
3. Simulere partisalgs med Do While
- Du trenger en variabel for å holde styr på løpende lager for Laptop Stand — start den med samme verdi som allerede står i
stockLevels(1)(58), slik at du ikke skriver inn et nytt tall som kan komme ut av synk med resten av makroen. - Løkkens betingelse skal sjekke om lageret fortsatt er over 20 — i det øyeblikket den sjekker og finner lageret på 20 eller lavere, skal den stoppe.
- Trekk fra 15 én gang per gjennomgang, og skriv ut den nye verdien rett etter at du har trukket fra — ikke før — slik at hvert utskrevne tall gjenspeiler et fullført salg.
- Gå gjennom det på papir først: 58 → 43 → 28 → 13. Merk at den siste verdien faller under 20 i stedet for å lande nøyaktig på det — dette er samme
Do While-overskridelsesatferd som løkkediagrammet tidligere i kapitlet viste, ikke en feil.
Punkt 2 — inne i CheckStockLevels, endre bare ett tall:
products(2) = "Wireless Mouse": stockLevels(2) = 25: reorderLevels(2) = 30
Kjør Sub på nytt.
Punkt 3 — legg til dette under eksisterende kode, fortsatt inne i CheckStockLevels (før 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
Takk for tilbakemeldingene dine!