Debugging VBA Code
Master debugging tools and techniques to find and fix VBA errors quickly
Quick Reference
F8: Step through code line by line
F9: Set/remove breakpoint
Ctrl+G: Open Immediate Window
Debug.Print: Output to Immediate Window
VBA Editor Debug Tools
Debug Menu Overview:
- Compile VBAProject: Check for syntax errors before running
- Step Into (F8): Execute one line, enter procedures
- Step Over (Shift+F8): Execute one line, skip over procedures
- Step Out (Ctrl+Shift+F8): Run until current procedure exits
- Run To Cursor (Ctrl+F8): Run until reaching cursor position
- Toggle Breakpoint (F9): Pause execution at line
- Clear All Breakpoints (Ctrl+Shift+F9): Remove all breakpoints
Key Keyboard Shortcuts:
| Key | Action |
|---|---|
| F5 | Run code / Continue |
| F8 | Step Into (line by line) |
| Shift+F8 | Step Over |
| F9 | Toggle Breakpoint |
| Ctrl+G | Immediate Window |
| Ctrl+Break | Stop running code |
Using Breakpoints
Breakpoints pause code execution at specific lines, letting you inspect variables and step through code.
Setting Breakpoints:
- Click in the left margin (gray bar) next to a line
- Press F9 with cursor on the line
- Red dot appears - code will pause here
- Line highlights in brown when breakpoint is hit
Example Use Case:
Set breakpoint inside loop to inspect values each iteration
When Code Pauses:
- Hover over variables to see current values
- Use Immediate Window to test expressions
- Press F8 to execute next line
- Press F5 to continue running
- Edit code and continue (if changes are simple)
Immediate Window (Ctrl+G)
The Immediate Window lets you test code, print values, and modify variables during debugging.
Print Values with Debug.Print:
Output appears in Immediate Window - perfect for logging
Test Expressions While Debugging:
When code is paused, type in Immediate Window:
Modify Variables:
Change variable values while debugging:
Execute Commands:
Watch Window
Monitor specific variables or expressions as code runs.
Adding Watches:
- View → Watch Window (or Debug → Add Watch)
- Enter expression to watch (variable name, calculation, etc.)
- Watch Window shows value as code executes
- Value updates automatically when changed
Watch Types:
Watch Expression:
Simply shows the value (most common)
Break When Value Is True:
Pause code when expression becomes True
x > 100Break When Value Changes:
Pause when variable changes
Useful Watch Expressions:
Locals Window
Automatically shows all variables in current scope - no setup required!
Accessing Locals Window:
View → Locals Window (when debugging)
What It Shows:
- All variables in current procedure
- Module-level variables
- Object properties (expandable)
- Array contents (expandable)
- Updates automatically as you step through code
Pro Tip: Locals Window is the easiest way to see all variable values at once. No need to add watches for everything!
Common Debugging Scenarios
1. Code Runs But Wrong Results:
Add Debug.Print statements to trace logic:
2. Loop Issues:
Set breakpoint inside loop, inspect counter:
3. Object Not Set Errors:
Check object before use:
4. Slow Code Performance:
Time sections of code:
Stop Statement
The Stop statement pauses code execution like a breakpoint, but written in code.
Usage:
When to Use: Conditional debugging - pause only when specific conditions are met. Remove Stop statements before production!
Debug.Assert Statement
Pauses code if a condition is False - perfect for validating assumptions.
Example:
Common Assertions:
Debugging Best Practices
Troubleshooting Common Issues
Code won't stop at breakpoint:
- Make sure code actually reaches that line
- Check if breakpoint is enabled (should be red, not white)
- Try Debug → Clear All Breakpoints and set again
Can't edit code while debugging:
- Simple changes OK, major changes require stopping
- Can't add/remove procedures or change declarations
- Press Stop or Reset button to exit debug mode
Immediate Window not showing output:
- Press Ctrl+G to open Immediate Window
- Check if output is scrolled up
- Verify Debug.Print statements are executing
Variables show "Out of context":
- Variable is out of scope (different procedure)
- Code must be paused in procedure where variable exists
- Use module-level variables if needed across procedures