Robby
Robby

Reputation: 827

Unhiding hidden rows in Excel

Here's my current code. If hidden rows are found, it puts red borders around the rows, a MsgBox details which rows were hidden, and the hidden rows are resized to a height of 15. It works perfectly unless the rows hidden are the last rows in the range. If they are the last rows in the range, this code unhides them but the red border does not get applied and the MsgBox doesn't include those rows in the reported list of hidden rows.

Is this because this method of finding the last row doesn't work if the last row is hidden? Or is the method acceptable and I just need to add/change something?

Sub UnhideRows()
Dim LastRow As Integer
LastRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
    Dim rng As Range
    Dim r As Range
    Dim sTemp As String

    Set rng = Range("A84:A" & LastRow)
    sTemp = ""
    For Each r In rng.Rows
        If r.EntireRow.Hidden = True Then
            sTemp = sTemp & "Row " & Mid(r.Address, 4) & vbCrLf
            r.EntireRow.Hidden = False
                With Range("A" & r.Row & ":W" & r.Row).Borders(xlEdgeLeft)
                     .Color = -16776961
                     .Weight = xlMedium
                End With

                With Range("A" & r.Row & ":W" & r.Row).Borders(xlEdgeTop)
                     .Color = -16776961
                     .Weight = xlMedium
                End With

                With Range("A" & r.Row & ":W" & r.Row).Borders(xlEdgeBottom)
                     .Color = -16776961
                     .Weight = xlMedium
                End With

                With Range("A" & r.Row & ":W" & r.Row).Borders(xlEdgeRight)
                     .Color = -16776961
                     .Weight = xlMedium
                End With
        End If
    Next r

     If sTemp <> "" Then
        sTemp = "The following rows were hidden:" & vbCrLf & _
          vbCrLf & sTemp
          MsgBox sTemp
     Else

     End If

         Cells.rowheight = 15
End Sub

Upvotes: 0

Views: 273

Answers (3)

QHarr
QHarr

Reputation: 84475

Try

Option Explicit

Public Sub UnhideRows()
    Dim LastRow As Long, rng As Range, r As Range, sTemp As String

    With ActiveSheet
        LastRow = .Cells.Find("*", [a1], xlFormulas, , xlByRows, xlPrevious).Row
        Set rng = .Range("A84:A" & LastRow)
        sTemp = vbNullString

        For Each r In rng.Rows
            If r.EntireRow.Hidden Then
                sTemp = sTemp & "Row " & Mid(r.Address, 4) & vbCrLf
                r.EntireRow.Hidden = False

                With .Range("A" & r.Row & ":W" & r.Row).Borders(xlEdgeLeft)
                    .Color = -16776961
                    .Weight = xlMedium
                End With
                With .Range("A" & r.Row & ":W" & r.Row).Borders(xlEdgeTop)
                    .Color = -16776961
                    .Weight = xlMedium
                End With
                With .Range("A" & r.Row & ":W" & r.Row).Borders(xlEdgeBottom)
                    .Color = -16776961
                    .Weight = xlMedium
                End With
                With .Range("A" & r.Row & ":W" & r.Row).Borders(xlEdgeRight)
                    .Color = -16776961
                    .Weight = xlMedium
                End With
            End If
        Next r

        If sTemp <> vbNullString Then
            sTemp = "The following rows were hidden:" & vbCrLf & _
                    vbCrLf & sTemp
            MsgBox sTemp
        End If
        .Cells.RowHeight = 15
    End With
End Sub

Which I would initially refactor into to benefit from using Union to handle all rows in one go.

Option Explicit

Public Sub UnhideRows()
    Dim LastRow As Long, rng As Range, r As Range, sTemp As String, unionRng As Range, borders(), i As Long
    With ActiveSheet
        LastRow = .Cells.Find("*", [a1], xlFormulas, , xlByRows, xlPrevious).Row
        Set rng = .Range("A84:A" & LastRow)
        sTemp = vbNullString

        For Each r In rng.Rows
            If r.EntireRow.Hidden Then
                sTemp = sTemp & "Row " & Mid(r.Address, 4) & vbCrLf
                If Not unionRng Is Nothing Then
                    Set unionRng = Union(unionRng, r.Resize(1, 23))
                Else
                    Set unionRng = r.Resize(1, 23)
                End If
            End If
        Next r

        If Not unionRng Is Nothing Then
            With unionRng
                .EntireRow.Hidden = False
                .borders(xlEdgeLeft).Color = -16776961
                .borders(xlEdgeLeft).Weight = xlMedium
                .borders(xlEdgeTop).Color = -16776961
                .borders(xlEdgeTop).Weight = xlMedium
                .borders(xlEdgeBottom).Color = -16776961
                .borders(xlEdgeBottom).Weight = xlMedium
                .borders(xlEdgeRight).Color = -16776961
                .borders(xlEdgeRight).Weight = xlMedium
            End With
        End If

        If sTemp <> vbNullString Then
            sTemp = "The following rows were hidden:" & vbCrLf & _
                    vbCrLf & sTemp
            MsgBox sTemp
        End If
        .Cells.RowHeight = 15
    End With
End Sub

Upvotes: 3

LFB
LFB

Reputation: 686

Indeed that seems to be the case. The method to find the last row skips hidden rows.

I think changing LastRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row to

With ActiveSheet.Cells(Rows.Count, 1).End(xlUp)
    If .Offset(1).EntireRow.Hidden = True Then
        LastRow = .Offset(1).Row
    Else
        LastRow = .Row
    End If
End With

will do the trick

EDIT If more than 2 rows could be hidden at the end of the range:

With ActiveSheet.Cells(Rows.Count, 1).End(xlUp)
For hidden_ones = 0 To ActiveSheet.Rows.Count
    If .Offset(hidden_ones + 1).EntireRow.Hidden = False Then Exit For
Next hidden_ones
    LastRow = .Offset(hidden_ones).Row
End With

Upvotes: 1

Storax
Storax

Reputation: 12207

Take this function found here

Function FindLastRow(R As Range) As Long
    Const NotFoundResult = 1 ' If all cells have an empty value, this value is returned
    FindLastRow = R.Worksheet.Evaluate("IFERROR(LARGE(ROW('" & R.Worksheet.Name & "'!" & R.Address & ")*--('" & R.Worksheet.Name & "'!" & R.Address & " <> """"),1)," & NotFoundResult & ")")
End Function

and adjust your code like that

LastRow = FindLastRow(ActiveSheet.Range("A:A"))

Upvotes: 1

Related Questions