How to Run a Macro if the cell value changes - excel

I created a macro that filters based on a cell value which works fine.
Range("A1:L1").AutoFilter Field:=4, Criteria1:=Range("U1")
I need this macro to run everytime the cell value changes.
I wrote a macro but it is not working i dont get any errors just nothing happens.
I tried:
Private Sub Worksheet_Tabelle1(ByVal Target As Range)
If Target.Address = "$U$1" Then
Application.EnableEvents = False
Range("A1:L1").AutoFilter Field:=4, Criteria1:=Range("U1")
Application.EnableEvents = True
End If
End Sub
This version should just execute the code and not call a macro. I changed the Worksheet_xxxxx to the sheet name and tried other things.
I also tried:
Private Sub Worksheet_Arbeitstabelle(ByVal Target As Range)
If Target.Address = "$U$1" Then
Call Macro1
End If
End Sub
This version should call the following Macro:
Sub Macro1()
Range("A1:L1").AutoFilter Field:=4, Criteria1:=Range("U1")
End Sub
I put all the Private Sub macros on the Worksheet and the Macro1 in a modul.
The file is .xlsm and doesnt have any problem running other macros so i dont know why its not working. My guess is i probably did something wrong with the names so here are the names:

Try this:
Dim KeyCells As Range
' The variable KeyCells contains the cells that will
' cause an alert when they are changed.
Set KeyCells = Range("A1:C10")
If Not Application.Intersect(KeyCells, Range(Target.Address)) _
Is Nothing Then
' Display a message when one of the designated cells has been
' changed.
' Place your code here.
MsgBox "Cell " & Target.Address & " has changed."
End If
End Sub

I changed:
Private Sub Worksheet_Arbeitstabelle(ByVal Target As Range)
To:
Private Sub Worksheet_Change(ByVal Target As Range)
#Siddharth Rout linked me to:
Why MS Excel crashes and closes during Worksheet_Change Sub procedure?
Here it is explained that its not necessary to add the name of the Sheet after Worksheet_
because the code is stored in the sheet so no need to tell it where to do stuff since its not in a module

Related

Solving "method range of object _Worksheet failed"? [duplicate]

I am having a problem with Excel crashing, when I run VBA code on an excel sheet.
I'm trying to add the following formula on worksheet change:
Private Sub Worksheet_Change(ByVal Target As Range)
Worksheets("testpage").Range("A1:A8").Formula = "=B1+C1"
End Sub
When this code is run i get a message saying "excel has encountered a problem and needs to close" and excel closes.
If I run the code in the Worksheet_Activate() procedure, it works fine and doesn't crash
Private Sub Worksheet_Activate()
Worksheets("testpage").Range("A1:A8").Formula = "=B1+C1"
End Sub
But I really need it to work in the Worksheet_Change() procedure.
Has anyone experienced similar crashes when using the Worksheet_Change() event and can anyone point in the right direction to fix this issue ?
I recommend this when using Worksheet_Change
You do not need the sheet name. In a Sheet Code Module, an unqualified Range reference refers to that sheet. That said, it is clearer to use the Me qualifier. If you are trying to use another sheet, then qualify the range reference with that sheet.
Whenever you are working with Worksheet_Change event, always switch Off events if you are writing data to any cell. This is required so that the code doesn't retrigger the Change event, and go into a possible endless loop
Whenever you are switching off events, use error handling to turn it back on, else if you get an error, the code will not run the next time.
Try this
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo Whoa
Application.EnableEvents = False
Me.Range("A1:A8").Formula = "=B1+C1"
Letscontinue:
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume Letscontinue
End Sub
Few other things that you may want to know when working with this event.
If you want to ensure that the code doesn't run when more than one cell is changed then add a small check
Private Sub Worksheet_Change(ByVal Target As Range)
'~~> For Excel 2003
If Target.Cells.Count > 1 Then Exit Sub
'
'~~> Rest of code
'
End Sub
The CountLarge was introduced in Excel 2007 onward because Target.Cells.Count returns an Long value which can error out in Excel 2007 becuase of increased total cells count.
Private Sub Worksheet_Change(ByVal Target As Range)
'~~> For Excel 2007
If Target.Cells.CountLarge > 1 Then Exit Sub
'
'~~> Rest of code
'
End Sub
To work with all the cells that were changed use this code
Private Sub Worksheet_Change(ByVal Target As Range)
Dim aCell As Range
For Each aCell In Target.Cells
With aCell
'~~> Do Something
End With
Next
End Sub
To detect change in a particular cell, use Intersect. For example, if a change happens in Cell A1, then the below code will fire
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("A1")) Is Nothing Then
MsgBox "Cell A1 was changed"
'~~> Your code here
End If
End Sub
To detect change in a particular set of range, use Intersect again. For example, if a change happens in range A1:A10, then the below code will fire
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("A1:A10")) Is Nothing Then
MsgBox "one or more Cells in A1:A10 range was changed"
'~~> Your code here
End If
End Sub
Note: If you were getting an error earlier and you made the above changes and If your code is still not working then it is possible that the events have not been reset. In the Immediate Window, type Application.EnableEvents = True and press the ENTER key. This will reset it to True. If you do not see the Immediate Window, the press the shortcut key Ctl+G to launch the Immediate Window.
Excel was crashing, not the VBA function.
The events were not disabled and the call stack was filled by an infinite loop of OnChange events.
A little advice that helps finding this type of errors: set a breakpoint on the first line of the event, then execute it step by step pressing F8.
Also this solution is good:
Option Explicit
Private Busy As Boolean
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Busy Then
Busy = True
Range("A1:A8").Formula = "=B1+C1"
Busy = False
End If
End Sub

Should I better modify some codes for .ClearContents?

I have simple macros for clearing cells on "Sheet1", which have drop down lists.
Sub reset1()
Range("D20:E21").ClearContents
Range("D8:E9").ClearContents
Range("D6:E7").ClearContents
End Sub
Sub reset2()
Range("D20:E21").ClearContents
Range("D8:E9").ClearContents
End Sub
Then I call these macros on "Sheet1" if the cell values change
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$D$4" Then
Call reset1
End If
If Target.Address = "$D$6" Then
Call reset2
End If
End Sub
This code is written on the "Sheet1".
Normally it works but sometimes reset1() doesn't work.
I should then save and reopen the excel or run the macro manually.
Should I better modify some codes?
First problem is that with Range("D20:E21") it is not clear in which worksheet that range should be. Always specify the worksheet like Worksheets("Sheet1").Range("D20:E21").
Second problem is that if you .ClearContents in a Worksheet_Change event this is a cell change and triggers another Worksheet_Change event and so on. So it is recommended to disable events Application.EnableEvents = False before changing cells in Worksheet_Change event.
Third problem is that if you test Target.Address = "$D$4" and you copy paste a range where D4 is included your code will not run even if your cell D4 changed. Therefore you always need to work with Intersect.
Option Explicit
Sub Reset1(ByVal ws As Worksheet)
ws.Range("D20:E21,D8:E9,D6:E7").ClearContents
' alternative:
' Union(ws.Range("D20:E21"), ws.Range("D8:E9"), ws.Range("D6:E7")).ClearContents
End Sub
Sub Reset2(ByVal ws As Worksheet)
ws.Range("D20:E21,D8:E9").ClearContents
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
On Error Goto ENABLE_EVENTS ' in any case an error happens make sure events are enabeld again
If Not Intersect(Target, Me.Range("D4")) Is Nothing Then
Reset1 Me ' here we tell Reset1 to take `Me` as worksheet. Me refers to the worksheet `Target` is in.
End If
If Not Intersect(Target, Me.Range("D6")) Is Nothing Then
Reset2 Me
End If
ENABLE_EVENTS:
Application.EnableEvents = True
If Err.Number Then
Err.Raise Err.Number
End If
End Sub

Use named range to trigger Worksheet_Change event causes 1004 error

I have an excel workbook and I am running some code to remove extra spaces from one cell in several sheets. When I enter something in cell "E4", it removes every instance of " " and replaces it with "". This works as anticipated.
I am trying to get this to work for more than one sheet, by using named ranges. In the sheets, I created a named range "ConfigurationInput" with a scope of sheet.
The following code is in one of the sheets, and it functions as expected:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("E4")) Is Nothing Then
Call RemoveSpaces(Range("E4"))
End If
End Sub
This calls the following Sub, located in a module:
Sub RemoveSpaces(RngRemove)
Dim rng As Range
Set rng = RngRemove
rng = WorksheetFunction.Substitute(rng, " ", "")
End Sub
I am trying to replace "E4" with the named range "ConfigurationInput", and I am receiving the following error which crashes Excel:
Does anybody have a suggestion? I tried simplifying to a single cell and using .Address but that didn't work either:
If Target.Address = Range("ConfigurationInput").Address Then
I finally figured it out:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If Not Intersect(Target, Range("ConfigurationInput")) Is Nothing Then
Call FixConfig(Range("ConfigurationInput"))
End If
Application.EnableEvents = True
End Sub
I had to wrap the code with Application.EnableEvents = False and Application.EnableEvents = True

Call Macro on a specific sheet / Excel

I want to run a macro on a specific sheet, in my case the sheet is called "Tablet".
If a cell value in "Tabelle1" changes, I want to run this macro in the "Tablet" sheet.
Code in my Tabelle1:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$C$2" Then
Call Delete_OptionB1
End If
End Sub
This part works.
Macro Code:
Sub Delete_OptionB1()
'
' Delete_OptionB1 Makro
'
With Worksheets("Tablet")
.Range("M2:AD2").Select
Selection.ClearContents
End With
End Sub
This wont do the job. Any suggestions how I get this working?
In your code using a with block
With Worksheets("Tablet")
.Range("M2:AD2").Select
Selection.ClearContents
End With
You are selecting .Range("M2:AD2").Select but then clearing the contents of the selection on whatever sheet may be active when you Delete_OptionB1. Change to include a . - .Selection.ClearContents.
Even better, get rid or the With...End With and Select altogether. A single line will do it all:
Sub Delete_OptionB2()
'
' Delete_OptionB1 Makro
'
Worksheets("Tablet").Range("M2:AD2").ClearContents
End Sub
Instead of …
Target.Address = "$C$2"
… better use the Application.Intersect method to make it work if Target is more than one cell (this can happen when you copy/paste a range):
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Target.Parent.Range("C2")) Is Nothing Then
Delete_OptionB1 'you don't need the Call statement
End If
End Sub
If Delete_OptionB1 is not in a public module but in a workbook use eg Tablet.Delete_OptionB1
Make Delete_OptionB1 public, and avoid using .Select and Selection. (also see How to avoid using Select in Excel VBA)
Public Sub Delete_OptionB1() 'make it public
ThisWorkbook.Worksheets("Tablet").Range("M2:AD2").ClearContents
End Sub
Place this in the Tabelle1 worksheet code area:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("$C$2")) Is Nothing Then
Application.EnableEvents = False
Call Delete_OptionB1
Application.EnableEvents = True
End If
End Sub
Place this in a standard module:
Sub Delete_OptionB1()
'
' Delete_OptionB1 Makro
'
With Worksheets("Tablet")
.Range("M2:AD2").ClearContents
End With
End Sub

excel VBA run macro automatically whenever a cell is changed

Is there a simple way to get Excel to automatically execute a macro whenever a cell is changed?
The cell in question would be in Worksheet("BigBoard").Range("D2")
What I thought would be a simple Google inquiry is proving to be more complicated - every sample involved intersects (whatever those are) or color formatting or any other number of things that appear to be irrelevant.
Yes, this is possible by using worksheet events:
In the Visual Basic Editor open the worksheet you're interested in (i.e. "BigBoard") by double clicking on the name of the worksheet in the tree at the top left. Place the following code in the module:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Me.Range("D2")) Is Nothing Then Exit Sub
Application.EnableEvents = False 'to prevent endless loop
On Error Goto Finalize 'to re-enable the events
MsgBox "You changed THE CELL!"
Finalize:
Application.EnableEvents = True
End Sub
Another option is
Private Sub Worksheet_Change(ByVal Target As Range)
IF Target.Address = "$D$2" Then
MsgBox("Cell D2 Has Changed.")
End If
End Sub
I believe this uses fewer resources than Intersect, which will be helpful if your worksheet changes a lot.
In an attempt to find a way to make the target cell for the intersect method a name table array, I stumbled across a simple way to run something when ANY cell or set of cells on a particular sheet changes. This code is placed in the worksheet module as well:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count > 0 Then
'mycode here
end if
end sub
In an attempt to spot a change somewhere in a particular column (here in "W", i.e. "23"), I modified Peter Alberts' answer to:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Target.Column = 23 Then Exit Sub
Application.EnableEvents = False 'to prevent endless loop
On Error GoTo Finalize 'to re-enable the events
MsgBox "You changed a cell in column W, row " & Target.Row
MsgBox "You changed it to: " & Target.Value
Finalize:
Application.EnableEvents = True
End Sub
I was creating a form in which the user enters an email address used by another macro to email a specific cell group to the address entered. I patched together this simple code from several sites and my limited knowledge of VBA. This simply watches for one cell (In my case K22) to be updated and then kills any hyperlink in that cell.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim KeyCells As Range
' The variable KeyCells contains the cells that will
' cause an alert when they are changed.
Set KeyCells = Range("K22")
If Not Application.Intersect(KeyCells, Range(Target.Address)) _
Is Nothing Then
Range("K22").Select
Selection.Hyperlinks.Delete
End If
End Sub

Resources