Home > Software engineering >  VBA selecting the first three rows after filtering
VBA selecting the first three rows after filtering

Time:01-11

The code below in VBA applies filter to a certain table, select the visible cells after the filter and then paste the content in another tab called "CICLICO". The problem is... I want only the first three items AFTER applying the filter. Any ideas?

Sub Select_TheFirstThreeItemsAfterFilter()
'
    Range("P8").Select 
    ActiveSheet.ListObjects("Tabela1").Range.AutoFilter Field:=10, Criteria1:= _
        "MONTAGEM A"
    ActiveSheet.ListObjects("Tabela1").Range.AutoFilter Field:=7, Criteria1:= _
        "A"
    ActiveSheet.ListObjects("Tabela1").Range.AutoFilter Field:=4, Criteria1:= _
        Array("100", "110", "1159", "118", "119", "120", "135", "139", "14", "144", "152", "16", _
        "161", "163", "171", "19", "209", "21", "212", "240", "25", "251", "280", "285", "3", "31", _
        "32", "34", "36", "381", "39", "390", "5", "51", "54", "63", "67", "70", "74", "8", "84", "94" _
        , "97"), Operator:=xlFilterValues
    ActiveSheet.ListObjects("Tabela1").Range.AutoFilter Field:=14, Criteria1:= _
        "="
        
    Range("B11:H400").Select 'here is the part I want to select only the First Three Items After the filter
    Selection.SpecialCells(xlCellTypeVisible).Select
    Selection.Copy
     
    Sheets("CICLICO").Select 'this select another tab and paste the information after the filter
    Range("B8").Select
    ActiveSheet.Paste

   
End Sub

I know I have to use the "Selection.SpecialCells(xlCellTypeVisible).Select" But I don't know how the select the first three items considering the number of the rows always change... But I don't know how to select the first three rows after applying the filter.

For example: Sometimes I want to select the rows 233, 500, 800 and another times 900, 1200 and 1800.

CodePudding user response:

Use .Resize to define how large a range you're selecting/copying.

Sub Select_TheFirstThreeItemsAfterFilter()

    Range("P8").Select 
    ActiveSheet.ListObjects("Tabela1").Range.AutoFilter Field:=10, Criteria1:= _
        "MONTAGEM A"
    ActiveSheet.ListObjects("Tabela1").Range.AutoFilter Field:=7, Criteria1:= _
        "A"
    ActiveSheet.ListObjects("Tabela1").Range.AutoFilter Field:=4, Criteria1:= _
        Array("100", "110", "1159", "118", "119", "120", "135", "139", "14", "144", "152", "16", _
        "161", "163", "171", "19", "209", "21", "212", "240", "25", "251", "280", "285", "3", "31", _
        "32", "34", "36", "381", "39", "390", "5", "51", "54", "63", "67", "70", "74", "8", "84", "94" _
        , "97"), Operator:=xlFilterValues
    ActiveSheet.ListObjects("Tabela1").Range.AutoFilter Field:=14, Criteria1:= _
        "="
        
    Range("B11:H400").SpecialCells(xlCellTypeVisible).Resize(3).Copy _
    Destination:= Sheets("CICLICO").Range("B8")

End Sub

Note that the entire select/copy/paste action was done in (effectively) a single line of code - it's good practice to avoid using select wherever possible.

CodePudding user response:

Copy Specified Number of Rows From Discontinuous Range

Sub CopyThreeFilteredRows()

    Const ROWS_COUNT As Long = 3

    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    Dim sws As Worksheet: Set sws = wb.Sheets("Unknown") ' adjust!
    Dim lo As ListObject: Set lo = sws.ListObjects("Tabela1")
    
    With lo
        If .ShowAutoFilter Then
            If .AutoFilter.FilterMode Then .AutoFilter.ShowAllData
        End If
        With .Range
            .AutoFilter Field:=10, Criteria1:="MONTAGEM A"
            .AutoFilter Field:=7, Criteria1:="A"
            .AutoFilter Field:=4, Criteria1:=Array( _
                "100", "110", "1159", "118", "119", "120", "135", "139", _
                "14", "144", "152", "16", "161", "163", "171", "19", _
                "209", "21", "212", "240", "25", "251", "280", "285", _
                "3", "31", "32", "34", "36", "381", "39", "390", _
                "5", "51", "54", "63", "67", "70", "74", "8", _
                "84", "94", "97"), Operator:=xlFilterValues
            .AutoFilter Field:=14, Criteria1:="="
        End With
        Dim vrg As Range ' visible rows
        On Error Resume Next
            Set vrg = .DataBodyRange.SpecialCells(xlCellTypeVisible)
        On Error GoTo 0
        .AutoFilter.ShowAllData
    End With
        
    If vrg Is Nothing Then Exit Sub
        
    Dim srg As Range: Set srg = Intersect(vrg, sws.Columns("B:H"))
    ' The previous is inappropriate. The following would be better...
    'Set srg = Intersect(vrg, lo.DataBodyRange.Columns(2).Resize(, 7))
    ' ... so you could freely move the table around.
    
    Dim ColumnsCount As Long: ColumnsCount = srg.Columns.Count
    
    Dim scrg As Range, srrg As Range, r As Long
    
    For Each srrg In srg.Rows
        r = r   1
        If scrg Is Nothing Then
            Set scrg = srrg
        Else
            Set scrg = Union(scrg, srrg)
        End If
        If r >= ROWS_COUNT Then Exit For
    Next srrg
    
    Dim dws As Worksheet: Set dws = wb.Sheets("CICLICO")
    Dim dfCell As Range: Set dfCell = dws.Range("B8")
    dfCell.Resize(ROWS_COUNT, ColumnsCount).Clear
    
    scrg.Copy dfCell
   
End Sub
  • Related