我想基于一个变量同时过滤这些列。我在循环中使用此过滤器来创建包含基于此过滤器的数据的pdf文件。(我删除了创建pdf的代码)
让我们看看以下示例:
Name1 Name2 Name3
Michael George Annet
George Michael Michael
Michael Jorge Annet
Jorge Annet Michtel
有3列有名称,我想根据一个包含名称的变量过滤这三列。所以例如name =" George"那么我希望看到每一行都包含名称" George"然后输出看起来:
Name1 Name2 Name3
Michael George Annet
George Michael Michael
我尝试了以下内容:
Set ws1 = Worksheets("Rooster")
For i = 1 To SelectionCount
name = NameArray(i)
If ws1.FilterMode Then ws1.ShowAllData
ws1.Range("AB8:AD157").AdvancedFilter _
Action:=xlFilterInPlace, _
CriteriaRange:=name, _
Unique:=False
Next i
NameArray(i)
是一个包含用户选择的所有名称的数组。 (NameArray()
是一个名为的函数)
SelectionCount
计算用户选择的单元格数。
("AB8:AD157")
是Excel应搜索变量的三列范围。
运行此代码时没有错误,但没有过滤任何内容。怎么了?或者AdvancedFilter不是正确的选择吗?
答案 0 :(得分:2)
afaik,你不能使用数组作为Range.AdvancedFilter method¹中的参数。但是,在VBA内存和范围引用中完全模仿.AdvancedFilter进程似乎并不太过分。
Sub pseudoAdvancvedFilter()
Dim n As Long, fnd As Range, rng As Range, addr As String, vNAMEs As Variant
vNAMEs = Array("george", "annet")
With Worksheets("Rooster")
With Range("AB8:AD157")
.EntireRow.Hidden = False
For n = LBound(vNAMEs) To UBound(vNAMEs)
Set fnd = .Cells.Find(What:=vNAMEs(n), LookIn:=xlValues, LookAt:=xlWhole, _
MatchCase:=False, SearchFormat:=False)
If Not fnd Is Nothing Then
addr = fnd.Address
If rng Is Nothing Then Set rng = fnd
Do
Set rng = Union(rng, fnd)
Set fnd = .Cells.FindNext(After:=fnd)
Loop Until addr = fnd.Address
End If
addr = vbNullString
Set fnd = Nothing
Next n
If Not rng Is Nothing Then
'Debug.Print rng.Address(0, 0)
.EntireRow.Hidden = True
rng.EntireRow.Hidden = False
End If
End With
End With
End Sub
将所有匹配项收集到数组中列出的名称后,使用循环Range.Find method和Union method,整个范围被隐藏,然后匹配单元格的并集用于取消匹配的行。< / p>
在运行pseudoAdvancvedFilter 之后运行pseudoAdvancvedFilter
¹有关详情和替代方法,请参阅 Can Advanced Filter criteria be in the VBA rather than a range? 。
答案 1 :(得分:0)
我从OP的Q那里得到了他想要隐藏任何不包含NameArray中所有名字的行。如果这实际上是他的需要,那么这就是我的解决方案
Option Explicit
Sub FilterMoreColumnsByName()
Dim iName As Long
Dim dataRng As Range, cell As Range, fnd As Range
Dim nameArray As Variant, name As Variant
nameArray = Array("george", "annet") ' <== it will be hidden any row NOT containing ALL of these names
With Worksheets("Rooster")
For iName = LBound(nameArray) To UBound(nameArray)
name = nameArray(iName)
Set dataRng = .Range("AB8: AB157").SpecialCells(xlCellTypeVisible) ' so as not to loop uselessly on rows that didn't match some previous name
Set fnd = .Cells(1, 1) ' add a "dummy" cell to prevent Union method to fail the first time -> it will be hidden -> it must be unhidden before exiting sub
For Each cell In dataRng
If cell.Resize(, 3).Find(What:=name, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=False, SearchFormat:=False) Is Nothing Then Set fnd = Application.Union(fnd, cell)
Next cell
fnd.EntireRow.Hidden = True
Next iName
.Rows(1).Hidden = False 'show the "dummy" cell row
End With
End Sub