Dictionary对象将替换Collection对象,并提供附加的语言从而使增加和删除记录的速度比以前提高三倍,虽然Visual Basic 6.0只有很少的新特点,但是具有某些功能强大的新的对象模型,其中之一就是Dictionary对象。

Dictionary对象是无处不在的Visual Basic Collection对象的新版本。它的介绍存在于VBScript 2.0,并通过Visual Basic 6.0对Scripting Runtime Library的支持涉入Visual Basic的全部内容。刚开始,Dictionary对象仅仅包含在VBScript中,并作为Perl相关内容的等价体对Web组请求进行答复。

与Collection对象相似,你能够通过Dictionary存储任何类型的数据或字典对象,这些数据和对象通常被看作字典的组成部分,每一部分都被赋予字符串型键值。虽然我不认为Microsoft意图使你完全摆脱收集和替换上述数据和对象的烦恼,但是实际上,在先前的Visual Basic 6.0文档中,对Dcitionary对象确实很少提及,因此我认为这是Visual Basic 6.0的一个最新的重要特点。

Dictionary对象与Collection对象的比较

从Visual Basic 4.0开始,Collection对象就作为主要的数据类型替代了用户自己定义的类型,由此以后,大多数Visual Basic程序都包含Collection对象。如果你从Visual Basic 4.0开始已经非常习惯于使用Collection对象,那么你又为什么需要作出改变呢?这主要有几个因素:

Dictionary对象比Collection 对象更快,这种速度优势主要体现在增加数据成员、在字典中进行迭代搜索和删除数据成员上。

Dictionary对象包括那些你经常不得不自己编制的封装函数,例如Exists函数和RemoveAll函数。

Dictionary对象让你能够创建Key值数组和Item值数组,从而加快在字典中进行迭代搜索的速度。

Dictionary对象让你能够覆盖已经存在的Key值和已经存在的数据成员。 Dictionary对象还确实存在着下述缺点,但它们本身并不
值一提:与Collection对象不同,Dictionary对象不是VBA语言DLL的一部分,这意味着你需要借助SCRRUN.DLL,并将之连接到相应的应用程序。

Dictionary对象实现For…Each…Next循环的方法也很奇怪,它不是返回Item值,而是返回Key值。

Dictionary对象还有一恼人之处,就是如果你想从字典中删除一个没有搜索到的成员,你就必须添加数据到这个空的条目或不存在的键。

访问Dictionary对象正如我先前所说,Dictionary对象不是VBA或Visual Basic实时语言的具体存在的部分,它是存在于Microsoft Scripting Runtime Library(SCRRUN.DLL)中的一个对象。为了在应用程序中使用Dictionary对象,就必须利用Reference对话框增加一个项目级的引用到Scripting Runtime Library。

增加完引用之后,创建Dictionary对象的实例,如下:Dim oDict As DictionarySet oDict = New Dictionary' Do some work.Set oDict = Nothing为了增加一个成员到Dictionary对象,利用Add方法,其中包括两个参数:需要增加的数据和与数据相关联的字符串型Key值,语法如下: dictionary.Add Key, Data在Dictionary对象中没有指明新的数据成员存放位置的参数,它将由字典自己挑出。你还需要注意Add方法的参数正好与Collection对象的Add方法相反,在Collection对象 中:collection.Add Data, [Key], [before], [after]与Collection对象类似,Dictionary对象的成员能够是任何数据类型、对象或其他字典,从而使你能够按照自己的意愿任意嵌套Dictionary对象。

访问Dictionary对象的成员

Dictionary对象的Item方法是访问包含在字典中数据的推荐方法,其好处是速度快,非常快。我所做的测试表明,访问Dictionary对象数据成员的速度要比访问Collection对象数据成员的速度快三倍。如果你打开对象浏览器,选择Dictionary对象,并观察隐藏的成员,你就会看到名为HashVal的属性,这表明Dictionary对象存在无用信息列表和一些奇怪的排队算法。

在设计Dictionary对象时,主要是利用将字符串型Key值作为一个参数传递给Item的方法来实现对数据的访问,这一点与Collection对象相
似,例如,你可以利用:VItem = oDictionary.Item(sKey)

这儿警告一句,如果试图利用一个并不存在的键值返回Collection成员的数值,将会出错(code 5, Invalid Procedure Call or Argument)。Dictionary对象并不这样,它在插入该新成员时,采用并不存在的键值对应某个键同时用零长度字符串对应数据成员。Dictionary对象总是检查你要使用的键是否存在于字典内,可以想象,这一特点能够轻易地捕捉不经意所犯的错误,至于检查键值存在性方法将在本文的后续内容中述及。

当使用Collection对象时,你不能直接顺序地访问字典中的数据,但是使用字典的Item方法时就不这样,你能够快速地创建所有数据成员的数组,并利用该数组顺序地访问所有数据:Dim vItems As VariantDim iOrdinal As IntegeriOrdinal = 10vItems = oDictionay.Items
vItem = vItems(iOrdinal)从Collection对象中删除数据的方法通常是采用For…Each…Next语句,在你初次对Dictionary对象使用For…Each…Next时,可以假设你从未对字典使用过该语句,但是尽管没有当前的记录位置,你仍能够使用For…Each…Next,你只需要Dictionary对象的inter_NewEnum函数返回的与条目有关的键值,而不是象Collection对象那样,需要返回字典条目的索引,你可以将这些键值传递给Item方法以便删除数据成员,如下所示: Dim sKey As VariantFor Each sKey in oDictionaryVItem = oDictionary.Item(sKey)
…Next

当你在封装类中利用Dictionary对象时,存在另一个使用For…Each…Next的次要关键。你不能在客户端使用For…Each…Next循环对数据成员进行迭代搜索,除非你愿意进行大量的复杂编程。其原因是Dictionary对象的internal_NewEnum函数不是一个隐含成员,而在Collection对象中它是,它不能通过Visual Basic调用,因此你不能够在封装类实现自己的_NewEnum函数,简单的Set NewEnum = mCol.[_NewEnum]语句不能与Dictionary对象共同工作,但是,使用Dcitionary对象获得的诸多好处使这种折中非常值得。

那么,怎样访问Dictionary对象封装类的每一个成员呢?Dictionary对象包含名为Items的方法,该方法返回所有Dictionary对象成员的一个可变数组,你只需要在自己的类中提供一个封装子程序以返回Item数组:Public Property Get Items() As VariantItems =mdDict.ItemsEnd Property

或者你愿意提供一个更加有意义的名字给封装特性,那么可以这样:Public Property Get Employees() As VariantEmployees = mdDict.ItemsEnd Property然后你的客户端程序代码就可以利用For…Each…Next或For…Next循环在
可变数组中进行迭代搜索,以下这些代码告诉你怎样才能实现这一点:Dim oEmployees As Employees ' wrapper classDim aEmployees As Variant ' Variant to hold arrayDim oEmp As Employee ' data member classDim i As Integer ' simple counterSet oEmployees = New Employees 'Dictionary wrapper classaEmployees = oEmployees.Employees 'return an array of objectsFor i = lBound(aEmployees) To uBound(aEmployees)Set oEmp = aEmployees(i)cboNames.AddItem oEmp.NameSet oEmp = NothingNext i
Set oEmployees = Nothing

那么性能怎样呢?当在同样的机器上调用动态连接库时,结合Dictionary封装类的Item数组和Foe…Each…Next的迭代搜索不如仅仅运用Collection封装类进行的迭代搜索快,但是如果你处理的是远程或进程外的服务程序,那么情况刚好相反。利用Dictionary的封装类,你只是进行简单数组的简单转换,而Collection类则反复调用远程服务程序,每一个迭代都要进行过程调用。我设置了一个简单的实验以考察远程Dictionary对象和Collection对象的迁移性,这些对象包括1000个简单的字符串成员并利用它们迁移一个客户端Form的列表,Dictionary对象迁移该列表只需要四分之一秒,而Collection对象迁移该列表则耗费了差不多三秒钟。

你的成员存在吗?
我反复抱怨Collection对象的一个因素是其没有能力让你预先知道Collection对象的某一个成员是否存在,如果该成员的键值并不存在,那么你就不得不处理出现的错误。由于这个原因,我通常利用一个类来封装我的Collection对象成员,并使它们包括Exists属性。

不管怎样,Microsoft使Dictionary对象具有Exists方法。Exists非常便于使用,并返回True或False,如下所示:If oDictionary.Exsits(sKey) Then' The key is there .vVal = oDictionary.Item(sKey)ElseMsgBox "The key doesn't exist"
End If由于Dictionary对象总是为成员添加一个键值和一个空字符串,所以当你试图返回一个并不存在键值的条目时,你总是能够在返回该条目之前利用Exists方法来检测它的存在性(如上面例子所示),这个特点使你免于直接访问一个并不存在的键值。

键值覆盖
如果你曾经试图改变某个与Collection对象成员对应的键值,那么你知道这不可能。当对象成员加入到Collection对象时,该成员的数据和键值就已经被固定下来了。你能做的唯一选择就是使用Remove方法清除该成员并增加一个新成员到该对象。但是,你能够利用Dictionary对象的Key特性来覆盖该键的键值,如下例所示:If oDictionary.Exists(sOldKey) Then' The key is there .oDictionary.Key(sOldKey) = sNewKeyElseMsgBox "The key dosen't exsit"End If

成员覆盖
我猜想Microsoft在编制Collection对象时,他们假设Collection对象的成员一旦加入就不再改变,他们为什么会认为开发人员仅仅与静态数据打交道呢?!因此,改变Collection对象成员的唯一办法就是先从Collection对象中删除它们并重新加入。

与Key特性相似,你能够利用存在于表达式两边的Dictionary对象的Item特性。在一个表达式的右边,你返回对象成员的值,而在表达式的左边,你可以设置成员的值,方法如下:
If oDictionary.Exists(sKey) Then
' The key is there .
oDictionary.Item(sKey) = vNewItem
Else
MsgBox "The key doesn't exist"
End If

补充
当你需要字典内所有键值的数组时,Item方法和Key方法也能够帮助你。Item方法可以返回包含字典内所有数据成员的可变数组,而Key方法则可以返回包含字典内所有键值的可变数组。 Dictionary对象的其他特性包括返回字典内成员数目的Count特性和能够让你控制内部搜索执行情况的CompareMode特性,还有Remove特性和RemoveAll特性,正如其名字所示,它们用于清除字典内的数据成员。

总结
Dictionary对象与Collection对象相比,是一个非常有价值的尝试。它不但速度快,而且具有许多特性,使你从原来不得不自己编制封装类的烦恼中解脱出来。虽然用Dictionary对象替换Collection对象还需要一些次要的记录技术(根据For…Each…Next等而定),但是利用Dictionary对象所带来的性能上的提高足以补偿这些努力。本专题的PROFESSIONAL RESOURCE CD包含一个例子类,从而向你展现样围绕Dictionary对象创建一个名为DictCLass.CLS的封装类,它还包括一个例子应用程序,该例子向你展示怎样利用这些类来获得超出于你应用程序的强大功能。

Collection相当普及,大部分Visual Basic数据类都源于此类,而Dictionary对象是重要的改进,在添加和删除对象成员方面要比Collection对象快三倍,你能够戏剧性地提高应用程序的性能。你也可以自己进行Dictionary对象和Collection对象的性能测试比较,你会得到与我大致相同的结果。

excel VBA 字典与集合(Dictionary与Collection)相关推荐

  1. Excel VBA 字典/数组 示例

    A 将数组作为字典的ValuePrivate Sub CommandButton3_Click() Dim arr, arr1, i&, d As Object arr = Sheets(3) ...

  2. VBA 字典嵌套字典 + 数组

    VBA 字典嵌套字典 + 数组 功能展示为Excel VBA字典中嵌套字典,内层字典值为一个数组 Public Sub arrayInDictWithInDict()myarr = Array(&qu ...

  3. python集合与字典区别_Python中的字典与集合

    今天我们来讲一讲python中的字典与集合 Dictionary:字典 Set:集合 字典的语法:Dictionary字典(键值对) 语法: dictionary = {key:value,key:v ...

  4. 【Excel VBA和Python对照学习】创建字典

    Excel VBA和Python双语对照学习 我们从小学习语文,都用过字典.查字典时可以从第一页开始,一页一页地往下找,直到找到为止.这样做明显效率低下,特别是字的位置比较靠后的时候.所以查字典时不这 ...

  5. Python中的list列表 tuple元组 set集合 dictionary字典

    list 访问列表 连接列表 for 循环遍历列表 while循环遍历 列表比较 添加列表元素 append末尾添加 insert() extend()方法 删除列表 del 更改列表值 查列表(in ...

  6. 来吧!带你玩转 Excel VBA

    来吧!带你玩转 Excel VBA(含CD光盘1张)(双色)(附带近500个VBA思考练习题,Exceltip.net出品) 罗刚君  杨嘉恺编著 ISBN 978-7-121-20627-6 201 ...

  7. 来吧 带你玩转 Excel VBA

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 来吧!带 ...

  8. Excel VBA编程常用语句300句

    Excel VBA编程常用语句300句 ************** * VBA 语句集 * * (第 1 辑) * ************** **************** * 定制模块行为 ...

  9. EXCEL VBA常用语句100句

    以下转自:http://www.bbioo.com/blog/bio/guohui/1524.htm EXCEL VBA常用语句100句 定制模块行为 Option Explicit '强制对模块内所 ...

最新文章

  1. 判断机器学习算法或深度学习算法优势常考虑的点
  2. Springmvc的handler method参数绑定常用的注解
  3. 转载:矩阵的掩膜操作实现图像对比度调整
  4. pytorch中的切片时的省略号
  5. Android camera (12)---camera ap在特殊的应用场景下额外使用一套独立的camera tuning参数
  6. spring cloud gateway 之限流篇
  7. 更改vmware esx机器的ip
  8. 转: 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?
  9. SSM面试题及相关答案
  10. 大胜凭德--入行选领导(转载分析)
  11. matlab绘制蜗牛圈圈图,Matlab实现的图像中的圆、矩形、正方形等形状识别
  12. 深度剖析mongos连接池
  13. 天线开路短路检测原理_LEA-5S的天线开路检测问题
  14. Ubuntu下安装Maskrcnn_benchmark(pytorch)踩坑分享
  15. 网易考拉海购Java开发面经(已拿offer)
  16. 无论创业还是做人,你都需要知道什么是MVPPMF
  17. 记一个vue router相关的 Uncaught (in promise) undefined 问题
  18. 颠覆互联网中介模式,他们想通过超级虚拟主机创建开源的商业系统
  19. 小区物业管理系统设计与开发论文
  20. 计算机中专专业规划400字,中专计算机专业规划书

热门文章

  1. 算法梳理(二)逻辑回归算法梳理
  2. Python缓存cacheout的使用
  3. x299服务器芯片组,【装机帮扶站】第770期:X79/X99/X299平台“高级”垃圾简析
  4. 理解矩阵、矩阵的现实意义(二)
  5. JAVA JDK8的介绍下载和安装(附网盘地址)
  6. 优秀个人博客网站应该长什么样子?
  7. uniapp父子组件传值
  8. elementUI级联选择器(Cascader)回显问题和clearCheckedNodes无效的解决方法
  9. 淘宝客引流玩法介绍(一)
  10. LruCache源码的理解