VBA Excel Double If - vba

I have various dropdown menus in the document and need to create a double conditional statement.
So I am trying to do the following:
If Cell B14 = Option 1 Then unhide Cells B16:B17
If Cells B17 = Yes Then hide Cells B19:B53
If Cells B17 = No Then show Cells B19:B34
So if someone picks Option 1 from the dropdown menu then there is another drop down menu that appear and if they select Yes from the second on it hide the required cells and if they pick No it unhides the required cells.
Options 2 & 3 in the first dropdown menu do not need to show the second drop down box.
I have it all working apart from the double if.
Current code is:
If Target.Address = "$B$14" Then
If Range("B14") = "Option 1: Travel Home" Then
ActiveSheet.Rows("16:35").EntireRow.Hidden = False
ActiveSheet.Rows("36:55").EntireRow.Hidden = True
ElseIf Range("B14") = "Option 2: Travel to next city" Then
ActiveSheet.Rows("15").EntireRow.Hidden = False
ActiveSheet.Rows("16:17").EntireRow.Hidden = True
ActiveSheet.Rows("19:35").EntireRow.Hidden = True
ActiveSheet.Rows("36").EntireRow.Hidden = False
ActiveSheet.Rows("37:55").EntireRow.Hidden = True
ElseIf Range("B14") = "Option 3: Make own arrangements" Then
ActiveSheet.Rows("15:36").EntireRow.Hidden = True
ActiveSheet.Rows("39:55").EntireRow.Hidden = False
End If
End If
Option 2 and 3 are working OK just option 1 isn't working to unhide/hide whats necessary and also then need to do the second dropdown option which the alters what is shown.

I tested the below code and it appears to be behaving as you desire. I did make some seemingly significant changes to the structure, but I did so in hopes of making it both easier to read and maintain going forward. I think my edits are self-explanatory.
I also took the liberty to assume this is a Worksheet_Change event even though you did not explicity state as such.
Private Sub Worksheet_Change(ByVal Target As Range)
Select Case Target.Address
Case Is = "$B$14"
Select Case Right(Left(Target.Value, 8), 1)
Case Is = 1 'Option 1
Me.Rows("16:17").EntireRow.Hidden = False
Case Is = 2 'Option 2
Me.Rows("15").EntireRow.Hidden = False
Me.Rows("16:17").EntireRow.Hidden = True
Me.Rows("19:35").EntireRow.Hidden = True
Me.Rows("36").EntireRow.Hidden = False
Me.Rows("37:55").EntireRow.Hidden = True
Case Is = 3 'Option 3
Me.Rows("15:36").EntireRow.Hidden = True
Me.Rows("39:55").EntireRow.Hidden = False
Case Else
Me.Rows("15:55").EntireRow.Hidden = True
End Select
Case Is = "$B$17"
Me.Range("B19:B35").EntireRow.Hidden = Not (Target.Value = "No")
End Select
End Sub
Here's the code to make sure all rows are hidden when the workbook is opened.
Private Sub Workbook_Open()
With Me.Worksheets("SheetName") ' change as needed
.Rows("1:3").EntireRow.Hidden = True
.Rows("15:55").EntireRow.Hidden = True
End With
End Sub

Related

How to automatically resize expanded rows?

So my problem is that I have a sheet in which a multitude of grouped rows exist. The rows are grouped in 2 levels. To put this in perspective, I have a group which covers the rows in A1:A55. Inside this first level group I have multiple second level groups covering smaller sections (e.g. rows in A2:A5, rows in A7:A10 and so on.). Because of Excel automatically adding groups together if they are adjacent to each other, I have added a blank row in between each 2nd level group of rows(A6, A11, etc.). I then proceeded to change the height of these blank rows to 0,00. This hid the + and - signs on the left hand bar for collapsing/expanding, which wasn't a problem as the collapsing and expanding is being handled via buttons on the sheet.
However, when all the grouped rows, or just the 2nd level grouped rows, are being expanded (either manually or via a macro), the row height of all the blank rows jumps back to a size at which Excel can display the + and - signs in the left hand bar again. This shows the blank rows which I want to prevent.
I know I probably can't prevent the resizing of the rows so it displays the + and - signs, however I was thinking about immediately resizing the blank rows to a height of 0.00. This is being built in the macro that is called via the buttons, but the concern is when a user expands the rows manually. There is no event for collapsing and or expanding for me to use in an event handler. Is there any way for me to have an automatic response on a manual expand action by the user?
I have provided a example of the code used below.
Sub Select1Year_Click()
Dim ws1 As Worksheet
Set ws1 = Worksheets("Overview")
Dim ws2 As Worksheet
Set ws2 = Worksheets("Selection Tab")
Dim ROffset As Integer
ROffset = ((ws2.Range("B33").Value - 1) * 4) 'User defined starting Year
'value
On Error Resume Next
With ws1
.Range("AJ2").Rows.ShowDetail = False '2018
.Range("AJ7").Rows.ShowDetail = False '2019
.Range("AJ12").Rows.ShowDetail = False '2020
.Range("AJ17").Rows.ShowDetail = False '2021
.Range("AJ22").Rows.ShowDetail = False '2022
.Range("AJ27").Rows.ShowDetail = False '2023
.Range("AJ32").Rows.ShowDetail = False '2024
.Range("AJ37").Rows.ShowDetail = False '2025
.Range("AJ42").Rows.ShowDetail = False '2026
.Range("AJ47").Rows.ShowDetail = False '2027
.Range("AJ52").Rows.ShowDetail = False '2028
End With
If ws2.Range("B31").Value = 1 Then 'User selected 1 year to be shown in
'expanded view
ws1.Range("AJ2").Offset(0, ROffset).Rows.ShowDetail = True
End If
End Sub
'------------------------------------------------------------------------
Sub Select10Year_Click()
Dim ws1 As Worksheet
Set ws1 = Worksheets("Overview")
Dim ws2 As Worksheet
Set ws2 = Worksheets("Selection Tab")
Dim i As Integer
Dim ROffset As Integer
ROffset = ((ws2.Range("B33").Value - 1) * 4) 'User defined starting Year
'value
If ws2.Range("B31").Value = 3 Then 'User selected all years to be expanded
On Error Resume Next
ws1.Shapes("Select10Year").ControlFormat.Value = True
With ws1
.Range("AJ2").Rows.ShowDetail = True '2018
.Range("AJ7").Rows.ShowDetail = True '2019
.Range("AJ12").Rows.ShowDetail = True '2020
.Range("AJ27").Rows.ShowDetail = True '2021
.Range("AJ22").Rows.ShowDetail = True '2022
.Range("AJ27").Rows.ShowDetail = True '2023
.Range("AJ32").Rows.ShowDetail = True '2024
.Range("AJ37").Rows.ShowDetail = True '2025
.Range("AJ42").Rows.ShowDetail = True '2026
.Range("AJ47").Rows.ShowDetail = True '2027
.Range("AJ52").Rows.ShowDetail = True '2028
End With
If ROffset > 0 Then 'User has selected a different starting year then
'2018, so collapse are years before selected
'starting year
For i = 0 To i = ROffset Step 1
ws1.Range("AJ2").Offset(0, ROffset).Rows.ShowDetail = False
Next i
End If
End If
End Sub
Any help would be greatly appreciated.
You can have your macro being launched as a result of a Worksheet_Change() event.

VBA single select on a Pivot Table field filter

I am working on my VBA code for a PivotTable field.
What I want to achieve is to only select Acc Payable in field Group. The following code can help me get what I want, but I'm considering whether there is a way to delete those False lines and make the code shorter?
With ActiveSheet.PivotTables("PivotTable1").PivotFields("Group")
.PivotItems("Acc Services").Visible = False
.PivotItems("FRG").Visible = False
.PivotItems("Non FinOps").Visible = False
.PivotItems("Semi Auto").Visible = False
.PivotItems("Acc Payable").Visible = True
End With
End With
You can use a For loop, to iterate through the PivotField named "Group" PivotItems, and if the PivotItem.Name = "Acc Payable" then make it visible.
Code
Dim PvtItm As PivotItem
For Each PvtItm In ActiveSheet.PivotTables("PivotTable1").PivotFields("Group").PivotItems
If PvtItm.Name = "Acc Payable" Then
PvtItm.Visible = True
Else
PvtItm.Visible = False
End If
Next PvtItm

Setting CheckBoxes from another userform in VBA

I have a userform which contains a number of checkboxes from 1 to 100. I have written some very simple code so that when you submit the form it creates a binary string that represents the state of those 100 checkboxes, where 0 is false and 1 is true. The code to do this is here:
Private Sub BusRulesSubmit_Click()
Dim myBinaryString As String
Dim nm As String
Dim c As Control
For busRuleIdx = 1 To 100
nm = "CheckBox" & busRuleIdx
Set c = Controls(nm)
If c.Value = True Then
myBinaryString = myBinaryString & "1"
Else
myBinaryString = myBinaryString & "0"
End If
Next
msgBox myBinaryString
End Sub
I now want to open this Userform from another form, where I have a similar binary string, and use this string to set the values of the checkboxes to true or false as appropariate. However I am having issues when setting my control. The code is here:
Private Sub populateBusRules()
Dim c As Control
Dim myBRBinary As String
myBRBinary = "000000000011100000000000000000000000000000000000000000000000000000000010000000000000000000000000000"
For busRuleIdx = 1 To 100
nm = "BusinessRules.CheckBox" & busRuleIdx
Set c = Controls(nm)
If Mid(myBRBinary, buRuleIdx - 1, 1) = 1 Then
c.Value = True
Else
c.Value = False
End If
Next
End Sub
When I run the above, I get a runtime error "Could not find the specified object" and when going to debug it highlights this problem where the code states "Set c = Controls(nm)" - and I can see that it is failing in the first round of the loop i.e. where nm = "BusinessRules.CheckBox1"
Interestingly if I run the code "Set c = Controls(BusinessRules.CheckBox1)" I get no such issue.
Any help would be much appreciated.
Thanks,
Paul.
I think the BusinessRules is giving you the issue. In the Controls collection, there is no Control named "BusinessRules.CheckBox1", only one named "CheckBox1" within the BusinessRules.Controls collection. Assuming there aren't other issues mentioned in the comments above (like the form being closed before this is called), then this should fix your issue

How can I use two conditions for my `IF` block?

I have a problem to create double conditions with If, so this is what I have for hiding a line:
If Target.Address = "$D$35" Then
If (Target.Value = "No") Then
ActiveSheet.Range("37:40").Rows.Hidden = False
End If
If (Target.Value = "Yes") Then
ActiveSheet.Range("37:40").Rows.Hidden = True
End If
End If
Now, I want to add another condition for this formula, let's say that that cell $D$35 need to be "No" and Cell $D$36 need to be "done" in order for the Hide function to work.
How do I insert this to my existing formula ?
1. You can use And for multiple conditions (cf #jonrsharpe comment). Actually take a look at other logical operators like Or etc ... Logical and Bitwise Operators
2. Why don't you use If\ElseIf\Else ? It's quite obvious that if Target.Value = "No" is true you do not have to test if Target.Value = "Yes" ...
So just do something like that:
If cond1 And cond2 Then
' Some code
ElseIf cond3 And cond4 Then '<--editted
' Some code
Else
' Some code
End If
Example: Let's say you want to do a condition on the values of cell D35 ($D$35) and D36 you can just do:
If Range("D35")= "No" And Range("D36")= "No" Then
ActiveSheet.Range("37:40").Rows.Hidden = False
ElseIf Range("D35")= "Yes" And Range("D36")= "done" Then
ActiveSheet.Range("37:40").Rows.Hidden = True
End If
Instead of
If Target.Address = "$D$35" Then
If (Target.Value = "No") Then
ActiveSheet.Range("37:40").Rows.Hidden = False
End If
If (Target.Value = "Yes") Then
ActiveSheet.Range("37:40").Rows.Hidden = True
End If
End If
Note 1: this assumes you are working on the right sheet
Note 2: this isn't especially the best way to do ...
First, it's not a formula, it's a subroutine. Second, you don't have to have multiple IF blocks. Just one should suffice.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("D35:D36")) Is Nothing Then
ActiveSheet.Range("37:40").Rows.Hidden = (Range("D35").Value = "No" And Range("D36").Value = "Done")
End If
End Sub
A little explanation is in order:
If Not Intersect(Target, Range("D35:D36")) Is Nothing returns TRUE if the change is detected in either D35 or D36. If you want the condition to check in non-contiguous ranges, use Union on the ranges you want to check.
(Range("D35").Value = "No" And Range("D36").Value = "Done") evaluates to TRUE if both conditions are met, FALSE if else. We then use this as the boolean trigger for the Hidden property of the given range.
Hope this helps.

How to hide columns based on name in Excel 2010?

I am trying to hide columns based on name using VBA inside Excel 2010. Each of my columns have a product version and some results below it. The product version does repeat throughout the spreadsheet since I have it categorized by OS. Thus, I'm hiding multiple columns based on selection, like a filter would do. If I could hide based on the name and not the column letter (A,B,C,...), then adding columns in between in the future would prevent more code changes on the location of those columns.
What I'm currently doing right now is fixed to the column letter. This limits me in the sense that I cannot add columns in between without having to change the code (column letter). Example:
`If productver_2dot5.Value = True Then
Columns("E").Hidden = False
Columns("M").Hidden = False
Columns("AC").Hidden = False
Columns("AT").Hidden = False
Columns("BD").Hidden = False
Columns("BR").Hidden = False
Else
Columns("E").Hidden = True
Columns("M").Hidden = True
Columns("AC").Hidden = True
Columns("AT").Hidden = True
Columns("BD").Hidden = True
Columns("BR").Hidden = True
End If`
What I would like to do is to hide any columns that contains the name 'Product Ver 2" (example) in one of its cells.
Sub HideBlahs()
Dim col As Range
For Each col In ActiveSheet.UsedRange.Columns
If Application.CountIf(col, "blah") > 0 Then
col.EntireColumn.Hidden = True
End If
Next col
End Sub
FYI your posted code reduces to:
Range("E1,M1,AC1,AT1,BD1,BR1").EntireColumn.Hidden = Not productver_2dot5.Value