如何在Excel 2007 VBA中"ReDim保留"2D阵列,以便我可以向阵列添加行而不是列?

use*_*520 9 excel vba

我正在使用Excel VBA中的动态数组.列数(m)是固定的,但是,我不知道需要多少行(n).

帮助文档声明ReDim Preserve myArray(n,m)允许我使m更大,但不能使n更大.但是,我需要增加行数(n),同时保留我的数据,而不是列(m)!

例如,我可能有一个(5,20)数组,我想扩展到(10,20)同时保留我的数据.

似乎如果有一些方法来转置我的数组,做一个ReDim Preserve来扩展"列"的数量,然后重新转置我的数组,我可以完成我想要的.

这是正确的方法吗?如果是这样,我该怎么做?

有没有更好的方法来实现我想要的?

jto*_*lle 12

做你想做的事情的一种方法是使用包含1-D数组而不是2-D数组的1-D数组.然后你可以ReDim保留你想要的外部数组.如果从函数返回外部数组,Excel将执行正确的操作并将其强制转换为二维数组.

例如,下面的函数将返回一个3x2数组到它调用的单元格:

Public Function nested()
    Dim outer
    outer = Array(Array(1, 2), Array(3, 4))

    ReDim Preserve outer(1 To 3)

    outer(3) = Array(5, 6)

    nested = outer
End Function
Run Code Online (Sandbox Code Playgroud)

我对这些问题的回答可能对您有用:将多维数组传递到VBA中的Excel UDFVBA将3维数组粘贴到工作表中

当然,如果你不是从UDF返回这个,你必须自己强迫它.在不编写循环代码的情况下,这样做的简单方法是:

Dim coerced
coerced = Application.Index(outer, 0, 0)
Run Code Online (Sandbox Code Playgroud)

这只是调用Excel的内置INDEX函数,零表示您想要返回所有行和所有列.Excel会自动将1-D阵列的1-D阵列强制转换为2-D阵列.(警告:有一些尺寸限制,但它们比10x20大得多.)


小智 6

你可以通过双转置改变两者之间的列数来实现它的一种方式.然而,这仅适用于二维阵列.它完成如下:

' Adding one row is done by a double transposing and adding a column in between.
' (Excel VBA does not allow to change the size of the non-last dimension of a
' multidimensional array.)
myArray = Application.Transpose(myArray)
ReDim Preserve myArray(1 To m, 1 To n + 1)
myArray= Application.Transpose(myArray)
Run Code Online (Sandbox Code Playgroud)

当然m并且n可以推断如下:

m = UBound(myArray, 1)
n = UBound(myArray, 2)
Run Code Online (Sandbox Code Playgroud)

因此,您使用Excel本身的内置转置功能.正如代码注释中所提到的,这对高阶矩阵不起作用.


Nik*_*nov 5

如果您是开发人员 - 行和列之间有什么区别?使用数组(N,2)(如果有2列)与数组(2,N)相同 - 您可以使用它

ReDim Preserve arr(1 to 2, 1 to N+1). 
Run Code Online (Sandbox Code Playgroud)

而你(作为开发人员)的不同之处在于将循环中的变量放在第二位,而不是第一位:

N = ubound(arr)
FOR i=1 to N
    GetColumn1Value = arr(1, i)
    GetColumn2Value = arr(2, i)
NEXT i
Run Code Online (Sandbox Code Playgroud)

或者你想要这个:

N = ubound(arr)
FOR i=1 to N
    GetColumn1Value = arr(i, 1)
    GetColumn2Value = arr(i, 2)
NEXT i
Run Code Online (Sandbox Code Playgroud)

有什么不同?

  • 我完全意识到这个限制。我的意思是,我不能每次都简单地转置数组,或者对仅更改最后一个维度大小的可能性感到满意。 (2认同)

use*_*520 3

解决了我自己的问题;这就是我解决问题的方法。我创建了一个临时数组,将 myArray 的内容复制到临时数组,调整 myArray 的大小,然后将内容从临时数组复制回 myArray。

tempArray = myArray
ReDim myArray(1 To (UBound(myArray()) * 2), 1 To m)
For i = 1 To n
     For j = 1 To m
          myArray(i, j) = tempArray(i, j)
     Next j
Next i
Run Code Online (Sandbox Code Playgroud)

如果有人可以建议一种更有效的方法来做到这一点,我很乐意听到。

  • -1:数组的每次重整都有两个嵌套循环 - 根本不是一个好主意!如果你有一个包含 10 000 个元素的数组,会发生什么? (2认同)