Search code examples
excelfiltercopy-pastevba

Copy/Paste/Calculate Visible Cells from One Column of a Filtered Table


I am using AutoFilter to sort through a table in VBA, which results in a smaller table of data. I only want to copy/paste the visible cells of one column after the filter is applied. Also, I would like to average the filtered values of one column and put the result in a different cell.

I've found this snippet on Stack which allows me to copy/paste the entire visible results of the filter, but I don't know how to modify it or another way to get only one column's worth of data (without the header) from it.

Range("A1",Cells(65536,Cells(1,256).End(xlToLeft).Column).End(xlUp)).SpecialCells(xlCellTypeVisible).Copy
Sheets("Sheet2").Range("A1").PasteSpecial xlPasteValuesAndNumberFormats
Application.CutCopyMode = False

Addition to answer (to calculate with the filtered values):

tgt.Range("B2").Value =WorksheetFunction.Average(copyRange.SpecialCells(xlCellTypeVisible))

Solution

  • I set up a simple 3-column range on Sheet1 with Country, City, and Language in columns A, B, and C. The following code autofilters the range and then pastes only one of the columns of autofiltered data to another sheet. You should be able to modify this for your purposes:

    Sub CopyPartOfFilteredRange()
        Dim src As Worksheet
        Dim tgt As Worksheet
        Dim filterRange As Range
        Dim copyRange As Range
        Dim lastRow As Long
    
        Set src = ThisWorkbook.Sheets("Sheet1")
        Set tgt = ThisWorkbook.Sheets("Sheet2")
    
        ' turn off any autofilters that are already set
        src.AutoFilterMode = False
    
        ' find the last row with data in column A
        lastRow = src.Range("A" & src.Rows.Count).End(xlUp).Row
    
        ' the range that we are auto-filtering (all columns)
        Set filterRange = src.Range("A1:C" & lastRow)
    
        ' the range we want to copy (only columns we want to copy)
        ' in this case we are copying country from column A
        ' we set the range to start in row 2 to prevent copying the header
        Set copyRange = src.Range("A2:A" & lastRow)
    
        ' filter range based on column B
        filterRange.AutoFilter field:=2, Criteria1:="Rio de Janeiro"
    
        ' copy the visible cells to our target range
        ' note that you can easily find the last populated row on this sheet
        ' if you don't want to over-write your previous results
        copyRange.SpecialCells(xlCellTypeVisible).Copy tgt.Range("A1")
    
    End Sub
    

    Note that by using the syntax above to copy and paste, nothing is selected or activated (which you should always avoid in Excel VBA) and the clipboard is not used. As a result, Application.CutCopyMode = False is not necessary.