Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unding in one step

Tags:

ms-word

vba

Is there a way to make VBA code of a Word 2013 macro execute as block, so if I undo it, it doesn’t undo the macro by the individual steps it goes through to execute? I would like macros to act more like built in functions.

I have macro that moves the cursor to the end of a word then deletes the previous three letters. If I undo it, I see each of the three letters reappear one by one.

I may not have worded this right. I was wondering if there was code to wrap a macro in to get Word to treat a macro like a built in Work command that executes all a once rather than executing a series of recorded steps. Then if I run a macro and decide I don't like the results, I can click on undo and the entire macro rewinds and undoes.

like image 382
user2609404 Avatar asked Feb 06 '15 05:02

user2609404


2 Answers

Use the Application.UndoRecord as follows:

Method One:

Sub YourMacroName
    Dim objUndo As UndoRecord 
    'Declares the variable objUndo of the UndoRecord type
    Set objUndo = Application.UndoRecord 
    'sets the object to an actual item on the undo stack
    objUndo.StartCustomRecord ("Undo Stack Display Text")
    'Tells Word where to begin "recording" the undo record
    'This item also lets you set the text you want to appear in the undo drop-down in word.

        Selection.MoveRight Unit:=wdWord 
        'Moves to the end of the current word
        Selection.MoveLeft Unit:=wdCharacter, Count:=3, Extend:=True 
        'Selects the last three letters of the word
        Selection.Delete
        'Deletes the last three letters of the word
    objUndo.EndCustomRecord
    'Denotes the End of The Undo Record
End Sub

You may also want to look at Microsoft's article on using the Application.UndoRecord Property.

Alternatively, as @Matteo NNZ Mentioned, you can just delete the three characters at once. To do that, use the code below.

Method Two:

Sub YourMacroName
     Selection.MoveRight Unit:=wdWord 
    'Moves to the end of the current word
    Selection.MoveLeft Unit:=wdCharacter, Count:=3, Extend:=True 
    'Selects the last three letters of the word
    Selection.Delete
    'Deletes the last three letters of the word
End Sub

The downside to the second method is that you can't control the Name of the Item in the undo drop-down.

Both methods are limited in that they do not restore the cursor to its original position.

like image 104
JRP Avatar answered Nov 09 '22 21:11

JRP


Thanks JRP that a big help, to solve this issue:

Both methods are limited in that they do not restore the cursor to its original position.

Once the UndoRecord is recording, add a space at the end of the current selection Selection.InsertAfter (" ") and remove it again.

The approximate block I use is:

Dim originalSelection As Range

Application.UndoRecord.StartCustomRecord ("Delete previous")

Set originalSelection = Selection.Range
Selection.InsertAfter (" ")
Selection.MoveRight Unit:=wdCharacter, Count:=1
Selection.TypeBackspace
originalSelection.Select

... your code here ...

Application.UndoRecord.EndCustomRecord
like image 28
Scott F. Avatar answered Nov 09 '22 20:11

Scott F.