ReDim保留从1维到2维

时间:2015-10-15 21:16:42

标签: arrays excel vba excel-vba

我有一维数组:

Dim array1() As Variant
array1 = Array("A", "B", "C", "D")

概念上看起来像这样:

A
B
C
D

我想在此数组中添加第二个维度,保留原始数据。我想添加两个"列"到这个数组来存储数据。

Dim lngArrayLength as Long
lngArrayLength = UBound(array1, 1)

' Zero-indexed, so now should have 3 columns
ReDim Preserve array1(lngArrayLength, 2)

导致:

A    NULL    NULL
B    NULL    NULL
C    NULL    NULL
D    NULL    NULL

问题是我的ReDim Preserve命令抛出了运行时错误:' 9':下标超出范围错误。我无法弄清楚原因。

2 个答案:

答案 0 :(得分:2)

这是一种俗气的解决方案:

Dim Array1() As Variant, TempArray() As Variant

Array1 = Array("A", "B", "C", "D", "E")
ReDim TempArray(0 To UBound(Array1), 0 To 2)

For i = 0 To UBound(Array1)
    TempArray(i, 0) = Array1(i)
Next i
Array1 = TempArray

答案 1 :(得分:2)

ReDim无法将数组重新调整为更大的等级(维度数)。

解决这个问题的常用方法是创建一个你想要的新数组,并循环遍历原始数组的所有元素,将它们逐个分配给新数组。

这是一个有趣的替代方案,在没有VBA循环元素的情况下可以完成相同的事情并不广为人知:

array1D = Array("A", "B", "C", "D")

array2D = Evaluate("{""" & Join(array1D, """;""") & """}&{"""","""",""""}")

结果:1​​D数组将转换为2维(3列宽,第1列中的源)。

结果:两个新列将保存与第一列完全相同的数据,但您现在可以自由地将所需的新值分配给新列。

警告:每个维度的下限都是1。

警告:这是针对文本数组的。类似的方法可以用于数值数组。

警告:原始数组元素不能包含任何分号。

上述方法最大的一点是,VBA的Evaluate()函数可以处理的字符串的最大长度只有255个字符。为了绕过这个限制,我们在评估期间使用函数调用,如下所示:

Private array1D

Public Sub Array1dTo2d()

    array1D = Array("A", "B", "C", "D")

    array2D = [transpose(Arr())&{"","",""}]

End Sub

Private Function Arr()
    Arr = array1D
End Function

<强>更新

这是一种实现此方法的动态方法,因此很容易指定生成的2D数组中的列数。

只需运行TestArrayConversions()例程即可看到三个不同的示例:

Private array_

Public Sub TestArrayConversions()

    array1 = Array("A", "B", "C", "D")
    array1 = Array1dTo2d(array1, 3)
    MsgBox "2D array has:" & vbLf & UBound(array1, 1) & " rows" & vbLf & UBound(array1, 2) & " columns"

    array1 = Array("A", "B", "C", "D", "E", "F", "G", "H")
    array1 = Array1dTo2d(array1, 25)
    MsgBox "2D array has:" & vbLf & UBound(array1, 1) & " rows" & vbLf & UBound(array1, 2) & " columns"

    array1 = Array("we", "can", "do", "it")
    array1 = Array1dTo2d(array1, 6)
    MsgBox "2D array has:" & vbLf & UBound(array1, 1) & " rows" & vbLf & UBound(array1, 2) & " columns"

End Sub

Public Function Array1dTo2d(arr1D, columns)
    array_ = arr1D
    Array1dTo2d = Evaluate("transpose(Arr())&{" & Application.Rept(""""",", columns - 1) & """""}")
End Function

Private Function Arr()
    Arr = array_
End Function