Vba 克隆收藏
我有两个收藏-Vba 克隆收藏,vba,excel,Vba,Excel,我有两个收藏-collection1和collection2 collection1中有许多类对象,我正在尝试使用以下命令用相同对象的副本填充collection2: Set collection2 = collection1 但这并没有给我想要的结果,因为当我使用 collection2.Remove 1 它从两个集合中删除索引1处的对象 下面是完整的代码,我希望在从collection2中删除一个对象后,可以在collection1中输出10对象 Sub test()
collection1
和collection2
collection1
中有许多类对象,我正在尝试使用以下命令用相同对象的副本填充collection2
:
Set collection2 = collection1
但这并没有给我想要的结果,因为当我使用
collection2.Remove 1
它从两个集合中删除索引1处的对象
下面是完整的代码,我希望在从collection2中删除一个对象后,可以在collection1
中输出10
对象
Sub test()
Dim collection1 As Collection
Dim collection2 As Collection
Dim testObj As Worksheet
Dim i As Integer
Set collection1 = New Collection
Set collection2 = New Collection
For i = 1 To 10
collection1.Add testObj
Next i
Set collection2 = collection1
collection2.Remove 1
Debug.Print collection1.Count
End Sub
我尝试了下面的代码,它可以工作,但我希望尽可能避免逐个填充这两个集合:
...
For i = 1 To 10
collection1.Add testObj
collection2.Add testObj
Next i
...
我之所以不喜欢这个选项,是因为最终我打算使用多个集合,在不同的点上对它们进行操作和复制,这样我的代码中就会有很多for循环,而不仅仅是一个。首先,您不需要
将collection1设置为Collection
和设置collection1=New Collection
。可将其替换为Dim collection1作为新集合
现在,您要做的是使collection2包含collection1。这就像在一个盒子上盖上很多盖子(collection1),然后把这个盒子放在另一个盒子里(collection2)
另一种方法是,要么同时填充这两个内容,要么编写代码复制内容,如
for i = 1 to collection1.count
collection2.add collection1.item(i)
next i
我正在尝试使用以下命令使用相同对象的副本填充collection2:
Set collection2 = collection1
然而,这不是该命令的作用。Set
关键字不会“复制对象”,也不会自动知道(甚至不关心)它正在处理一个包含项的Collection
对象
Set
关键字指定一个引用。不多不少
因此,Set collection2=collection1
所做的就是:
取collection1
对象的指针,并用该指针替换collection2
引用的任何对象
当您执行此操作时,Set
指令实际上放弃了您首先创建的对象:
Set collection2 = New Collection
您没有“复制对象”或“填充集合2”-您正在覆盖其对象引用,使collection2
指向与collection1
相同的对象
由于两个指针指向同一个对象。。。使用Collection
中的任何一个删除一个项实际上就是从“两个”集合中删除它,……因为只涉及一个集合对象
(未记录?
ObjPtr
关键字也有助于了解正在发生的事情:
Set collection1 = New Collection
Debug.Print "collection1: " & ObjPtr(collection1)
Set collection2 = New Collection
Debug.Print "collection2: " & ObjPtr(collection2)
'the debug output contains 2 different addresses at this point
Set collection2 = collection1
Debug.Print "collection1: " & ObjPtr(collection1)
Debug.Print "collection2: " & ObjPtr(collection2)
'now the debug output clearly shows that
'both collection1 and collection2 are pointing to the same object
如果需要集合的副本,则需要一个函数来获取集合并返回一个全新的对象:
Public Function CopyCollection(ByVal source As Collection) As Collection
Dim result As New Collection
Dim item As Variant
For Each item In source
result.Add item
Next
Set CopyCollection = result
End Function
不过,这仅在集合未设置关键帧时才起作用。由于
集合
的限制(您无法迭代其键),如果您需要克隆键控集合,则必须使用脚本.字典
。我想您的意思是设置集合2=collection1
也许……集合没有复制功能。这个:Set collection2=collection2只是对集合对象进行第二次引用。您最好的选择是避免IE同时填充这两个内容。@Rdster这只是一个输入错误,现已更正您可以创建一个函数“克隆”集合并返回副本(只要您不需要密钥)。不幸的是,您甚至无法为集合创建克隆函数,因为无法访问密钥。如果需要可克隆的通用容器,请使用Scripting.Dictionary
。不建议自动实例化对象,你会不同意吗?我在集合方面的经验是我的,它还没有给我带来任何问题。而且,答案的第一部分不是你要求的,所以请随意忽略。@CallumDA FWIW随着新的声明产生了一个“对象引用‘collection1’是自分配的”检查结果表明,“过程作用域中的自赋值对象变量声明会更改为空引用的工作方式,这可能导致意外行为”。没有说它是坏的或任何东西,只是说它的影响并不广为人知。