Avoiding copy/paste, selection to transfer data in VBA

ItalianPlatinum

Well-known Member
Joined
Mar 23, 2017
Messages
857
Office Version
  1. 365
  2. 2019
Platform
  1. Windows
Looking for a way to transfer a set of data over to another sheet after i set a filter without copy, selecting or pasting.
  1. Sheet 1: filtered to not show blanks
    1. Want to transfer the data left showing
  2. Sheet 2: Where I want to transfer the data to
  3. Columns match up like this:
    1. Column A to Column A13 down
    2. Column I to Column B13 down
    3. Column J to Column C13 down
    4. so on and so on.....
 
Looking for a way to transfer a set of data over to another sheet after i set a filter without copy, selecting or pasting.
OK, give this a try with a copy of your workbook

VBA Code:
Sub TransferData()
  Dim vRows As Variant, vCols As Variant

  vCols = Array(1, 9, 10, 11, 2, 3, 4, 5, 6, 7, 8)  '<- Columns of interest in specified order
  With Sheets("Periodic")
    With .Range("A1:K" & .Range("I" & Rows.Count).End(xlUp).Row)
      vRows = Filter(Application.Transpose(Evaluate(Replace("if(len(#),if(row(#)>2,row(#),""x""),""x"")", "#", .Columns(9).Address(External:=True)))), "x", False)
      Sheets("Compare").Range("A13").Resize(UBound(vRows), UBound(vCols)).Value = Application.Index(.Cells.Value, Application.Transpose(vRows), vCols)
    End With
  End With
End Sub
 
  • Like
Reactions: ZVI
Upvote 0

Excel Facts

Add Bullets to Range
Select range. Press Ctrl+1. On Number tab, choose Custom. Type Alt+7 then space then @ sign (using 7 on numeric keypad)
Hi Peter,
It's impressive & short code!
The only limitation is an array limit of the Application.Transpose:
VBA Code:
Debug.Print UBound(Application.Transpose(Range("A1:A100000")))
Not sure if it's critical - depends on max number of data rows in the sheet "Periodic".
 
Last edited:
Upvote 0
Another solution to test:
VBA Code:
Sub TransferData1()
 
  Dim a() As Variant
  Dim Sh1 As Worksheet, Sh2 As Worksheet
  Dim Rng1 As Range, Rng2 As Range
  Dim i As Long, j As Long
 
  ' Set variables for sheets and ranges
  Set Sh1 = Sheets("Periodic")
  Set Sh2 = Sheets("Compare")
  i = Sh1.Cells(Rows.Count, "A").End(xlUp).Row ' Last data row
  Set Rng1 = Sh1.Range("A3").Resize(i - 2)
  Set Rng2 = Sh2.Range("A3").Resize(i - 2)
 
  ' Copy the not filtered data
  Rng2.Columns("A").Value = Rng1.Columns("A").Value
  Rng2.Columns("B:D").Value = Rng1.Columns("I:K").Value
  Rng2.Columns("E:I").Value = Rng1.Columns("B:F").Value
 
  ' Get filter  criteria from Rng1.Columns("I")
  a() = Rng1.Columns("I").Value
  For j = 1 To UBound(a)
    If Len(a(j, 1)) <> 0 Then a(j, 1) = 1
  Next
 
  ' Freeze
  Application.ScreenUpdating = False
  Application.EnableEvents = False
 
  ' Filter using an extra column, it's fast
  Sh2.Columns(1).Insert xlShiftToRight
  With Rng2.Offset(, -1).Resize(, 10)
    .Columns(1).Value = a()
    .Sort .Cells(1), xlAscending, Header:=xlNo
    j = .Cells(1).Offset(UBound(a)).End(xlUp).Row
    If i > j Then .Rows(j - .Row + 2 & ":" & i).ClearContents
  End With
  Sh2.Columns(1).Delete
 
  ' Unfreeze
  Application.ScreenUpdating = True
  Application.EnableEvents = True
 
End Sub
 
Last edited:
Upvote 0
I forgot to mention that my codes (& I think Vlad's?) do not require column I to be Filtered for blanks. In fact, if you are only doing that to get the non-blank data to the other sheet then it would be better to not filter it first as it will save some time.

I should also mention
  • My earlier code resulted in one row and one column of the results missing :oops: - corrected below assuming Option Base has not been set to 1.
  • Formula recalculation due to filtering, column insertion etc could affect speed of code. However, the only recalculations that my codes should trigger are if there are any formulas that are triggered by changes to sheet 'Compare' A13:K13 and below
Code corrected from post 21
Rich (BB code):
Sub TransferData()
  Dim vRows As Variant, vCols As Variant

  vCols = Array(1, 9, 10, 11, 2, 3, 4, 5, 6, 7, 8)  '<- Columns of interest in specified order
  With Sheets("Periodic")
    With .Range("A1:K" & .Range("I" & Rows.Count).End(xlUp).Row)
      vRows = Filter(Application.Transpose(Evaluate(Replace("if(len(#),if(row(#)>2,row(#),""x""),""x"")", "#", .Columns(9).Address(External:=True)))), "x", False)
      Sheets("Compare").Range("A13").Resize(UBound(vRows) + 1, UBound(vCols) + 1).Value = Application.Index(.Cells.Value, Application.Transpose(vRows), vCols)
    End With
  End With
End Sub

The only limitation is an array limit of the Application.Transpose:
Hi Vlad
Yes, that could be a problem. Need to know the size of the data as you say.
Or I could fill the vRows array looping in a similar way to you have with your 'a' array above. In testing up to about 200,000 rows the time difference between my earlier code and the one below is negligible. These codes for me are running 2 - 3 times faster than the post 23 code but that may not be relevant as it produces different results to mine - see my results below.

VBA Code:
Sub TransferData_v2()
  Dim vCols As Variant, vRows As Variant
  Dim i As Long, k As Long

  vCols = Array(1, 9, 10, 11, 2, 3, 4, 5, 6, 7, 8)  '<- Columns of interest in specified order
  With Sheets("Periodic")
    With .Range("A1:K" & .Range("I" & Rows.Count).End(xlUp).Row)
      vRows = .Columns(9).Value
      For i = 3 To UBound(vRows)
        If Len(vRows(i, 1)) > 0 Then
          k = k + 1
          vRows(k, 1) = i
        End If
      Next i
      Sheets("Compare").Range("A13").Resize(k, UBound(vCols)).Value = Application.Index(.Cells.Value, vRows, vCols)
    End With
  End With
End Sub

My (small) sample data

ItalianPlatinum_1.xlsm
ABCDEFGHIJK
1
2Hdr 1Hdr 2Hdr 3Hdr 4Hdr 5Hdr 6Hdr 7Hdr 8Hdr 9Hdr 10Hdr 11
3395230375166671504148
43457572578597131237064
54381545128137813062
67935744057823552162832
752620664590774418672
83222162319414976371
93540114431494684188
103877147716264577622
1131139154193714114890
128218563789807161609995
1381235891040566777687
144372236052672855716860
1533838193415984121047
1636617415809520821526
17457783366768645866
18881797988881774332739
19269780939153385239416
2022222695722956415
21909198867481662817
Periodic


.. and corresponding results (using v2 code)

ItalianPlatinum_1.xlsm
ABCDEFGHIJK
13395041485230375166671
143423706457572578597131
157916283235744057823552
1651867226206645907744
178260999518563789807161
1881776872358910405667
194371686072236052672855
2031210473838193415984
21883327391797988881774
22262394169780939153385
Compare
 
  • Like
Reactions: ZVI
Upvote 0
Solution
I forgot to mention that my codes (& I think Vlad's?) do not require column I to be Filtered for blanks. In fact, if you are only doing that to get the non-blank data to the other sheet then it would be better to not filter it first as it will save some time.

I should also mention
  • My earlier code resulted in one row and one column of the results missing :oops: - corrected below assuming Option Base has not been set to 1.
  • Formula recalculation due to filtering, column insertion etc could affect speed of code. However, the only recalculations that my codes should trigger are if there are any formulas that are triggered by changes to sheet 'Compare' A13:K13 and below
Code corrected from post 21
Rich (BB code):
Sub TransferData()
  Dim vRows As Variant, vCols As Variant

  vCols = Array(1, 9, 10, 11, 2, 3, 4, 5, 6, 7, 8)  '<- Columns of interest in specified order
  With Sheets("Periodic")
    With .Range("A1:K" & .Range("I" & Rows.Count).End(xlUp).Row)
      vRows = Filter(Application.Transpose(Evaluate(Replace("if(len(#),if(row(#)>2,row(#),""x""),""x"")", "#", .Columns(9).Address(External:=True)))), "x", False)
      Sheets("Compare").Range("A13").Resize(UBound(vRows) + 1, UBound(vCols) + 1).Value = Application.Index(.Cells.Value, Application.Transpose(vRows), vCols)
    End With
  End With
End Sub


Hi Vlad
Yes, that could be a problem. Need to know the size of the data as you say.
Or I could fill the vRows array looping in a similar way to you have with your 'a' array above. In testing up to about 200,000 rows the time difference between my earlier code and the one below is negligible. These codes for me are running 2 - 3 times faster than the post 23 code but that may not be relevant as it produces different results to mine - see my results below.

VBA Code:
Sub TransferData_v2()
  Dim vCols As Variant, vRows As Variant
  Dim i As Long, k As Long

  vCols = Array(1, 9, 10, 11, 2, 3, 4, 5, 6, 7, 8)  '<- Columns of interest in specified order
  With Sheets("Periodic")
    With .Range("A1:K" & .Range("I" & Rows.Count).End(xlUp).Row)
      vRows = .Columns(9).Value
      For i = 3 To UBound(vRows)
        If Len(vRows(i, 1)) > 0 Then
          k = k + 1
          vRows(k, 1) = i
        End If
      Next i
      Sheets("Compare").Range("A13").Resize(k, UBound(vCols)).Value = Application.Index(.Cells.Value, vRows, vCols)
    End With
  End With
End Sub

My (small) sample data

ItalianPlatinum_1.xlsm
ABCDEFGHIJK
1
2Hdr 1Hdr 2Hdr 3Hdr 4Hdr 5Hdr 6Hdr 7Hdr 8Hdr 9Hdr 10Hdr 11
3395230375166671504148
43457572578597131237064
54381545128137813062
67935744057823552162832
752620664590774418672
83222162319414976371
93540114431494684188
103877147716264577622
1131139154193714114890
128218563789807161609995
1381235891040566777687
144372236052672855716860
1533838193415984121047
1636617415809520821526
17457783366768645866
18881797988881774332739
19269780939153385239416
2022222695722956415
21909198867481662817
Periodic


.. and corresponding results (using v2 code)

ItalianPlatinum_1.xlsm
ABCDEFGHIJK
13395041485230375166671
143423706457572578597131
157916283235744057823552
1651867226206645907744
178260999518563789807161
1881776872358910405667
194371686072236052672855
2031210473838193415984
21883327391797988881774
22262394169780939153385
Compare
I am sorry for some reason I did not get any notifications from this thread. I downloaded the app on my phone -- since doing so I no longer recieved emails for each post. Anywho. I will test both now and see with my dataset. To confirm size of filet he max I expect this dataset to be is 10,000 rows. it should never surpass.
 
Upvote 0
Another solution to test:
VBA Code:
Sub TransferData1()

  Dim a() As Variant
  Dim Sh1 As Worksheet, Sh2 As Worksheet
  Dim Rng1 As Range, Rng2 As Range
  Dim i As Long, j As Long

  ' Set variables for sheets and ranges
  Set Sh1 = Sheets("Periodic")
  Set Sh2 = Sheets("Compare")
  i = Sh1.Cells(Rows.Count, "A").End(xlUp).Row ' Last data row
  Set Rng1 = Sh1.Range("A3").Resize(i - 2)
  Set Rng2 = Sh2.Range("A3").Resize(i - 2)

  ' Copy the not filtered data
  Rng2.Columns("A").Value = Rng1.Columns("A").Value
  Rng2.Columns("B:D").Value = Rng1.Columns("I:K").Value
  Rng2.Columns("E:I").Value = Rng1.Columns("B:F").Value

  ' Get filter  criteria from Rng1.Columns("I")
  a() = Rng1.Columns("I").Value
  For j = 1 To UBound(a)
    If Len(a(j, 1)) <> 0 Then a(j, 1) = 1
  Next

  ' Freeze
  Application.ScreenUpdating = False
  Application.EnableEvents = False

  ' Filter using an extra column, it's fast
  Sh2.Columns(1).Insert xlShiftToRight
  With Rng2.Offset(, -1).Resize(, 10)
    .Columns(1).Value = a()
    .Sort .Cells(1), xlAscending, Header:=xlNo
    j = .Cells(1).Offset(UBound(a)).End(xlUp).Row
    If i > j Then .Rows(j - .Row + 2 & ":" & i).ClearContents
  End With
  Sh2.Columns(1).Delete

  ' Unfreeze
  Application.ScreenUpdating = True
  Application.EnableEvents = True

End Sub
I had to tweak one section Set Rng2 = Sh2.Range("A3").Resize(i - 2) to Set Rng2 = Sh2.Range("A13").Resize(i - 12)

Appears to be working formatting changes ever so slightly on my destination location. When running my formulas post it isn't calculating need to investigate further but if I input the formula in the cell it does. So i know it isnt a problem with the formula.
 
Upvote 0
I forgot to mention that my codes (& I think Vlad's?) do not require column I to be Filtered for blanks. In fact, if you are only doing that to get the non-blank data to the other sheet then it would be better to not filter it first as it will save some time.

I should also mention
  • My earlier code resulted in one row and one column of the results missing :oops: - corrected below assuming Option Base has not been set to 1.
  • Formula recalculation due to filtering, column insertion etc could affect speed of code. However, the only recalculations that my codes should trigger are if there are any formulas that are triggered by changes to sheet 'Compare' A13:K13 and below
Code corrected from post 21
Rich (BB code):
Sub TransferData()
  Dim vRows As Variant, vCols As Variant

  vCols = Array(1, 9, 10, 11, 2, 3, 4, 5, 6, 7, 8)  '<- Columns of interest in specified order
  With Sheets("Periodic")
    With .Range("A1:K" & .Range("I" & Rows.Count).End(xlUp).Row)
      vRows = Filter(Application.Transpose(Evaluate(Replace("if(len(#),if(row(#)>2,row(#),""x""),""x"")", "#", .Columns(9).Address(External:=True)))), "x", False)
      Sheets("Compare").Range("A13").Resize(UBound(vRows) + 1, UBound(vCols) + 1).Value = Application.Index(.Cells.Value, Application.Transpose(vRows), vCols)
    End With
  End With
End Sub


Hi Vlad
Yes, that could be a problem. Need to know the size of the data as you say.
Or I could fill the vRows array looping in a similar way to you have with your 'a' array above. In testing up to about 200,000 rows the time difference between my earlier code and the one below is negligible. These codes for me are running 2 - 3 times faster than the post 23 code but that may not be relevant as it produces different results to mine - see my results below.

VBA Code:
Sub TransferData_v2()
  Dim vCols As Variant, vRows As Variant
  Dim i As Long, k As Long

  vCols = Array(1, 9, 10, 11, 2, 3, 4, 5, 6, 7, 8)  '<- Columns of interest in specified order
  With Sheets("Periodic")
    With .Range("A1:K" & .Range("I" & Rows.Count).End(xlUp).Row)
      vRows = .Columns(9).Value
      For i = 3 To UBound(vRows)
        If Len(vRows(i, 1)) > 0 Then
          k = k + 1
          vRows(k, 1) = i
        End If
      Next i
      Sheets("Compare").Range("A13").Resize(k, UBound(vCols)).Value = Application.Index(.Cells.Value, vRows, vCols)
    End With
  End With
End Sub

My (small) sample data

ItalianPlatinum_1.xlsm
ABCDEFGHIJK
1
2Hdr 1Hdr 2Hdr 3Hdr 4Hdr 5Hdr 6Hdr 7Hdr 8Hdr 9Hdr 10Hdr 11
3395230375166671504148
43457572578597131237064
54381545128137813062
67935744057823552162832
752620664590774418672
83222162319414976371
93540114431494684188
103877147716264577622
1131139154193714114890
128218563789807161609995
1381235891040566777687
144372236052672855716860
1533838193415984121047
1636617415809520821526
17457783366768645866
18881797988881774332739
19269780939153385239416
2022222695722956415
21909198867481662817
Periodic


.. and corresponding results (using v2 code)

ItalianPlatinum_1.xlsm
ABCDEFGHIJK
13395041485230375166671
143423706457572578597131
157916283235744057823552
1651867226206645907744
178260999518563789807161
1881776872358910405667
194371686072236052672855
2031210473838193415984
21883327391797988881774
22262394169780939153385
Compare
looks to be working. formatting issues are also mitigated. seeing same issue as vlads where some formulas arent working. if both yours causing the formulas not to work it must be something with my formulas or last row potentially.
 
Upvote 0
You both can disregard my formula issue it was on my end. i didnt lock my formulas correctly. thank you both i am going to further stress test but right now seems to be working as i expect
 
Upvote 0
max I expect this dataset to be is 10,000 rows. it should never surpass.
In that case the Application.Transpose issue that Vlad raised shouldn't be an issue so I expect that either of my codes should work (unless some other issue exists that I don't know about yet :)
 
Upvote 0
In that case the Application.Transpose issue that Vlad raised shouldn't be an issue so I expect that either of my codes should work (unless some other issue exists that I don't know about yet :)
One slight issue just noticed the column 8 or column H is not transferring over and not sure why to the destination area of column K
 
Upvote 0

Forum statistics

Threads
1,223,896
Messages
6,175,265
Members
452,627
Latest member
KitkatToby

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top