VB之Collection---Collection集合类
由于要对⼀些数据进⾏处理,⽐较⿇烦,实现某个算法要处理⼤量不同的不同类型的数据。
所以考虑到⼀些因素,⼜在使⽤VB6(可惜微软不⽀持VB6了,改为DotNet框架了),所以使⽤ VB6 ⾃带的 Collection集合(类)最好。
其实Collection 也是有Key 和 Value⼀⼀对应的关系的。⽽且还有 ID 顺序。
现在不是流⾏ key-value的数据库么,collection如果可以保存到⽂件,那么不久完美了么??反正现在当作 key value的实时处理数据的库来⽤还是很好的。
从VB6的《类⽣成器实⽤⼯具》创建 collection挺⽅便,唯⼀不⽅便的是,默认不把 collection当作类来使⽤。其实这就是⼀个类⽽已么。⼀般collection只有⼀个就⾏,add多个元素。但是collection也可以创建多个,就是collection下有collection,下⼜有⼀些 class,复杂程度稍微⾼⼀点。
下⾯是⼀个简单的collection配合⼀个class的例⼦。
'FileName : OneKeyCls.cls
Option Explicit
Public Key As String
'FileName : OneKeyCol.cls
Option Explicit
'局部变量,保存集合
Private mCol As Collection
Public Function Add(Key As String, Optional sKey As String) As OneKeyCls
'创建新对象
Dim objNewMember As OneKeyCls
Set objNewMember = New OneKeyCls
'设置传⼊⽅法的属性
objNewMember.Key = Key
If Len(sKey) = 0Then
mCol.Add objNewMember
Else
mCol.Add objNewMember, sKey
End If
'返回已创建的对象
Set Add = objNewMember
Set objNewMember = Nothing
End Function
'下⾯做了错误处理!当没有关键字的时候就会返回Nothing了。
Public Property Get Item(vntIndexKey As Variant) As OneKeyCls
Err.Clear
On Error GoTo GetItemError
'引⽤集合中的⼀个元素时使⽤。
'vntIndexKey 包含集合的索引或关键字,
'这是为什么要声明为 Variant 的原因
'语法:Set foo = x.Item(xyz) or Set foo = x.Item(5)
Set Item = mCol(vntIndexKey)
Exit Property
GetItemError:
Debug.Print Err.Source & " : Error Was found in Item(vntIndexKey as Variant) as oneKeyCls . " & vbCrLf & Err.Description & " : " & Err.Number
Set Item = Nothing
End Property
Public Property Get Count() As Long
'检索集合中的元素数时使⽤。语法:Debug.Print x.Count
Count = mCol.Count
End Property
Public Sub Remove(vntIndexKey As Variant)
'删除集合中的元素时使⽤。
'vntIndexKey 包含索引或关键字,这是为什么要声明为 Variant 的原因
'语法:x.Remove(xyz)
mCol.Remove vntIndexKey
End Sub
Public Property Get NewEnum() As IUnknown
'本属性允许⽤ Each 语法枚举该集合。
Set NewEnum = mCol.[_NewEnum]
End Property
Private Sub Class_Initialize()
'创建类后创建集合
Set mCol = New Collection
End Sub
Private Sub Class_Terminate()
'类终⽌后破坏集合
Set mCol = Nothing
End Sub
使⽤范例:
Dim Cars As New OneKeyCol
Cars.Add "10.1", "2"
Cars.Add "10.2", "20"
Cars.Add "10.3", "200"
Cars.Add "key"
Debug.Print "Count:" & Cars.Count
Debug.Print Cars.Item("200").Key
Debug.Print TypeName(Cars.Item("300")) ' Error Nothing
Dim i
Dim key1 As OneKeyCls
'按照 index 索引进⾏遍历 ,效率要⽐下⾯的⽅法低⼀点
For i = 1To Cars.Count
Set key1 = Cars.Item(i)
Debug.Print key1.Key
Next
'推荐这种遍历⽅法
For Each key1 In Cars
Debug.Print key1.Key
Next
⼀下为稍微整理下VB6的 collection 的转载。
Visual Basic 集合对象()
集合是⽅法将⼀系列相关的项构成组的⼀种⽅法。Visual Basic 中集合可⽤于跟踪很多事情,例如程序中加载的窗体(窗体集合),或者在窗体中的所有控件(控件集合)。
Visual Basic 提供的类属 Collection 类可⽤来定义⾃⼰的集合。需要多少集合对象,就可以建⽴多少 Collection 对象-即 Collection 类的实例。还可使⽤集合对象作为⾃⼰的集合类和对象模型的基础,它将在本章后⾯的“创建⾃⼰的集合类”和“对象模型”中讨论。
例如,集合是跟踪多窗体的最好⽅法。在“创建⽤户界⾯”中的“多⽂档界⾯ (MDI) 应⽤程序”⾥讨论⽤户可以打开任何数⽬⽂档窗⼝的应⽤程序。以下代码段演⽰如何使⽤集合对象的 Add ⽅法,对⽤户建⽴的 MDI ⼦窗体列表进⾏管理。该代码假定已经存在⼀个名为 mdiDocument 的窗体,其 MDIChild 属性设置为 True。
'⽗ MDIForm 中的模块级集合。
Public colDocuments As New Collection
'建⽴新的 MDI ⼦⽂档窗体的代码。
Private Sub mnuFileNew()
Dim f As New mdiDocument
Static intDocumentNumber As Integer
intDocumentNumber = intDocumentNumber 1
'下⾯的语句创建窗体。
f.Caption = "Document" & intDocumentNumber
'给集合添加对象引⽤。
colDocuments.Add f
f.Showasp 字符串转数组
End Sub
colDocuments 的作⽤象是内置窗体集合的⼀个⼦集,它只包含窗体 mdiDocument 的⼀些实例。每添加⼀个新窗体,⾃动调节集合的⼤
⼩。可使⽤ For Each ... Next 在集合内进⾏迭代。如果赋予窗体⼀个可以检索的键,那么可提供⼀⽂本字符串作为 Add ⽅法的第⼆个参数,如本节后⾯部分所述。
在变量 colDocuments 的声明中,New 关键字导致当该变量第⼀次被引⽤时,在代码中创建集合对象。因为集合是类,⽽不是数据类型,所以必须建⽴集合实例,并且在变量中记录对该实例(对象)的引⽤。
象其它任何对象⼀样,当包含其引⽤的最后⼀个变量被设置成 Nothing 或不可见时,Collection 对象将被撤消。它包含的所有对象引⽤将被释放。因此,变量 colDocuments 在⽗ MDIForm 中声明,于是它将存在于程序存活期中的整个过程。
注意如果使⽤集合来跟踪窗体,当窗体被卸载之后,应使⽤集合的 Remove ⽅法从集合中删除该对象引⽤。只要对该窗体的引⽤仍然存在,就不能收回窗体使⽤的内存,并且 Collection 对象保存的引⽤象对象变量中的引⽤⼀样完好。
集合对象的构成
Collection 对象将每⼀项存储于 Variants 对象中。于是,能够添加到 Collection 对象⾥的内容列表就和能够存储到 Variants 中的内容列表是相同的。这包括标准数据类型、对象和数组-但不包括⽤户定义类型。
不管 Variants 中存储的是什么,它都占 16 字节,因此使⽤ Collection 对象不如使⽤数组的效率⾼。然⽽,不能 ReDim ⼀个 Collection 对象,ReDim Collection 对象能够使代码更清楚、更容易维护。此外,集合对象按键能进⾏快速的查,⽽数组却不能。
注意准确⼀点说,即使是把数据存储在其它地⽅,Variants 也总是只占 16 个字节。例如,如果把字符串或数组赋给 Variants,Variants 将包含⼀个指向字符串和数组数据备份的指针。在 32 位系统中,指针只使⽤了 Variants 的 4 个字节,⽽且 Variants 中实际上不存在数据。
若要存储⼀个对象,Variants 将包含该对象引⽤,就象对象变量所做的⼀样。对字符串和数组来说,也只使⽤ Variants 的 4 个字节。
数字数据类型存储在 Variants 中。不管什么样的数据类型,Variants 仍然占 16 个字节。
除了 Variants ⼤⼩之外,还有很多情况需要使⽤ Collection 对象来存储上⾯列出的所有数据类型。应该知道进⾏权衡:使⽤ Collection 对象能够编写清楚且容易维护的代码-所花费的仅是将⼀些项存储在 Variant 中。
集合对象的属性和⽅法
每个集合对象都有属性和⽅法,使⽤它们能够插⼊、删除和检索该集合中的项。
属性或⽅法描述
Add ⽅法给集合添加项。
Count 属性返回集合中项的数⽬。只读。
Item ⽅法通过索引或关键字,返回项。
Remove ⽅法通过索引或关键字,从集合中删除项。
这些属性和⽅法仅仅是集合最基本的功能。例如,要确保集合只包含⼀种对象,Add ⽅法并不能检查将要添加到集合⾥的对象类型。通过建⽴⾃⼰的集合类能够提供更强健的功能,以及额外的属性、⽅法和事件,正如本章后⾯的“创建⾃⼰的集合类”中所述。
集合中的增加、删除和检索的基本功能需要关键字和索引。关键字是⼀个 String 的值。它可以是能转换成字符串的名字、驾驶执照号、社会安全号或者简单的整数。Add ⽅法允许将关键字与项相关联,如本节后⾯部分所述。
索引是长整型,介于 1 和集合中项的数⽬之间。使⽤ before 和 after 命名的参数,可以控制项索引的初始值,但是随着其它项的增加和删除,其值会发⽣改变。
注意索引从 1 开始的集合称为基于 1,如“Visual Basic 中的集合”中所述。
使⽤索引能够在进⾏集合的项中迭代。例如,假定变量 mcolEmployees 中包含对集合对象的⼀个引⽤,下列代码使⽤两种⽅法把Employee 对象集合中所有雇员的薪⽔提⾼ 10%。
Dim lngCt As Long
For lngCt = 1To mcolEmployees.Count
mcolEmployees(lngCt).Rate = _
mcolEmployees(lngCt).Rate * 1.1
Next
Dim emp As Employee
For Each emp In mcolEmployees
emp.Rate = emp.Rate * 1.1
Next
提⽰为改善性能,应使⽤ For Each 对 Collection 对象中的项进⾏迭代。使⽤ For Each 迭代要⽐使⽤索引快很多倍。这并不是对所有集合都正确-它取决于集合内部存储数据的⽅法。
给集合添加项
Add ⽅法⽤于将项添加到集合。语法是:
Sub Add (item As Variant [, key As Variant] [, before As Variant]
[, after As Variant] )
例如,使⽤⼯作定单 ID 属性作为关键字,将⼯作定单对象添加到⼯作定单集合⾥,代码可编写为:
colWorkOrders.Add woNew, woNew.ID
这⾥假定 ID 属性是字符串。如果属性是数字(例如 Long),则应使⽤ CStr 函数将它转换成关键字所要求的字符串值:
colWorkOrders.Add woNew, CStr(woNew.ID)
Add ⽅法⽀持命名的参数。为了添加⼀项作为第三个元素,代码可编写为:
colWorkOrders.Add woNew, woNew.ID, after:=2
可以使⽤ before 和 after 命名的参数管理有序的对象集合。例如,before:=1 将在集合的开始插⼊⼀项,因为集合对象是基于 1 的。
从集合中删除项
Remove ⽅法⽤于从集合中删除项。语法是:
object.Remove index
index 参数可以是所删除项在集合中的位置,或者是该项的关键字。如果集合中第三个元素的关键字是“W017493”,则可使⽤这两条语句中的任何⼀条删除它:
colWorkOrders.Remove 3
- 或 -
colWorkOrders.Remove "W017493"
从集合中检索项
Item ⽅法⽤于从集合中检索特定项。语法是:
[Set] variable = object.Item(index)
和 Remove ⽅法⼀样, index 可以检索项在集合中的位置,或者是该项的关键字。使⽤ Remove ⽅法中的相同⽰例,这两条语句中的任⼀条都可检索集合中的第三个元素:
Set woCurrent = colWorkOrders.Item(3)
- 或 -
Set woCurrent = colWorkOrders.Item("W017493")
如果使⽤整数作为关键字,在将它们传递到 Item 或 Remove ⽅法之前,必须使⽤ CStr 函数将其转换成字符串。通常集合对象都假定整数是索引。
提⽰ Collection 对象不能决定所传递的值是索引还是键。如果想把值解释为键,并且包含该值的变量是除 String 以外的任何值,可以使⽤CStr 函数进⾏转换。如果想把值解释为索引,并且包含该值的变量不是整型数据类型中的⼀种,使⽤ CLng 进⾏转换。
Item 是缺省⽅法
对于集合对象来说,Item ⽅法是缺省⽅法,因此当访问集合中的项时,可忽略它。所以前⾯的代码⽰例也可以写成:
Set woCurrent = colWorkOrders(3)
- 或 -
Set woCurrent = colWorkOrders("W017493")
重点当添加和删除集合对象元素时,集合对象会⾃动地维护其数字索引编号。因此给定元素的数字索引随之改变。不能在程序中存储数字索引值,并⽤它检索同⼀个元素。为达到该⽬的,应使⽤键。
使⽤ Item ⽅法调⽤属性和⽅法
为了使⽤对象引⽤,不能从集合中检索该对象引⽤,并把它放到对象变量中。当对象仍然在集合⾥时能够使⽤其引⽤。
例如,假设上述代码中的 WorkOrder 对象具有 Priority 属性。下⾯的语句都可⽤于设置⼯作定单的优先级:
colWorkOrders.Item("W017493").Priority = 3
colWorkOrders("W017493").Priority = 3
可⾏的原因是 Visual Basic 要从左到右计算表达式。当遇到 Item ⽅法时-显式的或隐式的- Visual Basic 为指定的项(此时是键为
W017493 的 WorkOrder 对象)取得⼀个引⽤,并使⽤该引⽤计算该⾏的其余部分。
提⽰如果想调⽤集合中对象的多个属性或⽅法,⾸先将该对象引⽤复制到⼀个强类型的对象变量中。把引⽤放到⼀个强类型的对象变量中,然后使⽤,⽐使⽤集合⾥对象的引⽤要快(例如,Dim woCurrent As WorkOrder),因为 Collection 对象是把项存储在 Variants 中。Variants 中的对象引⽤总是最后绑定。
详细信息对很多⼀般的程序设计任务来说,集合对象也是数组的很有⽤的可选⽅案。请参阅“再论编程”中的“⽤集合替代数组”。
Visual Basic 提供很多内置集合。有关它们与集合对象的⽐较,请参阅“Visual Basic 中的集合”。
创建⾃⼰的集合类
⼀般可以采取三种办法⽤集合来实现对象包含。以上⾯“对象模型”中所讨论的 SmallBusiness 对象的 Employees 集合为例。为了实现该集合,可以这样做:
在 SmallBusiness 类模块中,将 Employees 变量声明为 As Collection,并使之成为 Public。这是最简单的解决⽅案
转⾃:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论