乐于分享
好东西不私藏

Excel VBA 编程基础 — 结构化数据类型(六)- 集合(一)

Excel VBA 编程基础 — 结构化数据类型(六)- 集合(一)

我们前面已经讲过了 UDT,特别是详细讨论了数组,今天我们讨论一个比较灵活的数据类型——集合(collection)
 与数组类似,集合也是一个包含多个元素的数据类型,但集合与数组有着多方面的区别:
  • 访问方式:数组元素需要通过索引(即元素的相对位置)来访问,而集合的元素是通过名字(即键值 Key)来访问的。
  • 更新方式:数组元素在程序运行过程中是可以更新的,但集合元素一旦赋值即不允许更新,只能通过“删除旧的,加入新的”方式来更新。
  • 可变尺寸:静态数组不允许改变大小,动态数组可以通过 ReDim 更改大小,集合的大小则可以随着 Add() 和 Remove() 方法的调用而自动增减。
  • 查找效率:数组只能通过查找来找到某个元素,集合则通过 Key 直接找到相应元素,效率比数组要高得多。
下面通过例子来具体感受一下集合数据类型。
例1. 一个简单的集合例子
Dim fruits As CollectionDim i As IntegerSet fruits = New Collectionfruits.Add "Apple"fruits.Add "Orange"fruits.Add "Strawberry"fruits.Add "Pear"For i = 1 to fruits.Count  Debug.Print fruits(i)Next i
与数组不同,集合是一个类类型(class type),集合类型的变量在类型声明之后,还需要使用 New 操作符为该变量分配空间,如:
Dim fruits As Collection  ' 声明 fruits 是一个 Collection 类型的变量Set fruits = New Collection  ' 实例化 Collection,赋给 fruits 变量
New Collection 的结果是生成一个 Collection 类型的对象,而 VBA 中的对象赋值都必须使用 Set 语句来完成,所以必须使用 Set fruits = … 来实现对象赋值。
这两步操作也可以合并在一个语句里完成,如:
Dim fruits As New Collection
另外,集合变量是通过 Add() 方法将元素添加到集合中去的,这一点也与数组不同。
但集合与数组相同的一点是:集合也可以通过索引来访问,只不过集合的下界是 1,上界是 Count 属性返回的值。所以通过 For i = 1 to fruits.Count 就可以遍历集合的所有元素。遍历集合还可以通过 For Each … Next 循环结构。
For Each … Next 循环结构
For Each … Next 语句用于遍历一个数组或集合,其一般形式如下:
For Each element in group  [ statements ]  [ Exit For ]  [ statements ]Next [ element ]
其中,element 是一个 Variant 类型的变量,group 是一个数组或集合变量。
注:用于 For Each 循环的数组不能是 UDT 类型,也就是是,其元素不能是用户自定义类型。
例. 使用 For Each … Next 结构遍历
Dim myA() As IntegerDim v As VariantReDim myA(3)myA(0) = 10myA(1) = 23myA(2) = 210For Each v in myA  Debug.Print vNext v
对于例1 中的集合 fruits,我们也可以使用 For Each … Next 结构对其进行遍历:
Dim v As VariantFor Each v in fruits  Debug.Print vNext v
再回到集合的话题上来。
例2. 使用 Key/Item 操作集合
图1 使用 Key/Item 的集合操作
在这个例子中,我们用水果名称作为集合元素的键(Key),以水果价格作为集合元素的值(Item),在使用 Add() 方法时,我们可以使用有名参数(named parameter)来添加元素,这样就不会由于参数位置的错位而导致方法失败。
所谓有名参数,就是将参数的名称和值一起指定,VBA 中是通过 Name := 值 的方式指定有名参数的,如 Key := “Apple”。
集合对象 Add() 的一般形式为:
object.Add item, key, before, after
其中,key、before、after 都是可选参数,只有 item 才是必须提供的参数。如果不使用命名参数,必须按照这个顺序提供 Item、key、before、after 才可以,而使用有名参数,就可以像这样:
fruits.Add Key := "Pear", Item := 3.6, Before := "Strawberry"
将 Key 为 Pear 的元素插到 Key 为 Strawberry 的元素前面。也可以将 Pear 插入到 Orange 的后面来达到同样的效果:
fruits.Add Key := "Pear", Item := 3.6, After := "Orange"
如果不使用有名参数,就得这么写:
fruits.Add 3.6"Pear", , "Orange"
这样写,明显不如有名参数的写法来得清楚、明白。
Collection 的 Key 有如下几种用途:
  • 添加元素时,作为元素的键值,起到标识元素的作用,如 fruits.Add Item := 3.6, Key := “Lemon”
  • 添加元素时,如果要插入到某个元素的前面或后面,作为参照的元素必须使用 Key 来标识,如上例的 Before := “Strawberry”
  • 读取元素的值时,可以使用 Key 来定位元素,如 fruits(“Apple”)
  • 删除某元素时,也必须指定元素的 Key,如删除集合 fruits 中的 Apple 元素
    fruits.Remove "Apple"
VBA Collection 的 Key,除了以上几种用法之外,再也没有其他的使用方式。