自动筛选和显示基于2列xlOR标准的行?

我正在寻找显示行列L =“ABC”,以及显示行AA列<>“DEF”的行。 我试过了,

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

,但似乎这只显示行的L列是“ABC”。 但是,我想要显示其列L是“ABC”,或者列AA不是“DEF”的行的联合。 我在哪里做错了?

TL; DR:为了实现和理解最快的方法,使用“帮助”列向下滚动到第二个选项。 当您有时间将新技术与您的特定情况相匹配时,请回头探索其他方法
并使效率最大化。

正如在注释中提到的那样, Range.AutoFilter方法中的xlOr操作符不能跨多个字段使用; 只为一个领域。 正如我所看到的,你至less有五个select。


选项1: 高级筛选方法

为高级筛选标准设置一个区域。 在下面,我使用了AC1:AD3。 高级filter或条件在连续的行上。

autofilter_or_fields_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

“帮手”栏是一个简单的方法来做出多重判断。 根据您的多个条件(例如=OR($L2="ABC",$AA2<>"DEF") )将一个简单的公式parsing为TRUE / FALSE到该列的未使用列和.AutoFilter。

autofilter_or_fields_Helper_Column
示例数据显示“助手”列中的工作表公式

作为代码:

  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 

保持公式尽可能简单。 请记住,在完成对已过滤结果的处理后,请删除“帮助程序”列并刷新xlCellTypeLastCell属性 。


选项3: 条件格式规则上的.AutoFilter

与“帮助”列解决scheme相同的逻辑可以通过条件格式规则应用,.AutoFilter可以过滤应用于匹配行的颜色。

autofilter_or_fields_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 

这里显而易见的好处是没有一列公式可以“清理”。


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

如果您有一个包含唯一值的列,请将您的条件与列L和AA中的值进行比较。 如果它们匹配,则从Scripting.Dictionary的键中的唯一列中logging值,并将键用作一组条件。

autofilter_or_fields_Scripting_Dictionary
显示条件格式规则的示例数据

作为代码:

  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.EntireRow属性上具有Range.Hidden属性的伪AutoFilter

这可能是最简单的解决scheme。 简单地循环比较列L和AA的标准行。 收集与Union方法 匹配的行,并在Range.EntireRow属性的集合上应用Range.Hidden属性。

autofilter_or_fields_Pseudo_Filter
示例数据行以接收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 

请记住,由于您计划隐藏匹配的行,因此必须将标准颠倒过来 。 这里隐含的警告是,您需要selectRange.CurrentRegion属性,并取消隐藏行以删除仿制filter。


结果:

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

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


¹ 请参阅自动filter是否可以从Dictionary键中使用包容性和非包含性通配符? 对于使用Scripting.Dictionary作为Range.AutoFilter方法的排列标准的复杂多标准示例