VBA For Loop - A Complete Guide: "History Is About Loops and Continuums" - Mike Bidlo
VBA For Loop - A Complete Guide: "History Is About Loops and Continuums" - Mike Bidlo
Introduction
Loops are by far the most powerful component of VBA. They are the rocket fuel of your Macros. They can perform tasks
in milliseconds that would take humans hours. They also dramatically reduce the lines of code your applications need.
If you have never used loops before then this post is a great place to start. It provides and in-depth guide to loops, written
in plain English without the jargon.
Let’s start with a very important question – what are loops and why do we need them?
Debug.Print 1
Debug.Print 2
Debug.Print 3
Debug.Print 4
Debug.Print 5
For i = 1 To 20
Debug.Print i
Next i
The output is
Output
If we needed print the numbers 1 to 1000 then we only need to change the 20 to 1000.
Normally when we write code we would use a variable instead of a number like 20 or 1000. This gives you greater
flexibility. It allows you to decide the number of times you wish to run the loop when the code is running. The following
example explains this.
Using a variable in the loop makes your code very flexible. Your will work no matter how many rows there are.
Let’s have a look at an example. Imagine you receive a sheet with a list of fruit types and their daily sales. You want to
count the number of Oranges sold and this list will vary in size depending on sales.
Sub CountFruit()
For i = 2 To LastRow
End If
Next i
End Sub
You can try this code for yourself. Change the number of fruit items and you will see that the code still works fine.
If you were to increase the number fruit items to a large value like 10,000 then you will hardly notice the difference in the
time it takes to run – almost instantly.
Loops are super fast. This is what makes them so powerful. Imagine performing a manual task on 10,000 cells. It would
take a considerable amount of time.
In the next sections we will look at the different types of loops and how to use them.
Dim i As Long
For i = 1 To 3
Debug.Print i
Next i
i is set to 2
The value of i(now 2) is printed
i is set to 3
The value of i(now 3) is printed
Dim i As Long
i = i + 1
Debug.Print i
i = i + 1
Debug.Print i
i = i + 1
Debug.Print i
The i = i + 1 line is used to add 1 to i and is a common way in programming to update a counter.
Using Step
You can see that i is increased by one each time. This is the default. You can specify this interval using Step.
For i = 2 To 20 Step 2
Debug.Print i
Next i
You can use a negative number with Step which will count in reverse
For i = 20 To 2 Step -2
Debug.Print i
Next i
Note: if Step is positive then your starting number must be lower than you ending number. The following loop will not run
because the starting number 20 is greater than 10. VBA therefore, thinks it has already reached the target value 10.
For i = 20 To 10 Step 1
Debug.Print i
Next i
If Step is negative then the start number must be greater than the end number.
Exit For
Sometimes you may want to leave the loop earlier if a certain condition occurs. For example if you read bad data.
You can use Exit For to automatically leave the loop as shown in the following code
For i = 1 To 1000
' If cell is blank then exit for
Exit For
End If
Next i
In the following example, we display the name of all the open workbooks
Dim i As Long
For i = 1 To Workbooks.Count
Debug.Print Workbooks(i).FullName
Next i
Sub ListWorksheets()
For i = 1 To Workbooks.Count
' Second loop goes through all the worksheets of workbook(i)
For j = 1 To Workbooks(i).Worksheets.Count
Next j
Next i
End Sub
The second loop then uses the workbook at 1 to go through the worksheets.
The second loop then uses the workbook at 2 to go through the worksheets.
and so on
It the next section we will use a For Each loop to perform the same task. You will find the For Each version much easier to
read.
Dim wk As Workbook
Debug.Print wk.FullName
Next wk
Format of the For Each Loop
For Each <variable> in <collection>
Next <variable>
To create a For Each loop we need a variable of the same type that the collection holds. In the example here we created a
variable of type Workbook.
If the collection has different types of items we can declare the variable as a variant.
VBA contains a collection called Sheets. This is a collection of sheets of type Worksheet(normal) and Chart(when you
move a chart to be a full sheet). To go through this collection you would declare the variable as a Variant.
The following code uses For Each to print out the name of all the sheets in the current workbook
Dim sh As Variant
Debug.Print sh.Name
Next sh
Order of Items
For Each goes through items in one way only.
For example, if you go through all the worksheets in a workbook it will always go through from left to right. If you go
through a range it will start at the lowest cell e.g. Range(“A1:A10”) will return A1,A2,A3 etc.
This means if you want any other order then you need to use the For loop.
Both loops in the following example will read the worksheets from left to right.
Dim wk As Worksheet
Debug.Print wk.Name
Next
Dim i As Long
For i = 1 To ThisWorkbook.Worksheets.Count
Debug.Print ThisWorkbook.Worksheets(i).Name
Next
As you can see the For Each loop is neater to write. However if you want to read the sheets in any other order e.g. right to
left then you have to use the for loop.
Dim i As Long
Debug.Print ThisWorkbook.Worksheets(i).Name
Next
Sub UseForEach()
Dim s As Variant
s = "Z"
Next
Debug.Print s
Next
End Sub
In the first loop we try to assign s to “Z”. When happens is that s is now referring the string “Z” and no longer to the item
in the array.
In the second loop we print out the array and you can see that none of the values have changed.
When we use the For Loop we can change the array item. If we change the previous code to use the For Loop you it will
change all the array values to “Z”
Sub UsingForWithArray()
Dim i As Long
arr(i) = "Z"
Next
Debug.Print arr(i)
Next
End Sub
If your Collection is storing Objects the you can change the items using a For Each loop.
For i = 1 To Workbooks.Count
For j = 1 To Workbooks(i).Worksheets.Count
Next j
Next i
End Sub
This time we will use the For Each loop to perform the same task
Sub ReadAllWorksheets()
Next sh
Next wk
End Sub
As you can see this is a neater way of performing this task than using the For Loop.
This code run as follows:
Summary
For
The For loop is slower than the For Each loop.
The For loop can go through a selection of items e.g. 5 to 10.
The For loop can read items in different orderse.g. 10 to 1.
The For loop is not as neat to write as the For Each Loop especially with nested loops.
To exit a For loop use Exit For.
For Each
The For Each loop is faster than the For loop.
The For Each loop goes through all items in the collection\array.
The For Each loop can go through items in one order only.
The For Each loop is neater to write than a For Loop especially for nested loops.
To exit a For Each loop use Exit For.