VBA这种依托于一个应用程序的的运行环境的代码,不同于直接直接的程序开发。VBA的数据的输入与输出是依托于Excel的工作表或word的工作页面的。所以如Excel VBA的数据,既可是直接来源于工作表对象的数据输入,也可以是数组、字典、集合的数据结构,与工作表的数据区域形成相互映射。
对于文本文件,我们可以理解为一个字符串(或一个字符串列表),对于工作表,你也可以理解为一个二维数组。字典可以理解为一个特殊的n行2列的二维数组。
集合是VBA的一种内置数据结构对象,封装了一些方法供用户操作。可以使用集合构造数据清单或数据源、或进行数据统计、查询。
集合是用户定制的一组数据信息,存放于一个一维数组中,以便用户随时访问、增添、删除同类信息。
对于集合中的数据类型,没有任何限制。即集合中元素可以是各种类型的数值、或文本,或单元格区域,或图片等。
在VBA中,工作簿worksheets、工作表workbooks、形状shapes等本身都是一些对象集合。
集合的声明:
dim col as new collection
1 集合方法
集合作为内置对象,封装了了4个方法:
1.1 Add
colObject.Add item[, key][, before][, after]
item 必需的。任意类型的表达式,指定要添加到集合中的成员。
key 可选的。唯一字符串表达式,指定可以使用的键字符串,代替位置索引来访问集合中的成员。
before/after 可选的。表达式,指定集合中的相对位置。
下面语句向集合增加一个对象TextBox1,并定义该成员的关键字为tx1。
col.Add TextBox1, "tx1"
然后,下面两句都可以向集合中增加一个TextBox2,并把它放在成员TextBox1的前面。
col.Add "红", "red",,2
1.2 Count
返回集合中的项的个数。
1.3 Item()
通过集合中的索引(即集合中项的序号)或键(假设该项添加到集合时指定了)检索集合中的成员。
1.4 Remove()
通过集合中的索引或键删除集合中的成员。
对于内置对象的方法及各方法的参数,在VBE内编写代码时,会有提示:
2 集合中关键词key的使用
2.1 必须是文本型字符串值,如果是数值必须用Cstr()函数进行转换;
2.2 key不能重复(这个和字典一样);
2.3 key结果不能反输出。(item可以按key或者按Index顺序输出返回值);
检索 不存在的key值时会出错,没有字典用法中 d.Exists 方法来容错。
Sub coltest()
Dim col As New Collection
col.Add "红"
col.Add "黄"
col.Add "橙", , 2
col.Add "绿", "green"
col.Add "青", "cyan"
For i = 1 To col.Count
Cells(i, 1).Value = i
Cells(i, 2).Value = col(i)
Next i
Cells(col.Count + 1, 2) = col("green")
End Sub
3 集合相对于一维数组的优势所在
既然集合是一个一维数组,那么为啥不直接让用户自建一个一维数组来存储信息,而要开发集合对象方法这样一个东东呢?应该说是各取所需,集合在特定场合下有一定优势。
总的来说是可以简化处理(添加、删除元素)过程,节省用户写代码的时间,也不容易错。
3.1 简化元素添加的操作
其中.Add添加时,不需要地址,总是自动添加到集合数组中的最后一个位置。
如果是自定义数组,也可以做到,但可能会是这样子:
Sub test2()
Dim arr()
For i=1 To 10
ReDim Preserve arr(1 To i)'每次在需要向一维数组中添加新元素时,需要先扩大数组
arr(i)=i'然后再添加新元素
Next
End Sub
虽然实际上集合方法中也是这么做的,但毕竟通过封装和后台运行,减少了用户的麻烦。
(读取集合中元素时,需要指定位置,这个和普通数组并无差异(只有字典可以直接用关键词key定位置))
3.1 简化元素删除的操作
直接删去/抹去已经不需要的某个特定位置的信息:
s.Remove (i),如:
s.Remove (1)
s.Remove (s.Count) '删除最后一个元素
删去一维数组中第 i 个信息,需要同时自动把数组大小缩减。
对应的普通数组做法就会比较复杂:
Sub test3()
ReDim arr(1 To 10)
For i = 1 To 10
arr(i) = i
Next
Rmv arr, 3 '子过程调用
End Sub
Sub Rmv(arr, j)
For i = j + 1 To UBound(arr)
arr(i - 1) = arr(i)
Next
ReDim Preserve arr(1 To UBound(arr) - 1)
End Sub
也许集合方法中也是这么做的,但毕竟封装、后台运行以后,用户就省心多了。
字典方法有RemoveAll方法可以一下子全部删去,而集合中只能一个一个来:
每次删去第一个的方法:
For i = 1 To s.Count
s.Remove (1)
Next
或者每次删去最后一个的方法:
For i = 1 To s.Count
s.Remove (s.Count)
Next
显然第一种方法,每次删去第一的做法更不容易错,也更简单
以下操作可以直接删除全部元素:
I 重新初始化集合s
Set s = New Collection
s成为一个已经初始化了的没有任何元素的空集合变量
II 变量s初始化:
Set s = Nothing
s成为一个变量类型为集合对象的空集合变量
4 集合操作实例
Sub 集合操作实例()
'Dim s As Collection '定义s变量为集合对象
'Set s = New Collection '初始化集合对象s (否则无法使用)
Dim s As New Collection '推荐这句代码,直接初始化,可以不用再Set了
'集合s中添加元素的方法
For i = 1 To 10
s.Add i '对于集合s,用Add方法可以加入集合元素
'当然事实上你可以添加任意内容来代替本例中的i
Next
'读取集合中元素的方法
For i = 1 To s.Count '可以用Count属性返回集合中元素总个数
t = s(i) '读取集合s中第i个变量存入临时变量t中
t = s.Item(i) '正规的代码写法应该是这样子(效果一样,推荐用上一句更简明)
Debug.Print s(i) '在立即窗口中观察s(i)的值
Next
'下面是集合s中元素删除的方法
For i = 1 To s.Count '遍历集合元素
s.Remove (1) '每次删去第1个……直至全部删除完毕 或直接简写为: s.Remove 1
's.Remove (s.Count) '或者每次删除最后一个,直至全部删除完毕(推荐用上一句,不容易错)
'或简写为 s.Remove s.Count
Debug.Print s.Count '在立即窗口中观察集合s中剩余元素个数
Next
End Sub
集合操作实例2:
Sub 集合操作实例2()
Dim s As New Collection
s.Add 1, CStr(1)
For i = 2 To 20 Step 2
s.Add i, CStr(i), Int(Rnd * (i - 1) + 1)
s.Add i + 1, CStr(i + 1), , Int(Rnd * i + 1)
Next
For i = 1 To 20
t1 = s.Item(i) '按现在的顺序返回集合元素
t2 = s.Item(CStr(i)) '按关键词key返回集合元素
Cells(i, 1) = t1
Cells(i, 2) = t2
Next
[c1:d1] = Array(t1, t2)
End Sub
5 集合与普通数组
5.1 通常只在末尾添加元素 (添加时不用考虑定义数组的大小,即集合中数组大小是自适应的)
(也可以像插入工作表那样,在某个指定位置之前或之后插入,但意义似乎不大)
5.2 不能改变已添加元素的内容
5.3 可以任意删除指定位置(指定顺序位置/或指定key值)的元素
5.4 不管如何添加和删除,集合中元素始终保持添加时的先后顺序不变
6 集合与字典
6.1 集合中可以反复添加相同内容的信息(按顺序作为新元素添加)
而字典的关键词是不可以重复的。(也可以说,是相当于以序号为关键词建立了字典)
6.2 集合中元素可以Write in , 但不可以Rewrite
(字典中key不可以改动,但Item可以任意改哦)
7 综合实例
Sub 统计当前页面控件()
Dim col As New Collection
Dim i%, j%
For Each sp In ActiveSheet.Shapes
col.Add sp
Next sp
Cells(1, 11) = "控件数量:" & col.Count
For i = col.Count To 1 Step -1
Cells(i + 1, 11) = col.Item(i).Name
col.Remove i
Next i
End Sub
-End-