我正在使用Microsoft Excel在VBA中使用AutoFilters。我遇到了如何处理数组进行过滤的问题;我已经将我的原始背景淡化为简化版本(原本希望能够理解这个问题):
在范围A1:A5的工作表中,假设我们分别有Fruit
,Apple
,Banana
,Orange
和Pear
。已应用AutoFilter,Fruit
是列标题。
运行以下代码会返回预期结果(Apple
,Banana
和Orange
,但不会返回Pear
):
Range("A1").Select
ActiveSheet.Range("A1:A5").AutoFilter Field:=1, _
Criteria1:=Array("=*an*", "=*app*"), Operator:=xlFilterValues
在我正在处理的项目中,过滤条件作为String变量传递,如上所述。问题在于并非每次都适用所有标准,因此其中一些标准应该没有效果。
例如:
Dim A As String, B As String, C As String
A = "=*an*"
B = Empty
C = "=*ap*"
Range("A1").Select
ActiveSheet.Range("A1:A5").AutoFilter Field:=1, _
Criteria1:=Array(A, B, C), Operator:=xlFilterValues
混合使用B
时,过滤不返回任何记录(无论是否为空,设置为Empty
,还是使用=*
等通配符。但是,在实际条件数组中用B
(硬编码)替换Empty
会返回预期结果。
我过去曾使用类似的代码(并且有效),尽管AutoFilter是ListObject的一部分。在这一点上,我唯一能想到的是将过滤器连接成带有分隔符的String并将其拆分为一个Array变量(这样它就是精确的大小,因为集合中未设置的项目会以同样的方式混淆标准变量确实)。但这似乎不直观且麻烦。
我错过了一些明显的东西吗?
答案 0 :(得分:4)
我想不出一种不涉及测试空参数的方法,这里有一种可能对你有用的方法,也可以防止重复的表达。
Sub Main()
Dim a As String
Dim B As String
Dim C As String
Dim filterCriteria as Variant
a = "=*an*"
B = Empty
C = "=*ap*"
filterCriteria = CombineArrays(Array(a, B, C))
If Not uBound(filterCriteria) = -1 Then
Range("A1").Select
ActiveSheet.Range("A1:A5").AutoFilter Field:=1, _
Criteria1:=filterCriteria, Operator:=xlFilterValues
End If
End Sub
Function CombineArrays(arr As Variant) As Variant
Dim a As Variant
Dim filterDic As Object 'Scripting.Dictionary
Set filterDic = CreateObject("Scripting.Dictionary")
For Each a In arr
If Not filterDic.Exists(a) And Not a = vbNullString Then
filterDic.Add a, a
End If
Next
CombineArrays = filterDic.Keys
Set filterDic = Nothing
End Function