VBA调用外部对象01:字典Dictionary
当你发现不停的用For循环来处理数据速度慢的受不了了,你肯定会想怎么才能提高一些效率。比如前面我们说到的对比2个表数据,我们是使用For循环去逐个的对比判断,如果能有1个东西让我们可以快速的在一组数据里找到需要的、或者是找不到的时候返回false的话,那我们就不需要用For循环了,那有没有这种东西呢?
是的,今天要说到的字典就是这么一个东西,作为1个新手,可能你只需要知道它有快速找到某个数据的功能就可以了。如果你还有兴趣深入了解,那就需要去学习数据结构和算法方面的东西了,字典就是一种Hash算法实现的东西。
1、COM对象
字典就是Windows系统做好了的一个东西,是一种叫做COM对象的东西,在VBA中如果要使用的话,有2种方法:
- 前期绑定:
在VBA编辑器里点击工具-引用,找到需要使用的项目勾选
- 后期绑定:
使用VBA的CreateObject函数,这种情况下要知道COM对象的名称。
VBA.CreateObject("XXXXX")
这样就可以在VBA里使用该对象了,2种方法有一点小的差异,主要是:
- 前期绑定的方法使用对象时就像是使用VBA内部对象一样了,但是一旦你把做好的程序发给别人使用,使用者也必须要 手动先添加引用 。
- 后期绑定不需要手动添加引用,但是使用过程中不大方便,不能直接声明对象的名称,要 用Object代替 ,写代码也不会像VBA内部对象那样自动列出属性和方法。
作为VBA的使用者,知道这样使用COM就可以了。
2、字典Dictionary
字典就是一种COM对象,前期绑定使用方法,找到Microsoft Scripting Runtime,勾选后确定,然后我们就可以使用字典了:
Sub TestDic()
Dim d As Dictionary
Set d = New Dictionary
Set d = Nothing
End Sub
那我们如何能知道COM对象有些什么方法呢?还记得F2打开的对象浏览器吧,一旦我们引用了这个COM对象,在对象浏览器里我们就可以查看它了。
我们可以看到,其实这个库里面不止字典一个对象,还有些其他的,我们这次只看字典,可以看到他的方法有6个(绿色图标),属性有4个(灰色图标,蓝色那个是特殊的缺省属性,就像Range的Value属性,意思就是不写属性名的时候,默认就是它),总共10个东西,看起来还是挺简单的。
字典的方法、属性简单介绍:
- 我们前面说了,字典最大的功能就是能够快速的查找到需要的东西,从里面的名称你应该能猜到, Exists 就是判断某个东西是否存在于字典里面。
- 而在判断是否存在之前,显然,我们需要先把数据装进去,很明显 Add 就是把数据装进去的方法。
- 有添加自然也就会有删除, Remove 就是删除某个数据,而 RemoveAll 显然就删除全部了,相当于把字典初始化了。
- Count: 很好理解,字典里存在多少个数据。
- CompareMode: 是设置文本的对比方式的,主要就是是否区分大小写。
- Key、Keys: 我们可以这样理解,字典,它真的很像我们使用的字典,比如汉字的新华字典,它的功能也是让我们快速查到需要的字,汉字的新华字典有一个可能我们没有在意过的特点,字在字典里是唯一的(多音字那些也是不同的字),也就是我们这个COM字典的重要特点, Key是唯一 的,Add添加的就是这个Key,字典内部是不会有重复的Key的。Keys显然就是字典里的所有Key的集合,也就是一个数组了。
-
Item、Imtes
:汉字的新华字典每一个字,都对应了一种对这个字的解释说明,这个解释说明显然是
可能重复
的。字典在添加Key的时候,同时也要指定这个Key所对应的Item。Items也就是Item的集合。
Sub TestDic() Dim d As Dictionary Set d = New Dictionary Dim arrA() As Variant Dim arrC() As Variant Dim rowA As Long Dim rowC As Long Dim i As Long, j As Long '获取A列和C列的最后一行行号 rowA = Cells(Cells.Rows.Count, 1).End(xlUp).Row rowC = Cells(Cells.Rows.Count, 3).End(xlUp).Row '将A列和C列的数据存放到数组中 arrA = Range("A1").Resize(rowA, 1).Value arrC = Range("C1").Resize(rowC, 1).Value '将A列数据记录到字典中 For i = 2 To rowA d.Add arrA(i, 1), i '声明存储结果的数组 Dim result() As Variant '数组使用一定要明确定义大小,结果数组肯定不会超过C列的数据数量 ReDim result(1 To rowC, 1 To 1) As Variant '记录标题 result(1, 1) = arrC(1, 1) '记录结果数据的个数 Dim resultCount As Long resultCount = 1 '标题占用1个 '用循环找出列C中不在列A中出现的数据 '数据是从第2行开始的 For i = 2 To rowC '判断C列的数据在字典中是否出现了 '存在的情况Exists返回True,我们需要的不存在的,所以前面要加Not If Not d.Exists(arrC(i, 1)) Then '说明是在A列没有出现的数据,记录下来 resultCount = resultCount + 1 '结果的数量增加1 result(resultCount, 1) = arrC(i, 1) End If '输出结果 Range("E1").Resize(resultCount, 1).Value = result