VBA字典具有最核心的两个优势:
-
字典的键(Key)具有唯一性,尝试添加重复键时会报错或覆盖,借此可高效实现数据去重
-
字典操作在内存中进行,避免了频繁读写单元格,极大减少了与Excel交互的开销,从而显著提速
为了让大家更深入地理解VBA字典的强大功能,并将其有效应用于工作中,接下来就从字典取值唯一和提速两方面展示字典的应用案例

案例需求与实现效果
如下图所示罗列的是“每周之星”的评选结果,B列和C列分别对应员工的姓名和当周的考核成绩,现要求在E列至G列中显示去重后的每周之星姓名、被评选次数和平均成绩

自动化实现后的效果如下图:

在Excel中处理这类数据时,VBA字典对象是高效解决重复数据统计的利器。通过键值对存储模式,它能自动去重并累加相关数值,完美适用于统计每位明日之星的评选次数和平均成绩
建议大家根据自己的逻辑来独立编码实现,然后再与参考代码进行比较,可以快速提升编码能力

参考代码
以下代码与传统创建字典的步骤不同,全程虽然没有使用add及Exists等方法,但却实实在在地创建了两个字典,这也能充分体现VBA代码的灵活性,建议结合单步调试进行理解
Sub 去重计数与求平均()Dim i As Integer, Dicl As Object, Dic2 As Object, NameArr(), CountArr()On Error Resume NextSet Dicl = CreateObject("scripting.dictionary")Set Dic2 = CreateObject("scripting.dictionary")For i = 2 To Cells(Rows.Count, 2).End(xlUp).RowDicl.Item(CStr(Cells(i, 2))) = Dicl.Item(CStr(Cells(i, 2))) + 1Dic2.Item(CStr(Cells(i, 2))) = Dic2.Item(CStr(Cells(i, 2))) + Cells(i, 3).ValueNextNameArr = Dicl.KeysCountArr = Dicl.ItemsFor i = 0 To UBound(CountArr)Dic2.Item(NameArr(i)) = Dic2.Item(NameArr(i)) / CountArr(i)Next iRange("E1:G1") = Array("每周之星", "评选次数", "平均成绩")Range("E2").Resize(Dicl.Count, 1) = WorksheetFunction.Transpose(NameArr)Range("F2").Resize(Dicl.Count, 1) = WorksheetFunction.Transpose(CountArr)Range("G2").Resize(Dic2.Count, 1) = WorksheetFunction.Transpose(Dic2.Items)Range("E1").CurrentRegion.Borders.LineStyle = 1End Sub
关键代码解析:
第7、8行代码利用了字典的键不能重复的特性来实现:当读取到“赵鑫”(也就是“键”)时,如果“键”不存在,会先自动创建一个“键”并将其值初始化为0;后续无论这个“键”出现多少次,Dicl和Dic2中都只有一个“赵鑫”键。每次遇到,计数器加1,成绩则累加,从而简化了代码。执行完循环后两个字典对象中存储内容分别是:
-
Dicl:存储了每个不重复的员工姓名及其评选次数
-
Dic2:存储了每位员工对应的总成绩
虽然以上代码实现了基本功能,但还是有优化的空间,比如适当增加一些错误处理,让代码更健壮;增加一些与用户的交互界面方便使用;还可以考虑性能提升(如数据量非常大时,先将数据一次性读入数组进行循环处理,而不是反复读取单元格,这会显著提高运行速度)
因此代码并不是一蹴而就的,平时我们可以先写出主要实现的功能,再慢慢优化

结束语
今天的分享到此结束了,咱么下期继续
公众号同时也在不间断地分享免费的编程案例,如果想学习更多的编程知识,无论是用来提升自动化办公效率还是想提升自我,都可以关注我的公众号“努力鸭是黑色的”,解锁更多的VBA技能
816

被折叠的 条评论
为什么被折叠?



