根据 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 运算符不适用于多个字段;仅针对单个字段。在我看来,您至少有五个选择。
为 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 并取消隐藏行以删除模仿过滤器。
上面详述的五种方法中的任何一种都应该产生类似于以下的结果。
应用任何过滤方法后的结果
¹ 请参阅 了解复杂的示例多个条件使用 Scripting.Dictionary 作为 Range.AutoFilter Method
的排列条件
我希望显示列 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 运算符不适用于多个字段;仅针对单个字段。在我看来,您至少有五个选择。
为 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 并取消隐藏行以删除模仿过滤器。
上面详述的五种方法中的任何一种都应该产生类似于以下的结果。
应用任何过滤方法后的结果
¹ 请参阅