返回列表 上一主題 發帖

[發問] 如何提高多條件加總效率 SUMIFS vs SUMPRODUCT vs VBA

[發問] 如何提高多條件加總效率 SUMIFS vs SUMPRODUCT vs VBA

多條件加總效率 SUMIFS最快,SUMPRODUCT 次之
我寫的VBA最慢。
不知道各位大大能否指點一下,是否有辦法提高VBA的效率。

兩個條件的加總 - Sonny.rar (491.08 KB)
ss

回復 2# c_c_lai

=column(a1)=1 to 12 (月)
ss

TOP

回復 6# Hsieh
感謝超版, 字典法妙. 讓我用時間好好消化一下. 有問題再問. Thanks in advance.

這裡真是個長知識的地方。高手如云。
ss

TOP

回復 8# ML089

在另一臺電腦 i3-2120(3.3GHz)+4GRAM, 結果如下
1.301        SUMIFS
3.87        AutoFilter
3.602        VBA CODE
5.023        SUMPRODUCT
0.481        超版Hsieh-字典
10.18        c_c_lai

1.無疑超版的最快
2.SUMIFS次之
3.重點是VBA For Loop 和 SUMPRODUCT、AutoFilter的效率對比 (1樓測試在一臺Netbook上)
好像For Loop 受CPU和RAM的限制較明顯。稍後有時間在把Netbook的測試時間放上來。
4.你的硬體配備如何?各位有時時間提供一下硬體配備和測試時間。看看上面的猜測是否正確。
5. 請問你測試c_c_lai的code是測試多少列的資料(70筆,還是52933筆)
6. xlsb的檔案size明顯比xlsx, xlsm小,速度略略快。 還是會有安全提示。我一般會用xlsb來存檔
ss

TOP

回復 10# ML089

看來CPU的cache對物件的讀取效率有很大影響
ss

TOP

回復 12# stillfish00

Stillfish00大大的確厲害,那個code果然有問題,改了一下(快了很多),請指教
  1. Sub sonny3_v2()
  2.     t1 = Timer
  3.     Dim RowsCnt, m, SubTotalAr() As Double
  4.     Dim DataArea As Variant
  5.     Dim i%, j%
  6.     AllType = Array("A類", "B類", "C類", "D類", "E類", "F類", "G類", "H類", "I類", "J類")
  7.     ReDim SubTotalAr(0 To UBound(AllType), 0 To 11)
  8.     Application.ScreenUpdating = False
  9.     With Sheets("原始資料")
  10.         RowsCnt = .Range("A1").CurrentRegion.Rows.Count
  11.         DataArea = .Range("A2").Resize(RowsCnt - 1, 3)
  12.         For m = 1 To UBound(DataArea)
  13.             i = -1
  14.             Do
  15.                 i = i + 1
  16.             Loop Until DataArea(m, 1) = AllType(i)
  17.             j = -1
  18.             Do
  19.                 j = j + 1
  20.             Loop Until Month(DataArea(m, 2)) = (j + 1)
  21.             SubTotalAr(i, j) = SubTotalAr(i, j) + DataArea(m, 3)
  22.         Next m
  23.     End With
  24.    
  25.     With Sheets("總表")
  26.         .Range("B4").Resize(UBound(AllType) + 1, 12) = SubTotalAr
  27.         .Range("B14:R14").FormulaR1C1 = "=SUM(R[-10]C:R[-1]C)"
  28.         .Range("N4:N13").FormulaR1C1 = "=SUM(RC[-12]:RC[-1])"
  29.         .Range("O4:R13").FormulaR1C1 = "=SUM(RC[-13]:RC[-11])"
  30.     End With
  31.     Application.ScreenUpdating = True
  32.     t2 = Timer
  33.     MsgBox "耗時" & t2 - t1
  34. End Sub
複製代碼
ss

TOP

回復 15# ML089

的確會更快

但是只能用在這種特殊情況, 例如條件二為地區(中部,東北部,南部...)就不適用

p.s. 這�媟Q討論比較通用的條件加總加速法
這�堛爾禤えO參照論壇�堨t一個貼編出來的, 當初沒有考慮到它的特殊性。
ss

TOP

回復  sunnyso
ML089 發表於 2013-6-5 21:38


當然設計程序時充分利用問題的特性絕對是正確的。
ss

TOP

回復 18# ML089
Netbook  N470 (1.83GHz) + 2GRAM 測試結果

4.234375        SUMIFS
21.234375        AutoFilter
26.953125        VBA Code
18.203125        SUMPRODUCT
1.078125        超版Hsieh
1.390625        New VBA Code
ss

TOP

回復 15# ML089

結合ML089的方法,利用原始資料的特性下面的CODE更快
  1. Sub sonny3_v3()
  2.     t1 = Timer
  3.     Dim RowsCnt, m, SubTotalAr() As Double
  4.     Dim DataArea As Variant
  5.     Dim i%, j%
  6.     AllTypeStr = "A類B類C類D類E類F類G類H類I類J類"
  7.     ReDim SubTotalAr(0 To UBound(AllType), 0 To 11)
  8.     Application.ScreenUpdating = False
  9.     With Sheets("原始資料")
  10.         RowsCnt = .Range("A1").CurrentRegion.Rows.Count
  11.         DataArea = .Range("A2").Resize(RowsCnt - 1, 3)
  12.         For m = 1 To UBound(DataArea)
  13.             i = (InStr(AllTypeStr, "D類") + 1) / 2
  14.             j = Month(DataArea(m, 2)) - 1
  15.             SubTotalAr(i, j) = SubTotalAr(i, j) + DataArea(m, 3)
  16.         Next m
  17.     End With
  18.    
  19.     With Sheets("總表")
  20.         .Range("B4").Resize(UBound(AllType) + 1, 12) = SubTotalAr
  21.         .Range("B14:R14").FormulaR1C1 = "=SUM(R[-10]C:R[-1]C)"
  22.         .Range("N4:N13").FormulaR1C1 = "=SUM(RC[-12]:RC[-1])"
  23.         .Range("O4:R13").FormulaR1C1 = "=SUM(RC[-13]:RC[-11])"
  24.     End With
  25.     Application.ScreenUpdating = True
  26.     t2 = Timer
  27.     MsgBox "耗時" & t2 - t1
  28. End Sub
複製代碼
ss

TOP

        靜思自在 : 脾氣嘴巴不好,心地再好也不能算是好人。
返回列表 上一主題