100

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?

2

5 Answers 5

118

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
Sign up to request clarification or add additional context in comments.

6 Comments

what if cell H5 is changed from another sheet, say sheet2 then the above function doesn't work. plz help in this.
For anyone coming here from a google search, make sure you paste this code into the sheet in vba, not a module like I did. look at stackoverflow.com/questions/15337008/…
Application.ActiveSheet.Range("H5"). ==> target.parent.range("H5") is even safer
@WillEdiger Whenever you don't explicitly specify a sheet reference, Excel assumes the ActiveSheet and whenever you don't explicitly specify that it is Excel you are working with, Excel assumes Application.
Note that, in a worksheet code module (which is where a Worksheet_Change event must be located), an unqualified Range does not default to ActiveSheet but instead refers to the sheet containing the code. The code in this answer is therefore effectively the same as the code in the question. (Note: Back in 2009 when this answer was written, it may have been different, but I'm pretty certain it wasn't.)
|
11

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.

1 Comment

This answer and the other answers here are great for triggering a macro when a cell is selected, but they are not detecting a change in the cell value. That is why they do not work when a cell value is changed from another location. If a user is changing a cell value the macro will be run -before- they change the value, not after they do.
8

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.

3 Comments

Thanks, it works. I check the range with, say, Target.Address = Range("H5").Address. Is there an easier way?
An alternative: Not (Intersect(Target, Range("H5")) Is Nothing) . Is this how you would do it?
The first comment (Target.Address = Range("H5").Address) wouldn't work if your cell was only part of the changed range. The second comment still suffers the problems described by Mike Rosenblum.
3

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

1 Comment

It's the same as one cell. You can either set a range as one cell, range of continuos cells, or even scattered cells (all separated by comma).
0

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

1 Comment

I can not get this to work for some reason. When I tell the code to run in VBA it is pulling up a pop up menue and asking me if I want to run the macro instead of running the macro automaticaly?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.