Automate hide-unhide button based on heading style

rahildhody

Board Regular
Joined
Aug 4, 2016
Messages
55
Office Version
  1. 365
Platform
  1. Windows
I want to be able to hide/unhide rows (or group them, whichever works better) based on heading styles & heading order. I've tried using an .Autofilter technique but very quickly realised its dangers if people dont use subtotals as sums & major information was missed because of that method in the past.

Headings are always in Column AV, FirstCell is always BA36. the space between headers can be dynamic depending on content section
YTsrd.png


I want it to work as follows:
Everything visible & hide pressed: hide everything below lowest header found & keep all section headers, when pressed again, hide the bottom most heading & work its way up. & opposite for show button.
7ya9f.png


Ive tried to modify a code that existed previously for only 2 Header sections, to include a 3 Heading section but its a little buggy in the scenario where Header 1 & Header 2 are shown & hide is pressed. I want it to show only Header 1, but it unhides everything.

I have a few headers in my worksheet but i need to make sure i select headers 1, 2 or 3 only & live with not being able to see the other headers & have it bug out in one section. it would be nice to have this replicated across n number of headers used in the sheet, by picking on the style name defined at the start of this code.

Any help on this matter would be greatly appreciated.

VBA Code:
Sub ShowHide_partial()
Dim FirstCell As Range

Const Header1Style As String = "Hdr1"
Const Header2Style As String = "Hdr2"
Const Header3Style As String = "Hdr3"
Const FakeStyle As String = "This is a fake style"

On Error GoTo TheEnd

    Application.StatusBar = "Hiding/showing rows: please wait..."



    Set FirstCell = Range("BA35")
    Do While FirstCell.Style <> Header1Style
        Set FirstCell = FirstCell.Offset(1, 0)
        If FirstCell.Row > Cells.SpecialCells(xlCellTypeLastCell).Row Then
            GoTo TheEnd
        End If
    Loop

    If Application.Caller = "ShowButton" Then 'show button pressed
        Application.StatusBar = "Unhiding rows: please wait..."
        
        Select Case SectionStatus(FirstCell, Cells.SpecialCells(xlCellTypeLastCell).Offset(-1, 0), Header1Style, Header2Style, Header3Style)
            Case 1 'a
                Call CycleSection(FirstCell, Cells.SpecialCells(xlCellTypeLastCell), 3, Header1Style, Header2Style, Header3Style)
                
            Case 2 'a
                Call CycleSection(FirstCell, Cells.SpecialCells(xlCellTypeLastCell), 4, Header1Style, Header2Style, Header3Style)
                
            Case 3 'a
                Call CycleSection(FirstCell, Cells.SpecialCells(xlCellTypeLastCell), 5, Header1Style, Header2Style, Header3Style)
            
            Case 4 'a
                Call CycleSection(FirstCell, Cells.SpecialCells(xlCellTypeLastCell), 5, Header1Style, Header2Style, Header3Style)
            
            Case 5 'a
                Call CycleSection(FirstCell, Cells.SpecialCells(xlCellTypeLastCell), 5, Header1Style, Header2Style, Header3Style)
            
            Case Else 'any other status, go to showing everything
                Call CycleSection(FirstCell, Cells.SpecialCells(xlCellTypeLastCell), 5, Header1Style, Header2Style, Header3Style)
          
        End Select
            
    ElseIf Application.Caller = "HideButton" Then 'hide button pressed
        Application.StatusBar = "Hiding rows: please wait..."
        
        Select Case SectionStatus(FirstCell, Cells.SpecialCells(xlCellTypeLastCell).Offset(-1, 0), Header1Style, Header2Style, Header3Style)
        
            Case 1 '
                Call CycleSection(FirstCell, Cells.SpecialCells(xlCellTypeLastCell), 5, Header1Style, Header2Style, Header3Style)
            Case 2 '
                Call CycleSection(FirstCell, Cells.SpecialCells(xlCellTypeLastCell), 2, Header1Style, Header2Style, Header3Style)
            Case 3 '
                Call CycleSection(FirstCell, Cells.SpecialCells(xlCellTypeLastCell), 3, Header1Style, Header2Style, Header3Style)
            Case 4 '
                Call CycleSection(FirstCell, Cells.SpecialCells(xlCellTypeLastCell), 4, Header1Style, Header2Style, Header3Style)
            Case 5 '
                Call CycleSection(FirstCell, Cells.SpecialCells(xlCellTypeLastCell), 5, Header1Style, Header2Style, Header3Style)
            Case Else 'any other status, go to showing only first headers (by using a fake colour for second headers)
                Call CycleSection(FirstCell, Cells.SpecialCells(xlCellTypeLastCell), 5, Header1Style, Header2Style, FakeStyle)
        
        End Select

    Else
        'procedure called not using buttons
        MsgBox "Invalid caller"
    End If

TheEnd:
    Application.StatusBar = False
    

End Sub


Sub CycleSection(FirstCell As Range, LastCell As Range, NewStatus As Integer, Header1Style As String, Header2Style As String, Header3Style As String)
'cycles hidden/visible status of section
'NewStatus=1 hides everything
'NewStatus=2 hides everything except header 1
'NewStatus=3 hides everything except header 1 & header 2
'NewStatus=4 hides everything except header 1, header 2 & header 3
'NewStatus=5 unhides everything
Dim VisibleRange As Range
Dim TheRow As Long
Dim LowerHeadersFound As Boolean
Const HdrCol = 4 'column D

    Select Case NewStatus
    
        'hide everything
        Case 1
            Range(FirstCell.Offset(1, 0), LastCell).EntireRow.Hidden = True
            FirstCell.EntireRow.Hidden = False
            
        'unhide all lower section headers below header 1
        Case 2
            LowerHeadersFound = False
            Set VisibleRange = FirstCell.EntireRow
            
            'find section headers
            For TheRow = FirstCell.Offset(1, 0).Row To LastCell.Row
                If Cells(TheRow, HdrCol).Style = Header1Style Then
                    LowerHeadersFound = True
                    Set VisibleRange = Union(VisibleRange, Cells(TheRow, HdrCol).EntireRow)
                End If
            Next TheRow
            If LowerHeadersFound = False Then 'no subheaders
                Range(FirstCell, LastCell).EntireRow.Hidden = False
            Else 'subheaders exist
                Range(FirstCell.Offset(1, 0), LastCell).EntireRow.Hidden = True
                VisibleRange.EntireRow.Hidden = False
            End If
            
        'unhide all lower section headers below header 1 & header 2
        Case 3
            LowerHeadersFound = False
            Set VisibleRange = FirstCell.EntireRow
            
            'find section headers
            For TheRow = FirstCell.Offset(1, 0).Row To LastCell.Row
                If Cells(TheRow, HdrCol).Style = Header1Style Or Cells(TheRow, HdrCol).Style = Header2Style Then
                    LowerHeadersFound = True
                    Set VisibleRange = Union(VisibleRange, Cells(TheRow, HdrCol).EntireRow)
                End If
            Next TheRow
            If LowerHeadersFound = False Then 'no subheaders
                Range(FirstCell, LastCell).EntireRow.Hidden = False
            Else 'subheaders exist
                Range(FirstCell.Offset(1, 0), LastCell).EntireRow.Hidden = True
                VisibleRange.EntireRow.Hidden = False
            End If
            
        'unhide all lower section headers below header 1, header 2, header 3
        Case 4
            LowerHeadersFound = False
            Set VisibleRange = FirstCell.EntireRow
            'find section headers
            For TheRow = FirstCell.Offset(1, 0).Row To LastCell.Row
                If Cells(TheRow, HdrCol).Style = Header1Style Or Cells(TheRow, HdrCol).Style = Header2Style Or Cells(TheRow, HdrCol).Style = Header3Style Then
                    LowerHeadersFound = True
                    Set VisibleRange = Union(VisibleRange, Cells(TheRow, HdrCol).EntireRow)
                End If
            Next TheRow
            If LowerHeadersFound = False Then 'no subheaders
                Range(FirstCell, LastCell).EntireRow.Hidden = False
            Else 'subheaders exist
                Range(FirstCell.Offset(1, 0), LastCell).EntireRow.Hidden = True
                VisibleRange.EntireRow.Hidden = False
            End If
            
        'unhide everything
        Case 5
            Range(FirstCell, LastCell).EntireRow.Hidden = False
            
        'do nothing
        Case Else
            'do nothing if something else has been passed
    End Select
    Debug.Print NewStatus
    'Stop

End Sub


Function SectionStatus(FirstCell As Range, LastCell As Range, Header1Style As String, Header2Style As String, Header3Style As String) As Integer
'sectionstatus=0 if not a section header
'sectionstatus=1 only header 1 is showing
'sectionstatus=2 header 1 and header 2 are showing
'sectionstatus=3 header 1, header 2 and header 3 are showing
'sectionstatus=4 if everything is visible
'sectionstatus=5 if anything else...

    
Dim SectionComplete As Boolean
Dim UpperLevelHiddenFound As Boolean
Dim UpperLevelVisibleFound As Boolean
Dim MidLevelHiddenFound As Boolean
Dim MidLevelVisibleFound As Boolean
Dim LowerLevelHiddenFound As Boolean
Dim LowerLevelVisibleFound As Boolean
Dim NoHeaderHiddenFound As Boolean
Dim NoHeaderVisibleFound As Boolean
Dim Counter As Long
Dim FirstCellStyle As String
Dim TheCell As Range 'index cell

    'set up variables
    FirstCellStyle = FirstCell.Style
    SectionComplete = False
    LowerLevelHiddenFound = False
    LowerLevelVisibleFound = False
    MidLevelHiddenFound = False
    MidLevelVisibleFound = False
    NoHeaderHiddenFound = False
    NoHeaderVisibleFound = False

    If FirstCellStyle <> Header1Style And FirstCellStyle <> Header2Style And FirstCellStyle <> Header3Style Then
        'initial cell is not a header
        SectionStatus = 0
    ElseIf FirstCell.Row = LastCell.Row Then
        'no section
        SectionStatus = 0
    Else
        'runs down rows to ascertain what is in the section
        Counter = 1
        Do While SectionComplete = False
            Set TheCell = FirstCell.Offset(Counter)
            If TheCell.Row > LastCell.Row Then
                SectionComplete = True
            ElseIf TheCell.Style = Header1Style Then
                If TheCell.EntireRow.Hidden = True Then
                    UpperLevelHiddenFound = True
                ElseIf TheCell.EntireRow.Hidden = False Then
                    UpperLevelVisibleFound = True
                End If
            ElseIf TheCell.Style = Header2Style Then
                If TheCell.EntireRow.Hidden = True Then
                    MidLevelHiddenFound = True
                ElseIf TheCell.EntireRow.Hidden = False Then
                    MidLevelVisibleFound = True
                End If
            ElseIf TheCell.Style = Header3Style Then
                If TheCell.EntireRow.Hidden = True Then
                    LowerLevelHiddenFound = True
                ElseIf TheCell.EntireRow.Hidden = False Then
                    LowerLevelVisibleFound = True
                End If
            Else
                If TheCell.EntireRow.Hidden = True Then
                    NoHeaderHiddenFound = True
                ElseIf TheCell.EntireRow.Hidden = False Then
                    NoHeaderVisibleFound = True
                End If
            End If
            Counter = Counter + 1
        Loop
        
'    Debug.Print UpperLevelHiddenFound
'    Debug.Print UpperLevelVisibleFound
'    Debug.Print MidLevelHiddenFound
'    Debug.Print MidLevelVisibleFound
'    Debug.Print LowerLevelHiddenFound
'    Debug.Print LowerLevelVisibleFound
'    Debug.Print NoHeaderHiddenFound
'    Debug.Print NoHeaderVisibleFound
    
         'determines status by what has been found in the section
        If NoHeaderVisibleFound = False And LowerLevelVisibleFound = False And MidLevelVisibleFound = False Then
            SectionStatus = 1
        ElseIf NoHeaderVisibleFound = False And LowerLevelVisibleFound = False Then
            SectionStatus = 2
        ElseIf NoHeaderVisibleFound = False And LowerLevelHiddenFound = False Then
            SectionStatus = 3
        ElseIf NoHeaderHiddenFound = False And LowerLevelHiddenFound = False Then
            SectionStatus = 4
        Else
            SectionStatus = 5
        End If
    End If
    
    Debug.Print SectionStatus

End Function
 

Excel Facts

VLOOKUP to Left?
Use =VLOOKUP(A2,CHOOSE({1,2},$Z$1:$Z$99,$Y$1:$Y$99),2,False) to lookup Y values to left of Z values.

Forum statistics

Threads
1,223,881
Messages
6,175,161
Members
452,615
Latest member
bogeys2birdies

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top