Excel中多条件求和VBA代码两种写法的比较

前两天在解决一位学员的问题时遇到的一个情况:

这是数据源,有50万行。

这是一个查询界面,在J3、K3单元格中可以通过下拉菜单来选择月和日,希望在左边G列能自动计算出日期、部门、产品、渠道对应的销售额。以上是一个模板中对应的一部分任务,整个模板中各个功能的实现都是通过VBA代码控制的,所以此任务也希望用VBA代码来解决。这个问题本身并不难,甚至可以说是比较简单,基本上大家都会想到两种思路。一种是利用工作表函数Sumifs解决,一种是利用字典解决,代码如下:

一、利用工作表函数Sumifs

Sub test1()

Dim t!, sht1 As Worksheet, sht2 As Worksheet, lastrow1&, lastrow2&, arr, brr(), y%, m%, d%, wsf As Object

t = Timer

Set sht1 = Sheets("DATA")

Set sht2 = Sheets("查询")

lastrow1 = sht1.UsedRange.Rows.Count

lastrow2 = sht2.UsedRange.Rows.Count

arr = sht2.Range("d2:g" & lastrow2)

ReDim brr(1 To UBound(arr), 1 To 1)

With sht2

y = .[i3]

m = .[j3]

d = .[k3]

End With

Set wsf = Application.WorksheetFunction

For i = 1 To UBound(arr)

With sht1

brr(i, 1) = wsf.SumIfs(.Range("h2:h" & lastrow1), _

.Range("b2:b" & lastrow1), y, _

.Range("c2:c" & lastrow1), m, _

.Range("d2:d" & lastrow1), d, _

.Range("e2:e" & lastrow1), arr(i, 1), _

.Range("f2:f" & lastrow1), arr(i, 2), _

.Range("g2:g" & lastrow1), arr(i, 3))

End With

Next

sht2.[g2].Resize(UBound(arr), 1) = brr

MsgBox Timer - t

End Sub

二、利用字典

Sub test2()

Dim t!, sht1 As Worksheet, sht2 As Worksheet, lastrow1&, lastrow2&, arr, brr(), y%, m%, d%, dic As Object

t = Timer

Set sht1 = Sheets("DATA")

Set sht2 = Sheets("查询")

lastrow1 = sht1.UsedRange.Rows.Count

lastrow2 = sht2.UsedRange.Rows.Count

arr = sht1.Range("a2:h" & lastrow1)

Set dic = CreateObject("scripting.dictionary")

For i = 1 To UBound(arr)

mystr = arr(i, 2) & arr(i, 3) & arr(i, 4) & arr(i, 5) & arr(i, 6) & arr(i, 7)

If dic.exists(mystr) Then

dic(mystr) = dic(mystr) + arr(i, 8)

Else

dic(mystr) = arr(i, 8)

End If

Next

arr = sht2.Range("d2:g" & lastrow2)

ReDim brr(1 To UBound(arr), 1 To 1)

With sht2

y = .[i3]

m = .[j3]

d = .[k3]

End With

For i = 1 To UBound(arr)

mystr = y & m & d & arr(i, 1) & arr(i, 2) & arr(i, 3)

If dic.exists(mystr) Then

brr(i, 1) = dic(mystr)

Else

brr(i, 1) = 0

End If

Next

sht2.[g2].Resize(UBound(arr), 1) = brr

MsgBox Timer - t

End Sub

以上两种方法在计算速度方面有什么区别呢?刚开始时,我要进行计算的数据行数只有50行,两种方法在计算速度上并没有太大区别,甚至用Sumifs公式还要更快那么一点点,但是当我把要计算的行数扩展到250行后,两种方法的计算速度有了明显的区别。

测试,第二种方法要比第一种方法在速度上快4倍多,如果需要计算的数据更多的话,估计计算速度的差别更大。
(职场责编:拓荒牛 )