VBA copy set amount of rows into forms until end of data set

willow1985

Well-known Member
Joined
Jul 24, 2019
Messages
888
Office Version
  1. 365
Platform
  1. Windows
I need help with writing a macro that can copy a set amount of rows (say 15 rows) from a table of data and paste the data into another sheet (forms) at set locations one after another until there is no more data to copy in the table.

I do not know what the max amount of rows/data that will be in the table or how many forms will be required, but I do know the form will repeat every 17 rows. See below example.

I hope someone can help me with this. Loop codes are not my strong suit.
Thank you!

Book1
ABCDEFG
1OrderDateRegionRepItemUnitsUnit CostTotal
26-Jan-21EastJonesPencil951.99189.05
323-Jan-21CentralKivellBinder5019.99999.5
49-Feb-21CentralJardinePencil364.99179.64
526-Feb-21CentralGillPen2719.99539.73
615-Mar-21WestSorvinoPencil562.99167.44
71-Apr-21EastJonesBinder604.99299.4
818-Apr-21CentralAndrewsPencil751.99149.25
95-May-21CentralJardinePencil904.99449.1
1022-May-21WestThompsonPencil321.9963.68
118-Jun-21EastJonesBinder608.99539.4
1225-Jun-21CentralMorganPencil904.99449.1
1312-Jul-21EastHowardBinder291.9957.71
1429-Jul-21EastParentBinder8119.991619.19
1515-Aug-21EastJonesPencil354.99174.65
161-Sep-21CentralSmithDesk2125250
1718-Sep-21EastJonesPen Set1615.99255.84
185-Oct-21CentralMorganBinder288.99251.72
1922-Oct-21EastJonesPen648.99575.36
208-Nov-21EastParentPen1519.99299.85
2125-Nov-21CentralKivellPen Set964.99479.04
2212-Dec-21CentralSmithPencil671.2986.43
2329-Dec-21EastParentPen Set7415.991183.26
2415-Jan-22CentralGillBinder468.99413.54
251-Feb-22CentralSmithBinder87151305
2618-Feb-22EastJonesBinder44.9919.96
277-Mar-22WestSorvinoBinder719.99139.93
2824-Mar-22CentralJardinePen Set504.99249.5
2910-Apr-22CentralAndrewsPencil661.99131.34
3027-Apr-22EastHowardPen964.99479.04
3114-May-22CentralGillPencil531.2968.37
3231-May-22CentralGillBinder808.99719.2
3317-Jun-22CentralKivellDesk5125625
344-Jul-22EastJonesPen Set624.99309.38
3521-Jul-22CentralMorganPen Set5512.49686.95
367-Aug-22CentralKivellPen Set4223.951005.9
3724-Aug-22WestSorvinoDesk3275825
3810-Sep-22CentralGillPencil71.299.03
3927-Sep-22WestSorvinoPen761.99151.24
4014-Oct-22WestThompsonBinder5719.991139.43
4131-Oct-22CentralAndrewsPencil141.2918.06
4217-Nov-22CentralJardineBinder114.9954.89
434-Dec-22CentralJardineBinder9419.991879.06
4421-Dec-22CentralAndrewsBinder284.99139.72
Data


Book1
ABCDEFG
1CENTRAL FORM
2OrderDateRegionRepItemUnitsUnit CostTotal
323-Jan-21CentralKivellBinder5019.99999.5
49-Feb-21CentralJardinePencil364.99179.64
526-Feb-21CentralGillPen2719.99539.73
618-Apr-21CentralAndrewsPencil751.99149.25
75-May-21CentralJardinePencil904.99449.1
825-Jun-21CentralMorganPencil904.99449.1
91-Sep-21CentralSmithDesk2125250
105-Oct-21CentralMorganBinder288.99251.72
1125-Nov-21CentralKivellPen Set964.99479.04
1212-Dec-21CentralSmithPencil671.2986.43
1315-Jan-22CentralGillBinder468.99413.54
141-Feb-22CentralSmithBinder87151305
1524-Mar-22CentralJardinePen Set504.99249.5
1610-Apr-22CentralAndrewsPencil661.99131.34
1714-May-22CentralGillPencil531.2968.37
18Company Name
19CENTRAL FORM
20OrderDateRegionRepItemUnitsUnit CostTotal
2131-May-22CentralGillBinder808.99719.2
2217-Jun-22CentralKivellDesk5125625
2321-Jul-22CentralMorganPen Set5512.49686.95
247-Aug-22CentralKivellPen Set4223.951005.9
2510-Sep-22CentralGillPencil71.299.03
2631-Oct-22CentralAndrewsPencil141.2918.06
2717-Nov-22CentralJardineBinder114.9954.89
284-Dec-22CentralJardineBinder9419.991879.06
2921-Dec-22CentralAndrewsBinder284.99139.72
30
31
32
33
34
35
36Company Name
37CENTRAL FORM
38OrderDateRegionRepItemUnitsUnit CostTotal
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54Company Name
55CENTRAL FORM
56OrderDateRegionRepItemUnitsUnit CostTotal
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72Company Name
Central Form


VBA Code:
Sub Macro3()
'
' Macro3 Macro
'

'
    ActiveSheet.ListObjects("Order_Data").Range.AutoFilter Field:=2, Criteria1:= _
        "Central"
    Range("A3:G31").Select
    Selection.SpecialCells(xlCellTypeVisible).Select
    Selection.Copy
    Sheets("Central Form").Select
    Range("A3").Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Sheets("Data").Select
    Range("A32:G44").Select
    Selection.SpecialCells(xlCellTypeVisible).Select
    Application.CutCopyMode = False
    Selection.Copy
    Sheets("Central Form").Select
    Range("A21").Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
End Sub
 

Excel Facts

How to fill five years of quarters?
Type 1Q-2023 in a cell. Grab the fill handle and drag down or right. After 4Q-2023, Excel will jump to 1Q-2024. Dash can be any character.
Hi,

Do you need the data to be split by "Region" ? i.e. Central first 15 row, then central 2nd 15 rows then East first 15 rows ... etc. ? All regions shall be in the same sheet "Central Form" ?
 
Upvote 0
Hi,

Do you need the data to be split by "Region" ? i.e. Central first 15 row, then central 2nd 15 rows then East first 15 rows ... etc. ? All regions shall be in the same sheet "Central Form" ?
There will be a separate sheet for each form: East Form, West Form and Central Form.
Currently I am just focusing on Central form to figure out the logistics.
My biggest issue is when I filter the data by Central, how can I (in VBA) count the first 15 visible cells, copy and paste them into the form, then go back to the data, grab the next set of 15 and so on. **Grabbing the filtered visible data in 15 row blocks until there are no results left is what has me stumped.

Thank you so much for your help!
 
Upvote 0
Try this on a copy.
VBA Code:
Sub PasteToCentralForm()
    Dim tableRange As Range, destSheet As Worksheet
    Dim tableArray() As Variant
    Dim numRows As Integer, numCols As Integer
    Dim i As Integer, j As Integer, loopCount As Integer

    Set tableRange = ThisWorkbook.Sheets("Data").ListObjects("Table1").DataBodyRange 'Change table name as needed
    Set destSheet = ThisWorkbook.Sheets("Central Form")
    chunkSize = 15
    
    numRows = tableRange.Rows.Count
    numCols = tableRange.Columns.Count
    loopCount = WorksheetFunction.RoundUp(numRows / chunkSize, 0)
    
    Dim firstCell As Range
    Set firstCell = tableRange.Cells(1, 1)
    
    Application.ScreenUpdating = False
    For i = 0 To loopCount - 1
        firstCell.Offset(i * chunkSize).Resize(chunkSize, numCols).Copy
        destSheet.Range("A1").Offset(i * (chunkSize + 2) + 2).PasteSpecial xlPasteAll
    Next i
    Application.ScreenUpdating = True

End Sub
 
Upvote 0
This is considerably faster if you have a large table.

VBA Code:
Sub PasteToCentralForm2()
    Dim tableRange As Range, destSheet As Worksheet
    Dim tableArray() As Variant
    Dim numRows As Long, numCols As Long
    Dim i As Long, j As Long, loopCount As Long
    Dim chunkSize As Long
    
    Set tableRange = ThisWorkbook.Sheets("Data").ListObjects("Table1").DataBodyRange 'Change table name as needed
    Set destSheet = ThisWorkbook.Sheets("Central Form")
    chunkSize = 15
    
    numRows = tableRange.Rows.Count
    numCols = tableRange.Columns.Count
    loopCount = WorksheetFunction.RoundUp(numRows / chunkSize, 0)
    
    ' Read data into array
    tableArray = tableRange.Value
    
    Application.ScreenUpdating = False
    ' Clear previous data in destination sheet
    destSheet.Range("A1").CurrentRegion.Clear
    
    ' Collect all data into one large array
    Dim outputData() As Variant
    ReDim outputData(1 To loopCount * (chunkSize + 2) - 2, 1 To numCols)
    
    Dim outputIndex As Long
    outputIndex = 1
    
    For i = 1 To loopCount
        Dim outputRowCount As Long
        outputRowCount = WorksheetFunction.Min(chunkSize, numRows - (i - 1) * chunkSize)
        For j = 1 To outputRowCount
            For k = 1 To numCols
                outputData(outputIndex, k) = tableArray((i - 1) * chunkSize + j, k)
            Next k
            outputIndex = outputIndex + 1
        Next j
        outputIndex = outputIndex + 2 ' Skip two rows for each chunk
    Next i
    
    ' Output all data to destination sheet at once
    destSheet.Cells(3, 1).Resize(UBound(outputData, 1), UBound(outputData, 2)).Value = outputData
    
    Application.ScreenUpdating = True
End Sub
 
Last edited:
Upvote 0
Try below code ...
VBA Code:
Sub Test()

Application.ScreenUpdating = False

Dim a, ws As Worksheet, Lr&
Set ws = Sheets("Data")
a = ws.[A1].CurrentRegion

With CreateObject("scripting.dictionary")
    For x = 2 To UBound(a)
        If Not .exists(a(x, 2)) Then
            .Add a(x, 2), Nothing
            If Not Evaluate("isref('" & a(x, 2) & "'!a1)") Then
                Sheets.Add(, Sheets(Sheets.Count)).Name = a(x, 2)
            Else
                Sheets(a(x, 2)).UsedRange.Clear
            End If
            ws.[K2] = "=""" & a(x, 2) & """=B2"
            ws.[A1].CurrentRegion.AdvancedFilter 2, ws.[K1:K2], Sheets(a(x, 2)).[A1]
            ws.[K2].Clear
            With Sheets(a(x, 2))
                With .UsedRange
                    .Interior.Color = xlNone
                    .Borders.LineStyle = xlNone
                    .Font.Bold = False
                End With
                Lr = .Range("A" & Rows.Count).End(3).Row
                For y = 2 To Lr Step 18
                    .Rows(y).Resize(3).Insert
                    With .Cells(y, 1)
                        .Value = "Company Name": .Resize(, 7).HorizontalAlignment = 7
                        .Offset(1) = a(x, 2) & " Form": .Offset(1).Resize(, 7).HorizontalAlignment = 7
                        .Offset(2).Resize(, 7) = [{"OrderDate","Region","Rep","Item","Units","Unit Cost","Total"}]
                        .Resize(3, 7).Font.Bold = True
                    End With
                Next
                .Rows(1).EntireRow.Delete
            End With
        End If
    Next
End With

End Sub
 
Last edited:
Upvote 0
Try this on a copy.
VBA Code:
Sub PasteToCentralForm()
    Dim tableRange As Range, destSheet As Worksheet
    Dim tableArray() As Variant
    Dim numRows As Integer, numCols As Integer
    Dim i As Integer, j As Integer, loopCount As Integer

    Set tableRange = ThisWorkbook.Sheets("Data").ListObjects("Table1").DataBodyRange 'Change table name as needed
    Set destSheet = ThisWorkbook.Sheets("Central Form")
    chunkSize = 15
 
    numRows = tableRange.Rows.Count
    numCols = tableRange.Columns.Count
    loopCount = WorksheetFunction.RoundUp(numRows / chunkSize, 0)
 
    Dim firstCell As Range
    Set firstCell = tableRange.Cells(1, 1)
 
    Application.ScreenUpdating = False
    For i = 0 To loopCount - 1
        firstCell.Offset(i * chunkSize).Resize(chunkSize, numCols).Copy
        destSheet.Range("A1").Offset(i * (chunkSize + 2) + 2).PasteSpecial xlPasteAll
    Next i
    Application.ScreenUpdating = True

End Sub

This code was the closest but it only does in 7 row chunks. I had to add in a filter code so it grabs only "Central".
Is there a reason it is only copying the data in 7 row chunks? Is there a way to fix this?

Here is my modified version but don't know how to fix the 7 row only thing...

VBA Code:
Sub PasteToCentralForm()
    Dim tableRange As Range, destSheet As Worksheet
    Dim tableArray() As Variant
    Dim numRows As Integer, numCols As Integer
    Dim i As Integer, j As Integer, loopCount As Integer

    Set tableRange = ThisWorkbook.Sheets("Data").ListObjects("Order_Data").DataBodyRange 'Change table name as needed
    Set destSheet = ThisWorkbook.Sheets("Central Form")
    chunkSize = 15
  
    numRows = tableRange.Rows.Count
    numCols = tableRange.Columns.Count
    loopCount = WorksheetFunction.RoundUp(numRows / chunkSize, 0)
  
        ThisWorkbook.Sheets("Data").ListObjects("Order_Data").Range.AutoFilter Field:=2, Criteria1:= _
        "Central"
  
    Dim firstCell As Range
    Set firstCell = tableRange.Cells(1, 1)
  
    Application.ScreenUpdating = False
    For i = 0 To loopCount - 1
        firstCell.Offset(i * chunkSize).Resize(chunkSize, numCols).Copy
        destSheet.Range("A1").Offset(i * (chunkSize + 2) + 2).PasteSpecial xlPasteValues
    Next i
    Application.ScreenUpdating = True

End Sub

Result of code:

VBA repeat form loop code template.xlsm
ABCDEFG
1CENTRAL FORM
2OrderDateRegionRepItemUnitsUnit CostTotal
323-Jan-21CentralKivellBinder5019.99999.5
49-Feb-21CentralJardinePencil364.99179.64
526-Feb-21CentralGillPen2719.99539.73
618-Apr-21CentralAndrewsPencil751.99149.25
75-May-21CentralJardinePencil904.99449.1
825-Jun-21CentralMorganPencil904.99449.1
91-Sep-21CentralSmithDesk2125250
10
11
12
13
14
15
16
17Company Name
18CENTRAL FORM
19OrderDateRegionRepItemUnitsUnit CostTotal
205-Oct-21CentralMorganBinder288.99251.72
2125-Nov-21CentralKivellPen Set964.99479.04
2212-Dec-21CentralSmithPencil671.2986.43
2315-Jan-22CentralGillBinder468.99413.54
241-Feb-22CentralSmithBinder87151305
2524-Mar-22CentralJardinePen Set504.99249.5
2610-Apr-22CentralAndrewsPencil661.99131.34
2714-May-22CentralGillPencil531.2968.37
28
29
30
31
32
33
34Company Name
35CENTRAL FORM
36OrderDateRegionRepItemUnitsUnit CostTotal
3731-May-22CentralGillBinder808.99719.2
3817-Jun-22CentralKivellDesk5125625
3921-Jul-22CentralMorganPen Set5512.49686.95
407-Aug-22CentralKivellPen Set4223.951005.9
4110-Sep-22CentralGillPencil71.299.03
4231-Oct-22CentralAndrewsPencil141.2918.06
4317-Nov-22CentralJardineBinder114.9954.89
444-Dec-22CentralJardineBinder9419.991879.06
4521-Dec-22CentralAndrewsBinder284.99139.72
46
47
48
49
50
51Company Name
52CENTRAL FORM
53OrderDateRegionRepItemUnitsUnit CostTotal
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68Company Name
Central Form
 
Upvote 0
Your filtering had to something to do with the 7 chunks only. The chunk is defined by the variable chunkSize in the code. Try this on a copy.
VBA Code:
Sub PasteToCentralForm3()
    Dim tableRange As Range, destSheet As Worksheet
    Dim tableArray() As Variant, Result() As Variant
    Dim numRows As Long, numCols As Long
    Dim i As Long, j As Long, loopCount As Long
    Dim chunkSize As Long
    
    Set tableRange = ThisWorkbook.Sheets("Data").ListObjects("Table1").DataBodyRange 'Change table name as needed
    Set destSheet = ThisWorkbook.Sheets("Central Form")
    chunkSize = 15 'adjust chunk size as needed.
    
    numRows = tableRange.Rows.Count
    numCols = tableRange.Columns.Count

    p = 1
    ' Read data into array
    tableArray = tableRange.Value
    ReDim Result(1 To numRows, 1 To numCols)
    For m = 1 To numRows
        If tableArray(m, 2) = "Central" Then
            For n = 1 To numCols
                Result(p, n) = tableArray(m, n)
            Next n
             p = p + 1
        End If
    Next m
    
    Application.ScreenUpdating = False
    loopCount = WorksheetFunction.RoundUp(UBound(Result, 1) / chunkSize, 0)
    
    ' Collect all data into one large array
    Dim outputData() As Variant
    ReDim outputData(1 To loopCount * (chunkSize + 2) - 2, 1 To numCols)
    
    Dim outputIndex As Long
    outputIndex = 1
    
    For i = 1 To loopCount
        Dim outputRowCount As Long
        outputRowCount = WorksheetFunction.Min(chunkSize, numRows - (i - 1) * chunkSize)
        For j = 1 To outputRowCount
            For k = 1 To numCols
                outputData(outputIndex, k) = Result((i - 1) * chunkSize + j, k)
            Next k
            outputIndex = outputIndex + 1
        Next j
        outputIndex = outputIndex + 2 ' Skip two rows for each chunk
    Next i
    
    ' Output all data to destination sheet at once
    destSheet.Cells(3, 1).Resize(UBound(outputData, 1), UBound(outputData, 2)).Value = outputData
    
    Application.ScreenUpdating = True
End Sub
 
Upvote 0
@willow1985 Have you tried the code in post #6 ? Does it produce the final expected results ?
#6 Created separate spreadsheets instead of using the existing forms, which would not work for what I require unfortunately. But I appreciate the help!
 
Upvote 0

Forum statistics

Threads
1,215,200
Messages
6,123,612
Members
449,109
Latest member
Sebas8956

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