VBAtoPython

VBA GoTo & Error Handling to Python

GoTo and On Error are the most challenging VBA patterns to convert. This guide shows how to refactor unstructured jumps into clean Python with try/except, while loops, and functions.

Why GoTo Exists in VBA

VBA inherited GoTo from BASIC. It serves three common purposes in legacy code:

  1. Error handling: On Error GoTo ErrHandler is VBA's only structured error mechanism.
  2. Retry loops: Jumping back to a label after a failed operation.
  3. Cleanup blocks: Jumping to a cleanup label before exiting a Sub.

Python has structured alternatives for all three — try/except, while loops, and try/finally.

Why the Converter Flags GoTo

The VBAtoPython converter does not attempt to automatically convert GoTo or On Error statements. Instead, it flags them with TODO comments and warnings. This is intentional:

  • GoTo can jump to arbitrary labels, creating control flow that has no direct Python equivalent.
  • Guessing the intent of a GoTo jump risks introducing subtle bugs that are harder to find than doing the refactor manually.
  • The right Python pattern depends on what the GoTo is doing (error handling, retry, cleanup), which requires human judgment.

Pattern 1: On Error GoTo → try/except

This is the most common GoTo pattern. VBA uses labels for error handlers; Python uses structured exception blocks.

VBA

Sub ProcessFile()
    On Error GoTo ErrHandler

    Open "data.txt" For Input As #1
    ' ... process file ...
    Close #1
    Exit Sub

ErrHandler:
    MsgBox "Error: " & Err.Description
    Close #1
End Sub

Python

def process_file():
    try:
        with open("data.txt") as f:
            # ... process file ...
            pass
    except Exception as e:
        print(f"Error: {e}")

Python's with statement also replaces the need for explicit Closecalls — the file is closed automatically when the block exits, even if an exception occurs.

Pattern 2: On Error Resume Next → explicit try/except

On Error Resume Next silently ignores all errors and continues execution. This is dangerous because it hides bugs. In Python, handle specific expected errors explicitly.

VBA

Sub SafeRead()
    On Error Resume Next
    val = Cells(1, 1).Value
    x = CDbl(val)
    If Err.Number <> 0 Then
        x = 0
        Err.Clear
    End If
    On Error GoTo 0
End Sub

Python

def safe_read(ws):
    val = ws.cell(row=1, column=1).value
    try:
        x = float(val)
    except (ValueError, TypeError):
        x = 0

Instead of suppressing all errors, Python catches only the specific exceptions you expect (ValueError, TypeError). Unexpected errors still propagate and surface immediately.

Pattern 3: GoTo Retry → while loop

VBA

Sub GetInput()
Retry:
    answer = InputBox("Enter a number:")
    If Not IsNumeric(answer) Then
        MsgBox "Invalid input"
        GoTo Retry
    End If
End Sub

Python

def get_input():
    while True:
        answer = input("Enter a number:")
        try:
            float(answer)
            break
        except ValueError:
            print("Invalid input")

Any GoTo that jumps backward to a label is effectively a loop. Replace with while True and break when the condition is met.

Pattern 4: GoTo Cleanup → try/finally

VBA

Sub DoWork()
    Dim conn As Object
    Set conn = CreateObject("...")
    On Error GoTo Cleanup

    ' ... work with conn ...

Cleanup:
    conn.Close
    Set conn = Nothing
End Sub

Python

def do_work():
    conn = create_connection()
    try:
        # ... work with conn ...
        pass
    finally:
        conn.close()

finally guarantees the cleanup code runs whether an exception occurred or not — exactly the same guarantee as VBA's GoTo Cleanup pattern.

VBA Labels → Comments

Labels that are only used as GoTo targets (not for error handling) are converted to comments by the converter, since Python has no label concept.

VBA

StartProcess:
    ' code here
Done:
    Exit Sub

Python (converter output)

# label: StartProcess
    # code here
# label: Done
    return

Related Guides

See what the converter flags

Paste a macro with GoTo or On Error and see exactly which lines need manual refactoring.