Excel根据多个条件过滤行

比方说,我有一个在Excel中命名的范围。 它具有链接到列A食谱。相邻的列有更多的食谱信息。

例如B栏有'配料',C栏有'需要的厨房用具',D栏有'过程'。

在B列的所有单元格中,还可能有多个条目,按随机顺序,用逗号分隔。 例如苹果派的配料应该是“苹果,黄油,鸡蛋,糖”。 厨房用具可以“烤箱,馅饼容器,搅拌机”

我做了一些列出所有可能的成分的列表框,列出了所有可能的用具等。我想用列表框来筛选出适当的配方。

现在,自动筛选器最多只能同时为一个特定列过滤两个字。 我希望能够同时查找任何数量的成分。 即使我select了10种成分,所有食谱都有选定的成分。

也有先进的filter,但是因为我有多个列(10为实际数据,这是不是食谱),并希望能够select多达10(或多或less)每列search值,组合的数量需要为高级filter供应快速增长失控。

有关如何在VBA中实现这一点的任何想法?

因此,列A包含的所有行(x或y或z或…)和列B包含(f或g或h或…),列C包含(q或p或r或…)等。

这里用一句话很容易写下来,但是我在翻译VBA代码的过滤方面有些遗憾。 我有一个字典中的列表框的选定的值。

您可以手动设置每行的可见性。

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 

我认为这是有道理的发布我的改动和一些额外的function,我根据user3964075的答案使用。

主过滤例程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为单元格中的选定单词执行正则expression式search:

 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