2016-04-08 99 views
1

我正在寻找显示列L =“ABC”的行以及列AA显示行的行数“DEF”。我试过了,自动筛选和显示基于2列xlOR标准的行?

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

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

+0

的复杂多准则的实例具有你尝试录制宏并研究生成的代码? –

+0

[Range.AutoFit](https://msdn.microsoft.com/en-us/library/office/ff820840.aspx)不起作用。使用[高级筛选方法](https://msdn.microsoft.com/en-us/library/office/aa221800(v = office.11​​).aspx)或(如果您有一列唯一值)字典'钥匙'。 – Jeeped

+0

顺便说一下,列AA不会是“字段:= 27”吗? – Jeeped

回答

0

TL; DR:对于实现和理解,向下滚动到与“助手”列中的第二个选项的最快方法。 当您有时间将新技术与您的特定情况相匹配时,请回头探索其他方法
并最大限度地提高效率。

正如评论所说,xlOr运营商在Range.AutoFilter Method不跨越多个领域的工作;仅适用于单个字段。正如我所看到的,你至少有五种选择。


选项1:Advanced Filter method

设置一个面积为Advanced Filter标准。在下面,我使用了AC1:AD3。高级过滤器OR标准将在连续的行上进行。

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_fields_Advanced_Filter
Advanced Filter标准区域

作为代码的示例数据.AutoFilter与工作表式 '助手' 列

“辅助”栏是一种简单的方法来进行多项确定。根据您的多个条件(例如=OR($L2="ABC",$AA2<>"DEF"))将一个简单的公式解析为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 property


选择3:Conditional Formatting规则

同样的逻辑为“助手”列溶液.AutoFilter可通过Conditional Formatting规则被应用和.AutoFilter可以施加到匹配行的滤色器。

autofilter_or_fields_Conditional_Formatting
样品的数据显示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.Dictionarykeys中唯一列的值,并将这些键用作一组条件。

autofilter_or_fields_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.EntireRow property

此所述Range.Hidden属性可能是最简单的解决方案。只需循环比较标准与列L和AA的行。收集不会Union method匹配的行,并在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 

请记住,你必须反向的标准,因为你打算隐藏行是不要匹配。这里隐含的警告是,您需要选择Range.CurrentRegion property并取消隐藏行以删除仿制过滤器。


Results:

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

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


¹参见Can AutoFilter take both inclusive and non-inclusive wildcards from Dictionary keys?用于使用Scripting.Dictionary作为排列标准的Range.AutoFilter Method