I have a worksheet which has many formulas and I need the following to happen: when this worksheet is used, and some cells on different rows are filled with a number other than 0, the rows which contain cells with 0, to hide automatically. And this should happen every time that worksheet is used, with different values.

About the attached example:

  • The value that changes is in column B
  • D, E and F are merged cells on each row
  • talking about the attached example: I need rows with Text2, Text 4 and Text 5 to be hidden automatically, because in B column the value is zero for these rows.
    enter image description here

  • IMPORTANT! - at each use of the worksheet, the rows that have 0 in column B are different. Not always the same. And also, this automatization must apply only to a certain selection in the document (let's say from rows 45 to 135).


This is similar to another answer but testing shows performance is nearly 1.5 orders of magnitude (70x) faster by doing all the property changes in two transactions; one each for hideRange.EntireRow.Hidden = True and unhideRange.EntireRow.Hidden = False.

There are three constants at the beginning of the file used to specify the column, starting row, ending row and value to hide on. The OP values have been plugged in.

Copy the following code into the specific vba WorkSheet module. This code will not work from a regular module. Press Alt-F11 to open the Visual Basic Editor. Press Ctrl-R to focus/open the Project Explorer pane. Navigate to VBAProject(<file name>), Microsoft Excel Objects and open the Sheet#(<sheet name>) where the hidden rows reside.

Private Sub Worksheet_Calculate()

  ' Hide Rows if row value in watch_Column is hide_On_Value.
  ' watch_Column must include start_on row number (e.g. A1 or C3)

  ' Hidden rows, beyond the range of cells with values, may not
  ' unhide. For speed, only process rows being used <= end_of_watch.
    Const watchColumn = "B45" ' Beginning Cell (row and column) to watch.
    Const endOfWatch = "135" ' Last row. if "", rest of rows in use.
    Const hideOnValue = 0

    Dim hideRange As Range
    Dim unhideRange As Range
    Dim r As Range
    Dim seeRow As Boolean
    Dim watchStart() As String
    Dim lastRow As String
    Dim tmpEnableEvents As Boolean

    Set r = Me.UsedRange ' call and discard to reset LastCell
    With Me.UsedRange
        lastRow = .Row + .Rows.Count - 1
    End With
    If endOfWatch <> "" Then
       If Val(lastRow) > Val(endOfWatch) Then lastRow = endOfWatch
    End If
    watchStart = Split(Me.Range(watchColumn).Address(True, False), "$")
    If Val(watchStart(1)) > Val(lastRow) Then Exit Sub
    tmpEnableEvents = Application.EnableEvents
    Application.EnableEvents = False
    For Each r In Me.Range(watchColumn & ":" & watchStart(0) & lastRow)
        seeRow = True
        If IsEmpty(r) Then
        ElseIf CStr(r.Value2) = vbNullString Then
        ElseIf r = hideOnValue Then
            seeRow = False
            If Not r.EntireRow.Hidden Then
                If hideRange Is Nothing Then
                    Set hideRange = r
                    Set hideRange = Union(hideRange, r)
                End If
            End If
        End If
        If seeRow And r.EntireRow.Hidden Then
            If unhideRange Is Nothing Then
                Set unhideRange = r
                Set unhideRange = Union(unhideRange, r)
            End If
        End If
    Next r
    If Not unhideRange Is Nothing Then
        unhideRange.EntireRow.Hidden = False
    End If
    If Not hideRange Is Nothing Then
        hideRange.EntireRow.Hidden = True
    End If
    Application.EnableEvents = tmpEnableEvents
End Sub

Regular Module Changes

  • Change the Sub name.
  • Change all the Me objects to a specific sheet reference.
    • Worksheets("Worksheet Name") criteria for one worksheet.
  • The OP, in a proposed edit to this answer, asked: if there is a condition - the rows with 0 in B column to be hidden only after a certain .... Adding details that the sheet needs to have multiple edits before hiding rows. Here is how to do this: Move the Sub to a regular module. Then change the Sub name from Worksheet_Calculate to Hide_Rows (save changes). Now hide the rows by opening the Macro dialogue using Alt-F8. Double click (run) Hide_Rows. N.B. This will hide the rows for the active sheet. Make additional edits to the Sub to specify the hidden rows sheet. – Ted D. Feb 25 '19 at 17:59

I would like to suggest one of the fastest methods is, VBA (Macro).

Note, Copy and Paste this Code with the Worksheet as Standard Module.

Private Sub Worksheet_calculate()

    Application.EnableEvents = False
    Set Rng = Intersect(UsedRange, Range("D:F"))

 If Rng Is Nothing Then GoTo ExitHere

    For Each i In Rng

        If i.Value = 0 Then
            Rows(i.Row).EntireRow.Hidden = True
            Rows(i.Row).EntireRow.Hidden = False
        End If
    Next i


    Application.EnableEvents = True
    Exit Sub

End Sub

N.B. Range("D:F") is editable, you may adjust Column reference as needed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.