Løkker
Stryg for at vise menuen
Alle teknikker hidtil har arbejdet med én værdi ad gangen. Løkker er måden, hvorpå du anvender den samme logik på mange værdier i træk — fem produkter, fem hundrede ordrer, eller hvor mange rækker en tabel nu end måtte indeholde — uden at skulle kopiere og indsætte den samme kodeblok igen og igen.
For...Next
Gentager en kodeblok et fast, kendt antal gange:
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økke starter i ved 1, koden indeni kører én gang med den værdi, derefter øges i automatisk med 1, og hele blokken kører igen — dette gentages, indtil i overstiger 5, hvorefter løkken stopper, og eksekveringen fortsætter efter Next. Step ændrer inkrementet: Step -1 tæller nedad i stedet for standarden, som er opad med 1, og Step 2 ville tælle med to ad gangen. Løkkevariablen i er ikke speciel syntaks — det er blot en almindelig Long-variabel, som VBA opdaterer for dig hver gang løkken kører.
For Each
Går direkte igennem hvert element i en samling, uden at du behøver vide, hvor mange elementer der er, eller selv styre en tæller:
Dim cell As Range
For Each cell In ThisWorkbook.Worksheets("Products").Range("B2:B6")
Debug.Print cell.Value
Next cell
Her får cell hver enkelt celle i området B2:B6 efter tur, og du læser indholdet med .Value. Sammenlign dette med For...Next: med For...Next tæller du gennem tal og bruger det tal til at slå noget op; med For Each går du direkte gennem elementerne selv, hvilket ofte læses mere naturligt, når du arbejder med regnearksområder.
Do While
Gentager så længe en betingelse forbliver True — løkken ved ikke på forhånd, hvor mange gange den vil køre, hvilket adskiller sig 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 tjekker stock > 0 før hvert eneste gennemløb af løkken, også første gang. Følg det manuelt: 134 → 104 → 74 → 44 → 14, og så tjekkes betingelsen igen — 14 er stadig større end 0, så løkken kører én gang mere og lander på -16. Først da bliver stock > 0 falsk, og løkken stopper med stock på -16, ikke pænt på 0 eller 14. Dette er værd at gennemgå nøje første gang, da det ofte fører til off-by-one-fejl: en Do While-løkke fortsætter, så længe betingelsen holder i det øjeblik, den tjekkes, selv hvis handlingen indeni løkken går forbi den grænse, du havde tænkt dig.
Do Until
Der findes også Do Until, som er spejlbilledet af Do While — den gentager, mens en betingelse er False, og stopper i det øjeblik, betingelsen bliver True, i stedet for omvendt. Hvilken der læses mest naturligt, afhænger af, hvordan du ville formulere forretningsreglen mundtligt: "fortsæt mens der er lager" antyder Do While; "fortsæt indtil lageret er opbrugt" antyder Do Until — de kan give identisk adfærd, blot formuleret fra hver sin retning.
Exit Statements
Lader dig bryde ud af en løkke før dens naturlige slutbetingelse er nået:
For i = 1 To 100
If i = 10 Then Exit For ' stop the loop immediately
Debug.Print i
Next i
Denne løkke er sat op til at tælle hele vejen til 100, men i det øjeblik i når 10, stopper Exit For den — intet efter Exit For køres, og eksekveringen hopper direkte til linjen efter Next i. Dette mønster bruges til at søge gennem en liste og stoppe, så snart du har fundet det, du leder efter, i stedet for unødigt at fortsætte gennem alle resterende elementer.
Samlet anvendelse
Alle teknikker fra dette kapitel — variabler, operatorer, funktioner, betinget logik og nu løkker — kombineres i proceduren, som dette kapitel har bygget op til:
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 tilsvarende linjer nedenunder erklærer arrays — hver især en nummereret række af fem bokse i stedet for én boks, så products(1) er navnet på det første produkt, products(2) det andet osv.;
- De fem linjer med kolon (
:) mellem sætninger samler flere tildelinger på én linje udelukkende for læsbarhed —products(1) = "Laptop Stand": stockLevels(1) = 58: reorderLevels(1) = 20svarer præcis til at skrive dem som tre separate linjer; For i = 1 To 5 ... Next igår igennem alle fem produkter ét ad gangen, hvor i bruges både som løkketæller og som indeks i hvert array;Select Case stockLevels(i)gentager den samme intervalbaserede beslutning fra afsnit 2.4, men nu mod rigtige arraydata i stedet for et enkelt hårdkodet tal;- Case Is <= reorderLevels(i) fanger ethvert produkt, hvis lager er faldet til eller under dets egen genbestillingsniveau — bemærk, at reorderLevels(i) selv er en variabel, ikke et fast tal, så hvert produkt vurderes mod sin egen grænse i stedet for én fælles grænse;
alertMessage = alertMessage & ... & vbNewLineopbygger en voksende tekststreng én linje ad gangen —vbNewLineer en indbygget konstant, der indsætter et linjeskift, så hvert markeret produkt vises på sin egen linje i den endelige besked;- Den afsluttende
If alertMessage = "" Then-kontrol afgør, hvilken af de toMsgBox-varianter brugeren faktisk ser — en tom streng betyder, at løkken aldrig fandt noget, der skulle markeres.
Kør dette, og du bør se Monitor Arm markeret som "watch closely" (18 enheder mod et genbestillingsniveau på 10) — gennemgå løkken manuelt for i = 4, hvis du vil bekræfte præcis, hvorfor det kun er denne, der fanges af det andet Case og ikke det første. Denne procedure bruger arrays, en løkke, en Select Case og strengopbygning, som alle arbejder sammen. Det er allerede tæt på produktionsklar logik, blot kørt mod eksempeldata indtastet direkte i koden i stedet for et rigtigt regneark.
Opgave
- Kopiér
CheckStockLevelsind i din projektmappe og kør den. Bekræft, at beskeden matcher skærmbilledet. - Ændr Wireless Mouse's lager til 25 og kør igen — den bør nu også vises som "watch closely".
- Tilføj en
Do While-løkke nedenunder, der simulerer salg af 15 enheder Laptop Stand ad gangen, indtil lageret falder til 20 eller derunder, og udskriv det løbende total til Immediate Window efter hvert salg. - Udfordring: omskriv
For i = 1 To 5-løkke ved at brugeFor Eachover et Variant-array i stedet — virker logikken stadig?
2. Ændring af lagerbeholdningen for Wireless Mouse
- Find linjen, der opsætter data for Wireless Mouse:
products(2) = "Wireless Mouse": stockLevels(2) = 134: reorderLevels(2) = 30. - Du skal kun ændre det midterste tal (
134) til25— lad produktnavnet og genbestillingsniveauet være uændret. - Inden du kører det, gennemgå manuelt, hvilken
Caseder skal fange det: er 25 ≤ 30 (genbestillingsniveauet)? Sammenlign det specifikt med linjenCase Is <= reorderLevels(i), ikke den anden.
3. Simulering af partisalgs med Do While
- Du skal bruge en variabel til at holde styr på Laptop Stand's løbende lager — start den med den samme værdi, der allerede står i
stockLevels(1)(58), så du ikke indtaster et nyt tal, der kan komme ud af sync med resten af makroen. - Løkkens betingelse skal kontrollere, om lageret stadig er over 20 — i det øjeblik den tjekker og finder lageret på 20 eller derunder, skal den stoppe.
- Træk 15 fra én gang pr. gennemløb, og udskriv den nye værdi lige efter fratrækningen — ikke før — så hvert udskrevet tal afspejler et gennemført salg.
- Gennemgå det på papir først: 58 → 43 → 28 → 13. Bemærk, at den sidste værdi falder under 20 i stedet for at lande præcis på det — det er den samme
Do Whileoverskridelsesadfærd, som kapitlets løkkediagram tidligere har gennemgået, ikke en fejl.
Punkt 2 — inde i CheckStockLevels, skal du blot ændre ét tal:
products(2) = "Wireless Mouse": stockLevels(2) = 25: reorderLevels(2) = 30
Kør Sub igen.
Punkt 3 — tilføj dette under den eksisterende kode, stadig inde 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
Tak for dine kommentarer!
Spørg AI
Spørg AI
Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat