简体   繁体   中英

Hide and unhide rows based on a value

I am trying to create a survey in Excel and want to hide and unhide rows based on their answers. For example, if D3 = "no" hide rows D4:D10, and I want to repeat this multiple times throughout, but the number of rows to hide changes. So if D3 = "yes" leave unhidden. Then move to answer D5, if D5 = "no" hide rows D6:D7. And this continues on and on throughout.

Using the worksheet_change() event. In your VBE double click the worksheet where this change (this cell) will happen. Then enter:

Private Sub Worksheet_Change(ByVal Target As Range)

    'Detect if the worksheet change was on cell D3
    If Not (Intersect(Target, Range("D3")) Is Nothing) Then
        'Hide rows if the value of D3 is "No"
        Range("D4:D10").EntireRow.Hidden = (Range("D3").Value = "No")
    End If
End Sub

Every time a change happens on this worksheet this subroutine will fire off, test if the change occured in cell "D2" then toggle the row's hidden property based on the value.

The Hidden property of the EntireRow range object takes a True or False value, so we are able to just set it equal to the result of the conditional statement (Range("D3").value = "No") which will return a True or False greatly simplifying the amount of code you need to write.

You'll just need to add more If Not (Intersect(Target, Range("whatever")) Is Nothing) Then lines to test for your other cells like D5 and hide the appropriate rows base on whatever value you are testing for in that cell.

If that gets to be too much code (testing all those intersects) you can just test the intersects once like:

If Not (Intersect(Target, Union(Range("D3"), Range("D5"), Range("D8"))) Is Nothing) Then
    'And then in here your individual lines that toggle the hidden property:
    Range("D4:D10").EntireRow.Hidden = (Range("D3").Value = "No")

    Range("D6:D7").EntireRow.Hidden = (Range("D5").Value = "No")

    ...
End If

Lastly, because this beast will fire any time any change is made on this worksheet, you may want to shut off event firing while the subroutine is running. So turn enableEvents off at the top of the subroutine and turn it back on at the end:

Private Sub Worksheet_Change(ByVal Target As Range)

    Application.EnableEvents = False

    If Not (Intersect(Target, Union(Range("D3"), Range("D5"), Range("D8"))) Is Nothing) Then            
        Range("D4:D10").EntireRow.Hidden = (Range("D3").Value = "No")    
        Range("D6:D7").EntireRow.Hidden = (Range("D5").Value = "No")
        Range("D9:D12").EntireRow.Hidden = (Range("D8").Value = "No")    
    End If

    Application.EnableEvents = True

End Sub

This will prevent this same subroutine getting called by itself while it's busy changing the sheet causing an infinite loop and locking up excel (which sucks if you didn't save the workbook before firing it off).

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