Keyword
For...Next
Description
Executes a series of statements a specified number of times.
Usage
For counter [ As datatype ] = start To | DownTo end [ Step value ]
[ Statements ]
[ Continue [ For ] ]
[ Exit [ For ] ]
[ Statements ]
Next [ counter ]
Part |
Description |
---|---|
counter |
A variable that is incremented or decremented every time the loop executes. It can be an Integer, Single or Double. By default the value is changed by 1 at the end of every iteration, i.e. when the Next statement is reached or a Continue statement is invoked inside the loop. Note that the counter can be changed inside the loop. See the Troubleshooting section. |
datatype |
The Datatype of the counter. |
start |
Initial value of counter. |
Use To to increment the counter at every loop iteration by the Step value (default: 1). Use DownTo to subtract the Step value from the counter at every iteration. You can also count down by using a negative Step value when using To as described in the "Step value" section below. |
|
end |
Final value of counter. The loop ends if the counter value has reached a value past the end value at the time the Next (or Continue) statement is reached (this means: If the counter gets incremented, the loop ends once counter > end; if the counter gets decremented, the loop ends once counter < end). |
Step value |
Amount to increment or decrement counter when a Continue or the loop's Next statement is reached. If Step is not used, the value defaults to 1. |
Statements |
Statements to be executed repeatedly inside the loop. |
If a Continue statement is present, execution skips directly to the loop's Next statement, thereby causing another loop iteration unless the end is reached. |
|
If an Exit statement is present, execution skips over the remaining statements in the loop and resumes with the statement following the Next statement. See the Exit statement for additional options that are relevant for nested loops. |
Notes
Declaring the counter inside the For statement
The counter variable in a For statement can be declared inside the For statement rather than externally, as a local variable.
For example, the code
Var i As Integer
For i = 1 To 10
...
Next
' i is now 11
can also be rewritten as
For i As Integer = 1 To 10
... ' i can be used in here
Next
' i is not available at this point any more
In the second code example the counter variable goes out of scope after the last iteration of the For loop, i.e. you can not read the value of the counter after the loop. In the first code example, the counter variable remains accessible after the loop.
Variables declared inside the loop remain private to it
Variables declared inside a loop are not accessible outside of it (which is the same as for other block statements such as If, While and so on).
For example:
For i As Integer = 1 To 5
Var multBy2 As Boolean
multBy2 = i * 2
Next
MessageBox(multBy2.ToString) ' "multBy2" is out of scope, i.e. you cannot access "multBy2" here. To solve this, move the Var statement before the For statement.
Counting backward
To count from 10 down to 0, you can write (the "Step 1" part is optional):
For loopIndex As Integer = 10 DownTo 0 Step 1
Or:
For loopIndex As Integer = 10 To 0 Step -1
Step usage
Aside from using -1 as a Step value to count backward, you can also use it to change counter by a different value in every loop iteration:
For i As Integer = 1 To 6 Step 2
MessageBox("i = " + i.ToString)
Next
The numbers 1, 3 and 5 will be shown.
Exit and Continue
Use Exit to leave a loop early:
Const attempts = 10
Var attempt As Integer
For attempt = 1 To attempts
Var randomValue As Double = Rnd
If randomValue > 0.9 Then
MessageBox("Found a random value above 0.9 after " + attempt.ToString + " iterations.")
Exit
End If
Next
If attempt > attempts Then
MessageBox("Found NO random value above 0.9 after " + attempts.ToString + " iterations.")
End If
Similar code using a Continue statement:
Const attempts = 100
Var matchCount As Integer
For attempt As Integer = 1 To attempts
Var randomValue As Double = Rnd
If randomValue <= 0.9 Then
Continue
End If
matchCount = matchCount + 1
Next
MessageBox("Found " + matchCount.ToString + " random values above 0.9 within " + attempts.ToString + " iterations.")
In the case of nested loops, you can Exit or Continue to the outer loops, provided they are of a different kind (For vs. While vs. Do):
For tries As Integer = 1 To 3 ' let's try this up to 3 times
Var misses As Integer
Do
Var randomValue As Integer = Rnd * 100
If randomValue = 0 And tries > 1 Then
Exit For ' Leaves both the Do and the For loops by jumping to #4
End If
If randomValue < 5 Then
Continue For ' Leaves the Do loop for another For loop by jumping to #3
End If
If randomValue < 20 Then
Continue Do ' Reiterates the Do loop by jumping to #1
End If
misses = misses + 1
If misses > 10 Then
Exit Do ' Leaves the Do loop by jumping to #2
End If
Loop ' #1
MessageBox("End of Do loop") ' #2
Next ' #3
MessageBox("End of For loop") ' #4
Using Single or Double values as loop counter
The following code shows the values 1.5, 2.5 and 3.5:
For dblValue As Double = 1.5 To 4
MessageBox("Now at " + dblValue.ToString)
Next
Counter value after the loop
If you declare the counter variable outside the loop, it will retain a value after the loop ends. If it finishes normally, i.e., it cycles though every element without encountering Exit, that value will be the end value plus 1 if you have not specified a Step value, or the end value plus Step if you have.
Var i As Integer
For i = 1 To 10
' Some code
Next i
' i = 11
For i = 1 To 10 Step 2
' Some code
Next i
' i = 12
For i = 10 DownTo 1
' Some code
Next i
' i = 0
For i = 10 To 1 Step -2
' Some code
Next i
' i = -1
Var d As Double
For d = 1.0 To 10.0
' Some code
Next d
' d = 11.0
For d = 1.0 To 10.0 Step 0.5
' Some code
Next d
' d = 10.5
If the loop exits early through Exit, the counter will retain the value it held at the point of exit.
Performance considerations
If start, end, or step are not constant values, they get evaluated every time the loop is executed, even if they evaluate to the same value for each iteration. Therefore, the loop:
For i As Integer = 0 To System.FontCount - 1
...
Next
will take more time than:
Var nFonts As Integer
nFonts = System.FontCount - 1
For i = 0 To nFonts
...
Next
Be especially aware of this when the end value changes during the loop! Also, you can modify the counter variable inside the loop.
The example below shows both techniques. While it adds new elements to the array, but it will still iterate over all items:
Var values() As Integer = Array(1,5,4,8)
' The loop inserts 0 after values above 4 inside the values array:
For i As Integer = 0 To values.LastIndex
If values(i) > 4 Then
values.AddAt(i + 1, 100)
i = i + 1 ' skip the next item because otherwise we'd add more values endlessly
End If
Next
Miscellaneous
For...Next statements can be nested but each For...Next statement must have its own counter variable.
When a For loop (same goes for While and Do loops) runs, it blocks the application's user interface, preventing the user from interacting with menus and controls. Ordinarily, this is of no concern. If, however, the loop is very lengthy, you can move the code for the loop to a separate Thread, allowing it to execute in the background and allowing the user interface to remain responsive.
When multiple threads are running, be aware that at every loop iteration Xojo might switch to another thread. This means that if you have a time critical loop that should not yield its processing time to other threads, consider adding #Pragma BackgroundTasks False in a line before the loop statement.
Troubleshooting
You may have trouble using the For...Next loop, e.g. it exits too soon, it never ends, it processes only one every two values... In such cases, you should set a breakpoint on the For...Next line to verify the counter value.
The most common mistakes are:
You have defined two different integers (say, i and j) in a method and you are using both as counters. However, you have copied and pasted some code which also uses i or jj as variables. As a consequence, the computations actually modify the counters you use and mess up the loops.
Whenever you plan to delete some items from a list, it is strongly recommended that you write a loop going from the end down to the start to avoid problems with the counter variable.
You used a limited Integer type (UInt32 or UInt8) and your loop end reach the minimum or maximum size of the Integer. In order for a loop to exit the counter, it has to go beyond the bounds of the loop's specified end value. For example if your end value is 255, but you used an UInt8 which has a maximum value of 255, then your loop counter can never exceed 255 and you will have an infinite loop. The same logic applies when DownTo is used.
Sample code
The code below uses the For...Next statement to test the values in an array and change those that are "Today" to "Tomorrow".
Var days() As String = Array("May 1", "Yesterday", "Today", "Next week")
For dayIndex As Integer = 0 To days.LastIndex
If days(dayIndex) = "Today" Then
days(dayIndex) = "Tomorrow"
End If
Next
The above code can also be written using the For...Each statement:
Var days() As String = Array("May 1", "Yesterday", "Today", "Next week")
For Each day As String In days
If day = "Today" Then
Var dayIndex As Integer = days.IndexOf(day)
days(dayIndex) = "Tomorrow"
End If
Next
Compatibility
All project types on all supported operating systems.
See also
Continue, Do...Loop, Exit, For...Each, While...Wend statements.