【问题标题】:Excel VBA autofilter all but threeExcel VBA自动过滤除三个之外的所有内容
【发布时间】:2013-10-30 03:07:49
【问题描述】:

在我的数据分析 (First Question) 的后续传奇中,我想删除所有部门(字段 7)不是 101、102 或 103 的行(名称已更改以保护无辜者)。数据中大概有一百个部门,所以使用Criteria1:=Array("104", "105", "106",等是不切实际的。

我想做这样的事情:

myrange.AutoFilter Field:=7, Criteria1:="<>101", Operator:=xlOr, _
    Criteria2:="<>102", Operator:=xlOr, Criteria3:="<>103"

但 Excel 不能识别超过 2 个条件。我可以添加一个辅助列,并让宏在每一行中运行(如果 101、102 或 103,则 value=Yes),过滤掉是,并删除所有剩余的,但我将其保存为最后度假村。

有没有办法自动过滤 Criteria1 不等于数组?比如:

myrange.AutoFilter Field:=7, Criteria1:="<>" & Array("101", "102", "103")

【问题讨论】:

    标签: excel vba autofilter


    【解决方案1】:

    我知道这已经晚了,但如果您需要超过 2 个条件,则必须使用数组。

    myrange.AutoFilter Field:=7, Criteria1:=Array("<>101", "<>102", "<>103"), Operator:=xlFilterValues
    

    【讨论】:

      【解决方案2】:

      我正在做类似的事情,但针对两个字段,这种语法对我有用:

      myrange.AutoFilter Field:=7, Criteria1:="<>101", Operator:=xlAnd, Criteria2:="<>102", Operator:=xlAnd
      

      希望对你有帮助。

      【讨论】:

        【解决方案3】:

        由于这是关于AutoFilter method,我将提供这种方法,涉及使用Scripting.Dictionary object 来模拟在工作表上手动执行时将使用的过程。

        在工作表上,用户将应用自动筛选,然后使用列 G 的下拉菜单“关闭”101、102 和 103 值。剩下的将被删除。在 VBA 中,我们可以抓取 G 列的所有内容并使用不是 101、102 或 103 的值填充字典对象,并将其用作过滤操作的条件。

        Sub filterNotThree()
            Dim d As Long, dDELs As Object, vVALs As Variant
        
            Set dDELs = CreateObject("Scripting.Dictionary")
        
            With Worksheets("Sheet6")
                If .AutoFilterMode Then .AutoFilterMode = False
                With .Cells(1, 1).CurrentRegion
                    'grab all of column G (minus the header) into a variant array
                    vVALs = .Resize(.Rows.Count - 1, 1).Offset(1, 6).Value2
        
                    'populate the dictionary object with the values that are NOT 101, 102, or 103
                    For d = LBound(vVALs, 1) To UBound(vVALs, 1)
                        Select Case vVALs(d, 1)
                            Case 101, 102, 103
                                'do not add
                            Case Else
                                'not a match, add it to the delete list
                                'the AutoFilter criteria needs to be text
                                ' so we set the Keys as text and the Items as numbers
                                dDELs.Item(CStr(vVALs(d, 1))) = vVALs(d, 1)
                        End Select
                    Next d
        
                    'check to make sure there is something to filter on
                    If CBool(dDELs.Count) Then
                        'filter on the dictionary keys
                        .AutoFilter field:=7, Criteria1:=dDELs.keys, Operator:=xlFilterValues
        
                        'delete the visible rows (there has to be some)
                        .Resize(.Rows.Count - 1, .Columns.Count).Offset(1, 0).EntireRow.Delete
                    End If
        
                End With
                If .AutoFilterMode Then .AutoFilterMode = False
            End With
        
            dDELs.RemoveAll: Set dDELs = Nothing
        End Sub
        

                
                       filterNotThree子过程之前的数据

                
                       filterNotThree子过程后的数据

        【讨论】:

          【解决方案4】:

          记住目标是删除不匹配的行; AutoFilter 只是帮助实现目标的一种工具。如果 AutoFilter 不能满足您的需求,请选择另一种方法。考虑:

          Sub AllBut()
              Dim rTable As Range, r As Range
              Dim rDelete As Range
              Set rTable = Selection
              Set rDelete = Nothing
              For Each r In rTable.Columns(7).Cells
                  v = r.Value
                  If v <> "101" And v <> "102" And v <> "103" Then
                      If rDelete Is Nothing Then
                          Set rDelete = r
                      Else
                          Set rDelete = Union(r, rDelete)
                      End If
                  End If
              Next
          
              If Not rDelete Is Nothing Then rDelete.EntireRow.Delete
          End Sub
          

          这里我们选择要处理的数据块(不包括标题行)。宏会向下扫描该块的第 7 列,并删除任何不符合条件的行。

          剩下的只有 101、102 和 103。

          【讨论】:

          • @garys-student 我很难做到这一点。我假设第 6 行的意思是“对于我的数据 G 列中的每个单元格”,但我不确定这是怎么回事,因为从未设置过 r 的范围。另外,我不熟悉Union 函数。假设它将当前单元格添加到rDelete 范围内,我是否正确?
          • 另外,v不需要声明吗?
          • @SMPerron :您的假设是正确的,在 For 循环中, r 每次通过循环时都是“设置”的,不需要明确地“设置”。如果 v 没有变暗,则假定它是 Variant。打开一个全新的工作簿,将一些临时数据放入其中并尝试使用宏。如果出现问题,您的真实数据不会被损坏.....祝您好运!
          猜你喜欢
          • 2016-11-19
          • 2018-10-27
          • 2023-02-02
          • 1970-01-01
          • 2011-04-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多