1

I need to filter a data table where 3 columns can contain the result I am looking for:

So if the criteria is found in columns 1, 2 or 3 then the row should be returned.

Data
(source: gulfup.com)

So in the above sample data lets say I select the criteria as "Fat"

I am looking for the autofilter to return rows 1 & 2; if I select the criteria as "Funny" I need rows 2 & 6 and so on....

Below is my code which is not working since apparently it tries to find the rows in which all columns contain the criteria, and it is not what I am looking to do.

With Sheet1
    .AutoFilterMode = False

    With .Range("A1:D6")
    .AutoFilter
    .AutoFilter Field:=2, Criteria1:="Fat", Operator:=xlFilterValues
    .AutoFilter Field:=3, Criteria1:="Fat", Operator:=xlFilterValues
    .AutoFilter Field:=4, Criteria1:="Fat", Operator:=xlFilterValues
    End With
End With

I have also tried to use Operator:=xlor but when I ran the code it returned no results.

In short: The row must be returned by the filter is the criteria is found in column B or C or D.

Help is definitely appreciated.

Community
  • 1
  • 1
CaptainABC
  • 1,229
  • 6
  • 24
  • 40
  • 1
    You can't do it in that way. But you can add additional column with formula `=OR(B2="Fat",C2="Fat",D2="Fat")` and apply filter to this column to get only `TRUE` values – Dmitry Pavliv Mar 15 '14 at 22:29
  • @simoco Mmm... Maybe, but the problem is that the criteria is set based on a value on a Userform Combobox so it won't be very easy to have an extra column and constantly update it as the criteria changes to filter the "TRUE" values. Any other workarounds I could try? – CaptainABC Mar 15 '14 at 22:33
  • With filter - no. Other way is to use simple `For` loop.. – Dmitry Pavliv Mar 15 '14 at 22:34
  • @simoco `For` loop? Please elaborate! – CaptainABC Mar 15 '14 at 22:40
  • iterate through each row `For i=2 to 6` and check `If .Range("B" & i)="Fat" Or .Range("C" & i)="Fat" Or .Range("D" & i)="Fat" Then do something` – Dmitry Pavliv Mar 15 '14 at 22:42
  • 1
    @CaptainABC Create a string variable that will store the value from the ComboBox. Then change the formula in VBA inserting the contents of that string where needed and fill the formula down (in VBA). This way you can use **simoco's** original idea. – Kapol Mar 15 '14 at 22:43
  • Or, do a variation of @simocos formula in a new column `="#" & B2 & "#" & C2 & "#" & D2 & "#"`. Then filter on `Contains "#Fat#`. – Nybbe Mar 15 '14 at 22:46
  • @simoco The idea behind filtering was so that I can then copy the rows I need to the clipboard using `Set copyFrom = .Offset(0, 0).SpecialCells(xlCellTypeVisible).EntireRow`. So, lets suppose I use the `For i = 2 to 6` loop, I don't see how get the rows I need in the clipboard? – CaptainABC Mar 15 '14 at 22:55
  • 1
    it that case use `If NOT (.Range("B" & i)="Fat" Or .Range("C" & i)="Fat" Or .Range("D" & i)="Fat") Then .Range("B" & i).EntireRow.Hidden = True` and then `.SpecialCells(xlCellTypeVisible)` or copy each row separatly. – Dmitry Pavliv Mar 15 '14 at 22:58
  • @simoco That would probably work. Thanks alot! I will be trying it now. – CaptainABC Mar 15 '14 at 23:11
  • @CaptainABC, a little bit simplier would be to use `UNION` instead hidding rows. Look into my code here on how to use union: http://stackoverflow.com/questions/22275423/delete-hidden-invisible-rows-after-autofilter-excel-vba/22275522#22275522 – Dmitry Pavliv Mar 15 '14 at 23:11
  • @simoco I posted a comment. – CaptainABC Mar 20 '14 at 23:28

1 Answers1

1

As follow up from comments, there are two ways for you.

Use additional column with formula:

Dim copyFrom As Range

With Sheet1
    .AutoFilterMode = False

    With .Range("A1:E6")
        'apply formula in column E
        .Columns(.Columns.Count).Formula = "=OR(B1=""Fat"",C1=""Fat"",D1=""Fat"")"
        .AutoFilter Field:=5, Criteria1:=True

        On Error Resume Next
        Set copyFrom = .Offset(1).Resize(.Rows.count - 1).SpecialCells(xlCellTypeVisible)
        On Error GoTo 0
    End With
End With

If Not copyFrom Is Nothing Then copyFrom.EntireRow.Copy

Use For loop with Union:

Dim copyFrom As Range
Dim i As Long

With Sheet1
    For i = 2 To 6
        If .Range("B" & i) = "Fat" Or .Range("C" & i) = "Fat" Or .Range("D" & i) = "Fat" Then
            If copyFrom Is Nothing Then
                Set copyFrom = .Range("B" & i)
            Else
                Set copyFrom = Union(.Range("B" & i), copyFrom)
            End If
        End If
    Next
End With

If Not copyFrom Is Nothing Then copyFrom.EntireRow.Copy

For copying also header:

Dim copyFrom As Range
Dim i As Long

With Sheet1
    Set copyFrom = .Range("B1")
    For i = 2 To 6
        If .Range("B" & i) = "Fat" Or .Range("C" & i) = "Fat" Or .Range("D" & i) = "Fat" Then
            Set copyFrom = Union(.Range("B" & i), copyFrom)
        End If
    Next
End With

copyFrom.EntireRow.Copy


UPDATE:

Dim hideRng As Range, copyRng As Range
Dim i As Long
Dim lastrow As Long

With Sheet1
    lastrow = .Cells(.Rows.Count, "B").End(xlUp).Row
    .Cells.EntireRow.Hidden = False
    For i = 2 To lastrow
        If Not (.Range("B" & i) = "Fat" Or .Range("C" & i) = "Fat" Or .Range("D" & i) = "Fat") Then
            If hideRng Is Nothing Then
                Set hideRng = .Range("B" & i)
            Else
                Set hideRng = Union(.Range("B" & i), hideRng)
            End If
        End If
    Next
    If Not hideRng Is Nothing Then hideRng.EntireRow.Hidden = True

    On Error Resume Next
    Set copyRng = .Range("B1:B" & lastrow).SpecialCells(xlCellTypeVisible)
    On Error GoTo 0
End With

If copyRng Is Nothing Then
    MsgBox "There is no rows matching criteria - nothing to copy"
    Exit Sub
Else
    copyRng.EntireRow.Copy
End If

enter image description here

Dmitry Pavliv
  • 35,333
  • 13
  • 79
  • 80
  • Thanks for the update. I have been testing the code and it seems to work fine as long as I paste the copied part within the same instance of excel. But when I open a new excel or try to paste it to notepad for some reason it seems to copy all the rows in the range. For example lets say row 3, 4, 5, 8, & 9 have "Fat" so what happens when I paste is that I get all rows 3-9 (inclusive) even though I should not be getting rows 6 & 7. Can't quite figure why it's happening? – CaptainABC Mar 20 '14 at 23:27
  • works fine for me with new instance of excel. As per notepad - it's by design, you can't do it in one step. You can paste "filtered" rows in temp sheet and then copy thouse rows again from temp sheet to notepad. – Dmitry Pavliv Mar 20 '14 at 23:32
  • Is it like a range problem when copying it somewhere else. Because I get the same thing not only when trying to paste to notepad but also to Word, Outlook or basically any other thing. – CaptainABC Mar 20 '14 at 23:51