ActiveSheet.AutoFilter.Range有时会根据所选单元格返回表格的AutoFilter

时间:2018-02-01 14:08:39

标签: excel vba excel-vba autofilter

编辑:我能做的最好的事情就是找到最后一个使用过的单元格,然后将它偏移一行和一列。如果用户使用整张表,这将失败,但我愿意抓住这个机会。我可以暂时选择此单元格,然后切换回用户的上一个单元格。

Public Function getCellOutsideUsedRange(ws As Worksheet) As Range
    Dim rng As Range
    Set rng = getLastCellOnSheet(ws)
    If rng.Row = ws.Rows.CountLarge Then
        If rng.Column = ws.Columns.CountLarge Then
            Set getCellOutsideUsedRange = Nothing
        Else
            Set getCellOutsideUsedRange = rng.offset(0, 1)
        End If
    ElseIf rng.Column = ws.Columns.CountLarge Then
        If rng.Row = ws.Rows.CountLarge Then
            Set getCellOutsideUsedRange = Nothing
        Else
            Set getCellOutsideUsedRange = rng.offset(1, 0)
        End If
    Else
        Set getCellOutsideUsedRange = rng.offset(1, 1)
    End If
End Function

Public Function getLastCellOnSheet(ByRef ws As Worksheet) As Range
    Set getLastCellOnSheet = ws.Cells.Find(What:="*", After:=Cells(1, 1), LookIn:=xlFormulas, LookAt:= xlPart, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False)
End Function

如果在表格中选择了一个单元格,ActiveSheet.AutoFilter.Range将返回应用于表格的自动过滤器,而不是工作表。例如:

Sub test()
    Dim af As AutoFilter

    Range("C1").Select
    Set af = ActiveSheet.AutoFilter
    MsgBox af.Range(1).Value2
    MsgBox af.Parent.Name

    Range("C12").Select
    Set af = ActiveSheet.AutoFilter
    MsgBox af.Range(1).Value2
    MsgBox af.Parent.Name

End Sub

enter image description here

The documentation对我没有帮助。即使用户碰巧在表格中选择了一个单元格,我怎么能确保自己可以进入工作表自动过滤器,而不必循环通过单元格,直到我在桌子外面找到一个单元格?

上下文:我有一个简短的宏,它返回已应用于工作表的所有过滤器的列表。总之,它查看工作表和任何表,并为每个表使用AutoFilter.Range属性获取筛选的范围,选择此范围的顶行以获取筛选标题,然后检查每个单元格中的每个单元格。任何标准的过滤标题。如果用户在表格中选择了一个单元格,他们将无法返回任何工作表过滤器。

1 个答案:

答案 0 :(得分:0)

通常,在VBA中使用Select并依赖它是一种不好的做法。 How to avoid using Select in Excel VBA

关于自动过滤器 - 每个工作表只允许一个自动过滤器,它位于表格之外。因此,可以通过ActiveSheet.AutoFilter.Range访问它,可以是NothingNot Nothing

关于表格中的自动过滤器,您可以简单地遍历表格并逐个检查AutoFilter是否存在:

Sub TestMe()

    Dim cntAutoFilters      As Long
    Dim cnt                 As Long
    Dim wks                 As Worksheet
    Dim tbl                 As ListObject

    Set wks = Worksheets(1)

    If Not wks.AutoFilter.Range Is Nothing Then
        Debug.Print wks.AutoFilter.Range.Address
    End If

    For Each tbl In wks.ListObjects
        If Not tbl.AutoFilter Is Nothing Then
            Debug.Print tbl.Range.Address
        End If
    Next tbl

End Sub

关于MSDN文档:

修改 看起来如果你在工作表的表格中选择了一个单元格,那么这个表格外的AutoFilter就不能被引用了。