你可以直接在excel VBA中声明锯齿状的数组吗?

在我的项目中,我工作了很多锯齿状的数组,即元素也是数组的数组。

直到知道我只设法这样定义这些数组:

dim subarray(1 to 3) as Integer dim MyArray(1 to 5) as Variant subarray(1) = 40 subarray(2) = 50 subarray(3) = 60 MyArray(1) = subarray 

但是我想要做这样的事情:

 dim MyArray(1 to 5)(1 to 3) as Variant/Integer MyArray(1)(1) = 40 

上面的例子不能编译。 有没有类似的,有效的方式来直接声明嵌套数组?

编辑:正确的术语是“锯齿状数组”而不是“嵌套数组”。

编辑2:编辑示例值,以防止索引和值之间的混淆。

在VBA中有多种方法来collections集合。 他们都有好处和缺点。

multidimensional array

好:

  • 简单的语法(只有一个variables)
  • types安全。 Integermatrix的所有元素都是已知的并且被强制为Integer
  • 非常快的数组访问

坏:

  • 如果内部arrays的大小有很大差异,matrix将会浪费一些空间,因为matrix中有未使用的“单元”。
  • 您只能使用ReDim Preserve更改最后一个维度的边界。 所以你不能在没有清除所有数据的情况下将“列”添加到matrix中。

通过包含用逗号分隔的多个边界来声明multidimensional array:

 Dim intMatrix(0 to 2, 0 to 4) As Integer 

如果首先声明数组没有任何边界,则可以dynamic增加multidimensional array的最后一维:

 Dim intMatrix() As Integer ' Uninitialized dynamic array ReDim intMatrix(0 to 4, 0 to 2) ' Initialize as a matrix ReDim Preserve intMatrix(0 to 4, 0 to 3) ' Add another "row" to the matrix, preserving existing data 

锯齿的数组

好:

  • 灵活

坏:

  • 您会失去编译时types的安全性
  • 由于嵌套结构,它们有点棘手/混乱
  • 调整内部数组的大小是很笨拙和昂贵的

你可以创build锯齿状数组,声明Variant()types的外部数组,并将其他数组指定给外部数组的元素:

 Dim outer() As Variant ' Dynamic, so new inner arrays can be added Dim inner() As Integer ' Dynamic, so new elements can be added ReDim outer(0 to 3) ReDim inner(0 to 4) outer(2) = inner 

编译时types信息丢失

所有的编译器“知道”外部数组是可以包含任何东西的 。 所以下面的代码将被编译:

 Set objWorksheet = outer(2)(3) 

虽然在运行时这将导致一个错误,因为outer(2)的内部数组包含Integers ,而不是Worksheet对象。

尴尬调整

锯齿状arrays的好处之一是内部arrays可以具有不同的尺寸。 但是,您不能直接调整内部数组的大小。 VBA不能处理语法; 以下不编译:

 ReDim Preserve outer(2)(0 to 5) 

为了调整内部数组的大小,首先必须将内部数组分配给一个单独的variables,调整该variables的大小,然后将其分配回锯齿形数组:

 Dim tempInts() As Integer tempInts = outer(2) ReDim Preserve tempInts(0 to 5) outer(2) = tempInts 

您必须将tempInts重新分配给outer数组的原因是数组在VBA中使用了按值的语义。 这意味着当你给一个variables分配一个数组时(如tempInts = outer(2) ,你复制整个数组。如果你的数组很长(比如几千个元素)数组包含string,因为每个string也必须被复制。

锯齿集合

好:

  • 简单的添加和删除元素的语法
  • 就像锯齿状arrays一样灵活
  • 集合使用引用语义,因此分配很便宜,并且可以对同一个集合对象有多个引用

坏:

  • 像锯齿状的数组,没有types安全性

如果您将频繁地向内部数组添加元素,则使用Collection对象而不是数组会更容易。 Collection不强制其元素的数据types,所以这与使用Variant数组具有相同的缺点 – 但是您必须这样做才能使用锯齿状数组。

 Dim cAnimals As New Collection ' Let's add stats on the Cheetah Dim cCheetah As New Collection ' Easy to add inner collections to the outer collection. Also, cCheetah refers ' to the same collection object as cAnimals(1). cAnimals.Add cCheetah ' Easy to add items to inner collection. ' Working directly with the cCheetah collection: For Each vMeasurment In GetMeasurements("Cheetah") cCheetah.Add vMeasurement Next ' Working on the same collection by indexing into the outer object For i = 1 To cAnimals.Count For j = 1 To cAnimals(i).Count cAnimals(i)(j) = cAnimals(i)(j) * dblNormalizingFactor Next Next 

正如Joshua所说:没有直接声明锯齿状数组的特定VBA语法。
但是锯齿形数组遵循正常的VBA规则进行赋值:例如

 Dim a as integer dim v as variant a=17 v=a a=19 

你不要指望V现在等于19!

数组arrays:

 Dim aa(), ax(), dd, x(), xx(), x2() ' all are " As Variant" ' Array of Arrays - Variant(0 To 2) with 3 Variant(0 To 2) ( 3 Variant/Integer each ) aa = Array( Array(1, 2, 3), Array(4, 5, 6), Array(7, 8, 9) ) aa(0)(0) = 0 ' Array of "Excel" arrays - Variant(0 To 2) with 3 Variant(1 To 3) (3 Variant/Integer each) ax = Array([{1,2,3}], [{4,5,6}], [{7,8,9}]) ax(0)(1) = 0 

另一个选项是collections集或字典词典:

 Set dd = CreateObject("Scripting.Dictionary") Set dd(2) = CreateObject("Scripting.Dictionary") dd(2)(4) = 24 

一些“Excel”矩形数组示例(因为不是VBAtypes,也适用于Excel公式):

 ' "row" array starts at 1 - Variant(1 To 3) with 3 Variant/Integer each x = [{1,2,3}] x(1) = 0 ' "column" array starts at 1, 1 - Variant(1 To 3, 1 To 1) xx = [{1;2;3}] xx(1, 1) = 0 ' "Excel" rectangular array - Variant(1 To 3, 1 To 3) x2 = [{1,2,3;4,5,6;7,8,9}] x2(1, 1) = 0 Stop ' pause to check the types in the Locals window