假设我在excel中有一个命名范围。它有链接到A列中的配方。相邻列有关于配方的更多信息。
例如,B栏有“成分”,C栏有“厨房用具”,D栏有“课程”。
在列B的所有单元格中,进一步可能有多个条目,以随机顺序,用逗号分隔。例如。对于苹果派而言,成分将是苹果,黄油,鸡蛋,糖等。厨房用具可以是烤箱,馅饼容器,混合机器等。
我制作了一些多个选择列表框,其中列出了所有可能的成分,列出了所有可能的用具,等等。我想使用列表框来过滤掉相应的配方。
现在,自动过滤器最多只能为一个特定列过滤两个单词。我希望能够同时查找任何数量的成分。即使我选择了10种成分,所有含有任何所选成分的食谱也必须出现。
还有高级过滤器,但是因为我有多列(实际数据10不是配方)并且希望能够为每列选择最多10(或多或少)的搜索值,我需要为高级过滤器提供的组合快速失控。
有关如何在VBA中实现此目的的任何想法?
因此,列A包含(x或y或z或...)和列B的所有行包含(f或g或h或...)和列C包含(q或p或r或... )等等。
在这里用一句话很容易写下来,但是在翻译到VBA代码进行过滤时我有点迷失了。我确实在dict中有列表框的选定值。
答案 0 :(得分:0)
您可以手动设置每行的可见性。
Sub custom_filter()
Dim test_row As Range
Dim row_hidden As Boolean
Dim keywords() As String
Dim col_index As Integer
Application.ScreenUpdating = False
'replace named_range with appropriate name
For Each test_row In ThisWorkbook.Names("named_range").RefersToRange.Rows
row_hidden = True
'test first column - fill the array with you words
ReDim keywords(2) As String
keywords(0) = "apple"
keywords(1) = "orange"
keywords(2) = "cheese"
col_index = 2 'assign column number inside the named range
If test_column(test_row.Cells(1, col_index).Value, keywords) Then
'test second column - fill the array with you words
ReDim keywords(1) As String
keywords(0) = "spoon"
keywords(1) = "fork"
col_index = 3 'assign column number inside the named range
If test_column(test_row.Cells(1, col_index).Value, keywords) Then
'test third column - fill the array with you words
ReDim keywords(2) As String
keywords(0) = "v1"
keywords(1) = "v2"
keywords(2) = "v3"
col_index = 4 'assign column number inside the named range
If test_column(test_row.Cells(1, col_index).Value, keywords) Then
'nest more conditions if needed
row_hidden = False
End If
End If
End If
test_row.EntireRow.hidden = row_hidden
Next
Application.ScreenUpdating = True
End Sub
test_column
函数可能如下所示:
Function test_column(col_value As String, keywords() As String) As Boolean
test_column = False
For i = LBound(keywords) To UBound(keywords)
If InStr(1, col_value, keywords(i), vbTextCompare) Then
test_column = True
Exit Function
End If
Next
End Function
答案 1 :(得分:0)
我认为根据用户3964075的回答发布我的修改和一些其他功能是有意义的。
主过滤例程custom_filter
:
Sub custom_filter()
Dim test_row As Range
Dim row_hidden As Boolean
Dim keywords As String
Dim ListBox As Object
Dim col_index As Integer
Application.ScreenUpdating = False
'replace named_range with appropriate name
For Each test_row In ThisWorkbook.Names("named_range").RefersToRange.Rows
row_hidden = True
'test first column - fill a regex search string with selected words
Set ListBox = Sheets("SheetWithListboxes").Shapes("ListBoxIngredients").OLEFormat.Object
keywords = getkeywords(Listbox)
col_index = 1 'assign column number inside the named range
If test_column(test_row.Cells(1, col_index).Value, keywords) Then
'test second column - fill the regex search string with selected words
Set ListBox = Sheets("SheetWithListboxes").Shapes("ListBoxUtensils").OLEFormat.Object
keywords = getkeywords(Listbox)
col_index = 2 'assign column number inside the named range
If test_column(test_row.Cells(1, col_index).Value, keywords) Then
'test third column - etc, nest more conditions if needed
row_hidden = False
End If
End If
test_row.EntireRow.hidden = row_hidden
Next
Application.ScreenUpdating = True
End Sub
函数getkeywords
以获取列表框中所选(可能的多个)条目
Public Function getkeywords(ListBox As Object) As String
Dim i, j As Integer
With ListBox.Object
For i = 0 To .ListCount - 1
If .selected(i) Then
If LCase(.List(i)) = "all" Then
'if "all" is selected then ignore any other selection, return an empty search string
getkeywords = ""
Exit For
End If
If j = 0 Then
getkeywords = .List(i) 'First selected, just add
Else
getkeywords = getkeywords + "|" + .List(i) 'any additional selections are appended with the or operator |
End If
j = j + 1
End If
Next i
End With
End Function
函数test_column
对单元格中选定的单词进行正则表达式搜索:
Public Function test_column(LookIn As String, LookFor As String) As Boolean
Set RE = CreateObject("VBScript.RegExp")
RE.IgnoreCase = True
RE.Pattern = LookFor
RE.Global = False
If RE.Test(LookIn) Then
test_column = True
End If
End Function