multiple if statement conditions vba - vba

I'm very new to VBA so need a little help. I have a macro (BEM) that is dependent on the value of two cells. I want to be able to run the macro if either of those values is changed. If either of them is blank, I need the code to do nothing until a value is inputted in both cells.
Here's what I have so far but it doesn't seem to work:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$B$3" Or Target.Address = "$B$4" And (IsEmpty(Range("B3").Value) Or IsEmpty(Range("B4").Value)) Then
Exit Sub
Else
BEM
End If
End Sub

The and operator has higher precedence than the or operator therefore your if condition in its current format is interpreted as if:
If Target.Address = "$B$3" Or (Target.Address = "$B$4" And (IsEmpty(Range("B3").Value)) Or IsEmpty(Range("B4").Value)) Then
But you want to goup the or conditions:
If (Target.Address = "$B$3" Or Target.Address = "$B$4") And ((IsEmpty(Range("B3").Value) Or IsEmpty(Range("B4").Value))) Then

When testing for multiple Ranges, you can use If Not Intersect(Target, Range("B3:B4")) Is Nothing.
And instead of checking each Cell if IsEmpty or Not, you can use the WorksheetFunction.CountA for an entire range, in your case your range consists of 2 cells, so you want to check that WorksheetFunction.CountA("YourRange") = 2.
Code
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("B3:B4")) Is Nothing And WorksheetFunction.CountA(Range("B3:B4")) = 2 Then
BEM
End If
End Sub

Related

Select specific cell after Inputting values In previous cells

so I have an input sheet and want to move the activated cell to another cell after data has been typed in/chosen.
So far I've got this:
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
If Range("F11").Value <> "" Then
Range("F13").Select
End If
End Sub
But the problem is this does not seem to work with more cells and ranges for some reason. So for example if then F13 is selected I want to move to F16. If F16 is selected I want to move to F17. So no rule here like always 2 rows down. How can I solve this?
Best
This is a simply type of a boilerplate, which can be increased further, following a specific business logic.
If you want to Add Range("D5") with 3 rows, then add it to the Union in this line: If Intersect(Target, Union(Range("F16"), Range("F13"))) and then make a Case Range("D5").
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
If Target.Cells.Count > 1 Then Exit Sub
If Target.Row > Rows.Count - 2 Then Exit Sub
If Target = vbNullString Then Exit Sub
If Intersect(Target, Union(Range("F16"), Range("F13"))) Is Nothing Then Exit Sub
Select Case Target
Case Range("F16")
Target.Offset(1).Select
Case Range("F13")
Target.Offset(2).Select
End Select
End Sub

Macro to Filter Pivot Table

I have a dataset where i want to click on a cell in column A and it filters a pivot table on a different worksheet. I have this code so far:
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Selection.Count = 1 Then
If Not Intersect(Target, Range("A2")) Is Nothing Then
Sheets("Labor Detail").Select
ActiveSheet.PivotTables("PivotTable1").PivotFields("WBS1").ClearAllFilters
ActiveSheet.PivotTables("PivotTable1").PivotFields("WBS1").CurrentPage = Range("A2").Value
End If
End If
End Sub
It does what i want but only for one cell. I want to be able to click on ANY cell in column A and have the cell value filter the pivot table. How do i specify a range instead of just one cell?
Try this instead:
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Column = 1 And Target.Value <> "" Then
Sheets("Labor Detail").Select
ActiveSheet.PivotTables("PivotTable1").PivotFields("WBS1").ClearAllFilters
ActiveSheet.PivotTables("PivotTable1").PivotFields("WBS1").CurrentPage = Target.Value
End If
End Sub
I got rid of Selection.Count = 1 as I don't think that's really doing anything. Instead I'm testing against Target.Value to make sure you have something to filter your pivot table by.

Capture the final change in a Worksheet Change Event

In the worksheet(1), I have multiple plan-to-change cells, A1 and other cells, and others cells value depends on the the value of A1 as I set up the function(eg.,B1=A1+1). In this way, if I change the value of A1, other cells would change value as well, and the total changed cells would be the A1 plus others changed cells. However, as the quantity of "other cells" is quite large, when I run the following function in VBA:
Private Sub Worksheet_Change(ByVal Target As Range)
Cells(Target.Cells.Count, 21) = "ok"
End Sub
The column 21 would appear 3 "ok"s as I suppose because the large cells change happen in order, which actives three times the Worksheet_Change function. (the first ok for I change A1, the second for the time delay of updated function, the third for the final cell) However, I only want the Worksheet_Change to capture the final cells change after I change the value of A1, what should I do to avoid the previous capturing of Worksheet_Change function?
Modify your code to run only when A1 is changed.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = Range("A1").Address Then
Cells(1, 21).Value = "ok"
End If
End Sub
Target is often more than a single cell. Determine if one of the changed cells is A1 with Intersect and then only deal with A1.
If you plan to change a value on the same worksheet, shut down event handling temporarily so the Worksheet_Change does not try to run on top of itself.
Private Sub Worksheet_Change(ByVal Target As Range)
if not intersect(target, range("a1")) is nothing then
on error goto safe_exit
application.enableevents = false
dim trgt as range
for each trgt in intersect(target, range("a1"))
Cells(trgt.row, 21) = "ok"
next trgt
end if
safe_exit:
application.enableevents = true
End Sub
Since I don't believe that a1 is the actual target of your Target in your real world, I've made the code a little more verbose than it probably needs to be.

Excel Macro to update Cells automatically based on User selection

I am trying to write a Macro that updates 4 Cell if the User select "Mailing" From Cell A1. If the User selects "Mailing" in A1, then Automatically update A2,A3,A4, and A5 to Value in B1. If the User selects something other than "Mailing", Then all four cells should be blank and the user should be able to type in any value. Any help is appreciated. Thanks
I have gotten this far, but VBA is not my thing:
Sub test()
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$A$1" And Target.Value = "Mailing" Then
Range("A2:A4").Value = "B1"
End If
End Sub
As the others have mentioned, you just need to put it to Sub Worksheet_Change. Note that if you are "typing" the word into cell A1, you will actually be in A2 after the "Enter".
Private Sub Worksheet_Change(ByVal Target As Range)
If Range("A1").Value = "Mailing" Then
Range("A2:A4").Value = "B1"
End If
End Sub
The problem is you are trying to change the value of some of the cells in your code, so the code should run itself. You need to turn off events before changing the cell values and then turn it back on:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$A$1" And Target.Value = "Mailing" Then
Application.EnableEvents = False
Range("A2:A4").Value = "B1"
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.