序言
VBA的基础数据类型里面并没有字典类型,但字典其实在很多应用场景中都很有用,那么如何在VBA中使用字典,本文就用几个例子和大家交流探讨一下。
场景1
某个医院每天都会从不同的制造商那里进三种材料中的一种,每天的进价都有可能不同,现在公司积累了半年的数据,想做个分析。数据的样式如下:
现在的要求是做半年度的分析,分析一下三个材料从半年来看哪个制造商的进价最低。那么有聪明的小伙伴就说了,可以用透视表。确实,第一反应就应该是用透视表,因为需求很简单就要看谁最便宜。但如果是在实际的工作中,领导可能还会要求你做几张图,分析一下各个制造商的报价趋势;亦或者要求算一下制造商报价的差异度,预测下个月各个制造商的报价等等。最终还要求把上面说的这个分析都放到一张表里面,形成一张汇总分析表。那么这个时候就不是生成透视表能解决了的。如果每次都要手工处理会很麻烦,那么我们就可以用VBA来做一张模板。而做模板我们首先会碰到的一个问题就是,制造商到底有几个不确定,保不齐哪天就蹦出一个新的制造商来。所以第一步我们就要建了一个制造商的列表。有几个方法,一个是复制C列到其他对方,使用删除重复项;或者嵌套循环;还有就是今天要说的字典。创建字典的语句很简单:
Dim zzs_dict
Set zzs_dict = CreateObject("Scripting.Dictionary")
创建完成后我们需要把C列的值添加进字典,因为字典的自带的exists方法,我们就可以筛选出唯一的制造商了。完整的代码如下:
Sub test()
'''zzs就是最终的我们需要的唯一的制造商的数组
Dim zzs() As String
'''zzs_dict是制造商的字典,因为字典不是VBA的基本数据类型,我们选择将结果存放在zzs数组中
Dim zzs_dict
Set zzs_dict = CreateObject("Scripting.Dictionary")
Dim max_row As Byte
With ThisWorkbook.Worksheets("Sheet13")
max_row = .Cells(Rows.Count, "a").End(xlUp).Row
For i = 2 To max_row
tem_da = .Cells(i, "c")
If Not zzs_dict.exists(tem_da) Then
zzs_dict.Add tem_da, Null
ReDim Preserve zzs(0 To counter)
zzs(counter) = tem_da
counter = counter + 1
End If
Next i
End With
End Sub
在这个例子里面,我们重点使用的是字典的exists的方法,主要是避免了多层嵌套循环;字典还有一个key:value的对应,我们没有用到。那么我们再考虑接下来的一个场景
场景2
假设有一个公司员工的绩效和员工本身的职级挂钩,每个职级有不同的系数,那计算各个员工的绩效的时候我们就可以将职级和对应的系数放到字典中,方便计算和后期的维护。数据如下:
细心的小伙伴就会发现说,你这绩效明明已经用公式,用VLOOKUP,算出来了,为啥还要用VBA呢?这不是脱裤子放屁么。不可否认在这个例子里面是用公式最简单,但这只是例子而已,实际工作中情况要复杂的多,我们就不多说了,看看用VBA怎么来计算这几个员工的绩效。代码如下:
Sub test()
Dim zc_dict
Set zc_dict = CreateObject("Scripting.Dictionary")
With ThisWorkbook.Worksheets("22年1月")
'''多个表的话用for each worksheet in ThisWorkbook.Worksheets
With .Cells.Find("参数区域").CurrentRegion
zc_dict.Add "初", .Cells.Find("初").Offset(0, 1)
zc_dict.Add "中", .Cells.Find("中").Offset(0, 1)
zc_dict.Add "高", .Cells.Find("高").Offset(0, 1)
End With
With .Cells.Find("计算区域").CurrentRegion
'''省略计算过程
End With
End With
End Sub
具体的计算工程就省略了,因为楼主很懒,写PYTHON语句习惯了,写VB每一句都是煎熬。。。
结语
总的来说字典在VBA中是一个很有用的数据类型,楼主自己在工作中经常会用到。当然在EXCEL里面要实现某个目标有很多的方法,大家平时多思考吧,能写公式就写公式,能用透视就直接透视。