Run Worksheet_Change if multiple defined cells are changes - vba

I have the following code that runs a goalseek if the defined named range "N" changes. However, I want the code to run if any of several cells changes. E.g. "N1", "N2", etc..
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
Application.EnableEvents = False
If Target.Address = Range("N").Address Then
'Goalseek for force equilibrium
Range("Delta_F").GoalSeek Goal:=0, ChangingCell:=Range("h_neutral")
End If
Application.EnableEvents = True
End Sub
I tried the following, but it did not work:
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
Application.EnableEvents = False
If Target.Address = Range("N, N1, N2").Address Then
'Goalseek for force equilibrium
Range("Delta_F").GoalSeek Goal:=0, ChangingCell:=Range("h_neutral")
End If
Application.EnableEvents = True
End Sub
Any help is appreciated. Thanks in advance.

Testing your criteria as a Range is easier than testing the Address as a string.
Building on #Michal's solution, the below will only execute when your changed cell (Target) overlaps (Intersects) with your 3 ranges (Set as the variable TargetRange here). The main difference is the double negative in the test statement which allows you to avoid Exit Sub resulting in moderately cleaner code.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim TargetRange As Range
Set TargetRange = Union(Range("B3"), Range("G19"), Range("N1"))
If Not Intersect(TargetRange, Target) Is Nothing Then
Application.EnableEvents = False
Range("Delta_F").GoalSeek Goal:=0, ChangingCell:=Range("h_neutral")
Application.EnableEvents = True
End If
End Sub

Your condition can be easily checked with Intersect function:
If Intersect(Range("N"), Target) Is Nothing Then Exit Sub
If Target doesn't lie within your range, it will exit the sub (this condition should be placed as the first command in your Sub).

Related

Excel Link two cells in different sheets using when changed macro

I have an Excel workbook with multiple worksheets. I have a cell in WORKSHEET A with range name TRACK1 and a cell in WORKSHEET B with range name TRACK2.
Each TRACK1 and TRACK2 are validated from a list. The user can change either cell from the drop-down list shown when the cell is selected.
I want to be able to allow the user to change either and have the other be also changed to match. Change value of TRACK1 and TRACK2 is changed, and vice versa.
I know how to do this basic macro, but how to stop the event propagating?
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Application.Intersect(Target, Range("TRACK1")) Is Nothing Then
Range("TRACK2") = Range("TRACK1")
End If
If Not Application.Intersect(Target, Range("TRACK2")) Is Nothing Then
Range("TRACK1") = Range("TRACK2")
End If
End Sub
In worksheet A's code module, use:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If Not Application.Intersect(Target, Range("TRACK1")) Is Nothing Then
Worksheets("WORKSHEET B").Range("TRACK2") = Range("TRACK1")
End If
Application.EnableEvents = True
End Sub
In worksheet B's code module, use:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If Not Application.Intersect(Target, Range("TRACK2")) Is Nothing Then
Worksheets("WORKSHEET A").Range("TRACK1") = Range("TRACK2")
End If
Application.EnableEvents = True
End Sub

When I delete or clear contents of a cells getting a debug message

I have a VBA code to capitalize most of my worksheet but when I delete or clear the contents I get the debug message.
Any help would be appreciated!
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If Not Intersect(Target, Range("A:Z")) Is Nothing Then
Target.Value = UCase(Application.Substitute(Target.Value, " ", ""))
End If
Application.EnableEvents = True
End Sub
If you delete/change/add more than a single cell then Target is more than one cell and you cannot make the value uppercase as you are doing. Loop through the intersection of Target and columns A:Z and make each uppercase.
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If Not Intersect(Target, Range("A:Z")) Is Nothing Then
dim rng as range
for each rng in Intersect(Target, Range("A:Z"))
rng.Value = UCase(Replace(rng.Value, chr(32), vbnullstring))
next rng
End If
Application.EnableEvents = True
End Sub

VBA - autoupdate filter in excel after entering data

I'm fairly new to VBA and have been trying to get my spreadsheets to do a little more than just pivot tables allow. I've been able to set up some autofilters in excel using VBA, but now I'd like to have the worksheet autofilter after I enter data into a cell. However, neither of the two lines below work after I press enter.
Here are the two various lines of code I've tried:
1
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$M$5" Then
Application.EnableEvents = False
FilterTo1Critera
Application.EnableEvents = True
End If
End Sub
2
Private Sub Worksheet_Change(ByVal Target As Range)
Dim ws As Worksheet
Dim cel As Range
Set ws = ThisWorkbook.Sheets("Sheet3")
If Not Intersect(Target, Range("A3")) Is Nothing Then
For Each cel In Target
Range("A3").Value = "Changed"
Application.EnableEvents = False
If IsEmpty(ws.Range("A")) Then Sheet1.Range("A").Value = 0
Application.EnableEvents = True
Next cel
End If
End Sub
What's the correct approach to take? Also, is there some good classes that I can take to brush up on some of these concepts??
Thanks in advance!

VBA Pivot Table One Cell Reference Different Sheet

I'm using this current code to update a pivot table filter based on a cell value (E1) within the same sheet. What i would like to do is to update a filter based on a cell in a sheet named summary. If I set the filed in the current filed equal to the cell in the summary I need to press f2 and enter otherwise it won't work. I'm sure a little bit of tweaking and my code could work for it.
Any tips?
Private Sub Worksheet_Change(ByVal Target As Range)
Set Target = Range("E1")
If Target Is Nothing Then Exit Sub
On Error Resume Next
Application.EnableEvents = False
Sheets("Tech Pivot Table").PivotTables("PivotTable2").PivotCache.Refresh
With Me.PivotTables("PivotTable2")
.PivotCache.Refresh
.PivotFields("Name").CurrentPage = Target.Value
End With
Application.EnableEvents = True
End Sub
I think the problem is you're changing the value the Target variable up front when you should be checking to see if Target = "E1". Try the code below and let me know if it works.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target = Range("E1") Then
If Target Is Nothing Then Exit Sub
On Error Resume Next
Application.EnableEvents = False
Sheets("Tech Pivot Table").PivotTables("PivotTable2").PivotCache.Refresh
With Me.PivotTables("PivotTable2")
.PivotCache.Refresh
.PivotFields("Name").CurrentPage = Target.Value
End With
Application.EnableEvents = True
End If
End Sub

Run-Time error '1004' with my VBA for hiding and unhiding rows

I have code for hiding and unhiding rows in my sheet based on changing the value in my dropdown. Every time I change the dropdown I get Run-Time error of '1004'. I had a private Sub before and changed it to a Sub but that doesn't seem to be the solution.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range
Set rng = Target.Parent.Range("L6")
If Target.Count > 1 Then Exit Sub
If Intersect(Target, rng) Is Nothing Then Exit Sub
Application.Run "dynamic_hide"
End Sub
Sub dynamic_hide()
If Target.Range = "$S$9:$S$51" Then
If Target.Range = 0 Then Rows("F9:T51").EntireRow.Hidden = True
If Target.Value <> 0 Then Rows("F9:T51").EntireRow.Hidden = False
End If
End Sub
You have a few problems going on here:
First, the default property of a Range object is Value, so Target.Range = "$S$9:$S$51" will always be false. Use Target.Address instead.
Second, don't use Application.Run to call Subs from the same VBProject. Use Call instead.
Third, you've not let the sub dynamic_hide know what Target is since Target is only a parameter of the Worksheet_Change event subroutine. You can solve this by declaring your sub like Sub dynamic_hide(ByVal Target As Range) And then you can use it: Call dynamic_hide(Target)
Lastly, since Target is a range you don't need to use Target.Range since Target is a range so you can simply omit every .Range from Target.Range Target.Parent.Range is fine.