克隆一个集合

我有两个集合 – collection1collection2

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 CollectionSet 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