Excel AutoFilter With Criteria in a Range

iconfilter2In Excel 2003, and earlier versions, an AutoFilter allows only two criteria for each column. If you want to filter for multiple criteria, you can use an Advanced Filter. List all the criteria on a worksheet, and use that list (and its heading cell) as the criteria range.

In Excel 2007 and Excel 2010, the AutoFilter feature has been improved, and you can select multiple criteria in each column.

autofiltermulti

Record an AutoFilter Macro

If you record a macro while selecting criteria in Excel 2007, it will look something like this:

autofiltermulti02

The criteria are entered as an array, showing all three items that were selected in the drop down list.

Create Your Own Array

In the Contextures mail bag this week, someone asked if it’s possible to create this type of AutoFilter criteria array from a list on the worksheet. And the answer is yes, you can!

For this example, there’s a dynamic named range — CritList — on the Lists worksheet. The items in the CritList range will be used as the AutoFilter criteria array.

autofiltermulti03

On the Orders sheet, the fourth column — Products — will be filtered using this criteria list.

autofiltermulti04

AutoFilter Code With Array

In an Excel VBA procedure, you can create a variable to store the values from the CritList named range. Define this variable as a Variant, and it will store the values as an array.

vCrit = rngCrit.Value

Then, to use this variable as the AutoFilter criteria list, transpose the array, so it’s read as a row, instead of a column. If you don’t transpose the array, only the first item would be used in the criteria array. (Or, create your worksheet list in a row, instead of a column, and you won’t have to transpose it.)

Criteria1:=Application.Transpose(vCrit)

Here’s the complete code for the AutoFilter:

Sub FilterRangeCriteria()
Dim vCrit As Variant
Dim wsO As Worksheet
Dim wsL As Worksheet
Dim rngCrit As Range
Dim rngOrders As Range
Set wsO = Worksheets("Orders")
Set wsL = Worksheets("Lists")
Set rngOrders = wsO.Range("$A$1").CurrentRegion
Set rngCrit = wsL.Range("CritList")

vCrit = rngCrit.Value

rngOrders.AutoFilter _
    Field:=4, _
    Criteria1:=Application.Transpose(vCrit), _
    Operator:=xlFilterValues

End Sub

Download the AutoFilter Array Sample File

To see the sample code and the named range, you can download the AutoFilter Criteria Array sample file. It’s in Excel 2007 format, zipped, and you can enable macros when you open the file.

_________

You may also like...

32 Responses

  1. P says:

    This is very useful code. Thank You.

    However, why does this fail when the named range contains more than 2 values with wildcard?

    {“*oranges*”;”*apples*”;”*grapes*”}

    • Dave says:

      Did you ever figure out why you can’t have 3 or more items in the array if they contain wildcards?
      I have the same problem, and can find no answers.

      Here is the code I am trying:
      ActiveSheet.Range(“$A$3”).CurrentRegion.AutoFilter Field:=2, Criteria1:=Array(“Block*”, “Cell*”, “Grid*”), Operator:=xlFilterValues

      I have also tried this:
      ActiveSheet.Range(“$A$3:$A$3”).AutoFilter Field:=2, Criteria1:=Array(“Block*”, “Cell*”, “Grid*”), Operator:=xlFilterValues

    • @p and @Dave, if you use wildcards, the Autofilter applies a Custom Filter — contains — and that is limited to 2 criteria.

  2. Steven Mulvenna says:

    This works perfectly, however, I have one minor problem and one question:

    1. My CritList contains numbers and these do not get included in filter, how can I do this?
    2. In addition to the range that I have in my CritList I want to remove the blank rows. How can I add this to my CritList?

    Thanks for this code… very useful!

    Steve

  3. Lincoln Pinho says:

    How would you return the autofilter Criteria1 if the filter is set on a date. In Excel 2003, there is no problem. However, in 2007+, dates get grouped on year, month, date. This is quite a pain to return the Criteria1. It shows an Application-defined or Object defined error. Text values are no hassle, dates are defintely a big problem.

    • Lincoln Pinho says:

      Never mind my query. I found a work around. To disable the dates in the AutoFilter from getting grouped, you need to go to File > Options > Advanced > Display Options For This Workbook, and make sure the Group Dates in the AutoFilter Menu is off. This will list the dates normally in the dropdown. Then Criteria1 and Criteria2 values get populated.

  4. Raul says:

    how can i use the array in a conditon that i have two columns with filter condition example:

    column A:selected# 1,2,3 and in column B i dont want to select that are equal to column A: 1,2,3. but the number in column B is not permanent meaning later on other numbers might be added and i want to capture it using the array.

    my logic conditon: Column A: 1,2,3 selected and Column B: does not equal to Array Column A.. im having problem in using array does not equal in more than 2 criteria using the filter funtion. im getting syntax error.

    Syntax Error:
    ActiveSheet.Range(“$A$7:$U$5974”).AutoFilter Field:=3, Criteria1:=Array( _
    “770”, “773”, “778”, “779”), Operator:=xlFilterValues
    ‘ActiveSheet.Range(“$A$7:$U$5974”).AutoFilter Field:=4, Criteria1:=Array( _
    ‘ “770”, “773”, “778”, “779”). Operator:= _
    xlFilterValues

  5. Raul says:

    Syntax Error:
    ActiveSheet.Range(“$A$7:$U$5974”).AutoFilter Field:=3, Criteria1:=Array( _
    “770”, “773”, “778”, “779”), Operator:=xlFilterValues
    ActiveSheet.Range(“$A$7:$U$5974”).AutoFilter Field:=4, Criteria1:=Array( _
    “770”, “773”, “778”, “779”). Operator:= _
    xlFilterValues

  6. Raul says:

    Syntax Error:
    ActiveSheet.Range(“$A$7:$U$5974”).AutoFilter Field:=3, Criteria1:=Array( _
    “770”, “773”, “778”, “779”), Operator:=xlFilterValues
    ActiveSheet.Range(“$A$7:$U$5974”).AutoFilter Field:=4, Criteria1:=Array( _
    “770”, “773”, “778”, “779”). Operator:= _
    xlFilterValues

    the does not symbol was immited when i paste it here.

  7. Jabes says:

    would there be a way to filter on Dates and when I only want to show the dates >=12/19/2012?

  8. Pete Rooney says:

    Good morning,

    I am trying to filter a range of duration data where the value falls between two hard coded values.
    What I would like to do is to be able to replace the hard coded values either with Constants or with references to worksheet cells.
    Whilst I can refer to a worksheet cell providing that I’m doing an “=”, I can’t do a >= or a 0″, Operator:=xlAnd, Criteria2:=”0″, Operator:=xlAnd, Criteria2:=FiveMinutes THIS REFERENCE TO A CONSTANT DOESN’T!
    ActiveSheet.Range(“Database”).AutoFilter Field:=FilterField, Criteria1:=”>0″, Operator:=xlAnd, Criteria2:= Range(“FiveMinutes”).Value THIS WORKS
    ActiveSheet.Range(“Database”).AutoFilter Field:=FilterField, Criteria1:=”>0″, Operator:=xlAnd, Criteria2:= ” Range(“Database”).Columns.Count Then ‘only if at least one row displayed
    .Interior.ColorIndex = 43
    .Font.ColorIndex = 1
    End If
    ‘5 to 10 minutes Yellow
    ActiveSheet.Range(“Database”).AutoFilter Field:=FilterField, Criteria1:=”>0.00347222″, Operator:=xlAnd, Criteria2:=”FiveMinutes”, Operator:=xlAnd, Criteria2:=” Range(“Database”).Columns.Count Then ‘only if at least one row displayed
    .Interior.ColorIndex = 6
    .Font.ColorIndex = 1
    End If

    [/code]

    Thanks in advance for your assistance.

  9. Katie says:

    I have three workbooks whose data is linked to a master workbook. If I add an item to the master and then sort alphabetically it sorts in all of the lined workbooks which is perfect. There is one issue some of the data in one of the linked workbooks is data that is manually entered in that workbook and when I sort in the master that data doesn’t sort along with the linked data. Is there a way to fix this issue?

  10. Krishnasamy.M says:

    how to fix the if contion on below criteria1 in vba code.
    ActiveSheet.Range(“$A$1:$O$10000”).AutoFilter Field:=14, Criteria1:=Array( _
    “BODY”, “BODY BANK”, “PAINT”, “PRE-TRIM”, “TCF”), Operator:=xlFilterValues

  11. Garrett says:

    I tried changing the field that is reference from 4 to 1, but i guess the code can only do the fourth field of the table? if not, how can i fix this?

  12. Garrett says:

    for example

    Sub FilterRangeCriteria()
    Dim vCrit As Variant
    Dim wsM As Worksheet
    Dim wsL As Worksheet
    Dim rngCrit As Range
    Dim rngOrders As Range
    Set wsM = Worksheets(“MfrBodyCode”)
    Set wsL = Worksheets(“Lists”)
    Set rngOrders = wsM.Range(“$A$3”).CurrentRegion
    Set rngCrit = wsL.Range(“CritList”)

    vCrit = rngCrit.Value

    With wsO
    rngOrders.AutoFilter _
    Field:=4, _
    Criteria1:=Application.Transpose(vCrit), _
    Operator:=xlFilterValues
    End With
    End Sub

    This is not working for me for some odd reason. I’ve been staring at it all day.

    • @Garrett, did you create named ranges “CritHead” and “CritList”?

      In the code, you’ve added “With wsO” and “End With” — you don’t need those lines, and you don’t have a variable named wsO.

      On the MfrBodyCode sheet, make sure that the first column is included in the filtered range. Try removing the filter, then adding it again.

    • Eric says:

      @Garrett
      first “Save” the entire book onto your desktop as a “macro-enabled” file.
      Then, open it and accept “Macro-Enabled” option if you are asked, when you open it up.

      Then it should work. Try it. If it doesn’t work, post your code here and I will look at it.

  13. Eric says:

    @Garrett
    What I meant was if your code has changed any from the previous code… ;)

  14. max leclerc says:

    Hi…

    Is there any way to pass the criteria as parameters?

    I mean, if the criteria are selected from a listbox (one or more) is there any way to have the criteria specified as variables?

    thanks in advance

  15. HarryS says:

    HarryS
    ‘thanks for for BLOG

    ‘ maybe this may help clarify some of the confusion

    ‘ The problem with operator 7 xlFilterValues is that they use operators as
    ‘ 0 if one
    ‘ 2 an OR if two
    ‘ 7 and an array if more than two selected
    ‘ the arrays and criteria have a lot of” =” that confuse excel when something like “=fredsFarm” is put in a cell
    ‘ so use as “#” & “>=4567 to store and mid(.. , 2 ) to retrive
    ‘ rather than use arrays as we had to in ancient times use the functions Join and Replace
    ‘ that way we can save and reload criteria into and from different ranges

    ‘ save the criteria in range RasFilt from the filter range RaFoFi

    ‘ the . are With RaFoFi

    Case 7 ‘, xlFilterValues
    ‘will work on one or two only then an array
    ‘..1 is a 0 operator
    ‘ 2 as is as an OR operator ‘xlOR
    ‘ any more it is as an array .. with = ..
    ‘ using # to replace = to allow storage in a ONE cell
    RaSFilt(Fi, 4) = .Operator
    If .Operator = 2 Then RaSFilt(Fi, 5) = “#” & .Criteria2
    If IsArray(.Criteria1) Then
    RaSFilt(Fi, 3) = Replace(Join(.Criteria1, “,”), “=”, “#”)
    Else
    RaSFilt(Fi, 3) = “#” & .Criteria1
    End If

    ‘ etc

    ‘ to reload the filter
    With RaFoFi
    For Fi = 2 To RaSFilt.Rows.Count
    F = Fi – 1

    Select Case RaSFilt(Fi, 4) ‘ the operator
    Case 0
    ‘ no operator
    If Mid(RaSFilt(Fi, 3), 2) “” Then .AutoFilter F, Mid(RaSFilt(Fi, 3), 2)

    Case 1, 2 ‘xlAnd, xlOr
    .AutoFilter F, Mid(RaSFilt(Fi, 3), 2), RaSFilt(Fi, 4), Mid(RaSFilt(Fi, 5), 2)

    Case 3 To 6
    ‘ xlTop10Items, xlBottom10Items , xlTop10Percent, xlBottom10Percent
    .AutoFilter F, Mid(RaSFilt(Fi, 3), 2), RaSFilt(Fi, 4)

    Case 7 ‘, xlFilterValues will work on one or two .. it is as an OR
    ‘ these have been done in case 0 .. 2 … else is a variable .criteria
    ‘ RaSFilt(Fi + 20, 3) = Replace(Join(.Criteria1, “,”), “=”, “#”)

    .AutoFilter F, Split(Replace(RaSFilt(Fi, 3), “#”, “=”), “,”), RaSFilt(Fi, 4)

  16. Naveen N says:

    The source file have columns with normal data and two columns with a tables.
    The filter is on non table column, but I need to selet all the columns
    I am getting error
    1004 autofilter method of range class failed
    please help me to resolve the issue

  17. Robert says:

    Reviving an old thread…

    I’m trying to do the opposite here, but totally relevant. I need to get a string listing the selected filter criteria for a column. I have code that works great if only 1 or 2 filters are selected, but when 3 filters are selected, it fails. Here is the code I’m using (forgot the original source):

    Function FilterCrit(rng As Range) As String
    Dim Filter As String
    Filter = “{All}”
    With rng.Parent.AutoFilter
    If Intersect(rng, .Range) Is Nothing Then GoTo Finish
    With .Filters(rng.Column – .Range.Column + 1)
    If Not .On Then GoTo Finish
    Filter = .Criteria1
    Select Case .Operator
    Case xlAnd
    Filter = Filter & “, ” & Mid(.Criteria2, 2, Len(.Criteria2) – 1)
    Case xlOr
    Filter = Filter & “, ” & Mid(.Criteria2, 2, Len(.Criteria2) – 1)
    End Select
    End With
    End With
    Finish:
    FilterCrit = Filter
    End Function

    Any ideas? Thanks for the help!

    • The AutoFilter Custom Filter feature only allows 2 criteria, whether you’re trying to do it manually or with a macro.
      Try an Advanced Filter instead, if you need more criteria
      http://www.contextures.com/xladvfilter01.html

      • Robert says:

        Thanks. I found a good function that works without advanced:

        Function GetFilteredItems(temp As String) As String
        Dim fl As Filter
        Dim ws As Worksheet: Set ws = ActiveSheet
        Dim i As Long: i = 0
        Dim myfilters As String

        For Each fl In ws.AutoFilter.Filters
        If fl.On Then
        If Len(myfilters) = 0 Then
        myfilters = ws.AutoFilter.Range.Offset(0, i).Resize(1, 1).Value
        Else
        myfilters = myfilters & “; ” & _
        ws.AutoFilter.Range.Offset(0, i).Resize(1, 1).Value
        End If
        If fl.Count > 2 Then
        myfilters = myfilters & “: ” & Replace(Join(fl.Criteria1), “=”, “”)
        Else
        myfilters = myfilters & “: ” & Replace(fl.Criteria1, “=”, “”)
        On Error Resume Next
        myfilters = myfilters & ” ” & Replace(fl.Criteria2, “=”, “”)
        On Error GoTo 0
        End If
        End If
        i = i + 1
        Next
        ‘Debug.Print “>” & myfilters

        GetFilteredItems = myfilters
        End Function

        Wanted to share in case it could help someone else!

  1. October 1, 2012

    […] […]

  2. January 8, 2013

    […] Excel AutoFilter With Criteria in a Range | Contextures Blog […]

  3. March 18, 2013

    […] what office version you are using? check out this page is well explained Excel AutoFilter With Criteria in a Range | Contextures Blog […]

Leave a Reply to Eric Cancel reply

Your email address will not be published. Required fields are marked *