根据 2 列的 xlOR 标准自动过滤和显示行?

Autofilter and display rows based on the xlOR criterions from 2 columns?

我希望显示列 L = "ABC" 的行以及列 AA <> "DEF" 的行。我试过了,

Cells.AutoFilter Field:=12, Criteria1:="ABC", Operator:=xlOr, 
                 Field:=28, Criteria1:="<>DEF"

,但似乎只显示其 L 列为 "ABC" 的行。但是,我想显示列 L 为 "ABC" 或其列 AA 不是 "DEF" 的行并集。我哪里做错了?

TL;DR: For the quickest method to implement and understand, scroll down to the second option with the 'helper' column. Come back to explore the other methods when you have time to match new techniques to your particular situation
and maximize efficiency.

如评论中所述,Range.AutoFilter Method 中的 xlOr 运算符不适用于多个字段;仅针对单个字段。在我看来,您至少有五个选择。


选项 1:Advanced Filter method

Advanced Filter 条件设置一个区域。在下文中,我使用了 AC1:AD3。高级过滤器或标准在连续的行上。


具有 Advanced Filter 标准区域的样本数据

作为代码:

    Dim crit As Range
    With Worksheets("Sheet1")
        If .AutoFilterMode Then .AutoFilterMode = False
        .Range("AC1:AD1") = Array(.Range("L1").Value, .Range("AA1").Value)
        .Range("AC2") = "ABC"
        .Range("AD3") = "<>DEF"
        Set crit = .Range("AC1:AD3")
        With .Cells(1, 1).CurrentRegion
            .AdvancedFilter Action:=xlFilterInPlace, _
                            CriteriaRange:=crit, Unique:=False
        End With
    End With

选项 2:.AutoFilter 在具有工作表公式的 'helper' 列上

'helper' 列是进行多项确定的简便方法。将根据您的多个条件(例如 =OR($L2="ABC",$AA2<>"DEF"))解析为 TRUE/FALSE 的简单公式放入未使用的列中,并在该列上使用 .AutoFilter。


示例数据显示 'Helper' 列中的工作表公式

作为代码:

    With Worksheets("Sheet1")
        If .AutoFilterMode Then .AutoFilterMode = False
        With .Cells(1, 1).CurrentRegion
            With .Resize(.Rows.Count - 1, 1).Offset(1, .Columns.Count)
                .Formula = "=OR($L2=""ABC"",$AA2<>""DEF"")"
            End With
        End With
        With .Cells(1, 1).CurrentRegion
            .AutoFilter Field:=.Columns.Count, Criteria1:="TRUE"
            'clean up the 'helper' column and refresh the last_cell afterwards
            If False Then
                .Columns(.Columns.Count).EntireColumn.Delete
                .Parent.UsedRange
            End If
        End With
    End With

使公式尽可能简单。请记得在完成筛选结果后删除 'helper' 列并刷新 xlCellTypeLastCell property


选项 3:.AutoFilter Conditional Formatting 规则

可以通过 Conditional Formatting 规则应用与 'helper' 列解决方案相同的逻辑,并且 .AutoFilter 可以过滤应用于匹配行的颜色。


示例数据显示 Conditional Formatting 规则

作为代码:

    With Worksheets("Sheet1")
        If .AutoFilterMode Then .AutoFilterMode = False
        With .Cells(1, 1).CurrentRegion
            With .Resize(.Rows.Count - 1, .Columns.Count).Offset(1, 0)
                .FormatConditions.Add Type:=xlExpression, _
                                      Formula1:="=OR($L2=""ABC"",$AA2<>""DEF"")"
                .FormatConditions(.FormatConditions.Count).SetFirstPriority
                .FormatConditions(1).Font.Color = vbRed
            End With
            .AutoFilter Field:=1, _
                        Criteria1:=vbRed, Operator:=xlFilterFontColor
            With .Resize(.Rows.Count - 1, .Columns.Count).Offset(1, 0)
                .FormatConditions(1).Delete
            End With
        End With
    End With

这里的明显好处是没有 'clean up'.

的公式列

选项 4:在具有唯一值的列上使用 Scripting.Dictionary 对象

如果您有一列包含唯一值,请遍历行,将您的条件与列 L 和 AA 中的值进行比较。如果它们匹配,则将来自唯一列的值记录在 Scripting.Dictionary 中,并将键用作条件数组。


示例数据显示 Conditional Formatting 规则

作为代码:

    Dim d As Long, dict As Object
    Set dict = CreateObject("Scripting.Dictionary")

    With Worksheets("Sheet1")
        If .AutoFilterMode Then .AutoFilterMode = False
        With .Cells(1, 1).CurrentRegion
            For d = 2 To .Rows.Count
                If LCase(.Cells(d, "L")) = "abc" Or LCase(.Cells(d, "AA")) <> "def" Then _
                    dict.Add Key:=CStr(.Cells(d, "A").Text), Item:=vbNullString
            Next d
            With .Columns(1)
                .AutoFilter Field:=1, Criteria1:=dict.keys, Operator:=xlFilterValues
            End With
        End With
    End With

    dict.RemoveAll: Set dict = Nothing

与其他方法相比,这可能看起来工作量很大,但对于具有复杂标准的大数据块来说,它最终会更快¹。


选项 5:使用 Range.Hidden property on the Range.EntireRow property

的伪自动过滤器

这可能是最简单的解决方案。只需循环遍历行,将标准与列 L 和 AA 进行比较。收集 Union method and apply the Range.Hidden property on the collection of Range.EntireRow 属性匹配的行。


           Sample data rows to receive the Range.Hidden 属性 调整

作为代码:

    Dim d As Long, rng As Range

    With Worksheets("Sheet1")
        If .AutoFilterMode Then .AutoFilterMode = False
        With .Cells(1, 1).CurrentRegion
            .EntireRow.Hidden = False
            For d = 2 To .Rows.Count
                If (LCase(.Cells(d, "L").Value2) <> "abc" And _
                    LCase(.Cells(d, "AA").Value2) = "def") Then
                    If rng Is Nothing Then
                        Set rng = .Rows(d)
                    Else
                        Set rng = Union(rng, .Rows(d))
                    End If
                End If
            Next d
            rng.EntireRow.Hidden = True
        End With
    End With

请记住,您必须反转 条件,因为您打算隐藏 匹配的行。这里隐含的警告是您需要 select Range.CurrentRegion property 并取消隐藏行以删除模仿过滤器。


Results:

上面详述的五种方法中的任何一种都应该产生类似于以下的结果。


应用任何过滤方法后的结果


¹ 请参阅 了解复杂的示例多个条件使用 Scripting.Dictionary 作为 Range.AutoFilter Method

的排列条件