克隆一个集合
我有两个集合 – 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循环,而不仅仅是一个循环。
我正在尝试使用以下命令填充collection2的相同对象的副本:
Set collection2 = collection1
然而这不是那个命令的作用。 Set
关键字不会“复制对象”,也不会自动知道(甚至是关心)它是否处理包含项目的Collection
对象。
Set
关键字指定一个引用 。 没有什么比这更less的了。
那么Set collection2 = collection1
做了什么,字面上是:
拿
collection1
对象的指针,并用那个replace指向的collection1
。
这个Set
指令实际上是放弃了你创build的对象,当你这样做的时候:
Set collection2 = New Collection
您不是“复制对象”或“填充collection2” – 您正在覆盖其对象引用,使collection2
指向与collection2
相同的对象 。
而且由于两个指针指向相同的对象 …使用两个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
正如在评论中已经指出的那样 ,这只有在你的collections没有被locking的情况下才能起作用。 由于Collection
有限性(不能迭代其键),如果需要克隆键控集合,则必须使用Scripting.Dictionary
。
首先,你不需要Dim collection1 As Collection
和Set collection1 = New Collection
。 这可以由Dim collection1 As New Collection
取代
现在,你在做的是使collection2包含collection1。 就像在一个盒子(collection1)上放了大量的帽子,然后把这个盒子放在另一个盒子(collection2)中。
另一种select是要么同时填写他们的两个或做一个代码来复制内容
for i = 1 to collection1.count collection2.add collection1.item(i) next i