How to perform SumIf using VBA on an array in Excel

后端 未结 3 542
一向
一向 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: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
    

提交回复
热议问题