使用两个数组sorting表

请耐心等待,试图解释困境。 我想写一个macros,这将帮助我sorting下表:

在这里输入图像说明

并尝试使用这些预格式化表格将销售IDsorting到另一个工作表(在同一工作簿中):

在这里输入图像说明

最终结果应该如下图所示我需要做的是填写销售ID和公式右侧的销售ID列计算或执行查找:

在这里输入图像说明

问题是我的团队已经手动填写表格或者使用sortingfunction的组合来手动填写表格。 问题是,当我们有超过10,000个销售ID并且没有自动化时,这可能是一个痛苦。 我试图编码这个来帮助我的团队没有得到我有限的vba知识的帮助 – 任何帮助表示赞赏:

编辑:我对开尔文的代码进行了一些修改(谢谢@ kelvin!),我想澄清的是,我想要做的就是将特殊值这些销售ID粘贴到我的“表”选项卡的基础上的预格式化表的位置。 请参阅下面的新图片以及重新提交的代码。 请注意我的“表格”选项卡中没有销售ID的公式(我的错误我不清楚)

最后一点:我试图解决的最后一件事情是扫描两个范围,并将唯一对筛选出来,使数组CFValues低于dynamic – 请帮助,如果你知道如何做到这一点比我更好!

在这里输入图像说明

Option Explicit Sub SortNCopy2TablesV2() Dim CFValues As Variant Dim r As Integer Dim i As Long Dim ws1 As Worksheet Dim ws2 As Worksheet Dim CombStr As Variant Const startRow As Long = 7 'kelvin added CFValues = Array("PA", "PB", "PC", "PF", "MA", "SP A", "SP B", "SP C") Set ws1 = Worksheets("Cashflow") Set ws2 = Worksheets("Tables") r = startRow 'kelvin changed 'kelvin added Application.ScreenUpdating = False On Error Resume Next For i = LBound(CFValues) To UBound(CFValues) Worksheets.Add ActiveSheet.Name = CFValues(i) If Err.Number = 1004 Then Application.DisplayAlerts = False Worksheets(CFValues(i)).Cells.Clear ActiveSheet.Delete Application.DisplayAlerts = True End If Next i On Error GoTo 0 With ws1 'kelvin added Do Until .Range("C" & r).Value = "" CombStr = .Range("C" & r).Text + " " + .Range("D" & r).Text 'kelvin changed For i = LBound(CFValues) To UBound(CFValues) If StrComp(CombStr, CFValues(i), vbTextCompare) = 0 Then 'kelvin changed 'kelvin added 1 lines of code: .Range("B" & r).Copy _ Worksheets(CFValues(i)).Range("B" & Application.WorksheetFunction.CountA(Worksheets(CFValues(i)).Range("B:B")) + 1) End If Next i r = r + 1 Loop End With 'kelvin added Dim nextRow As Long Dim tempRow As Long Dim numRows As Long nextRow = 5 For i = LBound(CFValues) To UBound(CFValues) tempRow = Application.WorksheetFunction.CountA(Worksheets(CFValues(i)).Range("B:B")) If tempRow > 0 Then numRows = Application.WorksheetFunction.CountA(Worksheets(CFValues(i)).Range("B:B")) ws2.Range("B" & nextRow + 1).EntireRow.Resize(numRows).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove ws2.Range("C" & nextRow & ":" & "F" & nextRow + numRows).FillDown Worksheets(CFValues(i)).Range("B2").CurrentRegion.Copy ws2.Range("B" & nextRow + 1) ws2.Range("B" & nextRow + 2 + tempRow) = CFValues(i) nextRow = nextRow + tempRow + 5 End If Next i Application.ScreenUpdating = True End Sub 

gudal写了一个可行的代码来生成表格。 请查看完整的代码,对gudal代码和input输出样本进行小改动。
代码:

 Private Sub SortNCopyTables2() Application.ScreenUpdating = False Dim saleIDs() As Variant Dim sellerClass() As Variant Dim bucketClass() As Variant Dim cashFlowSheet As Worksheet Set cashFlowSheet = Worksheets("CashFlow") Dim lastSaleIDRow As Long lastSaleIDRow = cashFlowSheet.Cells.SpecialCells(xlCellTypeLastCell).row saleIDs = cashFlowSheet.Range("A2:A" & lastSaleIDRow).Value sellerClass = cashFlowSheet.Range("B2:B" & lastSaleIDRow).Value bucketClass = cashFlowSheet.Range("C2:C3" & lastSaleIDRow).Value Dim classPairsArray() As Variant Dim classPairs() As String ReDim Preserve classPairs(0) ReDim Preserve classPairsArray(0) Dim size As Long size = 0 Dim saleID As String Dim tempArray() As String For counter = 1 To UBound(saleIDs, 1) sellerBucketString = sellerClass(counter, 1) + " & " + bucketClass(counter, 1) If UBound(Filter(classPairs, sellerBucketString)) < 0 Then ReDim Preserve classPairs(size) classPairs(size) = sellerBucketString ReDim Preserve classPairsArray(size) ReDim Preserve tempArray(0) tempArray(0) = sellerBucketString classPairsArray(size) = tempArray size = size + 1 End If Dim position As Long For i = 0 To UBound(classPairsArray) tempArray = classPairsArray(i) If sellerBucketString = tempArray(0) Then tempArray = classPairsArray(i) ReDim Preserve tempArray(UBound(tempArray) + 1) tempArray(UBound(tempArray)) = saleIDs(counter, 1) classPairsArray(i) = tempArray Exit For End If Next i Next counter 'loop through array and write to worksheet Dim tablesSheet As Worksheet Set tablesSheet = Worksheets("Tables") 'clear the tableSheet, just in case 'org: tablesSheet.Rows(10 & ":" & tablesSheet.Rows.Count).Clear tablesSheet.Cells.Clear 'kelvin edited Dim SaleIDRange, BalanceRange, MonthlyRange, RateRange As Range 'Change the letters and starting rows as necessary Set SaleIDRange = cashFlowSheet.Range("A2:A" & cashFlowSheet.Cells.SpecialCells(xlCellTypeLastCell).row) Set BalanceRange = cashFlowSheet.Range("D2:D" & cashFlowSheet.Cells.SpecialCells(xlCellTypeLastCell).row) Set MonthlyRange = cashFlowSheet.Range("E2:E" & cashFlowSheet.Cells.SpecialCells(xlCellTypeLastCell).row) ' not used now but assume is used for npv / price calcs Set RateRange = cashFlowSheet.Range("F2:F" & cashFlowSheet.Cells.SpecialCells(xlCellTypeLastCell).row) Dim tRow As Long tRow = 10 ' this is where I start to build my table Dim row As Long Dim tempSumRow As Range For i = 0 To UBound(classPairsArray) Dim tableStartRow As Long tableStartRow = tRow + 1 Dim tableSellerBucketGroup As String Dim tableArray() As String tableArray = classPairsArray(i) With tablesSheet .Cells(tRow, 1).Value = "Sale ID" .Cells(tRow, 1).Font.Underline = xlUnderlineStyleSingleAccounting .Cells(tRow, 2).Value = "NPV" .Cells(tRow, 2).Font.Underline = xlUnderlineStyleSingleAccounting .Cells(tRow, 3).Value = "Price" .Cells(tRow, 3).Font.Underline = xlUnderlineStyleSingleAccounting .Cells(tRow, 4).Value = "Balance" .Cells(tRow, 4).Font.Underline = xlUnderlineStyleSingleAccounting .Cells(tRow, 5).Value = "Rate" .Cells(tRow, 5).Font.Underline = xlUnderlineStyleSingleAccounting tRow = tRow + 1 For j = 1 To UBound(tableArray) .Cells(tRow, 1).Value = tableArray(j) '.Cells(tRow, 2).Value = ??? NPV formula? '.Cells(tRow, 3).Value = ??? price formula? 'org: .Cells(tRow, 4).Formula = "=INDEX(" + cashFlowSheet.Name + "!" + BalanceRange.Address + ",MATCH(A" + CStr(tRow) + "," + cashFlowSheet.Name + "!" + SaleIDRange.Address + ",0))" .Cells(tRow, 4).Formula = "=IFERROR(INDEX(" + cashFlowSheet.Name + "!" + BalanceRange.Address + ",MATCH(A" + CStr(tRow) + "," + cashFlowSheet.Name + "!" + SaleIDRange.Address + ",0)),)" 'kelvin edited .Cells(tRow, 4).NumberFormat = "$ #,##0.00" 'kelvin edited 'org: .Cells(tRow, 5).Formula = "=INDEX(" + cashFlowSheet.Name + "!" + RateRange.Address + ",MATCH(A" + CStr(tRow) + "," + cashFlowSheet.Name + "!" + SaleIDRange.Address + ",0))" .Cells(tRow, 5).Formula = "=IFERROR(INDEX(" + cashFlowSheet.Name + "!" + RateRange.Address + ",MATCH(A" + CStr(tRow) + "," + cashFlowSheet.Name + "!" + SaleIDRange.Address + ",0)),)" 'kelvin edited .Cells(tRow, 5).NumberFormat = "0%" 'kelvin edited .Cells(tRow, 2).Formula = "=IFERROR(NPV(RC[3],RC[2]),)" 'kelvin added. .Cells(tRow, 2).NumberFormat = "$ #,##0.00" 'kelvin added. .Cells(tRow, 3).Formula = "=IFERROR(RC[-1]/RC[1],)" 'kelvin added. .Cells(tRow, 3).NumberFormat = "0%" 'kelvin added. tRow = tRow + 1 Next j .Cells(tRow, 1).Value = tableArray(0) .Cells(tRow, 1).Font.Bold = True .Cells(tRow, 2).Formula = "=SUM(B" + CStr(tableStartRow) + ":B" + CStr(tRow - 1) + ")" 'org: .Cells(tRow, 3).Formula = "=AVERAGE(C" + CStr(tableStartRow) + ":C" + CStr(tRow - 1) + ")" .Cells(tRow, 3).Formula = "=IFERROR(RC[-1]/RC[1],)" 'kelvin added. .Cells(tRow, 3).NumberFormat = "0%" 'kelvin added. .Cells(tRow, 4).Formula = "=SUM(D" + CStr(tableStartRow) + ":D" + CStr(tRow - 1) + ")" 'org: .Cells(tRow, 5).Formula = "=AVERAGE(E" + CStr(tableStartRow) + ":E" + CStr(tRow - 1) + ")" Set tempSumRow = tablesSheet.Range("A" + CStr(tRow) + ":E" + CStr(tRow)) With tempSumRow.Borders(xlEdgeTop) .LineStyle = xlContinuous .Weight = xlThin End With With tempSumRow.Borders(xlEdgeBottom) .LineStyle = xlDouble .Weight = xlThick End With tRow = tRow + 2 End With Next i tablesSheet.Activate Application.ScreenUpdating = True End Sub 

样本input和样本输出: 排序表

感谢gudal。

根据你的代码,第一个表的头部从单元格B6开始,第一行数据从B7开始。 修改你的macros,我设法做sorting,并把结果放在表格上。 但是,我不能为你计算NPV,因为我不知道确切的公式。 请find代码:

  Option Explicit Sub SortNCopy2TablesV2() Dim CFValues As Variant 'Dim InsertRow As Variant Dim R As Integer Dim i As Long Dim ws1 As Worksheet Dim ws2 As Worksheet Dim CombStr As Variant Const startRow As Long = 7 'kelvin added CFValues = Array("PA", "PB", "PC", "PF", "MA", "SP A", "SP B", "SP C") ' InsertRow = Array(6, 11, 16, 21, 26, 31, 36, 41) Set ws1 = Worksheets("Cashflow") Set ws2 = Worksheets("Tables") R = startRow 'kelvin changed 'kelvin added Application.ScreenUpdating = False On Error Resume Next For i = LBound(CFValues) To UBound(CFValues) Worksheets.Add ActiveSheet.Name = CFValues(i) If Err.Number = 1004 Then Application.DisplayAlerts = False Worksheets(CFValues(i)).Cells.Clear ActiveSheet.Delete Application.DisplayAlerts = True End If Next i On Error GoTo 0 With ws1 'kelvin added 'org: Do Until ws1.Range("C" & R).Value = "" Do Until .Range("C" & R).Value = "" 'org: CombStr = ws1.Range("C" & R).Text + "" + ws1.Range("D" & R).Text CombStr = .Range("C" & R).Text + " " + .Range("D" & R).Text 'kelvin changed For i = LBound(CFValues) To UBound(CFValues) 'org: If StrComp(CombStr, CFValues(i), vbTextCompare) Then If StrComp(CombStr, CFValues(i), vbTextCompare) = 0 Then 'kelvin changed 'Return value of first insert row in InsertRow[] array - ' ie if PA, then it should return row 6 for insertion, if PB, then row 11, etc. 'insert new row, copying and pasting the formulas down and copying the sales ID 'Insert Sales ID value into Table tab 'org: ActiveCell.Offset(1, 0).EntireRow.Copy 'org: ActiveCell.Offset(2, 0).EntireRow.Insert Shift:=xlDown 'org: ActiveCell.Offset(2, 0).EntireRow.PasteSpecial Paste:=xlPasteFormulasAndNumberFormats 'org: Application.CutCopyMode = False 'org: ws1.Range("B" & R).Value = ws2.Range("B" & InsertRow(i) + 1).Value 'kelvin added 1 lines of code: .Range("A" & R).EntireRow.Copy _ Worksheets(CFValues(i)).Range("A" & Application.WorksheetFunction.CountA(Worksheets(CFValues(i)).Range("B:B")) + 1) 'decrement InsertRow[] array, so that the 'program always knows where to find the next tables for insertion 'Else End If Next i R = R + 1 Loop End With 'kelvin added ws2.Cells.Clear Dim nextRow As Long Dim tempRow As Long nextRow = startRow For i = LBound(CFValues) To UBound(CFValues) tempRow = Application.WorksheetFunction.CountA(Worksheets(CFValues(i)).Range("B:B")) If tempRow > 0 Then ws1.Range("A" & startRow - 1).EntireRow.Copy ws2.Range("A" & nextRow - 1) Worksheets(CFValues(i)).Range("B2").CurrentRegion.Copy ws2.Range("B" & nextRow) ws2.Range("A" & nextRow + tempRow) = CFValues(i) nextRow = nextRow + tempRow + 5 End If Next i Application.ScreenUpdating = True End Sub 

(糟糕…我无法发布图像,请查找input和输出的粘贴文本)示例input:

销售ID S类B类别余额月率1 PA 100 20 5 2 PA 200 25 4 3 PA 300 30 3 4 SP C 400 35 2 5 SP C 500 40 1 6 MC 600 45 2 7 MB 700 50 3 8 MB 800 55 4 9 PF 900 60 5 10 SP F 1000 55 6 11 MF 1100 50 7 12 MA 1200 45 8 13 Sp B 1300 40 9 14 Sp C 1400 35 10

示例输出:

 Sale ID S Class B Class Balance Month Rate 1 PA 100 20 5 2 PA 200 25 4 3 PA 300 30 3 

PA

 Sale ID S Class B Class Balance Month Rate 9 PF 900 60 5 

PF

 Sale ID S Class B Class Balance Month Rate 12 MA 1200 45 8 

 Sale ID S Class B Class Balance Month Rate 13 Sp B 1300 40 9 

SP B

 Sale ID S Class B Class Balance Month Rate 4 SP C 400 35 2 5 SP C 500 40 1 14 Sp C 1400 35 10 

SP C

请给出意见。 谢谢。

当我写这段代码的时候,我看到你收到了另外一个答案,不过我仍然会把它贴出来。 下面的代码应粘贴到表格工作表的vba部分。 然后,您应该在该工作表上创build一个button(在开发人员选项卡中),并将其分配给macrosStartSortClick

这段代码假设如下,并且必须相应地更改不正确的内容。 如果你在下面评论我的假设是错误的,我可以为你更新,或者你可以自己做。

  1. CashFlow选项卡在第1行中具有标题,其中销售ID为A1,卖家类别为B1等
  2. 在表格选项卡中,您希望第一个表格从第10行开始,并在第A列,以便第一个表格的销售ID用A10写入。
  3. 我没有input价格和npv的公式,如果你希望我提供你的公式。
  4. 字体也是可变的。 就在代码末尾的整个工作表(在代码运行之前,代码将覆盖手动字体更改,以确保正确放置表格边框)。

我相信它本来可以做得更干净,而且我认为10000行以上的速度可能会很慢,但它确实符合你的要求。 使用二维数组会更快,我现在看到。 在一个版本的工作(因为我需要更好地使用arrays我自己,你的问题是有趣的工作)

 Public Sub StartSortClick() If MsgBox("This will rebuild the Tables tab! Continue?", vbYesNo, "Rebuild Tables Tab?") Then SortNCopyTables End If End Sub Private Sub SortNCopyTables() Application.ScreenUpdating = False Dim sheetCollection As Collection Set sheetCollection = New Collection Dim cashFlowSheet As Worksheet Set cashFlowSheet = Worksheets("CashFlow") Dim SaleIDRange, BalanceRange, MonthlyRange, RateRange As Range 'Change the letters and starting rows as necessary Set SaleIDRange = cashFlowSheet.Range("A2:A" & cashFlowSheet.Cells.SpecialCells(xlCellTypeLastCell).row) Set BalanceRange = cashFlowSheet.Range("D2:D" & cashFlowSheet.Cells.SpecialCells(xlCellTypeLastCell).row) Set MonthlyRange = cashFlowSheet.Range("E2:E" & cashFlowSheet.Cells.SpecialCells(xlCellTypeLastCell).row) ' not used now but assume is used for npv / price calcs Set RateRange = cashFlowSheet.Range("F2:F" & cashFlowSheet.Cells.SpecialCells(xlCellTypeLastCell).row) 'loop through all rows, if encountering a new seller-bucket combo, create a new sheet, name it that seller-bucket combo and add it to the sheetCollection Dim cRow As Long cRow = 2 ' should be the location of first cashflow entry Dim sellerBucketString As String Dim tempSheet As Worksheet Dim firstUnusedRow As Long Do Until cashFlowSheet.Cells(cRow, 1) = "" ' here you should change the 1 to whatever column is your Sale ID column (mine are in A) sellerBucketString = cashFlowSheet.Cells(cRow, 2).Value + " & " + cashFlowSheet.Cells(cRow, 3).Value If Not InCollection(sheetCollection, sellerBucketString) Then 'create new sheet and add to collection With ThisWorkbook Set tempSheet = .Sheets.Add(After:=.Sheets(.Sheets.Count)) tempSheet.Name = sellerBucketString sheetCollection.Add tempSheet, tempSheet.Name End With End If ' select worksheet and insert row at the bottom) Set tempSheet = sheetCollection.Item(sellerBucketString) firstUnusedRow = tempSheet.Cells.SpecialCells(xlCellTypeLastCell).Offset(1, 0).row tempSheet.Cells(firstUnusedRow, 1).Value = cashFlowSheet.Cells(cRow, 1).Value cRow = cRow + 1 Loop 'loop through sheets in the collection and create appropriate report tables in Tables sheet Dim tablesSheet As Worksheet Set tablesSheet = Worksheets("Tables") 'clear the tableSheet, just in case tablesSheet.Rows(10 & ":" & tablesSheet.Rows.Count).Clear Dim tRow As Long tRow = 10 ' this is where I start to build my table Dim row As Long Dim tempSumRow As Range Dim ws As Worksheet For Each ws In sheetCollection Dim tableStartRow As Long tableStartRow = tRow + 1 With tablesSheet .Cells(tRow, 1).Value = "Sale ID" .Cells(tRow, 1).Font.Underline = xlUnderlineStyleSingleAccounting .Cells(tRow, 2).Value = "NPV" .Cells(tRow, 2).Font.Underline = xlUnderlineStyleSingleAccounting .Cells(tRow, 3).Value = "Price" .Cells(tRow, 3).Font.Underline = xlUnderlineStyleSingleAccounting .Cells(tRow, 4).Value = "Balance" .Cells(tRow, 4).Font.Underline = xlUnderlineStyleSingleAccounting .Cells(tRow, 5).Value = "Rate" .Cells(tRow, 5).Font.Underline = xlUnderlineStyleSingleAccounting tRow = tRow + 1 For row = 2 To ws.Cells.SpecialCells(xlCellTypeLastCell).row .Cells(tRow, 1).Value = ws.Cells(row, 1).Value '.Cells(tRow, 2).Value = ??? NPV formula? '.Cells(tRow, 3).Value = ??? price formula? .Cells(tRow, 4).Formula = "=INDEX(" + cashFlowSheet.Name + "!" + BalanceRange.Address + ",MATCH(A" + CStr(tRow) + "," + cashFlowSheet.Name + "!" + SaleIDRange.Address + ",0))" .Cells(tRow, 4).NumberFormat = "$#,##0.00" .Cells(tRow, 5).Formula = "=INDEX(" + cashFlowSheet.Name + "!" + RateRange.Address + ",MATCH(A" + CStr(tRow) + "," + cashFlowSheet.Name + "!" + SaleIDRange.Address + ",0))" .Cells(tRow, 5).NumberFormat = "0.0 %" tRow = tRow + 1 Next row ' add summing row .Cells(tRow, 1).Value = ws.Name .Cells(tRow, 1).Font.Bold = True .Cells(tRow, 2).Formula = "=SUM(B" + CStr(tableStartRow) + ":B" + CStr(tRow - 1) + ")" .Cells(tRow, 3).Formula = "=AVERAGE(C" + CStr(tableStartRow) + ":C" + CStr(tRow - 1) + ")" .Cells(tRow, 4).Formula = "=SUM(D" + CStr(tableStartRow) + ":D" + CStr(tRow - 1) + ")" .Cells(tRow, 5).Formula = "=AVERAGE(E" + CStr(tableStartRow) + ":E" + CStr(tRow - 1) + ")" Set tempSumRow = tablesSheet.Range("A" + CStr(tRow) + ":E" + CStr(tRow)) With tempSumRow.Borders(xlEdgeTop) .LineStyle = xlContinuous .Weight = xlThin End With With tempSumRow.Borders(xlEdgeBottom) .LineStyle = xlDouble .Weight = xlThick End With '.Cells( 'create space for new table (this leaves one row of space, increase to 3 or more if you wish) tRow = tRow + 2 End With Next ws tablesSheet.Cells.Font.Name = "Arial" ' change this to your appropriate font DeleteAll tablesSheet.Activate Application.ScreenUpdating = True End Sub Private Function InCollection(col As Collection, sKey As String) As Boolean Dim bTest As Boolean On Error Resume Next bTest = IsObject(col(sKey)) If (Err = 0) Then InCollection = True Else Err.Clear End If End Function Private Sub DeleteAll() Dim i As Integer i = Worksheets.Count For x = i To 3 Step -1 Application.DisplayAlerts = False Worksheets(x).Delete Application.DisplayAlerts = True Next x End Sub 

编辑:

好。 在将数组写入表格表之前,使用数组来存储单元格值。 它做得稍微快一点,57分钟2分22秒15000行。 这是另一种代码。 如果你想使用它,改变button点击调用这个公式。 注意这个代码可能会有点乱,因为我现在需要注销stackExchange。

 Private Sub SortNCopyTables2() Application.ScreenUpdating = False Dim saleIDs() As Variant Dim sellerClass() As Variant Dim bucketClass() As Variant Dim cashFlowSheet As Worksheet Set cashFlowSheet = Worksheets("CashFlow") Dim lastSaleIDRow As Long lastSaleIDRow = cashFlowSheet.Cells.SpecialCells(xlCellTypeLastCell).row saleIDs = cashFlowSheet.Range("A2:A" & lastSaleIDRow).Value sellerClass = cashFlowSheet.Range("B2:B" & lastSaleIDRow).Value bucketClass = cashFlowSheet.Range("C2:C3" & lastSaleIDRow).Value Dim classPairsArray() As Variant Dim classPairs() As String ReDim Preserve classPairs(0) ReDim Preserve classPairsArray(0) Dim size As Long size = 0 Dim saleID As String Dim tempArray() As String For counter = 1 To UBound(saleIDs, 1) sellerBucketString = sellerClass(counter, 1) + " & " + bucketClass(counter, 1) If UBound(Filter(classPairs, sellerBucketString)) < 0 Then ReDim Preserve classPairs(size) classPairs(size) = sellerBucketString ReDim Preserve classPairsArray(size) ReDim Preserve tempArray(0) tempArray(0) = sellerBucketString classPairsArray(size) = tempArray size = size + 1 End If Dim position As Long For i = 0 To UBound(classPairsArray) tempArray = classPairsArray(i) If sellerBucketString = tempArray(0) Then tempArray = classPairsArray(i) ReDim Preserve tempArray(UBound(tempArray) + 1) tempArray(UBound(tempArray)) = saleIDs(counter, 1) classPairsArray(i) = tempArray Exit For End If Next i Next counter 'loop through array and write to worksheet Dim tablesSheet As Worksheet Set tablesSheet = Worksheets("Tables") 'clear the tableSheet, just in case tablesSheet.Rows(10 & ":" & tablesSheet.Rows.Count).Clear Dim SaleIDRange, BalanceRange, MonthlyRange, RateRange As Range 'Change the letters and starting rows as necessary Set SaleIDRange = cashFlowSheet.Range("A2:A" & cashFlowSheet.Cells.SpecialCells(xlCellTypeLastCell).row) Set BalanceRange = cashFlowSheet.Range("D2:D" & cashFlowSheet.Cells.SpecialCells(xlCellTypeLastCell).row) Set MonthlyRange = cashFlowSheet.Range("E2:E" & cashFlowSheet.Cells.SpecialCells(xlCellTypeLastCell).row) ' not used now but assume is used for npv / price calcs Set RateRange = cashFlowSheet.Range("F2:F" & cashFlowSheet.Cells.SpecialCells(xlCellTypeLastCell).row) Dim tRow As Long tRow = 10 ' this is where I start to build my table Dim row As Long Dim tempSumRow As Range For i = 0 To UBound(classPairsArray) Dim tableStartRow As Long tableStartRow = tRow + 1 Dim tableSellerBucketGroup As String Dim tableArray() As String tableArray = classPairsArray(i) With tablesSheet .Cells(tRow, 1).Value = "Sale ID" .Cells(tRow, 1).Font.Underline = xlUnderlineStyleSingleAccounting .Cells(tRow, 2).Value = "NPV" .Cells(tRow, 2).Font.Underline = xlUnderlineStyleSingleAccounting .Cells(tRow, 3).Value = "Price" .Cells(tRow, 3).Font.Underline = xlUnderlineStyleSingleAccounting .Cells(tRow, 4).Value = "Balance" .Cells(tRow, 4).Font.Underline = xlUnderlineStyleSingleAccounting .Cells(tRow, 5).Value = "Rate" .Cells(tRow, 5).Font.Underline = xlUnderlineStyleSingleAccounting tRow = tRow + 1 For j = 1 To UBound(tableArray) .Cells(tRow, 1).Value = tableArray(j) '.Cells(tRow, 2).Value = ??? NPV formula? '.Cells(tRow, 3).Value = ??? price formula? .Cells(tRow, 4).Formula = "=INDEX(" + cashFlowSheet.Name + "!" + BalanceRange.Address + ",MATCH(A" + CStr(tRow) + "," + cashFlowSheet.Name + "!" + SaleIDRange.Address + ",0))" .Cells(tRow, 4).NumberFormat = "$#,##0.00" .Cells(tRow, 5).Formula = "=INDEX(" + cashFlowSheet.Name + "!" + RateRange.Address + ",MATCH(A" + CStr(tRow) + "," + cashFlowSheet.Name + "!" + SaleIDRange.Address + ",0))" .Cells(tRow, 5).NumberFormat = "0.0 %" tRow = tRow + 1 Next j .Cells(tRow, 1).Value = tableArray(0) .Cells(tRow, 1).Font.Bold = True .Cells(tRow, 2).Formula = "=SUM(B" + CStr(tableStartRow) + ":B" + CStr(tRow - 1) + ")" .Cells(tRow, 3).Formula = "=AVERAGE(C" + CStr(tableStartRow) + ":C" + CStr(tRow - 1) + ")" .Cells(tRow, 4).Formula = "=SUM(D" + CStr(tableStartRow) + ":D" + CStr(tRow - 1) + ")" .Cells(tRow, 5).Formula = "=AVERAGE(E" + CStr(tableStartRow) + ":E" + CStr(tRow - 1) + ")" Set tempSumRow = tablesSheet.Range("A" + CStr(tRow) + ":E" + CStr(tRow)) With tempSumRow.Borders(xlEdgeTop) .LineStyle = xlContinuous .Weight = xlThin End With With tempSumRow.Borders(xlEdgeBottom) .LineStyle = xlDouble .Weight = xlThick End With tRow = tRow + 2 End With Next i tablesSheet.Activate Application.ScreenUpdating = True End Sub