3

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

我想做这样的事情:

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

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

有没有办法让 Autofilter Criteria1 不等于数组?就像是:

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

4 回答 4

5

请记住,目标是删除不匹配的行;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。

于 2013-10-21T15:19:17.033 回答
3

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

在工作表上,用户将应用自动筛选,然后使用列 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_before
                filterNotThree 子过程之前的数据

        filterNotThree_after
                filterNotThree 子程序后的数据

于 2016-01-31T21:58:42.797 回答
0

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

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

希望能帮助到你。

于 2016-02-03T14:39:39.507 回答
0

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

myrange.AutoFilter Field:=7, Criteria1:=Array("<>101", "<>102", "<>103"), Operator:=xlFilterValues
于 2021-04-07T18:08:23.983 回答