在Excel 2007 VBA中如何“ReDim保留”二维数组,以便我可以添加行而不是列到数组?

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

帮助文件指出,ReDim保留myArray(n,m)允许我做大,但不是n。 但是,我需要增加行数(n),同时保留我的数据,而不是列(m)!

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

看来,如果有一些方法来转置我的数组,做一个ReDim保留来扩大“列”的数量,然后重新转置我的数组,我可以完成我想要的。

这是正确的方法来做到这一点? 如果是这样,我该怎么做?

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

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

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

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 

我对这些问题的回答可能对您也有用:将multidimensional array传递到VBA和VBA中的 Excel UDF, 将三维数组粘贴到表中

当然,如果你不从UDF返回,你必须自己强制它。 不用编写循环代码就可以做到这一点:

 Dim coerced coerced = Application.Index(outer, 0, 0) 

这只是调用Excel的内置INDEX函数,而零表示您要将所有行和所有列都备份。 Excel将自动将1-D数组的1-D数组强制转换为2-D数组。 (注意:有一些尺寸限制,但是比10×20大得多。)

如果你是开发者 – 行和列之间有什么区别? 使用数组(N,2)(如果有2列)与数组(2,N)相同 – 为此可以

 ReDim Preserve arr(1 to 2, 1 to N+1). 

你(作为开发人员)的区别是把循环中的variables放在第二位,而不是第一位:

 N = ubound(arr) FOR i=1 to N GetColumn1Value = arr(1, i) GetColumn2Value = arr(2, i) NEXT i 

或者你想要这个:

 N = ubound(arr) FOR i=1 to N GetColumn1Value = arr(i, 1) GetColumn2Value = arr(i, 2) NEXT i 

有什么不同?

一种方法可以解决这个问题的确是通过两次转置来改变中间的列数。 这将只适用于二维数组。 完成如下:

 ' 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) 

当然, mn可以推导如下:

 m = UBound(myArray, 1) n = UBound(myArray, 2) 

所以你使用Excel本身的内置转置function。 正如代码注释中所提到的,这对于更高阶的matrix不起作用。

“转置”这个词立即浮现在脑海中。 您可以简单地通过翻转列和行(即转置)将数据input到二维数组中,从而有效地允许您在需要时使n(现在的列数,但存储行值)变大。

为了引用这些值,例如在双循环中,交换指数。 例如,从i = 1到n和j = 1到m,其中您参考值(i,j),使用i = 1到m和j = 1到n。

解决了我自己的问题; 这是我如何解决我的问题。 我创build了一个临时数组,将myArray的内容复制到临时数组,调整了myArray的大小,然后将内容从temp数组复制到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 

如果有人能提出一个更有效的方法来做到这一点,我很乐意听到。

可以像这样创build一个2维数组,其中列数是固定的,行数是dynamic的:

 Sub test2DimArray() Dim Arr2D() As String Dim NumberOfCol As Long Dim I As Long, J As Long, x As Long Dim tmpValue As String, tmpValue2 As String, tmpValue3 As String NumberOfCol = 3 J = 1 Debug.Print "Run " & Now() Debug.Print "Sheet content" Debug.Print "Row col1 col2 col3" For I = 1 To 10 tmpValue = Cells(I, 1).Value tmpValue2 = Cells(I, 2).Value tmpValue3 = Cells(I, 3).Value Debug.Print I & " = " & tmpValue & " " & tmpValue2 & " " & tmpValue3 If Len(tmpValue) > 0 Then ReDim Preserve Arr2D(NumberOfCol, 1 To J) Arr2D(1, J) = tmpValue Arr2D(2, J) = tmpValue2 Arr2D(3, J) = tmpValue3 J = J + 1 End If Next 'check array values Debug.Print vbLf; "arr2d content" Debug.Print "Row col1 col2 col3" For x = LBound(Arr2D, 2) To UBound(Arr2D, 2) Debug.Print x & " = " & Arr2D(1, x) & " " & Arr2D(2, x) & " " & Arr2D(3, x) Next Debug.Print "=========================" End Sub 

从单元格A1:A10中读取TempValue,如果单元格Ax中存在一个值,则使用+1对数组进行重新定位,并向数组col1中添加Tempvalue,将Bx中的内容添加到数组col2中,将Cx中的内容添加到数组col3中。 如果Ax值的长度为0,则不会向数组添加任何内容。

Debug.print将结果显示在VB编辑器的“立即窗口”中。

没有testing线,并添加一个dynamic的数据范围代码可以是:

 Sub my2DimArray() Dim Arr2D() As String Dim NumberOfCol As Long, NumberOfRow As Long Dim FirstCol As Long, FirstRow As Long, LastCol As Long, LastRow As Long Dim I As Long, J As Long, X As Long Dim tmpValue As String, tmpValue2 As String, tmpValue3 As String 'if cells with values start in A1 With ActiveSheet.UsedRange NumberOfCol = .Columns.Count NumberOfRow = .Rows.Count End With 'if cells with values starts elsewhere With ActiveSheet.UsedRange FirstCol = .Column FirstRow = .Row LastCol = .Column + .Columns.Count - 1 LastRow = .Row + .Rows.Count - 1 End With J = 1 For I = 1 To NumberOfRow 'or For I = FirstRow to LastRow tmpValue = Cells(I, 1).Value 'or tmpValue = Cells(I, FirstCol).Value If Len(tmpValue) > 0 Then ReDim Preserve Arr2D(NumberOfCol, 1 To J) For X = 1 To NumberOfCol 'or For X = FirstCol to LastCol Arr2D(X, J) = Cells(I, X).Value Next X J = J + 1 End If Next I End Sub 

没有办法确定第一维中的元素数量? 游民。 对于具有固定第二维的二维数组,您可能需要考虑将其作为types的数组(其他语言的“结构”)。 这将允许您使用Redim Preserve,并且仍然会以合理的方式添加和访问值,尽pipe您现在将以Type的名称成员身份访问第二个维度,而不是索引值。

强制或切片似乎不工作与索引(或匹配(索引(当我想过滤数组(W / O循环)基于多个条件,当数据的大小跨越2 ^ 16行(~92000行)。

 Run-Time error '13': Type Mismatch 

转置不适用于大logging集,所以双转置也不起作用。 反正没有去过滤一个数组并获取数据而不诉诸多个循环?

我正在考虑用Excel来尝试词典方式或ADO。