VBA Loops Within Loops: How Nested Loops Work in Excel

VBA & macros · Updated November 3, 2026

VBA Loops Within Loops: How Nested Loops Work in Excel

Yes. VBA can run one loop inside another; this is called a nested loop. The outer loop runs once, the inner loop completes all its iterations, and then the outer loop advances. This pattern is useful for working through rows and columns, comparing every item in one list with every item in another, or repeating a task across multiple dimensions.

What a nested VBA loop means

A loop repeats a block of code while a counter moves through a range or a condition remains true. Putting a second loop inside that block creates a nested loop. The loop written on the outside is the outer loop; the loop inside it is the inner loop. VBA uses the same loop structures whether a loop stands alone or is nested.

For example, imagine checking each row in a worksheet and, within each row, checking several columns. The row loop selects a row. The column loop then visits each relevant column in that row. Only after the column loop finishes does the row loop move to its next row. If there are five rows and three columns, the inner block runs 15 times: five outer iterations multiplied by three inner iterations.

Nesting is not limited to two loops. You can put a third loop inside the second, but each added level makes the execution flow harder to follow. Use the fewest levels that clearly describe the task, and give loop variables meaningful names so it is obvious which dimension each one represents.

How For…Next loops run

A For...Next loop is a natural choice when you know how many times a section should repeat. The counter begins at the starting value, runs through the ending value, and changes by one by default. You can specify another increment with Step. In a nested structure, each loop needs its own counter and its own matching Next.

With the outer loop set to rows 2 through 6 and the inner loop set to columns 1 through 3, VBA processes A2, B2, and C2 first. It then processes A3, B3, and C3, continuing until it reaches row 6. The inner counter starts over at its initial value each time the outer loop begins another iteration. This reset is expected behavior, not a mistake.

Indent the inner loop and its contents. Indentation does not change how VBA runs the code, but it makes the loop boundaries visible and helps prevent a misplaced Next from going unnoticed. Naming the counter after its purpose, such as rowNum and colNum, is clearer than reusing a vague name like i for every level.

A worksheet example: visit every cell in a block

This macro writes a label into each cell in A2:C6. The row counter controls the worksheet row and the column counter controls the worksheet column. Before running any macro, save a copy of the workbook: VBA changes cannot be undone with Ctrl+Z. Save the working file as an Excel Macro-Enabled Workbook (.xlsm) if you need to retain the macro.

Option Explicit

Sub FillGrid()
    Dim ws As Worksheet
    Dim rowNum As Long
    Dim colNum As Long

    ' Use the active worksheet for this example.
    Set ws = ActiveSheet

    ' Visit rows 2 through 6 and columns A through C.
    For rowNum = 2 To 6
        For colNum = 1 To 3
            ws.Cells(rowNum, colNum).Value = "R" & rowNum & "C" & colNum
        Next colNum
    Next rowNum
End Sub

After the macro runs, A2 contains R2C1, B2 contains R2C2, and C2 contains R2C3. The same pattern continues through row 6, so 15 cells receive values. Cells(rowNum, colNum) uses numeric row and column indexes: column 1 is A, column 2 is B, and column 3 is C.

To use this example, open the Visual Basic Editor from Excel’s Developer tab, insert a standard module, and paste in the code. On Windows, you can add the Developer tab through File > Options > Customize Ribbon. In Excel for Mac, use Excel > Settings > Ribbon & Toolbar and enable Developer. Menu labels can vary slightly by release. Run only macros you understand and trust.

Choosing the right kind of nested loop

Use For...Next when the number of iterations is known or can be calculated before the loop starts. It is often the clearest option for a fixed worksheet range, a numbered sequence, or a known number of records. The counter also gives you a direct way to refer to a row or column.

Use Do While or Do Until when repetition depends on a condition rather than a fixed count. For example, a loop might continue until a cell is blank or until a value reaches a threshold. Nesting these structures works, but take care that each condition can eventually become false. Otherwise, a loop may never finish.

Use For Each when you want to visit every object in a collection, such as each worksheet in a workbook or each cell in a range. A For Each loop can be nested inside another loop, but consider whether the same cells or objects are being visited more than necessary. If the task is specifically a rectangular block of cells, two indexed For...Next loops may make the row-and-column relationship easier to see.

When nested loops are useful in Excel

Nested loops are helpful whenever one set of items must be processed in combination with another. A two-dimensional range is the most familiar example, but the same logic can apply to worksheets and rows, products and regions, or search terms and data records. The structure lets you express one repeatable action for each combination.

  • Format a range: Visit each cell in a defined rectangle and apply a value, number format, or check.
  • Compare lists: For each item in a first list, inspect items in a second list to find matches. For large lists, a lookup, dictionary, or other optimized approach may be preferable.
  • Build a report: Loop through categories on the outside and periods or measures on the inside to assemble output.
  • Check multiple conditions: Evaluate a group of fields for each record, then take an action if the required conditions are met.

For worksheet work, the order matters. Row-first traversal, as in the example, finishes one row before moving down. Column-first traversal would finish one column before moving across. Either order can be correct; choose the one that aligns with the task and makes the code easiest to understand.

How many times does the inner code run?

When both loop ranges are fixed and the inner loop completes on every outer iteration, the number of executions of the innermost block is the number of outer iterations multiplied by the number of inner iterations. A loop from 2 to 6 has five iterations, and a loop from 1 to 3 has three, so the example’s assignment runs 5 × 3 = 15 times.

With three complete nested loops, multiply all three iteration counts. For instance, four outer iterations, five middle iterations, and six inner iterations produce 120 executions of the innermost block. This multiplication is a useful way to estimate how much work a macro will perform. It does not necessarily predict the run time, because each operation can have a different cost.

If the inner loop’s limits depend on the outer counter, the total may differ from a simple fixed product. A condition may also cause an early exit, so the actual number of executions can be smaller. When performance matters, estimate the work from the real limits and conditions rather than counting only the visible loop levels.

Common mistakes and how to avoid them

  • Using the same counter at two levels: Give each active loop its own variable. Reusing a counter can change its value unexpectedly and make the result difficult to reason about.
  • Pairing the wrong Next statements: Close the inner loop before the outer loop, and include the counter name after each Next. This makes the intended pairing explicit.
  • Setting the wrong endpoint: VBA includes both the start and end values in a For...Next loop. A loop from 1 to 3 runs three times, not twice.
  • Forgetting that the inner loop restarts: The inner loop begins again on every outer iteration. If it should continue from its previous value instead, the logic needs a different design.
  • Creating an endless condition-based loop: Make sure the code inside a Do loop can change the condition, or provide another clear way for the loop to end.
  • Changing worksheet state without tracking it: If a macro changes active sheets, selections, or ranges, be clear about which worksheet each operation targets. Referencing a worksheet object directly, as the example does, reduces ambiguity.

A nested Exit For exits the loop it is currently inside, which is normally the inner loop. It does not automatically stop every outer loop. If a match should end the entire search, use a Boolean flag checked by the outer loop, or structure the search so the outer loop can also exit. This distinction is a common source of macros that continue searching after the desired result has already been found.

Performance, debugging, and safer habits

Nested loops can become slow when they perform many worksheet reads or writes. Interacting with worksheet cells repeatedly from VBA has overhead, so a macro that checks every cell in a large range may take longer than expected. For bigger jobs, read a range into a VBA array, process the values in memory, and write results back in a block. That approach can be substantially more efficient, though it requires care when handling ranges of different sizes.

First make the loop correct and easy to inspect; optimize only when the workload justifies it. Use the Visual Basic Editor’s Debug > Step Into command to advance through a macro one statement at a time, and inspect the counter values as the loops run. Testing on a small range helps reveal off-by-one errors before the macro processes a full worksheet.

Be especially cautious with code that deletes rows, clears cells, or overwrites existing data. Save a separate copy before running it, and consider testing on a duplicated sheet. Macros are not reversed by Excel’s Undo command. If a long process needs better responsiveness, application settings such as screen updating can sometimes be adjusted, but restore any setting you change even if an error occurs. Avoid adding such optimizations until you understand their effects.

Frequently Asked Questions

Can you put a For loop inside another For loop in VBA?

Yes. Put the complete inner For...Next block between the outer loop’s For and Next statements. Use a different counter for each loop and close the inner loop first.

Does the inner loop restart each time?

Yes. Each time the outer loop advances, VBA runs the inner loop again from its starting value through its ending value. That is what lets it process every inner item for each outer item.

Can VBA have more than two nested loops?

Yes. VBA allows additional nested loops, and each needs its own matching loop-ending statement. More levels increase the number of iterations and can make the code harder to maintain, so use them only when they represent genuinely separate dimensions of the task.

Does Exit For stop all nested loops?

No. It exits the nearest active For loop only. To stop an outer loop as well, add logic that communicates the condition to the outer level, such as a flag, or organize the code around a suitable procedure exit.

Are nested loops always the best way to process Excel data?

No. They are clear for small, straightforward tasks, but repeated cell-by-cell operations can be slow on large ranges. Excel worksheet functions, arrays, or a lookup structure may fit better depending on the task and data size.

Related

Try it: the Column Letter to Number: aA is 27, XFD is 16,384. Converts both ways.

More in VBA & macros

Sources: Function behaviour and menu paths: Microsoft Support documentation for Excel. Method & sources

Spotted an error in this guide? Let us know.