The For Next and For Each Next Loops Explained for VBA in Excel
31

The For Next and For Each Loops Explained for VBA & Excel

Bottom line: The For Next Loops are some of the most powerful VBA macro coding techniques for automating common tasks in Excel.  This article explains how the loop works to repeat actions on a collection of items, which saves us a ton of time with our jobs.

Skill level: Intermediate

For Next Code Loop Explained for VBA Excel

The Power of VBA Loops

In Excel we spend a lot of time repeating simple tasks.  This could be actions like: formatting multiple ranges, unhiding multiple sheets, copying and pasting to several workbooks, apply filters to multiple tables or pivot tables, replacing values, updating formulas, etc.

Can you think of a few tasks where you had to repeat the same process over and over again?

These tasks can be extremely time consuming and BORING!

Repetitive Excel Tasks Get Boring - VBA Loop

Fortunately, there is a way out.  We can use loops in our VBA macros to repeat actions very quickly.  Tasks that can take hours to do manually can be completed in a matter of seconds with a loop.

The For Next Loop is the most common type of loop that helps us with these repetitive jobs.  In this article we will look at the two types of For Next Loops.

Download the Example File

Download the free Excel file that contains examples of macros with the For Next Loop.

For Next Loop VBA Macro Examples.xlsm (79.0 KB)

Download a PDF version of the article for printing.

The For Next And For Each Loops Explained For VBA Excel - Excel Campus.pdf (490.5 KB)

How Does the For Next Loop Work?

The For Next Loop allows us to loop through a collection of items in Excel.  The collection can be a collection of objects or a list of numbers.

Examples of collections of objects include:

  • Cells in a range.
  • Worksheets in a workbook.
  • Open workbooks on the computer.
  • Pivot tables in a worksheet.
  • Pivot fields in a pivot table.
  • Shapes on a worksheet.
  • And any other object you interact with in Excel.

The job of the For Next Loop is to perform the same actions (lines of code) on each item in the collection.

How a For Next Loop Works in VBA

The example below contains a For Next Loop that loops through each worksheet in the workbook and unhides each sheet.  The loop starts at the first item in the collection (the first sheet in the workbook), and performs the line(s) of code between the For and Next lines for each item in the collection (every sheet in the workbook).

Sub Unhide_Multiple_Sheets()

Dim ws As Worksheet
    
    For Each ws In ActiveWorkbook.Worksheets
        ws.Visible = xlSheetVisible
    Next ws

End Sub

Of course we can use logical statements like If statements to test properties and conditions before performing the actions.  The following macro only unhides sheets that have the phrase “ABC Global Co.” in cell A1 of each sheet, and hides all other sheets.

Sub Unhide_Report_Sheets()

Dim ws As Worksheet
    
    For Each ws In ActiveWorkbook.Worksheets
        If ws.Range("A1").Value = "ABC Global Co." Then
            ws.Visible = xlSheetVisible
        Else
            ws.Visible = xlSheetHidden
        End If
    Next ws

End Sub

The Two Types of For Next Loops

There are really two types of For Next Loops.

  1. For Each Next Loops loop through a collection of items.
  2. For Next Loops loop through a set of numbers.

Let’s take a look at how each works.

The For Each Next Loop: Loops Through a Collection of Items

As we saw above, the The For Each Next Loop allows us to loop through a collection of items or objects.  This is probably the most common loop we use in Excel because we are working with collections of objects.  Again, these collections are the cells in a range, worksheets in a workbook, pivot tables in a worksheet, etc.

For Each Next Loop Loops Through All Items Worksheets in a Collection

We will use the example of writing a For Each Next Loop to loop through all the worksheets in a workbook.

The For Each Next Loop Explained for Excel VBA

There are 4 basic steps to writing a For Each Next Loop in VBA:

  1. Declare a variable for an object.
  2. Write the For Each Line with the variable and collection references.
  3. Add line(s) of code to repeat for each item in the collection.
  4. Write the Next line to close the loop.

Let’s take a look at each of these steps in detail.

Step 1 – Declare a Variable for an Object

We first need to declare a variable that will temporarily store a reference to the object.

The Dim line at the top of the macro declares a variable as an object.  In this case the object is a worksheet.  We can create any variable name we want as long as it is not the same as another reference in VBA.  “ws” is the most common variable name for a worksheet object, but you can change this.

Dim ws As Worksheet

Step 2 – The For Each Line

Next we will write the For Each statement.  This is the first line of code in the loop.

For Each ws In ActiveWorkbook.Worksheets

The first two words are For Each.  Then we type the variable name, followed by the word In  Finally, we specify where the collection exists.  In this case we want to loop through all the worksheets in the ActiveWorkbook.  So, we type ActiveWorkbook.Worksheets.  That line references all the worksheets in the ActiveWorkbook.

If you want to loop through worksheets of a specific workbook, then you can use the Workbooks property to reference that workbook by name.

For Each ws In Workbooks("Book2.xlsx").Worksheets

Just remember that the workbook you reference has to be open before the For Next line of code runs.  Of course, we can use the Workbooks.Open method to open the workbook as well.

Step 3 – Add Code to Repeat for Each Iteration

After the For Each line, we add the line(s) of code that will be performed on each sheet.  In this example we just have one line of code that unhides the sheet.

ws.Visible = xlSheetVisible

In this line of code we are using the ws variable to reference the current worksheet in the loop.  When the loop runs, it sets a temporary reference to the ws variable for each iteration in the loop.

This would be the same as if we were to set the ws variable to a specific sheet using the following line of code.

Set ws = Worksheets(1)

However, we do NOT need this line with the For Each Next Loop.  The loop takes care of setting the variable for us for each iteration in the loop.

For the first iteration in the loop, the ws is set to Worksheets(1).  In the next iteration, ws is set to Worksheets(2).  This continues as the loop iterates through all sheets in the workbook.  This is very powerful because we can reuse the variable to reference the worksheet several times within the the loop.

Step 4 – The Next Line Loops Back

The final line of code in the loop is the Next line.

Next ws

When the macro hits this line of code it does two things:

  1. First, it changes the variable reference to the next item in the collection.  In this example, the ws variable is changed to reference the next sheet in the workbook.
  2. Second, it loops back up to the run the line of code directly below the For Each line.  It then runs all the lines of code between the For Each and Next lines in top to bottom order.

What Happens When the Next Line Runs in a Loop Excel VBA

When the last item in the collection (worksheet in the workbook) is reached, the looping stops, and the macro continues on to the next line of code below the Next line.

What Order Does the For Each Loop Run In?

The For Each Loop always starts at the first item in the collection and loops through to the last item in the order they appear in Excel.  This is based on the index number of the items in the collection.  Here are some examples of the order the loop runs in for common objects.

  • Worksheets: Starts at the first sheet tab in the workbook and loops to the last in the order the tabs are displayed in the workbook.
  • Workbooks: Starts at the first workbook that was opened and loops in the order that workbooks were opened.  Workbooks are assigned an index number as they are opened.
  • Cells: Loops left-to-right, then down.  Starts in the first cell in the range and loops to the next column in the same row, then goes to the next row.
  • Tables & Pivot Tables: Starts with the first object that was create in the sheet and loops in the order the objects were created.  This same principle is true for other objects you create in sheets like shapes, charts, slicers, etc.

Items/Objects Are NOT Selected in the Loop

It’s important to note that when we loop through a collection of objects, each object is NOT selected in Excel.

Loops Do NOT Select Each Item or Object

The loop creates a reference to the item/object with the variable.  The variable is temporarily set to a reference of the object.  The object is NOT selected and does NOT necessarily become the active object.  To select the object we can use the Select or Activate methods.  You would also have to make sure the objects parent object(s) are selected first.  Checkout my article on the Excel Object Model and Object Hierarchy in VBA for more on this.

The Next Loop: Loops Through a Set of Numbers

We can also use the For Next Loop to loop through a set of numbers.  This can be useful when we are looping through userform controls, arrays, or if we want to loop through a collection backwards.
For Next Loop Code Explained Excel VBA Macro
The basic operation of the For Next Loop is the same as the For Each Loop.  The difference is the format of the For line.

Step 1 – Declare a Variable for a Number

To loop through a set of numbers we first need to declare a variable to a whole number data type.  We can use Integer or Long integer.

Dim i As Long

The variable is referred to as the Counter because it increments or counts up/down for each iteration in the loop.

A side note on Long: The Long (integer) data type holds a bigger number than Integer.  It takes up more memory, but today’s computer have so much memory that it’s no longer a problem.  We can use Long variables all the time.  The letter L looks like the number 1 in VBA, so I’m now using i as the variable name even though I use Long as the data type.  This is all a matter of personal preference and you can name the variable whatever you want.

Step 2 – Write the For Statement

Next we write the For statement.  The basic construct is the keyword For, followed by the variable name (counter), then equals sign, start value To end value.

For i = 1 To 10

The start and end values can be referenced as numbers, or we can use integer/long variables in their place.

For i = iStart To iEnd

We can also use properties of objects that return a number.

For i = 1 To ActiveWorkbook.Worksheets.Count

That line of code would return the number of sheets in the active workbook.  However, it is NOT looping through each worksheet.  The loop is just looping through a set of numbers.  We have to create a reference to a worksheet with the counter variable (i) as the index number of the Worksheets property.  Step 3 shows this reference.

Step 3 – Add Code that Repeats for Each Iteration

The rest of the loop functions the same as the For Each loop.  We can add lines between the For and Next lines that will run for each iteration of the loop.  The counter variable can be used multiple times in these lines of code.

Worksheets(i).Visible = True

Step 4 – The Next Line Increments the Number & Loops Back

Finally, we add the Next line at the bottom.

Next i

When the macro runs it will set the variable equal to the first number in the For line.  When the macro hits the Next line, it will add 1 to the value of the variable, or count up.  So, i = 2 in the second iteration of the loop.  It continues to loop until the last number in the loop is reached.

By default, 1 is added to the variable counter for each iteration in the loop.  This is called the Step Value, and we can control the value of each step in the counter.  The Step value is added to the end of the For line.  The following line will add 2 to the counter for each iteration in the loop.

For i = 2 To 20 Step 2

If you wanted to shade every other row in a sheet, you might use a loop like this.

For Next Loop Step Counter Banded Rows Example Excel VBA

Looping Backwards

We can also use the Step Value to loop backwards by specifying a negative number.

For i = 100 To 1 Step -1

Notice that the Start Value is now the larger number and the End Value is the smaller number.  The loops starts at 100 (Start Value) and subtracts 1 from the counter variable (Step -1) for each iteration in the loop until it gets to 1 (End Value).

The Step keyword is optional.  If you do not specify it then VBA assumes a Step value of 1.

Looping backwards is great if you are deleting items.  I will write a separate post on this, but the general idea is that when we are looping through a collection and deleting items, the size of the collection gets smaller as items are deleted.  The loop will typically hit an error once it gets to the 10th item, when there are now only 9 items in the collection.  Looping backwards prevents this potential error.

Exiting the Loop Early

Typically the loop will iterate through all items in the collection, then continue on to the next line of code below the Next line.  However, we can stop the loop early with an Exit For statement.

Exit For

The following macro uses the Exit For statement to exit the loop after the first sheet that starts with the word “Report” is found an unhidden.

Sub Unhide_First_Sheet_Exit_For()
'Unhides the first sheet that contain a specific phrase
'in the sheet name, then exits the loop.

Dim ws As Worksheet
    
    For Each ws In ActiveWorkbook.Worksheets
    
        'Find the sheet that starts with the word "Report"
        If Left(ws.Name, 6) = "Report" Then
            
            ws.Visible = xlSheetVisible
            
            'Exit the loop after the first sheet is found
            Exit For
        
        End If
    Next ws

End Sub

The ws variable retains the reference to the worksheet after the loop is exited early, and can be used again in the code below the loop.

Variable Reference Is Not Reset When VBA For Next Loop Exit Early

Variable Not Required After Next Keyword

You might have noticed that I added the variable after the Next keyword at the bottom of the loop in the examples above.

Next ws
Next i

This is NOT required, and you might not see it in other examples you find on the web. However, I like to include the variable after Next for two reasons.

  1. We can use it when debugging code to see the value of the variable by hovering the mouse over the variable when the code is stopped.
  2. It makes it easier to understand which For line the Next line is connected to. This is especially true when you have multiple loops or nested loops in your macros.

Variable After Next is Not Required in For Next Loop

Therefore, I recommend adding the variable after the Next keyword as a best practice.  A little extra work up front will save time & headache in the future.  Trust me! 😉

Macro Code Examples of VBA For Loops

Here are additional articles with macros that use at least one For Next Loop.

3 Ways to Unhide Multiple Sheets in Excel + VBA Tutorial

Automatic Default Number Formatting in Excel Pivot Tables

3 Tips to Save and Close All Open Excel Workbook Files + Macro

The SUBTOTAL Metrics Macro – Create a Summary Table of All Function Types

How to Add a Table of Contents Image Gallery Sheet to Your Excel Files

Hide & Unhide (Filter) Columns with a Slicer or Filter Drop-down Menu

Filter a Pivot Table or Slicer for the Most Recent Date or Period

How to Make Your Excel Dashboards Resize for Different Screen Sizes

Convert Pivot Table to SUMIFS Formulas + Free VBA Macro

VBA Macro to Hide All Columns That Contain a Value in a Cell

How to Repeat Tasks with VBA Code – Looping – Great article with lots of examples from my friend Chris Newman at The Spreadsheet Guru.

What Task Do You Want To Loop?

I hope that article helps get you started with loops.  Don’t forget to download the free Excel file that contains the code samples.

Loops are definitely an intermediate coding technique that force us to go beyond the macro recorder.  Unfortunately, the macro recorded cannot create loops.  However, this is a skill that you will be able to use over and over again throughout your career to automate simple and complex tasks.  Understanding how to use loops will give you magical powers with Excel.

Please leave a comment below with a task that you want to automate with a loop.  Thank you! 🙂

Please share
Jon Acampora
 

Welcome to Excel Campus! I am excited you are here. My name is Jon and my goal is to help you learn Excel to save time with your job and advance in your career. I've been an avid Excel user and VBA developer for 10+ years. I am also a Microsoft MVP. I try to learn something new everyday, and want to share this knowledge with you to help you improve your skills. When I'm not looking at spreadsheets, I get outdoors and surf. :) more about me

Click Here to Leave a Comment Below 31 comments
James Holmes - August 13, 2017

Hi Jon,
I have been looking at your Next Loop post as I am trying to create a macro to rename all the sheets in a workbook taking cell A2 on each sheet as containing the name for that sheet, but I can’t quite get it right. I wondered if you could get me some help on the code for this as it take along time to do manually when there are a lot of sheets in the workbook.

Reply
Nate O - August 8, 2017

Probably the clearest explanation of how loops work that I’ve ever read. Thank you!

Reply
Ernest - July 31, 2017

Thanks for your article as a beginner it is a very helpful article!

Reply
Edil - July 31, 2017

Dear Jon,

Thanks again for your contribution. I am quite familiar with the For …Next and For Each … Next loops (as well as with the Do While … Loop and Do Until … Loop).

In the For … Next and For Each … Next loops, I only reference the object variable or counter variable in the Next statement, when I use embedded loops.
I do that that for code clarity and readability.

Is it bad habit or even bad programming?

Reply
    Jon Acampora - July 31, 2017

    Hi Edil,

    I believe this is really a matter of personal preference. I added a section to the end of the article above with the heading “Variable Not Required After Next Keyword”. I’m not sure if you saw this. It’s a long article… 🙂

    I give two reasons there, but again it’s just a matter of preference. It’s a habit I’ve gotten into, but honestly I break my own rules sometimes if I’m in a hurry to create a quick macro.

    It’s probably best to just consider you audience, and who might be reading your code or maintaining it in the future. If it’s a project you are going to hand off at some point, then try to make it as easy as possible to read. It will also help when you come back to the macro a year later and have to figure out what you did… 🙂

    I hope that helps.

    Reply
Mitch Gross - July 31, 2017

I would like to automate changing links. We use spreadsheets with a lot of links to monthly worksheets. For example we have ‘lmpsheet 0617.xlsb’, ‘lmpsheet 0717.xlsb’, ‘poolA 0617.xlsb’, ‘poolA 0717.xlsb’, etc. Each month we copy the previous month’s file and name it for the new month, so’poolA 0717.xlsb’ is created from ‘poolA 0617.xlsb’. Then we have to update all of the links to the new month’s files.

For some of the links the new file is in the same folder as the old file. For some the folder changes, but in a predictable way (by month). I would like to create a macro that will open a list of files, change the links, recalculate, and save and close the file.

With the help of the internet I created a file that contains macros that will open, update the links, recalc, save, and close a list of files. My team loves it. They each have their own button and can update the list if needed.

I have been slowly working my way through your VBA Pro course. It has been great.

Reply
Parhat Zunun - July 29, 2017

Hello Jon,

Thank you so much for posting such a useful and easy to understand article. I will definitely use this skill in my daily work activities.

Reply
William - July 28, 2017

Great article Jon! Thank you for your excellent write-up.

Reply
Jerry - July 28, 2017

What I am trying to do is set up a macro to hide columns and set filters which I would store in a table for each worksheet I want to accomplish this on. The tables vary in length and would be able to be changed by the user. Would a For Next loop be possible for this?

Reply
    Jon Acampora - July 31, 2017

    Hi Jerry,
    Yes, you would probably use multiple For Next Loops for that project. Here is an article I have on how to hide columns that contains a specific value.

    You can also reference multiple columns in the same range reference, and then hide them all at one time. You can store strings of text with the range references, so you don’t have to loop.

    Range("B:C,D:D,J:L").EntireColumn.Hidden = True

    I hope that helps get you started. Thanks!

    Reply
Roman - July 28, 2017

Thanks for the great article. I have been trying to understand how FOR EACH loop works and the use of ws variable.

Would it be a good practice to clear the variable set WS = nothing after the loop if we are planning to use variable again in the code?

Reply
    Jon Acampora - July 28, 2017

    Hi Roman,

    Great question! Once the For Next Loop completes, the final iteration on the Next line will attempt to set the variable to the next item in the collection.

    With the For Each Loop, there are no more items in the collection. So, the variable will be set to Nothing. You can test this by adding a break point to a line of code below the loop, then hover over the variable to see that it is set to nothing. Here is a screenshot.

    For Each Next Loop Variable Set to Nothing After Loop

    There are some caveats to this.

    I forgot to mention in the article that we can use the Exit For line to exit the loop early. You might use this once a condition is met, and you no longer need to continue the loop. In this case the variable will still be set to the last object it was set to in the loop.

    So, if you are using an Exit For statement in your loop, you might want to reset the variable below the loop. You can also just set ws to the new worksheet reference. You don’t necessarily have to set it to nothing first.

    The For Next Loop (for looping through numbers) is a little different. After the final iteration in the loop, the Next line still adds the Step value amount to the Counter variable. In the screenshot below you can see that the value of i is 11, even though the End Value is 10.

    For Next Loop Variable Increments by Step Value After Loop VBA Excel

    In this case you might want to reset the variable back to the End Value, if that number is useful later on in the macro. I can’t think of a time when I actually needed to do this, but it’s good to know how it works. I hope that helps. Thanks for the question! 🙂

    Reply
Jen - July 27, 2017

Hi Jon, this is very helpful! I have question: can For Next Loop use for multiple workbook? I have folder content multiple excel workbook, I need to run a macros to lock some columns for each workbook (each workbook only have one worksheet). thanks!

Reply
    Jon Acampora - July 27, 2017

    Hi Jen,

    Great question! Yes, this is definitely possible. There are a few options for looping through workbooks in a folder. My friend Chris has a good article with an example of how to loop through all workbooks in a folder. His approach allows you to browse for the folder, or specify it, then the macro will find all the files in a workbook. You can then add code to run on each workbook.

    If you have all the files open, then you can use a more simple loop to loop through the open workbooks. Here is an example.

    Sub Loop_Open_Workbooks()

    Dim wb As Workbook

        For Each wb In Application.Workbooks
            If Left(wb.Name, 7) = "Report" Then
                'Add code here to perform on the workbook.
            End If
        Next wb
        
    End Sub

    That macro will run the code on the workbooks where the file name starts with Report. You can modify the Left function to match a naming convention for your files. This prevents the macro from being run on any files you have open accidentally or any files open in the background like the Personal Macro Workbook.

    Another solution is to create a list in a worksheet of all the full file paths to each file. Then write a macro that loops through the cells in the list and uses the Workbooks.Open method to open each file. This solution works well if you have files in multiple folders, or you only want to run the code on specific files in the folder.

    I teach this solution in module 11 of my VBA Pro Course. In that module we build an application I call the File Manager. This is a VBA application that allows you to run any macro on a set of files. Here’s a link to a video preview of module 11.

    I hope that helps get you started. Thanks again!

    Reply
      Jen - July 28, 2017

      Thank you so much! Jon, very useful instruction! Also, I am very interesting in your file manager application, I saw the overview video, what about the rest? thanks!

      Reply
Ong Chin Hooi - July 27, 2017

This is what I’m looking for VBA LOOP and that’s automation begins.
Thanks will follow closely.

Reply
Red Barron - July 27, 2017

Jon, great tutorial as usual!
One task I’ve always wanted to automate was the conversion of fields added to my pivot table from SUM to AVG (I deal with a lot of percentages). I find I have to select each field (using right-click in the table) to “Summarize Values By…”, choose AVG, modify the field name (get rid of “Average…” and add a space at the end), then set the Number Value to Percent (with zero decimals), OK, OK., and do this for each field (sometimes there are many!). I knew I couldn’t record a macro for this since it loops, but this tutorial gives me hope I can do it in VBA! If you have a suggestion for this, it would save me eons of time (well maybe not that much!). Keep up the great Excel work!

Reply
    Jon Acampora - July 27, 2017

    Great question Red! That definitely sounds like one of those boring repetitive tasks. 😉

    Yes, we can absolutely use a For Each Next loop to loop through the DataFields in a pivot table. The DataFields are the fields that are in the Values area of a pivot. Here is a macro that will change every field in the Values area of the selected pivot to COUNT.

    Sub Change_PivotField_Function()
    'Changes the function for each field in the values area
    'of the selected pivot table.

    Dim pt As PivotTable
    Dim pf As PivotField

        'Create a reference to the selected pivot table
        Set pt = ActiveCell.PivotTable
        
        'Alternate way to reference a pivot table
        'Set pt = Worksheets("Sheet1").PivotTables("PivotTable1")

        For Each pf In pt.DataFields
            pf.Function = xlAverage
            pf.Calculation = xlNoAdditionalCalculation
            pf.Name = pf.SourceName & " "
            pf.NumberFormat = "0%"
        Next pf

    End Sub

    There are a few properties of the pivotfield that we need to set.

    The Function is the Summarize Values By… property. Here is a list of all function enumerations on MSDN.

    The Calculation property is used for the Show Values As… property. If this has been set then you can change it to xlNoAdditionalCalculation to remove the calculation. Here is a list of all calculation enumerations on MSDN.

    To change the name of the field we can set the Name property to the SourceName and concatenate a space at the end. The SourceName is the name of the field in the source data.

    Finally, we can use some code from last week’s post on Automatic Pivot Table Number Formatting to change the NumberFormat property to a percentage format.

    I hope that helps. I’ll write up a more detailed article in the future on this. Thanks!

    Reply
      Red Barron - July 28, 2017

      Jon,
      I created a macro with this code and it worked beautifully! However I’ve hit an issue with storing this macro for use on future files. The best technique I saw was to save the file as an XLAM in the AddIns folder (then I made a ribbon item to invoke it). This worked but Excel through a security warning each time I opened a file that required me to hit the Enable button. I adjusted the Trusted settings slightly (and have since undone them) but now the macro will not run (“Unable to get the PivotTable property of the Range class”), and I still have the security warning. Any advice? Thanks again!

      Reply
    Red Barron - July 27, 2017

    Thanks for the great reply and code Jon!

    – Red

    Reply
Ray Passave - July 27, 2017

Hi Jon

Thank you so much.

Do you have please some courses on VBA for completly beginners? I would like learn VBA from scrach.

Regards,

Ray Passave

Reply
Ranveer - July 27, 2017

Wow such great article.thanks for writting this article and hope will get more article on VBA. Thanks

Reply
Tj Sleiman - July 27, 2017

The way you explained the code step by step is perfect!!

Thank you.

Reply
Jon Acampora - July 26, 2017

Please leave a comment with a repetitive task that you want to automate with a loop. Thanks! 🙂

Reply

Leave a Reply: