在我的项目中,我使用锯齿状数组工作很多,即元素也是数组的数组。
直到知道我才设法定义这样的数组:
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
上面的示例无法编译。是否有类似的有效方法直接声明嵌套数组?
编辑:正确的术语是'锯齿状数组'而不是'嵌套数组'。
EDIT2:编辑示例值,以防止索引和值之间的混淆。
答案 0 :(得分:12)
VBA中有多种方法可以收集集合。所有这些都有利有弊。
多维数组
好:
Integer
矩阵的所有元素都已知并强制为Integer
s。 坏:
ReDim Preserve
更改最后一个维度的范围。因此,您无法在不清除所有数据的情况下将“列”添加到矩阵中。通过包含用逗号分隔的多个边界来声明多维数组:
Dim intMatrix(0 to 2, 0 to 4) As Integer
如果您首先声明没有任何边界的数组,则可以动态增加多维数组的最后一个维度:
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
锯齿状阵列
好:
为:
您可以创建锯齿状数组,声明类型为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
丢失编译时类型信息
关于外部数组的所有编译器“知道”是它可以包含任何。所以下面的代码将编译:
Set objWorksheet = outer(2)(3)
虽然在运行时这会导致错误,因为outer(2)
的内部数组包含Integers
,而不是Worksheet
个对象。
调整大小
的尴尬锯齿状阵列的一个好处是内部阵列可以有不同的大小。但是,您无法直接调整内部数组的大小。 VBA只是无法处理语法;以下内容无法编译:
ReDim Preserve outer(2)(0 to 5)
为了调整内部数组的大小,首先必须将内部数组分配给单独的变量,调整该变量的大小,然后将其分配回锯齿状数组:
Dim tempInts() As Integer
tempInts = outer(2)
ReDim Preserve tempInts(0 to 5)
outer(2) = tempInts
您必须将tempInts
重新分配回outer
数组的原因是数组在VBA中使用按值语义。这意味着当你为一个变量分配一个数组时(如在tempInts = outer(2)
中,你复制整个数组。如果你的数组很长(比如几千个元素),这可能会非常昂贵,如果你的数组更贵包含字符串,因为每个字符串也必须被复制。
Jagged Collections
好:
为:
如果要经常向内部数组添加元素,使用Collection
个对象而不是数组将会容易得多。 Collection
不强制执行其元素的数据类型,因此使用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
答案 1 :(得分:0)
正如Joshua所说:没有特定的VBA语法可以直接声明锯齿状数组。
但Jagged数组遵循正常的VBA规则进行分配:例如
Dim a as integer
dim v as variant
a=17
v=a
a=19
你不希望V现在等于19!
答案 2 :(得分:0)
数组:
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
另一个选项是集合集合或词典词典:
Set dd = CreateObject("Scripting.Dictionary")
Set dd(2) = CreateObject("Scripting.Dictionary")
dd(2)(4) = 24
<小时/> 一些“Excel”矩形数组示例(因为不是VBA类型,也适用于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