Why Excel Macros Break: Five Causes and the Fix for Each
A recorded macro records what you did and where. It has no idea what it is looking at — which is why it keeps running after the data underneath it has changed, and why the failure is often silent.
Short answer
The root cause, in one sentence
A macro does not know what it is looking at. It knows that it wrote a value into cell D7, so next time it writes into D7 — even if D7 is now three columns to the right of where the amount lives.
The silent failure is the real problem
Cause 1: the structure moved
A column inserted, a row inserted, a header reworded, a new column added at the end. Recorded macros store addresses absolutely, so every reference after the insertion point is now off by one.
| What changed in the source | What the macro does | Why it does not error |
|---|---|---|
| A column inserted at the left | Writes to the old column numbers, one to the left of the intended columns | The cells exist — they are simply the wrong cells |
| A row inserted at the top | Reads the header as data and treats the first data row as a variable name | Reading a cell always succeeds, whatever it contains |
| A header reworded, e.g. “Inv No” to “Invoice Number” | A Find operation returns nothing and the macro proceeds from the wrong starting point | Find returning nothing is not an error unless you test for it |
| A column deleted | Reads the next column instead, silently shifting the meaning of every value | The cells are still there |
Cause 2: a name changed
| Renamed | What breaks |
|---|---|
| The sheet name | Every reference to Sheets("Data") and every recorded sheet switch |
| The workbook name | Every reference to Workbooks("Report.xlsx"), and any external reference in a formula |
| The folder | Every path stored in the macro — Open, SaveAs, Dir |
| The file extension | A macro that opens “August.xls” fails when the file becomes “August.xlsx” |
ActiveSheet is the trap
ActiveSheet.Range("A1").Value = ... writes into whatever sheet happens to be active — which depends on which sheet the user was on when they ran it. This works perfectly for the person who wrote it and fails for everybody else, and it fails without an error. Reference sheets explicitly.Cause 3: the data shape changed
This is the most common one in finance work, because the number of rows changes every month by design.
- A recorded range of fixed length. The macro was recorded selecting A2:F848, so it processes 847 rows for ever. Next month has 902 and 55 rows are ignored.
- A recorded range that is now too long. If the range was recorded when the file was longer, the macro now overwrites rows below the data.
- A loop bounded by a hard-coded number.
For i = 2 To 848is the same problem expressed in code rather than in a selection. - A newly blank row in the middle. Code that stops at the first blank cell stops early, silently processing only part of the data.
Cause 4: the environment changed
| Change | Effect |
|---|---|
| The file was emailed and is now blocked | Macros are disabled by default in files received from outside — the recipient sees a security warning and must enable content |
| The file was saved as .xlsx | Macros cannot be stored in .xlsx; the macro is lost unless the file is .xlsm |
| A Trust Center setting restricts macro locations | Macros in a download folder do not run at all |
| An add-in was installed | Another add-in can interfere with the object model or take over a shortcut key |
| A different Excel version | Rare in practice, but some object-model behaviours differ between versions |
| The file is open elsewhere | A macro that opens a file already open read-only in another session fails, or opens a stale copy |
A macro-enabled workbook must be saved as .xlsm. Renaming an .xlsx to .xlsm does not preserve macros that were never stored — the file has to be saved in the right format from the start.
Cause 5: the macro never checked anything
Every problem above would be caught by a check at the top of the macro. Most recorded macros have none, and many have the one thing that guarantees silence:
On Error Resume Next
This instruction tells Excel to continue past any error as though nothing happened. It is the most common single line in a broken macro, and it converts every failure above into a silent one. Remove it unless you have a specific reason and are handling the error explicitly.
How to make a macro robust
| Fragile | Robust | Why |
|---|---|---|
Sheets("Data").Range("D7") | wsData.ListObjects("tblSales").ListColumns("Amount").DataBodyRange | Refers to the column by name, so inserting a column to its left changes nothing |
Range("A2:F848") | rng.End(xlDown) | The range is discovered from the data rather than remembered |
ActiveSheet | Set ws = ThisWorkbook.Worksheets("Data") | Independent of which sheet the user happens to be looking at |
"C:\Reports\August.xlsx" | Application.FileDialog(msoFileDialogFolderPicker) | The folder is chosen at run time, so moving it does not break anything |
For i = 2 To 848 | lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row | The loop ends where the data ends, whatever the row count this month |
Selection.Copy | rngSrc.Copy Destination:=rngDest | Copying from a named object is faster and does not depend on the current selection |
On Error Resume Next | Remove the line | Removing it means failures are visible rather than absorbed |
The single most valuable guard: validate before you act
At the top of the macro, before anything is written, confirm that you are looking at the file you think you are. Three checks catch the great majority of breakages.
Confirm the sheet exists
Confirm the expected headers are present
Confirm the source file is where you think it is
Fail loudly, at the start
Then prove it worked
- Write a log. Append a line to a log sheet or a text file: the source file, the row count in, the row count out, and the total of a control column. When something is questioned later, the log answers it.
- End with a reconciliation. A total from the input that must equal a total in the output. If it does not, the macro should say so rather than finish quietly.
- Keep ScreenUpdating on while you develop. Turning it off makes the macro faster and removes the visual evidence of what it is doing. Turn it off only once the macro is proven, and always restore it in a cleanup section, including on the error path.
- Store the macro in the workbook, not in a personal macro workbook. A personal macro workbook lives on one machine; a shared process has to live with the file.
Debugging a macro that has already broken
- 1Open the VBA editor and step through the code with F8 rather than running it. You see each line execute and each variable change, which tells you exactly where the assumption fails.
- 2Watch the relevant values in the Immediate window with Debug.Print. Printing the last row, the sheet name and a header cell to the Immediate window is usually enough to reveal the problem.
- 3Check the recorded addresses against the current sheet. Compare the address in the code with the cell that actually holds the value today.
- 4Look for On Error Resume Next and remove it temporarily so the real error surfaces.
- 5Fix the macro at the point of the assumption, not at the point of the symptom — using a named range instead of an address is a fix; adding one to a column number is not.
When to stop repairing the macro
| If the macro mainly does this | Better tool |
|---|---|
| Imports files from a folder | Power Query From Folder |
| Cleans incoming data | Power Query — the cleaning steps are recorded and replayed |
| Combines sheets or workbooks | Power Query append |
| Matches two files and lists differences | Power Query anti joins, or a dedicated matching tool |
| Formats a report, creates sheets, exports PDFs, prints | A macro is the right tool — keep it |
| Sends emails with attachments | Neither, strictly — but a macro can drive that, and it is a reasonable use |
The dividing line is whether the macro is manipulating data or the application. Data work belongs in Power Query, which records steps and adapts to a changed row count. Application work — formatting, sheet management, exporting, printing — belongs in a macro, and a macro doing only that is far less likely to break, because formatting does not change shape the way data does.
If you are weighing up how far to take this, automating repetitive Excel tasks sets out the ladder in full. And where the recurring step is matching two sets of records rather than preparing them, the Piloteq Automate workflow replaces a recorded-position approach with saved rules — the same reason a named range survives an inserted column.
If you would rather not build this by hand
When the fragile step is the matching itself
Piloteq Automate handles the records-matching part of a recurring process with saved rules rather than recorded positions, so a change in the incoming file does not silently change the answer.
- ✓Match rules defined as settings, not as code
- ✓Group matching and amount tolerance
- ✓Duplicate detection across both files
- ✓The reason recorded against every result
Frequently asked questions
Why does my Excel macro stop working after I add a column?+
Because a recorded macro stores cell addresses and column numbers rather than the intent behind them. If you inserted a column, the macro continues to write to the same positions it recorded — which now hold something else. It often does not error at all; it simply puts the values in the wrong place and finishes. The fix is to reference columns by their header name or by a named range rather than by position.
Why does my macro run but produce the wrong output?+
A macro has no idea what it is looking at. It does what you did, in the cells where you did it. If the source layout changed, or the data now starts on a different row, the macro follows the recorded positions into the wrong data. This silent failure is more dangerous than a macro that stops with an error, because there is nothing to notice.
What is the most common cause of a macro breaking?+
A change in the source workbook rather than a change in the macro. In order of frequency: a column or row inserted so the recorded addresses no longer point at the right cells, a sheet renamed, the file moved to a different folder, and the number of rows changing so that a recorded range of fixed length no longer covers the data.
How do I make an Excel macro more reliable?+
Reference sheets by a variable rather than by whatever is active, find the last row dynamically instead of using a fixed range, store file paths in constants or ask for the folder at run time, remove On Error Resume Next so failures are visible, and add a validation step at the start that confirms the expected headers are present before the macro changes anything.
Why does Excel block my macro when I send the file to a colleague?+
Files received from outside often carry a mark that Excel treats as untrusted, and Excel disables macros in them by default. The colleague sees a security warning and has to enable the content. There are also Trust Center settings that can block macros from any location other than a trusted folder. Both are security features working as intended, and both mean a macro-based process needs the people receiving the file to know what to do with the warning.
Should I use a macro or Power Query?+
If the work is importing, cleaning, combining or reshaping data, Power Query is usually better — it records steps rather than positions, and it adapts to a changed number of rows without any code. If the work is driving the interface — formatting, creating sheets, exporting files, printing — a macro is the right tool. Many good processes use a query to prepare the data and a short macro to present it.