简体   繁体   中英

Excel VBA auto hide/ unhide rows - mulitiple cell selection

I am trying to hide/unhide rows based on the list value selected in a cell (Yes/No).

Scenario is that there are two drop-down lists (in Cell B1 and B4 ), when the value of Cell B1 is selected as 'No' , then rows 2 and 3 needs to be hidden else if value Yes is selected in B1 , then rows 2 and 3 to unhide.

Similarly, when the value of Cell B4 is selected as 'No' , then rows 5 and 6 needs to be hidden else if value Yes is selected in B4 , then rows 5 and 6 to unhide.

I have a working code (as shown below) but when I select a different drop down selection (say I have selected b1 as No initially and then went to B4 to select No) then my hidden rows dont remain hidden anymore and the rows are displayed (inspite of the selection being selected as No).

My Code as follows.

Private Sub Worksheet_Change(ByVal Target As Range)
    Worksheet_Change_A Target
    Worksheet_Change_B Target
End Sub  

Private Sub Worksheet_Change_A(ByVal Target As Range)
    Dim rng As Range      
    Set rng = Target.Parent.Range("B1") 
    If Target.Address <> Range("B1").Address Then 
        Exit Sub 
    Cells.EntireRow.Hidden = False
    Select Case Range("B1")   
        Case "Yes": 
            Range("2:3").EntireRow.Hidden = False
        Case "No": 
            Range("2:3").EntireRow.Hidden = True 
    End Select
End Sub  

Private Sub Worksheet_Change_B(ByVal Target As Range)
    Dim rng As Range
    Set rng = Target.Parent.Range("B4") 

    If Target.Address <> Range("B4").Address Then 
        Exit Sub
    Cells.EntireRow.Hidden = False
    Select Case Range("B4")  
        Case "Yes": Range("5:6").EntireRow.Hidden = False
        Case "No": Range("5:6").EntireRow.Hidden = True
    End Select
End Sub

Please note that I am a beginner in coding and trying to grow as I learn.

Your help is greatly appreciated. Please do let me know of you need any clarifications with respect to the scenario explained.

Thanks.

I think you can simplify it thus, but I may not have fully understood your intentions as to hiding rows. If B1 is No, should rows 2 and 3 remain hidden irrespective of the value of B4?

I'm not sure what the rng variable was intended to do but I don't think you need it and you can apply a general rule to hiding/showing.

Also, why call two other procedures (you may have a good reason)?

Private Sub Worksheet_Change(ByVal Target As Range)

If Target.Address = "$B$1" Or Target.Address = "$B$4" Then
    'Cells.EntireRow.Hidden = False
    Select Case Target.Value
        Case "Yes": Target.Offset(1).Resize(2).EntireRow.Hidden = False
        Case "No": Target.Offset(1).Resize(2).EntireRow.Hidden = True
    End Select
End If

End Sub

The issue is in the line Cells.EntireRow.Hidden = False . When you change B1, that line first unhides everything (including rows 4 and 5), then decides whether to hide rows 2 and 3.

The variable rng is never used.

The following explicitly checks the relevant cells in each subroutine. However, if you have expensive calculations, then you might want to include the line If Target.Address <> Range("B1").Address Then Exit Sub from your implementation.

Private Sub Worksheet_Change(ByVal Target As Range)
    Worksheet_Change_A Target
    Worksheet_Change_B Target
End Sub
Private Sub Worksheet_Change_A(ByVal Target As Range)
    Select Case Range("B1").Value
        Case "Yes": Range("2:3").EntireRow.Hidden = False
        Case "No": Range("2:3").EntireRow.Hidden = True
    End Select
End Sub
Private Sub Worksheet_Change_B(ByVal Target As Range)
    Select Case Range("B4").Value
        Case "Yes": Range("5:6").EntireRow.Hidden = False
        Case "No": Range("5:6").EntireRow.Hidden = True
    End Select
End Sub

I highly recommend indenting your code as I've shown, for readability. I used Range("B4").Value to explicitly show that I am using the cell contents. Lastly, the VBA debugger is your friend for tracking down issues like this. Click on the line of code you are interested about (or just before it), then in the VBA menu click Debug->Toggle Breakpoint (or F9). Then run the macro and the debugger wil stop at that line of code. You can inspect variables by hovering over them, step through the code or out of the sub. Very useful in cases like yours where you are not sure what is causing the issue.

Edit: SJRs solution is more elegant, in that it is more easily extensible if you want to add more ranges to hide.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM