VBAtoPython
Start Conversion

VBA Loops to Python

For/Next, For Each, Do While, Do Until — every VBA loop type converted to Python with the range() gotcha explained, Step support, and real cell iteration patterns.

Quick Reference: All VBA Loop Types

VBA LoopPython EquivalentKey Note
For i = 1 To 10for i in range(1, 11)Add +1 to stop value
For i = 0 To 20 Step 2for i in range(0, 21, 2)Third arg is step
For i = 10 To 1 Step -1for i in range(10, 0, -1)Countdown loops
For Each item In colfor item in col:Direct mapping
For i = 0 To UBound(arr)for i, v in enumerate(arr)Index + value together
Do While conditionwhile condition:Direct mapping
Do Until conditionwhile not (condition):Negated condition
Do ... Loop While condwhile True: ... if not cond: breakRuns at least once
Exit For / Exit DobreakEarly exit

For / Next → for ... in range()

VBA

For i = 1 To 10
    total = total + i
Next i

Python

for i in range(1, 10 + 1):
    total = total + i

The +1 Gotcha

VBA For i = 1 To 10 includes both 1 and 10 (inclusive). Python range(1, 10) excludes the upper bound (gives 1–9). You must add + 1 to the end value: range(1, 10 + 1). The converter handles this automatically.

For / Next with Step

VBA

' Count by 2
For i = 0 To 20 Step 2
    Debug.Print i
Next i

' Count down
For j = 10 To 1 Step -1
    Debug.Print j
Next j

Python

# Count by 2
for i in range(0, 20 + 1, 2):
    print(i)

# Count down
for j in range(10, 1 - 1, -1):
    print(j)

Python's range(start, stop, step) maps directly to VBA's For i = start To stop Step step. The converter adjusts the stop value for both positive and negative steps.

For Each → for ... in

VBA

For Each cell In Range("A1:A20")
    If cell.Value > 100 Then
        cell.Interior.Color = RGB(255, 0, 0)
    End If
Next cell

Python

for cell in ws["A1:A20"]:
    if cell.value > 100:
        cell.fill = PatternFill(
            start_color="FF0000",
            fill_type="solid"
        )

VBA For Each iterates over collections. Python for ... in works with any iterable. When iterating over cell ranges, openpyxl returns tuples of rows.

For Loop with Index → enumerate()

VBA For loops often use i as both a counter and an array index. Python's enumerate() is the direct equivalent — no separate counter needed.

VBA

Dim fruits(2) As String
fruits(0) = "Apple"
fruits(1) = "Banana"
fruits(2) = "Cherry"
For i = 0 To UBound(fruits)
    Debug.Print i & ": " & fruits(i)
Next i

Python

fruits = ["Apple", "Banana", "Cherry"]
for i, fruit in enumerate(fruits):
    print(f"{i}: {fruit}")

Use enumerate(fruits, start=1) if your VBA array starts at 1 instead of 0.

Do While → while

VBA

row = 2
Do While Cells(row, 1).Value <> ""
    total = total + Cells(row, 1).Value
    row = row + 1
Loop

Python

row = 2
while ws.cell(row=row, column=1).value != "":
    total = total + ws.cell(row=row, column=1).value
    row = row + 1

Do Until → while not

VBA

Do Until found = True
    row = row + 1
    If Cells(row, 1).Value = target Then
        found = True
    End If
Loop

Python

while not (found == True):
    row = row + 1
    if ws.cell(row=row, column=1).value == target:
        found = True

Do Until condition becomes while not (condition). The converter wraps the negated condition in parentheses to preserve operator precedence.

Post-Condition Loops (Do ... Loop While/Until)

VBA

Do
    answer = InputBox("Enter value:")
Loop While answer = ""

Python

while True:
    answer = input("Enter value:")
    if not (answer == ""):
        break

Python has no built-in do-while construct. The converter uses while Truewith a conditional break at the end to guarantee the body executes at least once.

Exit For / Exit Do → break

VBA

For i = 1 To 1000
    If Cells(i, 1).Value = "STOP" Then
        Exit For
    End If
Next i

Python

for i in range(1, 1000 + 1):
    if ws.cell(row=i, column=1).value == "STOP":
        break

Both Exit For and Exit Do map to Python's break. Exit Sub and Exit Function map to return.

Common Pattern: Cell Processing Loop

The most common VBA loop pattern is iterating through rows, reading cells, processing data, and writing results. Here is a complete example with actual converter output.

VBA

Sub CleanNames()
    Dim i As Long
    Dim raw As String
    For i = 2 To 50
        raw = Cells(i, 1).Value
        If raw <> "" Then
            Cells(i, 2).Value = Trim(UCase(raw))
        End If
    Next i
End Sub

Python (converter output)

import openpyxl

def vba_trim(s):
    return str(s).strip()

def vba_ucase(s):
    return str(s).upper()

def CleanNames(ws):
    # Dim i As Long
    # Dim raw As String
    for i in range(2, 50 + 1):
        raw = ws.cell(row=i, column=1).value
        if raw != "":
            ws.cell(row=i, column=2).value = \
                vba_trim(vba_ucase(raw))

This example combines loops, cell access, conditionals, and string functions — all handled automatically by the converter.

Related Guides

Convert your loops automatically

Paste a VBA macro with loops and see the Python output with correct range() bounds.