Worksheet_Change not firing due to Application.EnableEvents = False? - excel

I am creating a work order template for use by many users, that is intended to be an add-in that can generate a work order worksheet, where users will have the ability to edit certain information on the sheet and related cells will change accordingly. Currently, the add-in generates the new worksheet and adds the Worksheet_Change code programmatically. This was working correctly originally, until I added a more target cells as fail-safes in case someone accidentally edits the wrong cell. What is happening now, is that the add-in will create the worksheet as intended, but the target cells will not trigger the Worksheet_Change anymore.
I believe that the issue is Application.EnableEvents = False is turning off the Worksheet_Change events, but Application.EnableEvents = True is not turning the events back on afterwards in the code. Application.EnableEvents = True activates the Worksheet_Change again in the Immediate Window, but not in the code. I am fairly certain the code is in the same format it was when working, it just has more target cells. Am I adding Application.EnableEvents = True in the wrong place?
Here is the Worksheet_Change portion of the code.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("D7")) Is Nothing Then
Application.EnableEvents = False
Call addIDValue
Call ChangeIDD7
ElseIf Not Intersect(Target, Range("F7:G7")) Is Nothing Then
Call addCSDValue
ElseIf Not Intersect(Target, Range("C18")) Is Nothing Then
Call addIDValue
Call ChangeIDC18
ElseIf Not Intersect(Target, Range("C20")) Is Nothing Then
Call addCSDValue
Call ChangeCSDC20
Call ChangeG9
'several more ElseIf statements cut for brevity
End If
Application.EnableEvents = True
End Sub

Related

Excel clear the cell of the same row but next column [duplicate]

How can I automatically execute an Excel macro each time a value in a particular cell changes?
Right now, my working code is:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("H5")) Is Nothing Then Macro
End Sub
where "H5" is the particular cell being monitored and Macro is the name of the macro.
Is there a better way?
Your code looks pretty good.
Be careful, however, for your call to Range("H5") is a shortcut command to Application.Range("H5"), which is equivalent to Application.ActiveSheet.Range("H5"). This could be fine, if the only changes are user-changes -- which is the most typical -- but it is possible for the worksheet's cell values to change when it is not the active sheet via programmatic changes, e.g. VBA.
With this in mind, I would utilize Target.Worksheet.Range("H5"):
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Target.Worksheet.Range("H5")) Is Nothing Then Macro
End Sub
Or you can use Me.Range("H5"), if the event handler is on the code page for the worksheet in question (it usually is):
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("H5")) Is Nothing Then Macro
End Sub
I spent a lot of time researching this and learning how it all works, after really messing up the event triggers. Since there was so much scattered info I decided to share what I have found to work all in one place, step by step as follows:
1) Open VBA Editor, under VBA Project (YourWorkBookName.xlsm) open Microsoft Excel Object and select the Sheet to which the change event will pertain.
2) The default code view is "General." From the drop-down list at the top middle, select "Worksheet."
3) Private Sub Worksheet_SelectionChange is already there as it should be, leave it alone. Copy/Paste Mike Rosenblum's code from above and change the .Range reference to the cell for which you are watching for a change (B3, in my case). Do not place your Macro yet, however (I removed the word "Macro" after "Then"):
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("H5")) Is Nothing Then
End Sub
or from the drop-down list at the top left, select "Change" and in the space between Private Sub and End Sub, paste If Not Intersect(Target, Me.Range("H5")) Is Nothing Then
4) On the line after "Then" turn off events so that when you call your macro, it does not trigger events and try to run this Worksheet_Change again in a never ending cycle that crashes Excel and/or otherwise messes everything up:
Application.EnableEvents = False
5) Call your macro
Call YourMacroName
6) Turn events back on so the next change (and any/all other events) trigger:
Application.EnableEvents = True
7) End the If block and the Sub:
End If
End Sub
The entire code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("B3")) Is Nothing Then
Application.EnableEvents = False
Call UpdateAndViewOnly
Application.EnableEvents = True
End If
End Sub
This takes turning events on/off out of the Modules which creates problems and simply lets the change trigger, turns off events, runs your macro and turns events back on.
Handle the Worksheet_Change event or the Workbook_SheetChange event.
The event handlers take an argument "Target As Range", so you can check if the range that's changing includes the cell you're interested in.
I prefer this way, not using a cell but a range
Dim cell_to_test As Range, cells_changed As Range
Set cells_changed = Target(1, 1)
Set cell_to_test = Range( RANGE_OF_CELLS_TO_DETECT )
If Not Intersect(cells_changed, cell_to_test) Is Nothing Then
Macro
End If
I have a cell which is linked to online stock database and updated frequently. I want to trigger a macro whenever the cell value is updated.
I believe this is similar to cell value change by a program or any external data update but above examples somehow do not work for me. I think the problem is because excel internal events are not triggered, but thats my guess.
I did the following,
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Target.Worksheets("Symbols").Range("$C$3")) Is Nothing Then
'Run Macro
End Sub

Why is my subroutine not updating the current date and time as I expect?

My Workbook_SheetChange code seems to not be running.
I have tried changing it several different ways, including Setting objects and not Setting objects. No change event seems to trigger.
My current code is below, but I have completely scratched other versions that don't even reference sheet names. None of them seem to work. I have another wb with a Worksheet Change code that works.
I am expecting my summary sheet date and time cell - Worksheets("GL 1500").("B2") - to update with the current date and time any time anything in the range "C31:P46" on the summary tab, or the alternate range on any other tab, changes, but it has not updated with any changes I make to any worksheet.
What stupid mistake am I making?
Code:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
If Sh.Name = "GL 1500" Then
If Not Intersect(Target, Sh.Range("c31:p46")) Is Nothing Then
Application.EnableEvents = False
With Worksheets("GL 1500")
.Range("b2").Value = Now
End With
Application.EnableEvents = True
End If
Else
If Not Intersect(Target, Sh.Range("e14:k39")) Is Nothing Then
Application.EnableEvents = False
With Worksheets("GL 1500")
.Range("b2").Value = Now
End With
Application.EnableEvents = True
End If
End If
End Sub

Call a macro based on cell value changes but formula stays the same

I need to call a macro when cell B3 changes, however B3 is an RTD link so when the value changes the formula is still the same and excel doesn't recognise the change. How can I get my macro to run when the value changes but the formula doesn't?
I've tried using a simple Range("B3").Value but that gives me a run-time error "424". I then tried creating a range object to get around this but still got another error message.
Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("B3")) Is Nothing Then
Call Copy_Values
End If
End Sub
I'm relatively new to VBA so I know I could be missing something obvious, thanks for any help you can provide
You want Worksheet_Calculate not Worksheet_Change. Use a static var to 'remember' the value from the last calculation cycle.
Sub Worksheet_Calculate()
static beeThree as variant
If Range("B3").value2 <> beeThree Then
application.enableevents = false
application.calculation = xlcalculationmanual
Copy_Values
beeThree = Range("B3").value2
application.calculation = xlcalculationautomatic
application.enableevents = true
End If
End Sub

Tables - Worksheet_Change Fires Multiple Times

I'm trying to capture the worksheet change event when a table heading is cleared by the user.
Private Sub Worksheet_Change(ByVal Target As Range)
application.EnableEvents = False
If Not Intersect(Target, Me.ListObjects("Table1").HeaderRowRange) Is Nothing Then
msgbox "Hello"
end if
application.EnableEvents = True
End Sub
If the user presses "delete" to clear a non-default heading name on the table, Excel automatically replaces the blank heading with the default heading name (eg. "Column1"). This seems to cause the worksheet change event to run multiple times. I'd like to figure out a way to have this event run only once when the user clears the a heading.
Any help is greatly appreciated.
The easiest workaround for this is to add an assertion at the beginning of your event, that checks that the target cell does not already contain a default column name.
I would do this with a simple if and like statement, which catches when a heading begins with "Column" and exits the event using Exit Sub. You could do all of this in one simple line of code. Something like...
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.value Like "Column*" Then Exit Sub
application.EnableEvents = False
If Not Intersect(Target, Me.ListObjects("Table1").HeaderRowRange) Is Nothing Then
msgbox "Hello"
end if
application.EnableEvents = True
End Sub
This code is admittedly untested but it should provide you with a good base to start from.

disable editing in cells without protecting worksheet vba

I want to disable cell editing (direct typing into cell) but want to update that cell through code without protecting worksheet
Does anyone have any idea?
In the worksheet's code module:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Range("A1:A10"), Target) Is Nothing Then
Application.EnableEvents = False
Target.ClearContents '// Assuming you want to keep it blank
Application.EnableEvents = True
End If
End Sub
Then in your code whenever you want to change a value, just disable events before hand:
'// Will be deleted
Range("A5").Value = "TEST"
'// Will not be deleted
Application.EnableEvents = False
Range("A5").Value = "TEST AGAIN"
Application.EnableEvents = True
I had a similar issue and found a workaround. For whatever reason I couldn't get my macros to run correctly with the sheets protected so what I did is as a code to Pop up a message box for any cells that I didn't want the user to change. Then I added "Application.DisplayAlerts = False" to the beginning of any codes that needed to modify those cells and reset the alerts back to True at the end of those codes.

Resources