标签:VBA,Evaluate方法
在文章:
使用Evaluate方法筛选数据
中,我们讨论了不使用筛选器而筛选数据的方法技巧,它可以替代自动筛选方法。这里我们进一步以示例扩展这个技巧。
本文的重点是基于多个条件筛选数据,并将结果放在一张新的工作表中。为此,我们仍使用Evaluate方法。
我们要做的是测试数据集的第3列中是否有“No”或“Maybe”。如果有,则把所有这些单元格所在的行中的数据复制到Res工作表中。
要筛选的数据集很简单,如下图1所示。
图1
标题从第10行开始,数据集的宽度为4列。首先,我们测试第3列中是否有含有“Yes”的数据。如果没有,则退出该过程。
If Application.CountIf(Sheet1.Columns(Col), "Yes") = 0 Then Exit Sub
接着,我们告诉VBA数据集从哪里(第10行)开始:
With Sheet1.[A10].CurrentRegion
设置变量(ar):
ar = Filter(.Parent.Evaluate("transpose(if((" & .Columns(Col).Address & _
"=""No"")+(" & .Columns(Col).Address & "=""Maybe""),row(1:" & _
.Rows.Count & "),char(2)))"), Chr(2), 0)
上面是代码中最复杂的部分,但知道要改变什么才是最重要的。我们希望评估的列是第3列,该列中包含Yes、No或Maybe。以下变量:
Dim Col As Integer
Col = 3
可以修改Col=?,其中?代表要评估的列。
下一个可以修改的部分是希望数组的大小以及希望在输出中包含哪些列。在下面的示例中,有4列。
ar = Application.Index(.Value, Application.Transpose(ar), [{1,2,3,4}])
上面在数组ar中包括4列。如果想要第1列和第4列,代码如下所示:
ar = Application.Index(.Value, Application.Transpose(ar), [{1,4}])
此时,还需要更改输出数组的大小:
Sheet2.[A2].Resize(UBound(ar, 1), 2).Value = ar
其中,2等于列(1和4)。在本示例的完整版本中,我们将包括所有4列。程序如下:
Sub FilterToNewLoc2Crit()
Dim ar As Variant
Dim Col As Integer
Col = 3
If Application.CountIf(Sheet1.Columns(Col), "Yes") = 0 Then Exit Sub
With Sheet1.[A10].CurrentRegion
ar = Filter(.Parent.Evaluate("transpose(if((" & .Columns(Col).Address & _
"=""No"")+(" & .Columns(Col).Address & "=""Maybe""),row(1:" & _
.Rows.Count & "),char(2)))"), Chr(2), 0)
ar = Application.Index(.Value, Application.Transpose(ar), [{1,2,3,4}])
End With
Sheet2.[A2].Resize(UBound(ar, 1), 4).Value = ar
End Sub
注意到,这个Excel VBA宏将输出数据到sheet2(工作表代码名称)。
注:本文学习整理自thesmallman.com,有兴趣的朋友,可以到原网站下载示例工作簿,也可以到知识星球App完美Excel社群下载示例工作簿。