Public Sub CustomSubTotal() AppSettings On Error GoTo ErrHandler Dim StartTime, UsedTime As Variant StartTime = VBA.Timer 'Input code here Dim i As Long, j As Long, k Dim Wb As Workbook Dim Sht As Worksheet Dim oSht As Worksheet Dim Dic As Object Dim Arr As Variant Dim Rng As Range Set Dic = CreateObject("Scripting.Dictionary") Dim SendDate$, Client$, Cargo$, Style$, Num# Set Wb = Application.ThisWorkbook Set Sht = Wb.Worksheets("数据表") Set oSht = Wb.Worksheets("统计表") With Sht endrow = .Cells.Find("*", .Cells(1, 1), xlValues, xlWhole, xlByRows, xlPrevious).Row Set Rng = .Range("A2:Z" & endrow) Arr = Rng.Value For i = LBound(Arr) To UBound(Arr) SendDate = Format(CStr(Arr(i, 2)), "yyyy年mm月") 'Debug.Print mydate Client = Arr(i, 4) If Client = "" Then Client = "空" Cargo = Arr(i, 5) If Cargo = "" Then Cargo = "空" Num = Arr(i, 10) If InStr(1, Arr(i, 8), ",") > 0 Then Style = Split(Arr(i, 8), ",")(0) Else Style = Arr(i, 8) End If 'Debug.Print Style Key = SendDate & ";" & Client & ";" & Cargo & ";" & Style Dic(Key) = Dic(Key) + Num Next i End With With oSht .Cells.Clear .Range("A1:E1").Value = Array("月份", "客户", "货品", "花色", "数量") Arr = SubTotalDicToArr(Dic, ";") .Range("A2").Resize(UBound(Arr), UBound(Arr, 2)).Value = Arr CustomSort .Range("A1").CurrentRegion SetEdges .Range("A1").CurrentRegion End With UsedTime = VBA.Timer - StartTime Debug.Print "UsedTime:" & Format(UsedTime, "0.000 Seconds") ErrorExit: AppSettings False Set Wb = Nothing Set Sht = Nothing Set oSht = Nothing Set Rng = Nothing Set Dic = Nothing Exit Sub ErrHandler: If Err.Number <> 0 Then MsgBox Err.Description & "!", vbCritical, "NextSeven QQ 84857038" Debug.Print Err.Description Err.Clear Resume ErrorExit End If End Sub Public Sub AppSettings(Optional IsStart As Boolean = True) If IsStart Then Application.ScreenUpdating = False Application.DisplayAlerts = False Application.Calculation = xlCalculationManual Application.StatusBar = ">>>>>>>>Macro Is Running>>>>>>>>" Else Application.ScreenUpdating = True Application.DisplayAlerts = True Application.Calculation = xlCalculationAutomatic Application.StatusBar = False End If End Sub Public Function SubTotalDicToArr(ByVal Dic As Object, ByVal Separator As String) As Variant() Dim Arr(), OneKey, Key$, Item$, iRow&, iCol& Dim Keys, Items, m&, n&, KeyCount&, ItemCount& iCol = 0 For Each OneKey In Dic.Keys iCol = UBound(Split(OneKey, Separator)) + 1 iCol = iCol + UBound(Split(Dic(OneKey), Separator)) + 1 Exit For Next OneKey iRow = Dic.Count ReDim Arr(1 To iRow, 1 To iCol) m = 0 For Each OneKey In Dic.Keys m = m + 1 Keys = Split(OneKey, Separator) KeyCount = UBound(Keys) + 1 For n = 1 To KeyCount Arr(m, n) = Keys(n - 1) Next n Items = Split(Dic(OneKey), Separator) ItemCount = UBound(Items) + 1 For n = 1 To ItemCount Arr(m, KeyCount + n) = Items(n - 1) Next n Next OneKey SubTotalDicToArr = Arr End Function Private Sub SetEdges(ByVal Rng As Range) With Rng .HorizontalAlignment = xlCenter With .Borders(xlEdgeLeft) .LineStyle = xlContinuous .Weight = xlThin .ColorIndex = xlAutomatic End With With .Borders(xlEdgeTop) .LineStyle = xlContinuous .Weight = xlThin .ColorIndex = xlAutomatic End With With .Borders(xlEdgeBottom) .LineStyle = xlContinuous .Weight = xlThin .ColorIndex = xlAutomatic End With With .Borders(xlEdgeRight) .LineStyle = xlContinuous .Weight = xlThin .ColorIndex = xlAutomatic End With If .Cells.Count > 1 Then With .Borders(xlInsideVertical) .LineStyle = xlContinuous .Weight = xlThin .ColorIndex = xlAutomatic End With With .Borders(xlInsideHorizontal) .LineStyle = xlContinuous .Weight = xlThin .ColorIndex = xlAutomatic End With End If End With End Sub Sub CustomSort(ByVal RngWithTitle As Range) With RngWithTitle .Sort Key1:=RngWithTitle.Cells(1, 1), Order1:=xlAscending, _ Key2:=RngWithTitle.Cells(1, 2), Order2:=xlAscending, Header:=xlYes, _ MatchCase:=False, Orientation:=xlTopToBottom, SortMethod:=xlPinYin End With End Sub