查找ListObject中的最后一个可见行

时间:2015-08-01 16:00:31

标签: excel-vba vba excel

我使用下面的代码查找ListObject中最后一个可见行的Sheet.Row。它似乎运行正常,但我想知道当ListObject非常大时是否有更快的方法可以做到这一点。

干杯

Function GetLastDataRowNumber(aListObj As ListObject, Optional bVisibleOnly As Boolean = True) As Long
CheckArgNotNothing aListObj, "aListObj"

Dim k As Long: k = aListObj.ListRows.Count
Dim lstRow As ListRow: Set lstRow = aListObj.ListRows(k)

GetLastDataRowNumber = lstRow.range.Row

If bVisibleOnly Then
    Do Until (lstRow.range.EntireRow.Hidden = False)
        k = k - 1
        If k = 0 Then
            ' no visible rows at all
            GetLastDataRowNumber = 0
            Exit Function
        End If
        Set lstRow = aListObj.ListRows(k)
    Loop
    GetLastDataRowNumber = lstRow.range.Row
End If

结束功能

更新

今天我不得不重新审视这个令人遗憾的话题。我的原始代码工作,但并不总是,并没有高效的非常大的表。寻找RowHeight = 0是尝试获取Range.EntireRow.Hidden时罕见但偶尔失败的升级。以下是更好的工作代码:



'modified from https://www.mrexcel.com/forum/excel-questions/593611-find-last-row-filtered-data.html
Function LastFilteredRowFor(anLo As ListObject) As Long
On Error GoTo NoFilterOnSheet
    With anLo.AutoFilter.Range.Columns(1)
        Dim rngVisible As Range: Set rngVisible = .Resize(.Rows.Count - 1).Offset(1, 0).SpecialCells(xlCellTypeVisible)
        LastFilteredRowFor = GetLastRowNbrFromSpecialCells(rngVisible.Address, anLo.ShowTotals)
    End With
NoFilterOnSheet:
End Function

Function GetLastRowNbrFromSpecialCells(anAddr As String, bHasTotalRow As Boolean) As Long
    Dim v As Variant: v = Split(Replace(anAddr, ",", ":"), ":")
    Dim k As Long: k = UBound(v)
    Dim sLastWord As String: sLastWord = v(k)
    If k = 0 Or (Not bHasTotalRow) Then
        If bHasTotalRow Then
            GetLastRowNbrFromSpecialCells = 0 'the word *is* the TotalRow, not what we want
        Else
            GetLastRowNbrFromSpecialCells = Range(sLastWord).Row
        End If
    Else
        Dim sLastDelim As String: sLastDelim = Mid(Right$(anAddr, Len(sLastWord) + 1), 1, 1)
        Select Case sLastDelim
            Case ":"
                GetLastRowNbrFromSpecialCells = Range(sLastWord).Offset(-1).Row
            Case ","
                GetLastRowNbrFromSpecialCells = Range(v(k - 1)).Row
        End Select
    End If
End Function




1 个答案:

答案 0 :(得分:1)

如果隐藏行的范围是连续的并且在表的末尾,则可以避免循环:

Public Function GetLastDataRowNumber(ByRef aListObj As ListObject) As Long

    GetLastDataRowNumber = aListObj.Range.SpecialCells(xlCellTypeVisible).Rows.Count

End Function

否则,请尝试直接访问行高属性( lstRow.Range.Height<> 0 ):

Public Function GetLastDataRowNumber(ByRef aListObj As ListObject, _
                                     Optional ByVal bVisibleOnly As Boolean = True) As Long

    CheckArgNotNothing aListObj, "aListObj"

    Dim k As Long, lstRow As ListRow

    k = aListObj.ListRows.Count
    Set lstRow = aListObj.ListRows(k)
    GetLastDataRowNumber = lstRow.Range.Row
    If bVisibleOnly Then
        Do Until (lstRow.Range.Height <> 0)
            k = k - 1
            If k = 0 Then
                GetLastDataRowNumber = 0
                Exit Function
            End If
            Set lstRow = aListObj.ListRows(k)
        Loop
        GetLastDataRowNumber = lstRow.Range.Row
    End If 
End Function