What VBAtoPython Converts — and What It Doesn't
No converter handles 100% of VBA. Here's an honest breakdown of what our engine does well, what it flags for review, what's out of scope, and how your code is handled.
How the Converter Works
VBAtoPython is a deterministic, rule-based engine. No AI by default, no LLMs, no guessing. It processes your VBA through a 4-stage pipeline:
Blocks
Multi-line structures (If, For, Select Case, With)
Chains
Dot-chained expressions (.Range, .Value, .Interior)
Lines
Individual statements, functions, operators
Cleanup
Indentation, imports, helper injection
When the converter encounters a pattern it doesn't have a rule for, it flags it with a warning comment instead of guessing. You always know exactly what needs manual attention.
Real Converter Output
Every Python snippet below was generated by the VBAtoPython engine — not hand-written. This is exactly what the tool produces.
CalcBonus — If / ElseIf / Else with Range access
Conditional logic with Range reads and writes. The converter maps Range to openpyxl worksheet indexing and preserves branching structure.
Sub CalcBonus()
Dim score As Double
Dim bonus As Double
score = Range("B2").Value
If score >= 90 Then
bonus = 1000
ElseIf score >= 70 Then
bonus = 500
Else
bonus = 0
End If
Range("C2").Value = bonus
End Subimport openpyxl
def CalcBonus(ws):
# Dim score As Double
# Dim bonus As Double
score = ws["B2"].value
if score >= 90:
bonus = 1000
elif score >= 70:
bonus = 500
else:
bonus = 0
ws["C2"].value = bonusRateOrder — Select Case with Case Is
Select Case with comparison operators converts to if/elif/else chains. The converter preserves the branching logic exactly.
Sub RateOrder(amount As Double)
Dim discount As Double
Select Case amount
Case Is >= 1000
discount = 0.15
Case Is >= 500
discount = 0.10
Case Is >= 100
discount = 0.05
Case Else
discount = 0
End Select
Range("D2").Value = amount * (1 - discount)
End Subimport openpyxl
def RateOrder(ws, amount):
# Dim discount As Double
if amount >= 1000:
discount = 0.15
elif amount >= 500:
discount = 0.10
elif amount >= 100:
discount = 0.05
else:
discount = 0
ws["D2"].value = amount * (1 - discount)CleanNames — String functions with Cells loop
Trim and UCase map to Python helper functions. The converter auto-generates helper definitions and converts Cells to openpyxl cell() calls.
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 Subimport 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))SumColumn — For loop with Cells and MsgBox
A basic For loop summing cell values. Cells() maps to ws.cell(), MsgBox maps to print(), and the loop range adjusts for Python's exclusive upper bound.
Sub SumColumn()
Dim total As Double
Dim i As Long
total = 0
For i = 2 To 100
total = total + Cells(i, 3).Value
Next i
MsgBox "Total: " & total
End Subimport openpyxl
def SumColumn(ws):
# Dim total As Double
# Dim i As Long
total = 0
for i in range(2, 100 + 1):
total = total + ws.cell(row=i, column=3).value
print("Total: " + total)Fully Automated Conversions
EasyThese patterns convert cleanly with no manual intervention. The output is production-ready.
| Pattern | VBA | Python | Status |
|---|---|---|---|
| Control Flow | If/ElseIf/Else, For/Next, For Each, Do While/Until, Select Case | if/elif/else, for/range, while | Full |
| Function Definitions | Sub/Function with params | def with ws param injection | Full |
| String Functions (19) | Trim, UCase, LCase, Len, Left, Mid, Right, InStr, Replace, Split, Join, etc. | .strip(), .upper(), slicing, .find(), etc. | Full |
| Math Functions (9) | Abs, Int, Sqr, Round, Rnd, Log, Exp, Sgn | abs(), int(), math.sqrt(), round(), etc. | Full |
| Type Functions (12) | CStr, CInt, CLng, CDbl, CBool, IsEmpty, IsNull, IsDate, Val, TypeName | str(), int(), float(), bool(), etc. | Full |
| Date/Time (11) | Now, Year, Month, Day, Hour, Minute, Second, DateAdd, etc. | datetime module | Full |
| Constants (12) | vbCrLf, vbTab, vbNewLine, True, False, Nothing, Empty, Null | "\r\n", "\t", "\n", True, False, None | Full |
| Operators | & , <>, And, Or, Not, = | +, !=, and, or, not, == | Full |
| Comments | ' and Rem | # | Full |
| Variable Declarations | Dim x As Type | # comment (Python doesn't need declarations) | Full |
Converted with Warnings
ModerateThese patterns produce working Python but may need manual review. The converter adds # TODO or # WARNING comments where you should double-check the output.
| Pattern | What Happens | Notes |
|---|---|---|
| Range("A1").Value | ws["A1"].value | Works for simple ranges |
| Cells(r,c).Value | ws.cell(row=r, column=c).value | Named params for clarity |
| .Interior.Color = RGB() | PatternFill() | Only RGB format supported |
| WorksheetFunction.Sum/Min/Max | sum(), min(), max() | Simple mappings work |
| WorksheetFunction.VLookup/Match/Index | Helper stubs with TODO | Needs manual implementation |
| CreateObject("Scripting.Dictionary") | {} | Methods mapped (.Item→[], etc.) |
| CreateObject("Scripting.FileSystemObject") | import os | 10 method mappings |
| On Error GoTo <label> | try/except block | Structure converted, verify logic |
| On Error Resume Next | # TODO comment | Must manually wrap risky lines |
| Call SubName(args) | SubName(ws, args) | Auto ws injection |
| Exit Sub/Function | return | Clean mapping |
| Exit For/Do | break | Clean mapping |
Flagged for Manual Implementation
HardThese patterns are too context-dependent for automated conversion. The converter flags them with comments so you know exactly where to focus manual effort.
| Pattern | Why It's Hard | What We Do |
|---|---|---|
| .Find() / .FindAll() | Complex search with multiple optional params | Flag with warning |
| .Sort() | Multi-key sorting with custom orders | Flag with warning |
| .AutoFilter() | Interactive Excel feature, no openpyxl equivalent | Flag with warning |
| GoTo (non-error) | No structured Python equivalent | Comment with TODO |
| ReDim Preserve | Dynamic array resizing mid-loop | Comment with TODO |
| .Copy/.Paste/.PasteSpecial | Clipboard operations don't exist in openpyxl | Not yet handled |
| .Offset/.Resize | Relative references need context | Not yet handled |
| .Font.Bold/.Size/.Color | openpyxl Font() object has different API | Not yet handled |
| .NumberFormat | Excel format strings ≠ Python format strings | Not yet handled |
Currently Not Supported
Very HardThese patterns require fundamental restructuring that goes beyond line-by-line conversion. They need a human developer who understands both the VBA architecture and the target Python design.
| Pattern | Why |
|---|---|
| Class Modules | VBA classes → Python classes requires OOP restructuring |
| UserForms | GUI dialogs have no direct Python equivalent |
| ActiveX Controls | COM-based UI components |
| Workbook Events (Workbook_Open, etc.) | Event-driven model doesn't map to scripts |
| External COM Objects (Outlook, Word, etc.) | Each needs its own Python library |
| Multi-sheet operations | Converter assumes single worksheet context |
| Array formulas | Require understanding of Excel's calculation engine |
The Numbers
Current converter coverage at a glance:
53
VBA functions
mapped to Python (from 5 categories)
12
VBA constants
mapped to Python equivalents
10+
COM patterns
mapped (Dictionary, FSO, WorksheetFunction)
13
Control flow constructs
mapped (If, For, While, Select Case, With, etc.)
122
Automated tests
ensuring conversion accuracy
4
Pipeline stages
Blocks, Chains, Lines, Cleanup
AI Usage & Code Handling
AI is selective, not default
VBAtoPython is deterministic-first and rule-based. Most VBA macros convert without any AI involvement. When the engine detects a construct that cannot be safely normalized (for example, ambiguous error handling or unstructured control flow), that specific block is flagged and may be optionally assisted by AI. AI is never applied silently, never used as the default path, and all AI-assisted output is clearly labeled for review.
Your code is not retained
Your VBA is processed in-memory to produce a conversion result and compatibility notes. We don't use customer code to train models. We don't retain your code after processing beyond what's required to return results in your session.
FAQ
Does VBAtoPython use AI?
Short answer: Yes — but only when explicitly needed.
Long answer: The default conversion path is deterministic and rule-based, designed to preserve VBA intent without hallucinations. If the engine encounters a construct that cannot be safely converted using deterministic rules alone, it flags that section and may optionally use AI to assist with rewriting that specific block. AI is never used silently, never applied to the entire macro by default, and all AI-assisted output must be reviewed before use.
What's the best use case?
Worksheet-driven automation: data cleanup, report generation, workbook-to-Python migrations. If your macros mostly work with ranges, cells, loops, and standard VBA functions, you'll get clean output with minimal manual review.
What's the worst use case?
Heavy UserForm apps, multi-workbook event-driven systems, or macros that rely on Windows APIs and COM add-ins. These require architectural restructuring that goes beyond line-by-line conversion.
Is my code safe?
Yes. Your VBA is processed in-memory and is not stored, shared, or used for training. We don't retain code after processing.
Related Guides
- Complete Syntax Mapping Reference — Every VBA construct mapped to Python side-by-side.
- Excel VBA to Python with openpyxl — Practical examples of Range, Cells, and worksheet operations.
- VBA String Functions to Python — Trim, Left, Mid, InStr, Replace with edge cases.
- VBA Loops to Python — For, For Each, Do While/Until with range adjustments.
Try It Yourself
Paste any VBA macro and see what converts automatically. The output flags everything that needs manual attention with clear TODO comments.