How to perform SumIf using VBA on an array in Excel

后端 未结 3 530
一向
一向 2020-12-10 00:19

I\'m trying to come up with the fastest way to perform a SumIf function in Excel on a dataset that has approx. 110\'000 lines. I\'ve come up with three ways, but none of the

相关标签:
3条回答
  • 2020-12-10 00:33

    My version was inspired by kevin999's solution.

    ++ works with unsorted sumif criteria
    ++ will bring the rows back to the original order

    -- doesn't support multiple criteria columns

    Please note: The columns containing the criteria and the data to sum up must be one next to another.

    Option Explicit
    
    Sub Execute()
    Call FasterThanSumifs(1)
    End Sub
    
    Private Sub FasterThanSumifs(Criteria As Long)
    'Expects two coloumns next to each other:
    'SumIf criteria (left side)
    'SumIf data range (right side)
    
    Dim SumRange, DataNumber, HelpColumn, SumifColumn, LastRow As Long
    SumRange = Criteria + 1
    DataNumber = Criteria + 2
    HelpColumn = Criteria + 3
    SumifColumn = Criteria + 4
    LastRow = UF_LetzteZeile()
    
    Columns(DataNumber).Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
    Columns(HelpColumn).Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
    Columns(SumifColumn).Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
    
    'Remember data order
    Cells(2, DataNumber).Value = 1
    Cells(2, DataNumber).AutoFill Destination:=Range(Cells(2, DataNumber), Cells(LastRow, DataNumber)), Type:=xlFillSeries
    
    'Sort the range of returned values to place the largest values above the lower ones
    Range(Cells(1, Criteria), Cells(LastRow, SumifColumn)).Sort Key1:=Columns(Criteria), Order1:=xlAscending, Header:=xlYes
    ActiveSheet.Sort.SortFields.Clear
    
    'If formula sums the range-to-sum where the values are the same
    With Range(Cells(2, HelpColumn), Cells(LastRow, HelpColumn))
        .FormulaR1C1 = "=IF(RC[-3]=R[-1]C[-3], RC[-2] + R[-1]C,RC[-2])"
        '.Value = .Value
    End With
    
    'If formula returns the maximum value for each concatenated value match &
    'is therefore the equivalent of using a Sumifs formula
    With Range(Cells(2, SumifColumn), Cells(LastRow, SumifColumn))
        .FormulaR1C1 = "=IF(RC[-4]=R[+1]C[-4], R[+1]C, RC[-1])"
        .Value = .Value
    End With
    
    Columns(HelpColumn).Delete
    
    'Sort the range in the original order
    Range(Cells(1, Criteria), Cells(LastRow, SumifColumn)).Sort Key1:=Columns(DataNumber), Order1:=xlAscending, Header:=xlYes
    ActiveSheet.Sort.SortFields.Clear
    
    Columns(DataNumber).Delete
    
    End Sub
    
    0 讨论(0)
  • 2020-12-10 00:51

    Give this a whirl

    Sub test()
        StartTimer = Now()
        With ActiveSheet.Range("D2:D6285")
            .FormulaR1C1 = "=SUMIF(Tabelle1[KUNDENBESTELLNR],Test!RC[-3],Tabelle1[ANZAHL NACHFRAGE])"
            .Value = .Value
        End With
        EndTimer = Now()
        MsgBox (DateDiff("s", StartTimer, EndTimer))
    End Sub
    
    0 讨论(0)
  • 2020-12-10 00:57

    I’d been searching for a faster method for calculating Sumifs for some time when I came up with the following solution. Instead of using Sumifs, you concatenate the values used in the criteria ranges as a single value, then using simple If formulas – combined with one range Sort – you achieve the same results as if you’d used Sumifs.

    In my own case, using Sumifs with 25K rows and 2 criteria ranges to evaluate was taking 18.4 seconds on average – using the If and Sort method, it was taking 0.67 seconds on average.

     Sub FasterThanSumifs()
        'FasterThanSumifs Concatenates the criteria values from columns A and B -
        'then uses simple IF formulas (plus 1 sort) to get the same result as a sumifs formula
    
        'Columns A & B contain the criteria ranges, column C is the range to sum
        'NOTE: The data is already sorted on columns A AND B
    
        'Concatenate the 2 values as 1 - can be used to concatenate any number of values
        With Range("D2:D25001")
            .FormulaR1C1 = "=RC[-3]&RC[-2]"
            .Value = .Value
        End With
    
        'If formula sums the range-to-sum where the values are the same
        With Range("E2:E25001")
            .FormulaR1C1 = "=IF(RC[-1]=R[-1]C[-1],RC[-2]+R[-1]C,RC[-2])"
            .Value = .Value
        End With
    
        'Sort the range of returned values to place the largest values above the lower ones
        Range("A1:E25001").Sort Key1:=Range("D1"), Order1:=xlAscending, _
        Key2:=Range("E1"), Order2:=xlDescending, Header:=xlYes
        Sheet1.Sort.SortFields.Clear
    
        'If formula returns the maximum value for each concatenated value match &
        'is therefore the equivalent of using a Sumifs formula
        With Range("F2:F25001")
            .FormulaR1C1 = "=IF(RC[-2]=R[-1]C[-2],R[-1]C,RC[-1])"
            .Value = .Value
        End With
    
        End Sub
    
    0 讨论(0)
提交回复
热议问题