Key takeaways
- A macro that fails silently can leave a partial write and no evidence.
- Use one cleanup path so settings are restored on success and failure.
- Log the context, error details, affected record, and outcome of each run.
- Test the failure path as deliberately as the successful one.
On this page
Silent failure is the real risk
A macro that stops with an error dialog is inconvenient. A macro that stops after writing half its output, with screen updating switched off and alerts suppressed, is dangerous. The user sees a frozen screen or a partial report and cannot tell which records were processed.
Error handling is the part of the macro that decides what happens after something goes wrong. Logging is the part that leaves evidence. Together they turn an opaque failure into a message, a record, and a recoverable state.
Structure every routine
Give each procedure one job and a predictable shape: validate inputs, switch settings, do the work, restore settings, then exit. Put the error handler at the end and jump over it on success. VBA has no finally block, so the cleanup steps need their own label and must run from both paths.
Use On Error GoTo rather than On Error Resume Next for the main flow. Resume Next is appropriate for a specific, expected failure, such as deleting a file that may not exist, and should cover one statement rather than the whole procedure.
Restore application settings in the cleanup path, not at the end of the happy path. If the routine disables events, alerts, or screen updating, a failure before the last line would leave the application in that state for the next run.
- Validate the workbook, sheet, and input range before changing anything.
- Record the original calculation and screen settings.
- Use one cleanup path for success and failure.
- Exit the procedure before the error label on success.
- Never leave events or alerts disabled after a failure.
Handle, do not hide
An error handler should capture the number, description, and source, then decide whether to retry, skip, or stop. A missing optional file may be skippable. A missing required sheet is not. If the procedure cannot continue, report the failure and leave the workbook in a known state.
Avoid empty handlers that swallow every error. They convert a bug into a silent wrong answer. When you re-raise an error, preserve the original details so the next handler or the log can show what actually happened.
- Missing optional file: log a warning and continue.
- Missing required sheet: stop and report.
- Locked output file: retry briefly, then stop.
- Bad row in a loop: log the key and skip.
- Unexpected error: stop, log, and restore settings.
What a useful log contains
A log entry needs enough context to reconstruct the run without the user's memory. Record the time, the workbook, the procedure, the severity, the error number, the description, the record or file being processed, and the outcome. Add a run identifier when one execution processes many records.
Write to an append-only table on a dedicated sheet, or to a text file when the workbook may be closed or corrupt. Do not overwrite the previous entry. Logging can fail too, so wrap the write in its own handler and fall back to a message rather than taking down the main job.
Keep the log bounded. Append rows to a table, archive or clear old entries on a schedule, and batch writes rather than writing one cell at a time inside a long loop. Never store credentials in the log.
| Field | Purpose | Example |
|---|---|---|
| Timestamp | Orders events and shows duration | 09:14:22 |
| Run ID | Groups entries from one execution | R-1042 |
| Procedure | Locates the failing routine | RefreshReport |
| Severity | Separates warnings from failures | Error |
| Record key | Identifies the affected row | INV-2291 |
| Error details | Supports diagnosis | 53, file not found |
| Outcome | States what was written or skipped | Skipped, no total |
Test the failure path
Force the errors you expect: rename a source file, lock the output, remove a sheet, pass an empty range, and use a read-only workbook. Confirm that the message is accurate, the log entry exists, and the cleanup restored the application settings.
Then test the recovery. Can the user re-run the macro without duplicating records? Is there a staging area or a backup? Document the restart point, the owner, and the meaning of each severity. A macro is easier to support when failure is a designed path rather than an exception.
- Test with a missing file and a locked output.
- Check that the log records skipped rows.
- Re-run after a failure and compare the output.
- Confirm settings are restored on every path.
Frequently asked questions
Is On Error Resume Next ever acceptable?+
Yes, for a specific expected failure where continuing is safe. Scope it to one statement, check Err immediately, and clear it with On Error GoTo 0. Do not use it to suppress an entire procedure.
Where should a macro write its log?+
A dedicated log sheet or a text file outside the data area. Use whichever survives the failure you are guarding against, and make sure support can read it.
How can a loop log an error without stopping?+
Record the row key, error number, and outcome, increment a failure count, and continue when the record is safe to skip. Stop when the error affects the workbook structure or the output destination.
Need help applying this?
Improve your excel & google sheets.
Review the service scope or tell us what you are trying to improve. We will reply with a clear next step.
Free KPI definition templateRelated reading
Excel data validation for reliable inputs
Data validation prevents many input errors, but only if the rules match the real work. Design lists, ranges, and custom checks that survive paste and handover.
Building a pricing calculator in Excel
A pricing calculator is a small model with large consequences. Separate cost, margin, discount, and quote logic so every price can be explained and checked.