最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

excel - Filter, but skip to another step if the filter does not provide results - Stack Overflow

programmeradmin1浏览0评论

I'm completely new to writing macros and used the record function to start the script for my macro and then used Google to basically adjust my code as I needed to. Now I've run into a more complicated filtering issue that I need help on. Basically, the macro is to filter out 0s from columns G, H and J, and copy the results of column A for each filter into a new sheet. The data I work with is different every time and sometimes, column H only has 0s in it. When this happens, the macro will copy all the results under column A and paste it into the new sheet. But I don't want the results of 0s. How do I tell my macro that if the filtering options are only 0, don't copy/paste and move onto the next step? This is my current macro code:

Sub ProactiveHTAT()
'
' Test1 Macro
' Proactive HTAT
'

'
    Selection.AutoFilter
    ActiveSheet.Range("$A$1:$T$1000").AutoFilter Field:=19, Criteria1:="Pass"
    ActiveSheet.Range("$A$1:$T$1000").AutoFilter Field:=7, Criteria1:="<>0"
    Range(("A2"), Range("A2").End(xlDown)).Select
    Selection.Copy
    Sheets.Add After:=ActiveSheet
    ActiveSheet.Paste
    Sheets("Sheet1").Select
    ActiveSheet.Range("$A$1:$T$500").AutoFilter Field:=7
    ActiveSheet.Range("$A$1:$T$500").AutoFilter Field:=8, Criteria1:="<>0"
    Selection.Copy
    Sheets("Sheet2").Select
    ActiveSheet.Range("A1").End(xlDown).Offset(1, 0).Select
    ActiveSheet.Paste
    Sheets("Sheet1").Select
    ActiveSheet.Range("$A$1:$T$500").AutoFilter Field:=8
    ActiveSheet.Range("$A$1:$T$500").AutoFilter Field:=10, Criteria1:="<>0"
    Selection.Copy
    Sheets("Sheet2").Select
    ActiveSheet.Range("A1").End(xlDown).Offset(1, 0).Select
    ActiveSheet.Paste
    ActiveSheet.Range(("A1"), Range("A1").End(xlDown)).RemoveDuplicates Columns:=1, Header:=xlNo
End Sub

I'm completely new to writing macros and used the record function to start the script for my macro and then used Google to basically adjust my code as I needed to. Now I've run into a more complicated filtering issue that I need help on. Basically, the macro is to filter out 0s from columns G, H and J, and copy the results of column A for each filter into a new sheet. The data I work with is different every time and sometimes, column H only has 0s in it. When this happens, the macro will copy all the results under column A and paste it into the new sheet. But I don't want the results of 0s. How do I tell my macro that if the filtering options are only 0, don't copy/paste and move onto the next step? This is my current macro code:

Sub ProactiveHTAT()
'
' Test1 Macro
' Proactive HTAT
'

'
    Selection.AutoFilter
    ActiveSheet.Range("$A$1:$T$1000").AutoFilter Field:=19, Criteria1:="Pass"
    ActiveSheet.Range("$A$1:$T$1000").AutoFilter Field:=7, Criteria1:="<>0"
    Range(("A2"), Range("A2").End(xlDown)).Select
    Selection.Copy
    Sheets.Add After:=ActiveSheet
    ActiveSheet.Paste
    Sheets("Sheet1").Select
    ActiveSheet.Range("$A$1:$T$500").AutoFilter Field:=7
    ActiveSheet.Range("$A$1:$T$500").AutoFilter Field:=8, Criteria1:="<>0"
    Selection.Copy
    Sheets("Sheet2").Select
    ActiveSheet.Range("A1").End(xlDown).Offset(1, 0).Select
    ActiveSheet.Paste
    Sheets("Sheet1").Select
    ActiveSheet.Range("$A$1:$T$500").AutoFilter Field:=8
    ActiveSheet.Range("$A$1:$T$500").AutoFilter Field:=10, Criteria1:="<>0"
    Selection.Copy
    Sheets("Sheet2").Select
    ActiveSheet.Range("A1").End(xlDown).Offset(1, 0).Select
    ActiveSheet.Paste
    ActiveSheet.Range(("A1"), Range("A1").End(xlDown)).RemoveDuplicates Columns:=1, Header:=xlNo
End Sub
Share Improve this question edited Mar 14 at 21:33 Hazel asked Mar 14 at 19:23 HazelHazel 12 bronze badges 3
  • 3 Please do not post screenshots of your code. No one can copy/paste it when it's a screenshot. – braX Commented Mar 14 at 19:24
  • I'm sorry! I tried to copy/paste the code into the body, but it wasn't letting me click the post button. I was getting an error message telling me that the format was wrong. I tried to Ctrl+K as instructed in the error message, but the error wasn't going away. I wasn't sure how else to post it. – Hazel Commented Mar 14 at 19:27
  • Try 3 backticks, newline, the code, newline, then 3 backticks again. – braX Commented Mar 14 at 19:29
Add a comment  | 

2 Answers 2

Reset to default 0

It looks like you want to turn on one Filter (ColS="Pass")
Toggle 3 different filters (Cols G, H, and J)
Copy the results of each to a single column in a new worksheet
Remove duplicates in ColA of your new worksheet
Here's the VBA that I've come up with. If one of your columns (G, H, or J) is all 0s, then ColA on your new worksheet might have a blank row....that's for the column with all 0s. If needed, that can be removed.

Sub Filtering_WithPass()
'''store filter results
Dim arr
arr = ActiveSheet.Evaluate("=UNIQUE(VSTACK(FILTER(A2:A1000,(S2:S1000=""Pass"")*(G2:G1000<>0),""""),FILTER(A2:A1000,(S2:S1000=""Pass"")*(H2:H1000<>0),""""),FILTER(A2:A1000,(S2:S1000=""Pass"")*(J2:J1000<>0),"""")))")
'''copy the results to a different sheet
Dim ws As Worksheet
Set ws = Sheets.Add(after:=ActiveSheet)
ws.Range("A1").Resize(UBound(arr, 1)).Value = arr
End Sub

Option 1

  • Using ActiveSheet is not reliable, especially when a new sheet is created within the script.
  • The table range reference can be determined dynamically.
  • If the filtered table is empty (no rows in the data body range), the script incorrectly copies all cells in Column A to the output sheet.
Option Explicit

Sub ProactiveHTAT()
    Dim srcSht As Worksheet: Set srcSht = ActiveSheet
    With srcSht
        ' get range of the data table
        Dim rTab As Range: Set rTab = .Range("A1").CurrentRegion
        ' get the 1st column of data body in table (w/o header row)
        Dim rColA As Range: Set rColA = rTab.Resize(rTab.Rows.Count - 1).Offset(1).Columns(1)
        ' show all data in table
        If .AutoFilterMode Then
            If .AutoFilter.FilterMode Then
                .ShowAllData
            End If
        End If
    End With
    ' first filter
    rTab.AutoFilter Field:=19, Criteria1:="Pass"
    Dim desSht As Worksheet
    ' create a new sheet
    Set desSht = Sheets.Add(After:=srcSht)
    Dim rCell As Range: Set rCell = desSht.Range("A1")
    Dim iCol, lastRow As Long
    ' loop through the 2nd filter column
    For Each iCol In Array(7, 8, 10)
        ' apply the 2nd filter
        rTab.AutoFilter Field:=iCol, Criteria1:="<>0"
        ' get the last row#
        lastRow = srcSht.Cells(srcSht.Rows.Count, 1).End(xlUp).Row
        If lastRow > 1 Then ' filtered table is NOT blank
            rColA.Copy rCell ' copy to dest. sheet
            ' get the next blank cell
            Set rCell = desSht.Cells(desSht.Rows.Count, 1).End(xlUp).Offset(1)
        End If
        ' remove the 2nd filter
        rTab.AutoFilter Field:=iCol
    Next
    ' remove duplicated values on dest. sheet
    desSht.Range("A1").CurrentRegion.RemoveDuplicates Columns:=1, Header:=xlNo
End Sub


Option 2: The second option is more efficient for processing data in an array.


Sub ProactiveHTAT2()
    Dim srcSht As Worksheet: Set srcSht = ActiveSheet
    ' load table into an array
    Dim arr: arr = srcSht.Range("A1").CurrentRegion.Value
    Dim brr: ReDim brr(1 To UBound(arr), 0)
    Dim i As Long, iR As Long
    For i = LBound(arr) + 1 To UBound(arr)
        ' check the 1st filter
        If arr(i, 19) = "Pass" Then
            ' check the 2nd filter
            If arr(i, 7) & arr(i, 8) & arr(i, 10) <> "000" Then
                iR = iR + 1
                brr(iR, 0) = arr(i, 1)
            End If
        End If
    Next
    If iR > 0 Then
        Dim desSht As Worksheet
        Set desSht = Sheets.Add(After:=srcSht)
        desSht.Range("A1").Resize(iR).Value = brr
    End If
End Sub
发布评论

评论列表(0)

  1. 暂无评论