To speed this up you can:
- Limit the number of cells you reference on the sheet
- Hide/Unhide all the required rows in one operation
- Only Hide/Unhide rows you want to change the visibility on
The code achieves this by
- Creates a Range that extends from the last tested row to the sheet end
- Uses
Match
to locate the next cell containing the test value
- Tests if the row visibility needs to be changed
- Tracks two sets of ranges, one to be hidden and the other to be unhidden
- Applies the Hide/Unhide to all rows at once
- Generalises the code to allow you to specify Worksheet, Column, TestValue and Hide Mode
Option Explicit
Enum HideMode
Hide = 0
Show = 1
Toggle = 2
End Enum
Sub Demo()
Hide_Columns_Toggle 8, "Header", HideMode.Toggle
End Sub
Sub Hide_Columns_Toggle(Col As Long, TestValue As Variant, Mode As HideMode, Optional ws As Worksheet)
Dim rng As Range
Dim rToHide As Range
Dim rToShow As Range
Dim rw As Variant
' Default to ActiveSheet
If ws Is Nothing Then Set ws = ActiveSheet
Set rng = ws.Range(ws.Cells(1, Col), ws.Cells(ws.Rows.Count, Col))
rw = Application.Match(TestValue, rng, 0)
Do Until IsError(rw)
Select Case Mode
Case HideMode.Toggle
If rng.Cells(rw, 1).EntireRow.Hidden = True Then
AddToRange rToShow, rng.Cells(rw, 1)
Else
AddToRange rToHide, rng.Cells(rw, 1)
End If
Case HideMode.Hide
If rng.Cells(rw, 1).EntireRow.Hidden = False Then
AddToRange rToHide, rng.Cells(rw, 1)
End If
Case HideMode.Show
If rng.Cells(rw, 1).EntireRow.Hidden = True Then
AddToRange rToShow, rng.Cells(rw, 1)
End If
End Select
Set rng = ws.Range(rng.Cells(rw + 1, 1), ws.Cells(ws.Rows.Count, Col))
rw = Application.Match(TestValue, rng, 0)
Loop
If Not rToHide Is Nothing Then
rToHide.EntireRow.Hidden = True
End If
If Not rToShow Is Nothing Then
rToShow.EntireRow.Hidden = False
End If
End Sub
Private Sub AddToRange(rng As Range, AddRange As Range)
If rng Is Nothing Then
Set rng = AddRange
Else
Set rng = Application.Union(rng, AddRange)
End If
End Sub