前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >VBA调用外部对象01:字典Dictionary

VBA调用外部对象01:字典Dictionary

作者头像
xyj
发布2020-07-28 10:30:42
3.2K0
发布2020-07-28 10:30:42
举报
文章被收录于专栏:VBA 学习

当你发现不停的用For循环来处理数据速度慢的受不了了,你肯定会想怎么才能提高一些效率。比如前面我们说到的对比2个表数据,我们是使用For循环去逐个的对比判断,如果能有1个东西让我们可以快速的在一组数据里找到需要的、或者是找不到的时候返回false的话,那我们就不需要用For循环了,那有没有这种东西呢?

是的,今天要说到的字典就是这么一个东西,作为1个新手,可能你只需要知道它有快速找到某个数据的功能就可以了。如果你还有兴趣深入了解,那就需要去学习数据结构和算法方面的东西了,字典就是一种Hash算法实现的东西。

1、COM对象

字典就是Windows系统做好了的一个东西,是一种叫做COM对象的东西,在VBA中如果要使用的话,有2种方法:

  • 前期绑定:

在VBA编辑器里点击工具-引用,找到需要使用的项目勾选

  • 后期绑定:

使用VBA的CreateObject函数,这种情况下要知道COM对象的名称。

代码语言:javascript
复制
VBA.CreateObject("XXXXX")

这样就可以在VBA里使用该对象了,2种方法有一点小的差异,主要是:

  • 前期绑定的方法使用对象时就像是使用VBA内部对象一样了,但是一旦你把做好的程序发给别人使用,使用者也必须要手动先添加引用
  • 后期绑定不需要手动添加引用,但是使用过程中不大方便,不能直接声明对象的名称,要用Object代替,写代码也不会像VBA内部对象那样自动列出属性和方法。

作为VBA的使用者,知道这样使用COM就可以了。

2、字典Dictionary

字典就是一种COM对象,前期绑定使用方法,找到Microsoft Scripting Runtime,勾选后确定,然后我们就可以使用字典了:

代码语言:javascript
复制
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的集合。

3、使用

代码语言:javascript
复制
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
    Next
    
    '声明存储结果的数组
    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
    Next
    
    '输出结果
    Range("E1").Resize(resultCount, 1).Value = result
    
    '释放
    Set d = Nothing
End Sub

有了字典,我们就不需要循环内部再加循环的去判断了,你可以多加些数据对比程序运行的速度,一定会很惊奇字典查找数据的速度。

最后推荐大家看一下这个帖子:

呼之即来,挥之即去:

http://club.excelhome.net/forum.php?mod=viewthread&tid=926188&ordertype=1&page=1

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 VBA 学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档