【问题标题】:VBA - Loop Through Multiple Worksheets and Apply FilterVBA - 遍历多个工作表并应用过滤器
【发布时间】:2018-05-08 16:39:26
【问题描述】:

我需要对同一工作簿中的所有工作表应用相同的过滤器。

所有工作表在第一行都有标题,但应该应用过滤器的标题名称并不总是在同一列中,即工作表一个有问题的标题在工作表 2 的 H 列中它在 A 列中,在工作表 3 中它在 L 列中,依此类推......

此外,有些标题与标准不完全匹配 - 即,有些标题为“STATUS”,有些为“prefix_Status”,其他为“CurrentStatus”等等..所以我需要使用Instr 功能(除非有更好的选择)但我似乎无法弄清楚在哪里或如何使用它..

这是我目前的代码:

Sub WorksheetLoop()

         Dim WS_Count As Integer
         Dim I As Integer

         ' Set WS_Count equal to the number of worksheets in the active
         ' workbook.
         WS_Count = ActiveWorkbook.Worksheets.count

         ' Begin the loop.
         For I = 1 To WS_Count

            Dim count As Integer, rngData As Range
            Set rngData = Range("A1").CurrentRegion

            count = Application.WorksheetFunction.Match("STATUS", Range("A1:AZ1"), 0)

            rngData.autofilter Field:=count, Criteria1:="INACTIVE"

         Next I

End Sub

此代码仅将过滤器应用于一张纸。

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    只要您没有在代码中明确指定工作表,您总是指的是ActiveSheet。因此,在Range() 中,您必须像这样引用工作表:

    发件人:

    Set rngData = Range("A1").CurrentRegion
    count = Application.WorksheetFunction.Match("STATUS", Range("A1:AZ1"), 0)
    

    改为:

    With Worksheets(I)
        Set rngData = .Range("A1").CurrentRegion
        count = Application.WorksheetFunction.Match("STATUS", .Range("A1:AZ1"), 0)
    End With
    

    With Worksheets(I) - End With 之间的代码中的点是不同之处:


    关于Application.WorksheetFunction.Match,它只匹配包含完全单词“STATUS”的单元格。如果前面有空格或后面有符号,那么这样的做法是个好主意:

    count = Application.Match("*STATUS*", Worksheets(1).Range("A1:AZ1"), 0)
    

    那么仍然需要检查。像这样:

    If Not IsError(count) Then
        rngData.autofilter Field:=count, Criteria1:="INACTIVE"
    End If
    

    关于问题的第二部分,在 Match 函数中的值周围使用*

    Public Sub TestMe()    
        Range("E1") = "5teSt34"
        Debug.Print Application.WorksheetFunction.Match("*Test*", Range("A1:H1"), 0)    
    End Sub
    

    将始终返回5

    【讨论】:

    • 嗨 Vitata,谢谢你的回复。我包含了“with”语句,但它仍然只适用于我执行宏的工作表。
    • @EitelDagnin - 你确定吗?你可以保存excel文件,退出,打开它再试一次吗?你看到代码中Range 之前的. 了吗?其中有 2 个,它们非常重要。
    • 对不起,我删除了我的最后一条评论,因为我没有看到你更新了帖子......我很抱歉,我没有注意到上面代码中的点,我只是添加了“with”陈述。我把点放在那里,它工作得很好,但是当它到达第四张纸时,我收到错误消息:“无法获取 WoeksheetFunction 类的匹配属性”。在我对 SJR 的最后评论中,这是 SJR 的代码似乎“跳过”的同一张表。有什么建议吗?
    • @EitelDagnin - 它跳过工作表,因为count 返回错误,只要在其中找不到“状态”。可能是写成"STATUS ",后面或前面有一个空格或任何东西。
    • 感谢 Vityata 的帮助 :)
    【解决方案2】:

    基本上,您需要做的是在循环时引用代码中的工作表,而您并没有这样做 - 您只是通过不包含任何引用来引用活动工作表。

    通过 Match,您可以使用通配符。

    Sub WorksheetLoop()
    
    Dim WS_Count As Long
    Dim I As Long
    
    WS_Count = ActiveWorkbook.Worksheets.count
    
    Dim count As Variant, rngData As Range
    For I = 1 To WS_Count
       Set rngData = Worksheets(I).Range("A1").CurrentRegion
       count = Application.Match("STATUS", Worksheets(I).Range("A1:AZ1"), 0)
       If IsNumeric(count) Then rngData.AutoFilter Field:=count, Criteria1:="INACTIVE"
    Next I
    
    End Sub
    

    【讨论】:

    • 嗨 SJR,谢谢你,它似乎工作了一半......应用过滤器的前 3 个工作表,然后我收到错误消息:“无法获取 WoeksheetFunction 类的匹配属性” .目前有 10 个工作表,但有时可能更少,有时可能更多..
    • 我在上面做了修改,你能再试一次吗。
    • 它工作得非常好! :) 只有一个工作表不适用。我进行了三次检查,并且标题拼写正确,并且该列确实联系了正确的搜索条件。除此之外,该解决方案效果很好!对一张纸有什么建议吗?
    • 你的意思是它不应用过滤器吗?单步执行代码并检查count 的值。
    • 顺便问一下,您是否将通配符添加到匹配行中? "*STATUS*".
    猜你喜欢
    • 2017-11-26
    • 1970-01-01
    • 2014-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    相关资源
    最近更新 更多