使用数组填充集合

时间:2009-09-10 00:46:39

标签: vb.net vba vb6 excel-vba excel

Dim A As Collection
Set A = New Collection

Dim Arr2(15, 5)
Arr2(1,1) = 0
' ...

A.Add (Arr2)

如何通过Arr2访问A?例如,我想要执行以下操作:

A.Item(1) (1,1) = 15

所以上面会改变集合中第一个二维数组的第一个元素......

5 个答案:

答案 0 :(得分:8)

嗯...语法看起来很合法而没有VBA在我面前。我是对的,你的问题是你的代码“编译”并执行而不会引发错误,但集合中的数组永远不会改变?如果是这样,我认为那是因为您的A.Item(1)可能正在返回您存储在集合中的数组的副本。然后,您可以正常访问和修改所选元素,但它没有您想要的效果,因为它是错误的数组实例。

通常,VBA集合在存储对象时效果最佳。然后他们会像你想要的那样工作,因为他们存储了引用。它们适用于存储值,但我认为它们总是复制它们,甚至像数组变体这样的“大”,这意味着你不能改变存储数组的内容。

考虑这个答案只是一个推测,直到知道基础COM东西的人更好地权衡。嗯...寻呼Joel Spolsky?

编辑:在Excel VBA中尝试此操作后,我认为我是对的。将数组变体放在一个集合中会产生一个副本,因此将其中一个变为一个副本。因此,似乎没有直接的方法来编码您实际要求的内容。

看起来你真正想要的是一个三维数组,但是你想要为第一个维度使用一个集合的事实意味着你希望能够在那个维度上改变它的大小。 VBA只允许您更改数组最后一个维度的大小(请参阅帮助中的“redim preserve”)。您可以将您的二维数组放入一个可以改变大小的一维数组中:

ReDim a(5)
Dim b(2, 2)
a(2) = b
a(2)(1, 1) = 42
ReDim Preserve a(6)

请注意,a用ReDim声明,在这种情况下不是Dim。

最后,很有可能对你正在尝试做的任何其他方法会更好。至少可以说,可增长的,可变的3-D阵列很复杂且容易出错。

答案 1 :(得分:5)

@jtolle是正确的。如果你运行下面的代码并检查Arr2和x的值(Quick Watch是Shift-F9),你会发现它们是不同的:

Dim A As Collection
Set A = New Collection
Dim Arr2(15, 5)

Arr2(1, 1) = 99

' ...

A.Add (Arr2) ' adds a copy of Arr2 to teh collection

Arr2(1, 1) = 11  ' this alters the value in Arr2, but not the copy in the collection

Dim x As Variant

x = A.Item(1)
x(1, 1) = 15  ' this does not alter Arr2

答案 2 :(得分:2)

也许VBA在将数组分配给集合时会复制该数组? VB.net没有这样做。在此代码之后,(3,3)在vba中为20,在vb.net中为5。

Dim c As New Collection
Dim a(10, 10) As Integer

a(3, 3) = 20
c.Add(a)
c(1)(3, 3) = 5

答案 3 :(得分:1)

我最近有这个问题。我通过使用有问题的项数组填充数组来进行循环,对此数组进行更改,从集合中删除项数组,然后将更改的数组添加到集合中。不漂亮,但它起作用....我找不到另一种方式。

答案 4 :(得分:0)

如果希望集合具有数组的副本,而不是对数组的引用,则使用array.clone方法: -

Dim myCollection As New Collection
Dim myDates() as Date
Dim i As Integer

Do
   i = 0
   Array.Resize(myDates, 0)
   Do
       Array.Resize(myDates, i + 1)
       myDates(i) = Now
       ...
       i += 1
   Loop
   myCollection.Add(myDates.Clone)
Loop

最后,myCollection将包含myDates()的累积集合。