Control Flow Statements: Loops and Goto
For Next| For Each| Do Loop| Do Until| Do While| While Wend| Nested Loops| Goto| Escape Loops
Iteration/Loop statements are a mechanism used to repeat the same or essentially same action(s) for the duration of the loop. Suppose we want to add one to a variable X three times. We could write:
X = 0
X = X + 1
X = X + 1
X = X + 1
To get a final value of 3 for X. But if we needed to perform many repetitive calculations, this approach would fast become cumbersome. This is where loop statements can be useful. They are simply a short-hand way of performing the same repetitive calculations, and all have the same general structure:
Beginning of Loop
Actions
Ending of Loop
So for the above calculations, the action would be X = X + 1.
This article discusses six loop statement types and how to nest loops:
- For … Next
- For Each … Next
- Do … Loop
- Do … Loop Until
- Do While … Loop
- While … Wend
- Nested Loops
Goto statements are also presented here as they so often are used inside loops, especially Do loops. And a special section on How to Escape from an Infinite Loop should not be skipped.
For … Next
For counter = start To end [ Step step ]
Actions
[ Exit For ]
Actions
Next [ counter ]
The For Loop requires a counter, usually an integer. Brackets show optional specifications. The program flow begins with the counter set equal to the start value. On the next iteration, the counter is incremented by the Step value step, which defaults to one if left unspecified. Sometimes, the loop will need to stop when certain conditions occur. The [Exit for] construct provides a mechanism for effecting this.
For Each … Next
For Each member In group
Actions
[ Exit For ]
Actions
Next [ member ]
A For Each Loop allows iteration through members of a group, which may be of any data type.
For Each Loop stepping through string collections
Sub forEachLoop()
Dim str(2) As String
Dim rstr As Variant
str(0) = "cat"
str(1) = "dog"
str(2) = "elephant"
For Each rstr In str
MsgBox rstr
Next
End Sub
In this example, the array of elements str(2) is the group (of dimension 3) and rstr is a variant variable used to step through the group.
Note: VBA array indexing always begins with zero (0) and not one (1). Had we dimensioned str as str(3), then Msgbox would be invoked four times, instead of three, and in the final iteration, it would display a blank since str(3) was never set.
Try this example by first dimensioning str as str(2), then as str(3).
Do … Loop
Do
Counter = Counter + 1
If Counter > Nmax then exit do
Actions
[ Exit Do ]
Actions
Loop
A Do Loop needs at least one specified condition for exit, otherwise an infinite loop occurs. See Infinite Loops and How to Escape Them.
Do Loop with exit criteria
Sub doLoop()
Do
I = I + 1
If I > 10 Then Exit Do
MsgBox "Hello"
Loop
End Sub
In this example, the counter I is used to help limit the number of iterations the loop is allowed. This is a common safeguard, but does not guarantee exit from the loop because it cannot guarantee that the maximum of 10 will always be reached, since coding inside the loop can interfere with reaching the end goal. Consider the absurd example below.
Do Loop with exit criteria but an infinite loop
Sub doLoop()
I = 0
Do
I = I + 1
If I > 10 Then Exit Do
MsgBox "Hello"
I = I - 1
Loop
End Sub
In this scenario, I never reaches the maximum of 10, it always stays at the value of one (1), resulting in a program that will continue running until an outside intervention stops it.
Do … Loop Until
Do Until Criteria Met
Actions
[ Exit Do ]
Actions
Loop
Or
Do
Actions
[ Exit Do ]
Actions
Loop Until Criteria Met
This type of Do Loop provides a more compact method of placing a limit on the number of iterations allowed, but for the same reasons as above, cannot guarantee loop exit.
Do Until Loop — two methods
Sub doUntilLoop()
Dim I as Integer
Do Until I = 10
I = I + 1
MsgBox "Hello"
Loop
End Sub
Or
Sub doUntilLoop()
Dim I as Integer
Do
I = I + 1
MsgBox "Hello"
Loop Until I = 10
End Sub
Do While … Loop
Do While Criteria Not Met
Action
[ Exit Do ]
Actions
Loop
Or
Do While
Action
[ Exit Do ]
Actions
Loop While Criteria Not Met
Similar to the Do Until Loop, this type of loop continues as long as the criteria has not been met. The Do Until Loop is equivalent to the Do While Loop, just slightly different ways of stating the exit criteria.
Do While Loop — two methods
Sub doWhileLoop()
Dim I as Integer
Do While I < 10
I = I + 1
MsgBox "Hello"
Loop
End Sub
Or
Sub doWhileLoop()
Dim I as Integer
Do
I = I + 1
MsgBox "Hello"
Loop While I < 10
End Sub
While … Wend
While Criteria Not Met
Actions
[ Goto ]
Actions Wend
The While Loop is a more succinct way to construct an iteration. Exiting a While loop early can be done in one of two ways: use a Goto statement or use a Boolean Flag to exit before the outer loop criteria is reached.
While Loop with early exit — Goto or Boolean flag
Sub whileLoop()
Dim I as Integer
While I < 10
I = I + 1
MsgBox "Hello"
If I > 5 Then Goto 6
Wend
6 ' Continue
End Sub
Or
Sub whileLoop()
Dim Flag as Boolean
Flag = True
While Flag
I = I + 1
MsgBox "Hello"
If I > 5 then Flag = False
Wend
End Sub
While Loop with both exit types — Goto and Boolean flag
The two exit mechanisms for While Loops can be used inside the same loop to accommodate multiple scenarios for controlling the number of iterations.
Sub whileLoop()
Dim Flag as Boolean
Dim I as integer
Dim str as string
Flag = True
While Flag and I < 10
I = I + 1
Str = functionSetStr(I)
If str = "Name" then Flag = False
If I > 5 then Goto 6
Wend
6 Msgbox "Exited While Loop"
End Sub
Nested Loops
Loops may be nested meaning that you can construct loops within loops. Nested loops work something like peeling layers of an onion. The outer most loop executes first, then the next closest to the outer loop, and so on. This continues until the outer limit stop criteria is met or some other escape mechanism is triggered.
Nested For Loop using Step and early exit
Sub forLoop()
Dim I, J As Integer
For I = 1 To 20 Step 2
If I > 10 Then Exit For
MsgBox "I = " & I
For J = 1 To 4
MsgBox "J = " & J
Next
Next
End Sub
The For J loop is nested inside the For I loop, so For J is the outer loop and For I the inner loop. If we nest another loop inside the For J loop, say a For K loop, then For K is a inner loop to For J, which in turn is an outer loop to For K.
In this example, the For I loop iterates with I value set to 1, 3, 5, 7, 9, after which this loop is exited. At each value of I, the For J loop steps through J values 1, 2, 3, 4.
Loops involved in nesting can be of different types, so one loop can be a For Loop and another a Do Loop, totally a mix and match. You can also have two or more independent loops nested inside an outer loop. So the inner loops are not nested inside one another, but are all nested inside the outer loop. Nesting loops can become complicated the more levels you use.
Goto statements
Goto N
N Line of code
OrGoto N
N Comment Line
Goto statements are branching statements that transfer control to a specified line within the routine. The line to which transfer is given begins with the same number in the Goto statement. No two lines can have the same number.
Goto branching
Sub gotoExample()
Dim I as integer
Dim str as string
While I < 10
I = I + 1
Str = functionSetStr(I)
If str = "Name" then Goto 5
Wend
5 ' Continue with a comment line or a line of code
End Sub
How to Escape from an Infinite Loop
An Infinite Loop is a code configuration in which the program cannot stop running. It most often occurs within a loop of some sort, but can also happen outside loops. Let's start with a simple example.
Infinite loop
Sub infiniteLoop()
Do
MsgBox "Hello"
Loop
End Sub
This program will continue running indefinitely because there are no exits from this Do Loop. Although VBA is great at warning about improper coding, it will not and cannot alert you to infinite loops.
In a Windows environment, there are three options for stopping program execution:
- Hold the Esc key down for a few seconds.
- Depress the Ctr + Break/Pause buttons simultaneously.
- Bring up the Task Manager using Ctr + Alt + Delete. Click on any instance of Excel, then click the End Task button. This will close all open Excel applications and provide for a recovery file.
The first two options do not always work, but when they do, your Excel application will still be open without loss of data. The third option can lead to loss of data if your work was not saved before running the program. For this reason you should save your work before running new/untested code. Of course, you could always power down and restart your computer, but this is not recommended and should only be done as a last-ditch effort.