Sub BillGenerator()
Dim ws As Worksheet, rng As Range, startCell As Range, endCell As Range
Dim arr(), arrTem(), iRows As Integer, iCols As Integer, iPages As Integer
Dim dic As Object, dKey As String, arrItem()
Dim totalPages As Integer, arrStr() As String
Set ws = ThisWorkbook.Sheets("销售明细表")
Set dic = CreateObject("Scripting.Dictionary")
arr = ws.UsedRange
For i = 2 To UBound(arr)
dKey = arr(i, 2) & "|" & arr(i, 3) & "|" & arr(i, 4)
If Not dic.exists(dKey) Then '如果dkey不存在
k = 0
Else
arrTem = dic(dKey)
k = UBound(arrTem, 2) + 1
End If
ReDim Preserve arrTem(0 To 6, 0 To k)
For j = 0 To 6
arrTem(j, k) = arr(i, j + 5)
Next
dic(dKey) = arrTem '把数组存入字典
Next
For Each Item In dic.items
totalPages = totalPages + Application.WorksheetFunction.RoundUp((UBound(Item, 2) + 1) / 15, 0)
Next
Set ws = ThisWorkbook.Sheets("生成出仓单")
Set rng = ThisWorkbook.Sheets("模板").Range("A1:H22")
iRows = rng.Rows.Count
iCols = rng.Columns.Count
With ws
.Cells.Clear
.ResetAllPageBreaks
For i = 1 To totalPages
Set startCell = .Range("A1").Offset((i - 1) * iRows, 0)
Set endCell = startCell.Offset(rng.Rows.Count - 1, iCols - 1)
rng.Copy Destination:=startCell
.HPageBreaks.Add before:=endCell.Offset(1, 0)
Next
.PageSetup.FitToPagesWide = 1
arrTem = .UsedRange
End With
p = 0
For Each Key In dic.keys
arrStr = Split(Key, "|")
arrItem = dic(Key)
iPages = Application.WorksheetFunction.RoundUp((UBound(arrItem, 2) + 1) / 15, 0)
For i = 1 To iPages
arrTem(3 + p * iRows, 7) = arrStr(0)
arrTem(4 + p * iRows, 7) = arrStr(1)
arrTem(4 + p * iRows, 2) = arrStr(2)
arrTem(3 + p * iRows, 8) = "第" & i & "/" & iPages & "页"
For j = (i - 1) * 15 To Application.WorksheetFunction.Min(UBound(arrItem, 2), i * 15 - 1)
For k = 0 To UBound(arrItem)
arrTem(6 + p * iRows + j - (i - 1) * 15, k + 2) = arrItem(k, j)
Next
arrTem(21 + p * iRows, 5) = arrTem(21 + p * iRows, 5) + Val(arrItem(3, j))
arrTem(21 + p * iRows, 7) = arrTem(21 + p * iRows, 7) + Val(arrItem(5, j))
Next
p = p + 1
Next
Next
ws.Cells(1, 1).Resize(UBound(arrTem), UBound(arrTem, 2)) = arrTem
MsgBox "Done!"
ws.Activate
End Sub