在列中使用多个通配符条件的自动过滤
- 将完整代码复制到标准模块中,例如
Module1
- 调整常量部分中的值。
- 只运行第一个过程
filterMultipleCriteria,其余的都被它调用。
守则
Option Explicit
Sub filterMultipleCriteria()
Const wsName As String = "Sheet1"
Const HeaderRow As Long = 1
Const HeaderCriteria As String = "Targeted"
Const CriteriaStrings As String = "Word 1,Word 2,Word 3"
Const CriteriaDelimiter As String = ","
Dim wb As Workbook
Set wb = ThisWorkbook
Dim ws As Worksheet
Set ws = wb.Worksheets(wsName)
If ws Is Nothing Then Exit Sub
Debug.Print ws.Name
Dim cel As Range
Set cel = findCellInRow(ws.Rows(HeaderRow), HeaderCriteria)
If cel Is Nothing Then Exit Sub
Debug.Print cel.Address
Dim rng As Range
Set rng = defineNonEmptyColumnRange(cel.Offset(1))
If rng Is Nothing Then Exit Sub
Debug.Print rng.Address
Dim Data As Variant
Data = getColumn(rng)
If IsEmpty(Data) Then Exit Sub
Debug.Print "[" & LBound(Data, 1) & "," & UBound(Data, 1) & "]"
Dim wcFilter As Variant
wcFilter = getWildcardFilters(Data, CriteriaStrings, CriteriaDelimiter)
If IsEmpty(wcFilter) Then Exit Sub
Debug.Print Join(wcFilter, vbLf)
ws.Cells.AutoFilter Field:=cel.Column, Criteria1:=wcFilter, _
Operator:=xlFilterValues
End Sub
Function findCellInRow(RowRange As Range, ByVal Criteria As Variant) As Range
Dim cel As Range
Set cel = RowRange.Find(What:=Criteria, _
After:=RowRange.Cells(RowRange.Columns.Count), LookIn:=xlFormulas)
If Not cel Is Nothing Then Set findCellInRow = cel
End Function
Function defineNonEmptyColumnRange(FirstCell As Range) As Range
Dim cel As Range
With FirstCell.Resize(FirstCell.Worksheet.Rows.Count - FirstCell.Row + 1)
Set cel = .Find(What:="*", LookIn:=xlFormulas, _
SearchDirection:=xlPrevious)
If Not cel Is Nothing Then
Set defineNonEmptyColumnRange = .Resize(cel.Row - .Row + 1)
End If
End With
End Function
Function getColumn(ColumnRange As Range) As Variant
If ColumnRange.Columns(1).Rows.Count > 1 Then
getColumn = ColumnRange.Value
Else
Dim Data As Variant: ReDim Data(1 To 1, 1 To 1)
Data(1, 1) = ColumnRange.Value
getColumn = Data
End If
End Function
Function getWildcardFilters(ColumnData As Variant, CriteriaStrings As String, _
Optional ByVal CriteriaDelimiter As String = ",") _
As Variant
Dim Crit As Variant: Crit = Split(CriteriaStrings, CriteriaDelimiter)
Dim cUpper As Long: cUpper = UBound(Crit)
Dim Key As Variant, i As Long, n As Long
With CreateObject("Scripting.Dictionary")
.CompareMode = vbTextCompare
For i = 1 To UBound(ColumnData, 1)
Key = ColumnData(i, 1)
For n = 0 To cUpper
If InStr(1, Key, Crit(n), vbTextCompare) > 0 Then
.Item(Key) = Empty
Exit For
End If
Next n
Next i
If .Count > 0 Then getWildcardFilters = .Keys
End With
End Function