Forum Discussion
VBA - Filter data, copy only visible cells after filter and move onto next filter if no data.
- Oct 20, 2020
Please give this a try and let me know if you get the desired output.
Sub FilterAndCopy() Dim wsData As Worksheet Dim dws As Worksheet Dim lr As Long Dim x As Variant Dim dict As Object Dim it As Variant Dim i As Long Application.ScreenUpdating = False Set wsData = Worksheets("Sheet1") lr = wsData.Cells(Rows.Count, "A").End(xlUp).Row x = wsData.Range("A2:A" & lr).Value Set dict = CreateObject("Scripting.Dictionary") For i = 1 To UBound(x, 1) dict.Item(x(i, 1)) = "" Next i For Each it In dict.keys On Error Resume Next Set dws = Worksheets(CStr(it)) dws.Cells.Clear On Error GoTo 0 If dws Is Nothing Then Set dws = Worksheets.Add(after:=Worksheets(Worksheets.Count)) dws.Name = it End If With wsData.Range("A1").CurrentRegion .AutoFilter field:=1, Criteria1:=it wsData.Range("C2:I" & lr).SpecialCells(xlCellTypeVisible).Copy dws.Range("A1") .AutoFilter End With Set dws = Nothing Next it Application.ScreenUpdating = True End SubPlease click the button called "Filter And Copy" on Sheet1 in the attached to run the code.
Yes thats great thanks. I do have one other query:
If there was already data in the sheets the data is being copied into, is there a way to paste it below that data?
Thanks so much!
Okay, please give this a try.
And if that takes care of your original question, please take a minute to accept the post with the provided solution as a Best Response to mark your question as Solved.
Sub FilterAndCopy()
Dim wsData As Worksheet
Dim dws As Worksheet
Dim lr As Long
Dim x As Variant
Dim dict As Object
Dim it As Variant
Dim i As Long
Dim dlr As Long
Application.ScreenUpdating = False
Set wsData = Worksheets("Sheet1")
lr = wsData.Cells(Rows.Count, "A").End(xlUp).Row
wsData.AutoFilterMode = False
x = wsData.Range("A2:A" & lr).Value
Set dict = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(x, 1)
dict.Item(x(i, 1)) = ""
Next i
For Each it In dict.keys
On Error Resume Next
Set dws = Worksheets(CStr(it))
On Error GoTo 0
If dws Is Nothing Then
Set dws = Worksheets.Add(after:=Worksheets(Worksheets.Count))
dws.Name = it
End If
With wsData.Range("A1").CurrentRegion
.AutoFilter field:=1, Criteria1:=it
dlr = dws.Cells(Rows.Count, "A").End(xlUp).Row
If dws.Range("A1").Value <> "" Then dlr = dlr + 1
wsData.Range("C2:I" & lr).SpecialCells(xlCellTypeVisible).Copy dws.Range("A" & dlr)
.AutoFilter
End With
Set dws = Nothing
Next it
Application.ScreenUpdating = True
End Sub
- RAM98988Oct 21, 2020Copper Contributor
Perfect thank you, out of interest and for potential future reference is it possible to use offsets within this code in order to move the paste range up/down/left/right?
Thanks.
- Subodh_Tiwari_sktneerOct 21, 2020Silver Contributor
You're welcome!
Yes, you just need to change the destination range dws.Range("A" & dlr) in the following line as per your requirement.
wsData.Range("C2:I" & lr).SpecialCells(xlCellTypeVisible).Copy dws.Range("A" & dlr)- FliptoeJun 22, 2021Copper Contributor
I know this is an old post, but how can I change the column which is being filtered (to column B for example)?
I've tried simply changing:
x = wsData.Range("A2:A" & lr).Value
to
x = wsData.Range("B2:B" & lr).Value
But I get a run-time error '1004' "No Cells Were Found".
Any suggestions are much appreciated, this is my first time using VBA so I'm a complete beginner!