Страницы: 1
RSS
Суммарные итоги по нескольким столбцам
 
Добрый день, помогите построить макрос для расчета суммарных значений по столбцу сумма для каждого магазина и региона с учетом месяца. В файле на листе задача - исходный файл, на листе результат - то, что должно быть на выходе
 
Добрый день! Может Вам будет достаточно Сводной таблицы
Изменено: msi2102 - 30.07.2021 14:02:45
 
недостаточно, к сожалению, нужно для передачи руководству в таком виде как результат. Пример приведен небольшой, а таблицы на самом деле большие, бывает до нескольких тысяч строк.
 
Код
Option Explicit

Sub Sverdlovsk()
    Application.ScreenUpdating = False
    Application.EnableEvents = False
    Dim Application_Calculation As Long
    Application_Calculation = Application.Calculation
    Application.Calculation = xlCalculationManual
    
    Dim arr As Variant
    Dim y As Long
    With ActiveSheet
        y = .Cells(.Rows.Count, 1).End(xlUp).Row
        arr = .Range(.Cells(1, 1), .Cells(y, 4))
    End With
        
    SortArr arr
    
    Dim dic As Object
    Set dic = GetDic(arr)
    Erase arr
    
    arr = DicToArr(dic)
    
    OutArr arr
    
    Application.ScreenUpdating = True
    Application.EnableEvents = True
    Application.Calculation = Application_Calculation
End Sub

Sub OutArr(arr As Variant)
    Dim wb As Workbook
    Set wb = Workbooks.Add(1)
    Dim sh As Worksheet
    Set sh = wb.Sheets(1)
    Dim r As Range
    Set r = sh.Cells(1, 1).Resize(UBound(arr, 1), UBound(arr, 2))
    r = arr
    
    r.ColumnWidth = 30
    
    wb.Saved = True
End Sub

Function DicToArr(dic As Object) As Variant
    Dim arr As Variant
    Dim y As Long
    Dim v1 As Variant
    Dim v2 As Variant
    Dim v3 As Variant
    Dim v4 As Variant
    
    Dim s3 As Double
    Dim dic1 As Object
    Dim dic3 As Object
    
    Dim i As Byte
    For i = 0 To 1
        Set dic1 = CreateObject("Scripting.Dictionary") 'Сумма всех регионов ключ месяц
        For Each v1 In dic.Keys
            For Each v2 In dic.Item(v1).Keys
                Set dic3 = CreateObject("Scripting.Dictionary") 'Сумма одного магазина ключ месяц
                For Each v3 In dic.Item(v1).Item(v2).Keys
                    For Each v4 In dic.Item(v1).Item(v2).Item(v3).Items
                        Select Case i
                        Case 0
                            y = y + 1
                        Case 1
                            y = y + 1
                            arr(y, 1) = v1
                            arr(y, 2) = v2
                            arr(y, 3) = v3
                            arr(y, 4) = v4
                            
                            dic3(v3) = dic3(v3) + v4
                        End Select
                    Next
                Next
            
                'Магазин Итог месяц
                s3 = 0
                For Each v3 In dic3.Keys
                    Select Case i
                    Case 0
                        y = y + 1
                    Case 1
                        y = y + 1
                        arr(y, 1) = v1
                        arr(y, 2) = "Итог " & v2
                        arr(y, 3) = v3
                        arr(y, 4) = dic3.Item(v3)
                        s3 = s3 + arr(y, 4)
                    End Select
                Next
            
                'Магазин все месяцы
                Select Case i
                Case 0
                    y = y + 1
                Case 1
                    y = y + 1
                    arr(y, 1) = v1
                    arr(y, 2) = "Итог " & v2
                    arr(y, 3) = Join(dic3.Keys(), "+")
                    arr(y, 4) = s3
                End Select
            
            
            Next
            
            
            Set dic3 = CreateObject("Scripting.Dictionary") 'Сумма одного региона ключ месяц
            For Each v2 In dic.Item(v1).Keys
                For Each v3 In dic.Item(v1).Item(v2).Keys
                    For Each v4 In dic.Item(v1).Item(v2).Item(v3).Items
                        dic3(v3) = dic3(v3) + v4
                        dic1(v3) = dic1(v3) + v4
                    Next
                Next
            Next
            
            'Регион Итог месяц
            s3 = 0
            For Each v3 In dic3.Keys
                Select Case i
                Case 0
                    y = y + 1
                Case 1
                    y = y + 1
                    arr(y, 1) = "Итог " & v1
                    'arr(y, 2) = v2
                    arr(y, 3) = v3
                    arr(y, 4) = dic3.Item(v3)
                    s3 = s3 + arr(y, 4)
                End Select
            Next
        
            'Регион все месяцы
            Select Case i
            Case 0
                y = y + 1
            Case 1
                y = y + 1
                arr(y, 1) = "Итог " & v1
                arr(y, 2) = v2
                arr(y, 3) = Join(dic3.Keys(), "+")
                arr(y, 4) = s3
            End Select
            
        Next
        
        '--------------------------------------------
                    'Регион Итог месяц
            s3 = 0
            For Each v3 In dic1.Keys
                Select Case i
                Case 0
                    y = y + 1
                Case 1
                    y = y + 1
                    arr(y, 1) = "Итог "
                    'arr(y, 2) = v2
                    arr(y, 3) = v3
                    arr(y, 4) = dic1.Item(v3)
                    s3 = s3 + arr(y, 4)
                End Select
            Next
        
            'Регион все месяцы
            Select Case i
            Case 0
                y = y + 1
            Case 1
                y = y + 1
                arr(y, 1) = "Итог "
                'arr(y, 2) = v2
                arr(y, 3) = Join(dic1.Keys(), "+")
                arr(y, 4) = s3
            End Select
        '--------------------------------------------------
        
        
        Select Case i
        Case 0
            ReDim arr(1 To 2 * y, 1 To 4)
            y = 0
        Case 1
        End Select
    Next
    
    DicToArr = arr
End Function

Function GetDic(arr As Variant) As Object
    Dim dic As Object
    Set dic = CreateObject("Scripting.Dictionary")
    
    Dim di2 As Object
    
    Dim y As Long
    For y = 2 To UBound(arr, 1)
        If Not dic.Exists(arr(y, 1)) Then Set dic.Item(arr(y, 1)) = CreateObject("Scripting.Dictionary")
        If Not dic.Item(arr(y, 1)).Exists(arr(y, 2)) Then Set dic.Item(arr(y, 1)).Item(arr(y, 2)) = CreateObject("Scripting.Dictionary")
        If Not dic.Item(arr(y, 1)).Item(arr(y, 2)).Exists(arr(y, 3)) Then Set dic.Item(arr(y, 1)).Item(arr(y, 2)).Item(arr(y, 3)) = CreateObject("Scripting.Dictionary")
        Set di2 = dic.Item(arr(y, 1)).Item(arr(y, 2)).Item(arr(y, 3))
        di2.Item(di2.Count) = arr(y, 4)
    Next

    Set GetDic = dic
End Function

Sub SortArr(ByRef arr As Variant)
    Dim wb As Workbook
    Set wb = Workbooks.Add(1)
    Dim sh As Worksheet
    Set sh = wb.Sheets(1)
    Dim r As Range
    Set r = sh.Cells(1, 1).Resize(UBound(arr, 1), UBound(arr, 2))
    r = arr
    With sh.Sort
        .SortFields.Clear
        .SortFields.Add Key:=r.Columns(1), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        .SortFields.Add Key:=r.Columns(2), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        .SortFields.Add Key:=r.Columns(3), SortOn:=xlSortOnValues, Order:=xlAscending, CustomOrder:= _
        "Январь,Февраль,Март,Апрель,Май,Июнь,Июль,Август,Сентябрь,Октябрь,Ноябрь,Декабрь" _
        , DataOption:=xlSortNormal
        .SetRange r
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
    arr = r
    wb.Close False
End Sub
 
Благодарю! Вы очень помогли
Страницы: 1
Наверх