Usages for Worksheet_SelectionChange and Workbook_SheetSelectionChange events - vba

As far as I understand it they do the same thing, but while
Worksheet_SelectionChange
is triggered every time selection is changed on a single worksheet,
Workbook_SheetSelectionChange
is triggered every time selection is changed in any worksheet in the workbook.
Are there any other differences between these events?

The single parameter supplied by the Worksheet_SelectionChange event macro is the cell or range of cells that have just been selected, e.g. Target. The Workbook_SheetSelectionChange supplies that but adds the worksheet where the selection was made with Sh.
If you want the same thing to happen on multiple worksheets (not necessarily all of them), use Workbook_SheetSelectionChange and deal with the Sh parameter. This also centralizes your code so that modifications do not have to be repeated in several places. If you are only planning on reacting to selection changes on a single worksheet, use that worksheet's Worksheet_SelectionChange event macro on its own sheet code page.

It seems you answered your own question.
If you want Change events to happen specific to ONE sheet, then put Worksheet_SelectionChange into the Sheet's module.
If you want Change events to happen on every sheet in the book, then put Workbook_SheetSelectionChange into the Book's module.
Note, if you only want say 3 of 5 sheets triggering, you could run a check at the beginning of the Workbook_Change event to check for Sheet.Name

Related

Is there an event in Excel that runs when the application opens and before cells are calculated?

I'm trying to prevent Excel from recalculating cells containing my UDFs (because they run slowly).
My aim is to cache all the cell values by address in a dictionary store when the application first loads, the UDF will return a value from the store if it exists, otherwise it'll do a full recalculation.
I've attempted using the Workbook_Open() event to gather all the formulas in the sheet when the application loads. My issue is that the Workbook_Open() event fires after excel tries to recalculate all the cells.
Is there an event that runs before Workbook_Open()?

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

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!

How to get the worksheet that a regular (non-ActiveX) control is on?

I have a sub that I am calling by clicking a button. I've chosen to use a regular button (aka Form Control), not an ActiveX one, because I've been seeing the text size on ActiveX controls fluctuating and regular buttons don't have this problem. I want the sub to be able to use the worksheet that the button is on. I was thinking of something like this:
Sub showSheetName()
Dim sht As Worksheet
'this would work if the code was in the worksheet's module
Set sht = Me
msgbox sht.Name
End Sub
But this sub is in a shared module, not the worksheet's module, because I want several sheets to be able to use it. So Me doesn't point to the worksheet, and this approach just gives an Invalid use of Me keyword.
How can I get a reference to the worksheet that the button is on?
EDIT: If it wasn't clear, the reason why it's important that it's not an ActiveX control is because that means there's no myButton_Click() event in the worksheet that I can use to get the worksheet object and pass to a version of showSheetName() that takes a worksheet argument.
Set sht = ActiveSheet...
This of course assumes that the procedure is being invoked manually (i.e., the user is actively clicking the button) rather than being invoked through a Call or Application.Run statement.
The button can only be clicked by the user when the worksheet is active view.
There is no such thing as a regular button. Nor anymore are there ActiveX controls.
ActiveX is a marketing terminology by MS that described controls using COM. It, as a terminology, was retired years ago (the technology is still current).
Therefore it is hard to know what you are referring to.
Use names that HELP uses. List code that specifies the objects/etc that you are using.

Adding code to new excel sheet dynamically

I need some help Regarding VBA.
In My code I add an excel sheet and rename it and add a validation list to it.I need to run some code on changing value in that validation list.And that must run only on change of that particular cell.
If I am not clear please let me know.Please Help me solving this.
Instead of trying to create the individual code for each new worksheet with the Visual Basic Extensibility (see this link for further reading), simply use the Workbook wide event Workbook_SheetChange (you need to place it in the ThisWorkbookmodule).
In this event code first check, if the worksheet which caused the event is one of the newly created worksheets. This can be done most easily, be checking the .Name of the worksheet.
you can use SelectionChange Event and Change event or it is also possible to use the event Thisworkbook module. SheetChange or SheetSelectionChange.

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.