Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save undo stack during macro run

Tags:

undo

excel

vba

I am wondering if there is a way to save ability to undo actions after macro has been run. I do not care about results of macro - just need to undo actions that were done by user before macro.

Background: I have a macro on the worksheet_change event that logs who and when made the change on this worksheet. I do not want it to restrict user's ability to undo his/her actions.

like image 216
Eduard3192993 Avatar asked Jun 12 '14 13:06

Eduard3192993


People also ask

Can you undo after running a macro?

When we run a macro, we cannot undo the macro's actions using the usual Ctrl + Z shortcut. Running a macro removes the list of actions stored in Undo, meaning that it is not possible to undo a macro.

How do I recover an unsaved macro?

Step 1: Open the MS Excel, not corrupted excel workbook and navigate to the File menu tab. Step 2: Scroll down and click on the Options at the left panel of the Excel screen. Step 3: A new window will show you where click on Add-ins on the left panel of the window.

How do you undo a subroutine after it has been run?

If you get bored of stepping through a long subroutine, you can always press F5 at any stage to run the rest of the code, or click the Reset tool (it's the one that looks like a little blue square) on the toolbar to stop the code running.

How do I save a macro module?

In the Save As box, in the Save as type list box, choose Excel Macro-Enabled Workbook (*. xlsm). Click Save.


1 Answers

There is no easy way to do this, but it's possible. The approach to this is to create three macros, and use some global variables to save state:

  1. MyMacro
  2. MyStateSavingMacro
  3. MyStateRevertingMacro

E.g. My macro changes Cells in Range A1:A10 of the active sheet. So, whenever the code to run my macro is called, it executes

Sub MyMacro()       
    Call MyStateSavingMacro() 
    ' Copies contents and formulae in range A1:A10 to a global data object

    '... Code for MyMacro goes here
    '
    '................

    Call Application.OnUndo("Undo MyMacro", "MyStateRevertingMacro")
    'This puts MyStateRevertingMacro() in the Undo queue
    'So pressing ctrl-Z invokes code in that procedure
End Sub


Sub MyStateSavingMacro()
    ' Code to copy into global data structures anything you might change
End Sub

Sub MyStateRevertingMacro
    ' Code to copy onto the spreadsheet the original state stored in the global variables
End Sub

So there it is. It's not pretty, but can be done. Ref: http://msdn.microsoft.com/en-us/library/office/ff194135%28v=office.15%29.aspx

Edit: To preserve the Undo queue prior to your MyMacro being run, the inelegant solution would be to create a chain of 4-5 MyStateRevertingMacro_1, _2, etc. where you can apply the information from your Worksheet_Change logging system and then chain-up the Application.OnUndo in each of those, so Application.OnUndo for each of those Reverting Macros would refer the previous state reversion code.

like image 128
hnk Avatar answered Sep 28 '22 01:09

hnk