Is it possible to undo a macro action? [duplicate] - vba

This question already has answers here:
Building Undo Into an Excel VBA Macro
(3 answers)
Closed last year.
I want to know if we can undo the macro action by any chance. I am using the excel sheet as a form and I am having a submit button(Macro) which takes the sum of counts of the sheet(based on the form input) and stores it in the next sheet.
My problem is, if we press the submit button without completing it or if we press it twice, the sum which I store in the next sheet, becomes inaccurate. If there a way we can undo the macro actions in excel? I tried using the undo button, but it didn't work for macros. Is there a way we can undo it?
Can we add another macro which would undo the previous macro's work?

I agree with all the commenters who've suggested that the best practice is to validate the starting conditions and/or input values before allowing the macro to make any changes. However, validation is often very complex and totally impractical in a lot of "we need it now" situations.
Here are two very easy things I can suggest:
1) Have the macro save the workbook before any changes are made, but not save the workbook after the changes have been made. This way, if you see something went wrong, you can just close and reopen the workbook and you'll be back to where you were before the macro did whatever the macro does.
2) Have the macro save copies of any affected worksheets before taking any action, so, if things go wrong, you can revert (or create a macro to revert) back to the starting point.
The first option requires the least amount of code, just:
ThisWorkbook.Save
before letting the macro do whatever the macro does.
I frequently use this method when testing macros.
The second option is a little more complex, but not much:
ThisWorkbook.Worksheets("YourWorksheet").Copy(After:=ThisWorkbook.Worksheets("NameOfSheetYouWantItToAppearAfter")
Note that this will activate the copy. If necessary, you can reactivate the original worksheet like this:
ThisWorkbook.Worksheets("OriginalWorksheet").Activate
I hope that helps!

Related

Pause VBA Macro to allow manual input of data

I have an Excel workbook macro that opens another workbook and starts copying data into it and formatting it. At one point in the process, I want the macro to pause and let the user manually enter data into the target workbook and then resume processing.
MsgBox, Application.Wait(), and Sleep are all application modal and will not let the user update anything in the other workbook while they are executing.
I found this while searching for a solution. It gets me halfway there in that I can manipulate the other sheet but only with my mouse. No keyboard presses get sent to the workbook.
Any ideas on getting all the way there?
I was thinking that I could just have two macros. The user would run one, then perform his manual tasks, then run the other. This appears to work but I would have to convert everything to globals so hopefully, someone has a better idea.
Thanks!
Depending on the macro being run to copy and paste, is the main concern with user intervention during execution of the macro getting the active cell/sheet (if being used) back to being active after the user manipulates something.
I'd recommend storing the active cell/sheet address in a variable prior to the Application.Wait() and then setting the active cell to that stored value on resume.
Without a posting of what your macro is doing though, it is hard to know if this suggestion helps your current situation.

Using Excel while macros are running

There are a half-dozen answers to this. "Open a second instance" "Have a pause" Etc. I'm not looking for that.
I'm looking for the user of the workbook to be able to manipulate the workbook while the macro is running. I've seen this working before, where the user could scroll around, change tabs, even add and remove data, all while the macro was running. Unfortunately, I couldn't get permission to look at the code (And committing CFAA violations ins't my cup of tea), so I have no idea how they did it.
How can you enable a user to edit the workbook as macros are running? For a specific example, I have Conway's Game of Life running. Users select cells to flip live/dead, then can run a macro to run the entire thing. I think it'd be nice for users to be able to change cells as the macro is running. (which is a second on select macro)
Thank you
Sorry just reread the question. I wouldn't expect the permutation to run for very long - not long enough to interrupt really.
But if it does, then the advice about using lots of DoEvents stands.
The other option is that you can use the OnTime event to have a "heartbeat"
VBA Macro On Timer style to run code every set number of seconds, i.e. 120 seconds
You can set the timer to say 3 seconds. Every time the OnTime event occurs you do one step of your permutation. In the three seconds in between they can edit.
Refactor your macro to use Events. In which case, you would have a series of event handlers (instead of one monolithic macro) to respond to various triggers. This is assuming that the macro is influenced by what the user is doing in the worksheet.
One way of (sort of) doing this is to use a Modeless Userform (UserForm.Show vbModeless)
The user form stays visible but the VBA stops running when the form is shown and the user can then interact with Excel. Then when the user clicks a button on the form the code behind the button starts running again.
So in reality the user is either interacting with Excel or interacting with the form ...

Run-time Error '32809' and Active X controls changed name

Huge problem here. I sent an excel form (a workbook with several sheets, thousands of active x controls and many many macros) to several people that they need to fill and return to me. Only one of the completed form I received is now completely impossible to use. All active X controls have changed name. If I select one I see the old name, but if I click on it the macro doesn't start and if I try to see its code it opens a new empty Macro with the new control name_click (Ex: a button called cmd_button1 opens a Macro called cmd_button2_click). When I start the Macro in VBA, I get the Run-time Error '32809' every time the code wants to unprotect sheets or to change the visible value of a sheet.
I looked on other posts and every solution I found would require a huge amount of work. What happened? Is there an easy solution to this?
Thank you.
I saved the workbook in .xlsx and copy/pasted all my macros back, transfered the forms and modules back then saved it back to .xlsm and now the buttons call the macros and no run time errors occur anymore.

Control Button to initiate the writing of a new VBA macro

Would it be possible to have a control button (or any mechanism) that once clicked on, a textbox would appear with fields like macro name Sub "NewMacroTitle"(), a field for the date, a field for reference sources ("Getting Links/URL from a webpage-Excel VBA"found this here"), a brief description of what the macro is to do. All of these fields, except Sub "NewMacroTitle"(), would start with a ' to show a comment and all of this would be inserted into the VBA editor, or enter it into cells on a spreadsheet that could then be copied and pasted into the VBA editor.
My problem is this. I'm new to VBA. I'm also the world's worst at documenting macros. I get an idea for a macro, I'm off into the VBA editor writing away, maybe even get the macro complete. A week later I'm reviewing the macro and the first thing is "what the heck does this thing do?"
I hope you see what I'm trying to do, essentially some way to force me to document the macro before even starting the actual code.
There are tools that will add pre-defined text to the header and/or footer of a sub. I use the one from MZ Tools for error handling code and adding my name and date to the header of each proc. It is worth a look.

Excel Automatic Calculation Setting

I have a complex project in `Microsoft Office Excel 2007' which utilises a large number of UDFs. Through VBA in a Workbook_Open Event, I set Excel Automatic calculation to OFF and a strategically placed Calculate method to manually calculate the cells whenever I need it so that the UDF doesn't perform recalculation unintentionally.
If the workbook is the ONLY one opened (or the first to open) in an Excel instance, everything works perfect. Only when it's opened AFTER another workbook (within the same instance), my project will inherit the Automatic calculation setting from the FIRST workbook and perform endless calculation on my UDFs. The disable code placed in the Workbook_Open event isn't executed until the UDF finishes the calculation (which can take forever). This only happens if my project is NOT the one opened first.
Through http://www.decisionmodels.com/calcsecretse.htm, I discover that it is the nature of Excel to perform the calculation process BEFORE the Workbook_Open event is executed.
So the question I have obviously relates to the project being opened AFTER another workbook is opened with automatic calculation turned ON:
How do I force my project to disable automatic calculation
without it performing recalculation first (remember, problem only
occurs when the project not the first one to be opened since it will
follow settings from previously opened workbook) OR...
How do I get the project to open in ANOTHER INSTANCE (when double clicked) to avoid
inheriting automatic calculation setting from the previous workbook.
Either way, the answer I'm seeking is for the project to open without performing the calculation first.
Thanks
One way is to use a different workbook (Opener.xls) to initiate opening the UDF workbook (udf.xls)
in Opener.xls the Workbook_Open code
- sets calculation to manual
- opens udf.xls
In your question I don't recognize the way you use to change and inherit that option to your workbooks, But I answer it as a solution:
Use VBA and running VBA macros to change that option for just your active sheet as soon as you need to calculate; by using it like this:
With ActiveSheet
.EnableCalculation = False
.EnableCalculation = True
.Calculate
End With
In another ways that may you need, you can read this part of MSDN article.