Excel根据多个条件过滤行

时间:2014-08-25 14:17:15

标签: excel excel-vba vba

假设我在excel中有一个命名范围。它有链接到A列中的配方。相邻列有关于配方的更多信息。

例如,B栏有“成分”,C栏有“厨房用具”,D栏有“课程”。

在列B的所有单元格中,进一步可能有多个条目,以随机顺序,用逗号分隔。例如。对于苹果派而言,成分将是苹果,黄油,鸡蛋,糖等。厨房用具可以是烤箱,馅饼容器,混合机器等。

我制作了一些多个选择列表框,其中列出了所有可能的成分,列出了所有可能的用具,等等。我想使用列表框来过滤掉相应的配方。

现在,自动过滤器最多只能为一个特定列过滤两个单词。我希望能够同时查找任何数量的成分。即使我选择了10种成分,所有含有任何所选成分的食谱也必须出现。

还有高级过滤器,但是因为我有多列(实际数据10不是配方)并且希望能够为每列选择最多10(或多或少)的搜索值,我需要为高级过滤器提供的组合快速失控。

有关如何在VBA中实现此目的的任何想法?

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

在这里用一句话很容易写下来,但是在翻译到VBA代码进行过滤时我有点迷失了。我确实在dict中有列表框的选定值。

2 个答案:

答案 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