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

Jaz*_*eus 2 arrays 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
Run Code Online (Sandbox Code Playgroud)

但我想做这样的事情:

dim MyArray(1 to 5)(1 to 3) as Variant/Integer
MyArray(1)(1) = 40
Run Code Online (Sandbox Code Playgroud)

上面的例子没有编译.是否有类似的有效方法直接声明嵌套数组?

编辑:正确的术语是'锯齿状数组'而不是'嵌套数组'.

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

Jos*_*nig 12

VBA中有多种方法可以收集集合.所有这些都有利有弊.

多维数组

好:

  • 语法简单(只有一个变量)
  • 类型安全.矩阵的所有元素Integer都是已知的并且被强制为Integers.
  • 非常快速的阵列访问

坏:

  • 如果内部数组的大小存在很大差异,则矩阵将浪费一些空间,因为矩阵中存在未使用的"单元".
  • 您只能使用更改最后一个维度的边界ReDim Preserve.因此,您无法在不清除所有数据的情况下将"列"添加到矩阵中.

通过包含用逗号分隔的多个边界来声明多维数组:

Dim intMatrix(0 to 2, 0 to 4) As Integer
Run Code Online (Sandbox Code Playgroud)

如果首先声明没有任何边界的数组,则可以动态增加多维数组的最后一个维度:

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
Run Code Online (Sandbox Code Playgroud)

锯齿状阵列

好:

  • 灵活

坏:

  • 你失去了编译时类型的安全性
  • 由于嵌套结构,它们有点棘手/混乱
  • 调整内部数组的大小既笨拙又昂贵

您可以创建锯齿状数组,声明类型的外部数组Variant(),并将其他数组分配给外部数组的元素:

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
Run Code Online (Sandbox Code Playgroud)

丢失编译时类型信息

所有编译器"知道"外部数组是它可以包含任何东西.所以下面的代码将编译:

Set objWorksheet = outer(2)(3)
Run Code Online (Sandbox Code Playgroud)

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

调整大小的尴尬

锯齿状阵列的一个好处是内部阵列可以具有不同的大小.但是,您无法直接调整内部数组的大小.VBA只是无法处理语法; 以下内容无法编译:

ReDim Preserve outer(2)(0 to 5)
Run Code Online (Sandbox Code Playgroud)

为了调整内阵列,首先必须内阵列分配给一个单独的变量,调整大小该变量,并且然后将其指定返回到交错数组:

Dim tempInts() As Integer
tempInts = outer(2)
ReDim Preserve tempInts(0 to 5)
outer(2) = tempInts
Run Code Online (Sandbox Code Playgroud)

您必须重新分配tempIntsouter数组的原因是数组在VBA中使用按值语义.当你将数组分配给一个变量(如意味着tempInts = outer(2),你将整个阵列,这是非常昂贵的,如果你的数组是长(比如几千元素),甚至更昂贵,如果您的数组包含字符串,因为每还必须复制单个字符串.

铁血收藏

好:

  • 添加和删​​除元素的简单语法
  • 就像锯齿状阵列一样灵活
  • 集合使用by-reference语义,因此赋值很便宜,并且您可以对同一个集合对象进行多次引用

坏:

  • 像锯齿状阵列一样,没有类型安全性

如果要经常向内部数组添加元素,则使用Collection对象而不是数组会容易得多.Collections不强制执行其元素的数据类型,因此这具有使用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
Run Code Online (Sandbox Code Playgroud)