How to perform SumIf using VBA on an array in Excel

后端 未结 3 547
一向
一向 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条回答
  •  慢半拍i
    慢半拍i (楼主)
    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
    

提交回复
热议问题