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 them are satisfying.
Here the first one I tried: Execution time on my PC 100 seconds!
Sub Test1_WorksheetFunction()
Dim MaxRow As Long, MaxCol As Long
Dim i As Long
Dim StartTimer, EndTimer, UsedTime
StartTimer = Now()
With wsTest
MaxRow = .UsedRange.Rows.Count
MaxCol = .UsedRange.Columns.Count
For i = 2 To MaxRow
.Cells(i, 4) = WorksheetFunction.SumIf(wsData.Range("G2:G108840"), .Cells(i, 1), wsData.Range("R2:R108840"))
Next i
End With
EndTimer = Now()
MsgBox (DateDiff("s", StartTimer, EndTimer))
End Sub
Here is the second Method: Execution Time a bit better at 55 seconds
Sub Test2_Formula_and_Copy()
Dim MaxRow As Long, MaxCol As Long
Dim i As Long
Dim StartTimer, EndTimer, UsedTime
StartTimer = Now()
With wsTest
MaxRow = .UsedRange.Rows.Count
MaxCol = .UsedRange.Columns.Count
Range("D2").Select
ActiveCell.FormulaR1C1 = _
"=SUMIF(Tabelle1[KUNDENBESTELLNR],Test!RC[-3],Tabelle1[ANZAHL NACHFRAGE])"
Range("D2").Select
Selection.AutoFill Destination:=Range("D2:D6285")
Range("D2:D6285").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End With
EndTimer = Now()
MsgBox (DateDiff("s", StartTimer, EndTimer))
End Sub
Third attempt: Execution so slow it never finished.
Sub Test3_Read_in_Array()
Dim MaxRow As Long, MaxCol As Long
Dim SearchRange() As String, SumRange() As Long
Dim i As Long, j As Long, k
Dim StartTimer, EndTimer, UsedTime
Dim TempValue
StartTimer = Now()
With wsData
MaxRow = .UsedRange.Rows.Count
ReDim SearchRange(1 To MaxRow)
ReDim SumRange(1 To MaxRow)
For i = 1 To MaxRow
SearchRange(i) = .Range("G" & (1 + i)).Value
SumRange(i) = .Range("R" & (1 + i)).Value
Next i
End With
With wsTest
MaxRow = .UsedRange.Rows.Count
For i = 2 To MaxRow
For j = LBound(SearchRange) To UBound(SearchRange)
k = .Cells(i, 1).Value
If k = SearchRange(j) Then
TempValue = TempValue + SumRange(j)
End If
Next j
.Cells(i, 4) = TempValue
Next i
End With
EndTimer = Now()
MsgBox (DateDiff("s", StartTimer, EndTimer))
End Sub
Clearly I have not yet mastered VBA (or any other programming language for that matter). Can someone help me in getting this to be efficient? There must be a way! Right?
Thanks!
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.
Give this a whirl
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.