我开始在VBA(Excel AddIn - > xlam)中使用Collection
,但发现它很难使用。我无法检索任何我放入的东西,除了Variants。例如,在Java中,如果你创建一个Collection
,你可以给它分配一个类型,比如Collection<MyPerfectObjectThatStoresSomeData>
,所以当我预先知道它时,我知道我得到了我的对象并可以像这样使用它。当我想在VBA中做同样的事情时,我会回到Variant
类型,我甚至无法将其转换为我的类型。
实施例。
我想说我希望得到Collection
的最后一个条目,我填写如下:
Private Function FindTargets(sheet As Worksheet, target As String) As Collection
Dim result As New Collection
Dim aCell As range
Dim i As Long
For i = 1 To 10456
Set aCell = sheet.Rows(i).Find(What:=target, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not aCell Is Nothing Then
MsgBox "Value Found in Cell " & aCell.Address & _
" and the Cell Column Number is " & aCell.Column
result.Add aCell
End If
Next i
Set FindTargets = result
End Function
之后,我想循环查看结果,但我无法在没有错误的情况下获取最后一个条目:
Dim targetCollection As Collection
Set targetCollection = FindTargets(targetSheet, "some text")
Dim target As range
target = targetCollection.Item(targetCollection.Count - 1)
我收到错误:
Run-time error '91':
Object variable or With block variable not set
如果我尝试
Set target = targetCollection.Item(targetCollection.Count - 1)
我明白了:
Run-time error '1004':
Application-defined or object defined error
我是否只能循环并将Collection
的条目转换为Variant
以外的类型?
编辑:更具体地说,此代码需要范围的坐标,但在Variant
中,我得到了单元格的文本。我想创建一个新的类,比如CellProperties
,其中包含文本和坐标属性,并将其放入Collection中,但同样,我无法从Collection
中检索除Variant之外的任何内容。
答案 0 :(得分:4)
看来您的错误是由假设Collection的项目从零开始,但Collection
中的第一个项目的索引为1
以下是我用于测试的FindTargets
的缩减版本,以及返回添加到Address
的最后一个单元格的Collection
的测试子例程:
Private Function FindTargets(sheet As Worksheet, target As String) As Collection
Dim result As New Collection
Dim i As Long
For i = 1 To 100
result.Add Cells(i, 1)
Next i
Set FindTargets = result
End Function
Sub test()
Dim targetCollection As Collection
Set targetCollection = FindTargets(Worksheets("Sheet1"), "some text")
Dim target As Range
Set target = targetCollection.Item(targetCollection.Count)
MsgBox target.Address 'will display $A$100
End Sub
答案 1 :(得分:1)
VBA-Collection是可以包含异构对象的数据结构。因此,与Collection Of MyPerfectObjectThatStoresSomeData
不同,集合确保可以添加某些数据类型的对象,在VBA-Collection
中我们可以在集合中存储任何内容,以便它可以同时包含异构对象类型。但在您的情况下,该集合实际上包含Variant\Object\Range
类型的对象。这意味着它包含Variant
类型和子类型Range
的对象。可以枚举VBA-Collection
并且它具有Item
方法,该方法可用于访问第一个项目具有1
索引的集合的项目。
在你的情况下你可以做到,例如这样:
targetCollection.Add "Banana"
targetCollection.Add ActiveSheet
targetCollection.Add Excel.Application
Dim itm As Variant
For Each itm In targetCollection
If TypeName(itm) = "Range" Then _
Debug.Print itm.Address
Next itm
安全地获取最后一个元素(如果最后一个元素是Range
类型):
Dim lastElement As Range
If targetCollection.Count > 0 Then _
Set lastElement = targetCollection.Item(targetCollection.Count)
作为旁注:为什么不使用Dim As New。