Row.Count 即使在使用 xlCelltypevisible 时也计算不可见的单元格

Row.Count counts invisible cells even when using xlCelltypevisible

我正在尝试过滤 table,但有时会导致没有数据。我正在尝试计算可见的行数以做出此决定。

如果只有 Header 行 - “无单元格” 如果有可见行 - “有提供者”

在下面的代码中,似乎仍在计算过滤后的行...

Sub Add_New_Name()

    Dim pTable1 As Range
    Dim pVisible As Range

    'Application.DisplayAlerts = False
    'Application.ScreenUpdating = False
            
    ' Select Roster & Clear Roster Table Filters
    Sheet8.Activate
    Sheet8.ListObjects("Table1").AutoFilter.ShowAllData
                    
    ' Set Variables
    Set pTable1 = Range("B2").CurrentRegion
    Set pVisible = pTable1.SpecialCells(xlCellTypeVisible)
                    
    ' Check for New Associate
    With Sheet8.ListObjects("Table1")
        .Range.AutoFilter Field:=23, Criteria1:="0"
        .Range.AutoFilter Field:=22, Criteria1:="Associate"
    End With
                    
    If pVisible.Rows.Count > 1 Then
        MsgBox "No Cells"
    Else
        MsgBox "Has Provider"
    End If
                    
End Sub

在自动过滤器之后设置 pVisible。

With Sheet8.ListObjects("Table1")
    .Range.AutoFilter Field:=23, Criteria1:="0"
    Range.AutoFilter Field:=22, Criteria1:="Associate"
End With

Set pVisible = pTable1.SpecialCells(xlCellTypeVisible)

备选方案

Dim pTable As ListObject      'use instead of range
Dim pVisible As Range

Set pTable = Sheet8.ListObjects("Table1")

With pTable              
    .Range.AutoFilter Field:=23, Criteria1:="0"
    .Range.AutoFilter Field:=22, Criteria1:="Associate"                    
End With

On Error Resume Next
    Set pVisible = pTable.DataBodyRange.SpecialCells(xlCellTypeVisible)
On Error GoTo 0
'Stores range of visible cells. Does not raise error in case of not data.

If Not pVisible Is Nothing Then    'Checks if some info is present.
    MsgBox "Has Provider"
Else
    MsgBox "No Provider"
End If

这是通常的做法:

Sub Add_New_Name()
    Dim pVisible As Range

    Sheet8.Activate
    With Sheet8.ListObjects("Table1")
        .AutoFilter.ShowAllData
        .Range.AutoFilter Field:=23, Criteria1:="0"
        .Range.AutoFilter Field:=22, Criteria1:="Associate"
        
        On Error Resume Next 'ignore error if no visible rows
        Set pVisible = .DataBodyRange.SpecialCells(xlCellTypeVisible) 'ignore headers
        On Error GoTo 0      'stop ignoring errors
    End With
    
    If pVisible Is Nothing Then
        MsgBox "No Cells"
    Else
        MsgBox "Has Provider"
    End If
End Sub

将 headers 从对 SpecialCells 的调用和 trap/ignore 错误中排除(如果没有行可见)会更清晰。

这样,如果您继续使用 pVisible,您就没有 headers 了。

是否有过滤的行?

  • 您可以使用 On Error Resume Next,如 Tim Williams 的回答所示。
  • 您不能在 non-contiguous 范围内使用行数,因为它仅指范围的第一个区域。因此,如果第一行数据不可见,则无论之后有多少行可见,它都会 return1。
  • 但是您可以在 non-contiguous 单列范围内使用单元格计数。
Option Explicit

Sub Add_New_Name()
    
    Application.ScreenUpdating = False
    
    Dim cc As Long
    With Sheet8.ListObjects("Table1")
        If .ShowAutoFilter Then ' remove filter
            If .AutoFilter.FilterMode Then .AutoFilter.ShowAllData
        End If
        .Range.AutoFilter Field:=23, Criteria1:="0"
        .Range.AutoFilter Field:=22, Criteria1:="Associate"
        ' Get the cells count of any single column range!
        cc = .ListColumns(1).Range.SpecialCells(xlCellTypeVisible).Cells.Count
        .AutoFilter.ShowAllData ' remove filter
    End With
    
    Application.ScreenUpdating = True ' before the message box
    MsgBox IIf(cc = 1, "No Cells", "Has Provider")
    
End Sub

这对我来说是最直接的方法:

 VisibleRowCount = WorksheetFunction.SUBTOTAL(103, Sheet2.ListObjects("Table1").ListColumns(22).DataBodyRange)

但是如果您不确定 table 是否为空,请使用:

If not Sheet2.ListObjects("Table1").DataBodyRange is Nothing then _
   VisibleRowCount = WorksheetFunction.SUBTOTAL(103, Sheet2.ListObjects("Table1").ListColumns(22).DataBodyRange)

附录

正如 VisualBasic2008 指出的那样:

If you have just filtered the column by a value, then it's perfectly safe to use SubTotal.

回想起来,我会在计数中包括整个 ListColumn.Range 和 -1 以避免错误。

 VisibleRowCount = WorksheetFunction.SUBTOTAL(103, Sheet2.ListObjects("Table1").ListColumns(22).Range) -1