Heading

This is some text inside of a div block.
This is some text inside of a div block.
This is some text inside of a div block.
min read

Undo records in macros

Word • Macros
Peter Ronhovde
5
min read

Some macros make multiple changes to a document, and it can be frustrating to undo each individual edit if there is a problem or you just change your mind. Enter undo records.

Thanks for your interest

This content is part of a paid plan.

Create Undo Records in Macros

Undo records allow us to define a sequence of macro steps as a group, so an undo command will revert all of them at once. Ideally, the sequence forms a logical action, but undo records are general enough that you can group any tasks you wish. They make our macros work and feel more like native Word commands.

Warning

This is a handy addition to our macro toolbox; however, please read the gotcha below. This is not a VBA concept where you should skip the details.

Set undo record

We first need to tell VBA we’re about to record an undo block.

Set myUndo = Application.UndoRecord

The UndoRecord is a member of the Application which is a top level object in Word.

We need to Set the variable myUndo because an UndoRecord is not just a regular value like an integer or plain text.

Start custom undo record

Tell VBA to start grouping the macro steps into an undo record using the StartCustomRecord method with your undo record variable.

myUndo.StartCustomRecord("Record name")

We can provide an optional record name which will show up in the Undo list when viewing the Word menu commands. I always add a name for clarity in case something unexpected happens, or if you want to back up to a specific task.

We don’t have to start an undo record at the beginning of a macro. In fact, we could define multiple separate records within the same macro, if needed.

End custom undo record

The command to end the undo record is simple:

myUndo.EndCustomRecord

What is the result?

Put together, the steps are:

Set myUndo = Application.UndoRecord
myUndo.StartCustomRecord("VBA record name")

' All macro steps in between are one undo record ...

myUndo.EndCustomRecord

Unfortunately, you can lose text using this, so please read the gotcha below for more information.

Gotcha

Most gotchas lie on a spectrum anywhere between a nuisance and an annoying problem. A few others can mess up some text occasionally. It hurts, but most can be corrected with a little effort. I elevate using undo records closer to a “Danger, Will Robinson!” moment.

I definitely use undo records, and I encourage you to do so as well, but guard yourself (I dislike legalese but see the disclaimer below).

“You’re scaring me … what’s the problem?”

End the custom undo record

“Oh that’s all—”

Just hold on and keep reading.

If you don’t end the custom undo record, you can lose text in your document. I’ve lost notes or novel text several times. For some of those, I was able to recover most of the changes, but at least once, I lost more than an hour of work.

I hate it for my teaching documents, but it’s almost painful when I lose novel text. I’m sure any authors out there are breaking out in a cold sweat as we speak … well, as I type … no, as you read. But still, you get the point.

What happens?

When the end custom record is missing before a macro ends, every command or change after running the faulty macro is included in the undo record.

Then you try to undo something later, which you’ll probably do in the middle of an avalanche of wonderful productivity, but it all comes screeching, terrifying halt when the undo backs up all the way to the beginning of the faulty macro.

And you don’t remember when that was.

Whoa.

At a minimum, it’s scary to see so many changes reversed at once. At worst, it’s gonna hurt to say bye-bye to that text forever if it doesn’t properly restore.

And it won’t always.

Restoring the text with a Redo sometimes works. If not, the undo action may throw away the recent changes. If this happens, you may not can’t even be able to recover the missing content with a cloud-based document restore.

End the undo record. Every time. Always.

I’m not saying to avoid undo records. I like them and use them frequently just … end the custom undo record.

Triple check that every macro you create with an undo record ends with an EndCustomRecord command.

If you want to be extra safe, see the extended content below where we implement an error handler.

Disclaimer

Given the warning for this content, please read the disclaimer below.

All content on this site is provided as is and in good faith with no guarantees for completeness, accuracy, or fitness whether expressed or implied. The user accepts full responsibility for implementing any content provided by the author, and the author assumes no liability or responsibility for such implementation.

Undo Record Improvement

Some macro bugs pop up only with certain commands or documents. For example, a macro editing a style will work flawlessly most of the time, but it will crash if the style is missing. If you’re using an undo record, the macro quits immediately on the error, possibly leaving an open undo record still recording any subsequent actions.

Let’s fix that.

Even safer

If you have some steps that you aren’t completely sure will work flawlessly every time the macro runs, you can be even safer by adding an error handler to ensure the undo record is ended. See a previous article segment for a very brief introduction to error handling.

Starting undo record

As before, we’ve started our custom undo record using:

Set myUndo = Application.UndoRecord
myUndo.StartCustomRecord("VBA record name")

Add undo record error handler

We add a step to enable error handling in the macro.

On Error GoTo EndUndoRecord:

' All steps in between are one undo record ...

End undo record on an error

Then we include the EndUndoRecord line label.

EndUndoRecord:

The error handler will jump to this line if an error occurs any time after the error command and then continue with the steps after this line.

We now include the end custom undo record method in the error steps.

myUndo.EndCustomRecord ' Do this with an error or not

We don’t need to add an Exit Function command before the error steps since we want to close the undo record either way.

Resulting steps

Putting the new commands together, we get:

Set myUndo = Application.UndoRecord
myUndo.StartCustomRecord("Record name")

On Error GoTo EndUndoRecord:

' All steps in between are one undo record ...

EndUndoRecord:
myUndo.EndCustomRecord ' Do this with an error or not

A small problem with using an error handler is it makes debugging the macro a little harder, so make sure your macro is working well before enabling it (comment out the On Error GoTo line until you need it). Otherwise, it will just jump to the error steps rather than tell you what specific command was a problem.

Affiliate Links

If you're interested in using Word or another tool related to the article, check out these affiliate links. I may make a small commission if you purchase when using them, but there is no increase in cost for you, and it helps to support this site and associated content.

I've been using Microsoft for Business for commercial use (that's us writers) on one of the lower pricing tiers for years. I get to use my macros, have online storage, and don't have to worry about software updates.