Vba 如何调整循环中数组的大小?
我正在尝试返回excel中的数组。我一直在使用此网站作为参考: 因此,我从这个基本示例脚本开始,它返回一个值矩阵(取自上述站点): 当我使用Vba 如何调整循环中数组的大小?,vba,excel,Vba,Excel,我正在尝试返回excel中的数组。我一直在使用此网站作为参考: 因此,我从这个基本示例脚本开始,它返回一个值矩阵(取自上述站点): 当我使用ctrl+shift+enter将=Test()键入3x4个单元格范围时,我得到了预期的结果: 1 2 3 4 5 6 7 8 9 10 11 12 现在假设我想在填充数组时调整数组的大小。我尝试将函数更改为: Function Test() As Variant Dim V() As Variant Dim N As Lon
ctrl+shift+enter
将=Test()
键入3x4个单元格范围时,我得到了预期的结果:
1 2 3 4
5 6 7 8
9 10 11 12
现在假设我想在填充数组时调整数组的大小。我尝试将函数更改为:
Function Test() As Variant
Dim V() As Variant
Dim N As Long
Dim R As Long
Dim C As Long
For R = 1 To 3
For C = 1 To 4
N = N + 1
ReDim Preserve V(1 To R, 1 To C)
V(R, C) = N
Next C
Next R
Test = V
End Function
当我使用vba IDE时,我想我没有任何方法来诊断为什么上面的代码只返回
#VALUE
。我做错了什么?在直接窗口中调用此方法会在我的测试中引发索引越界错误。然后我通过代码,问题是以下几行:
ReDim Preserve V(1 To R, 1 To C)
对于R循环的中的第一次运行(当R为1时),这没有问题,当C
循环的内部结束时,数组的大小将调整为(1到1,1到4)
但是,一旦R的进入第二个循环(当R为2时),它的大小将调整为(1到2,1到1)
,因此有效地尝试减小第二维度的大小,这会由于Preserve
语句而引发错误。删除Preserve
语句可以消除错误,但也会导致第二维度内的数据丢失
要解决这个问题,您必须在开始循环数组并填充它之前设置数组维度的最终大小(因此您永远不会减小大小)。但尺寸的大小可以是动态的,例如作为方法参数提供,如下所示:
Function Test(MaxR As Long, MaxC As Long) As Variant
Dim V() As Variant
Dim N As Long
Dim R As Long
Dim C As Long
'Set array size
ReDim Preserve V(1 To MaxR, 1 To MaxC)
'Then start filling array
For R = 1 To MaxR
For C = 1 To MaxC
N = N + 1
V(R, C) = N
Next C
Next R
Test = V
End Function
然后,您可以使用以下公式在3x4单元格范围的数组公式(ctrl+shift+enter
)中使用该方法:
=Test(3; 4)
从上的MSDN页面:
- 使用Preserve调整大小。如果使用“保留”,则只能调整数组的最后一个维度的大小。对于每个其他维度,必须指定现有数组的边界。
例如,如果数组只有一个维度,则可以调整该维度的大小,但仍保留数组的所有内容,因为您正在更改最后一个也是唯一一个维度。但是,如果数组有两个或多个维度,如果使用“保留”,则只能更改最后一个维度的大小
因此,问题是试图重新划分第一个等级(即R或第一维度)。您不能使用Preserve来执行此操作。然而,你可以用你想要的一切保留重新划分第二等级(C或第二维度)
ReDim Preserve V(1 To 3, 1 To 1)
For R = 1 To 3
For C = 1 To 4
N = N + 1
ReDim Preserve V(LBound(V, 1) To UBound(V, 1), 1 To C)
V(R, C) = N
Next C
Next R
如果重新定义二维阵列的第一列是至关重要的任务,那么首先对其进行转置
ReDim Preserve V(1 To 1, 1 To 1)
For R = 1 To 3
V = application.Transpose(V)
ReDim Preserve V(LBound(V, 1) To UBound(V, 1), LBound(V, 2) To R)
V = application.Transpose(V)
For C = 1 To 4
N = N + 1
ReDim Preserve V(LBound(V, 1) To UBound(V, 1), LBound(V, 2) To C)
V(R, C) = N
Next C
Next R
我在循环中看到过这种方法,可以将更多的“行”放入二维数组中,但转置有其局限性,它是额外的处理,尽管是在内存中。这种方法行不通。当R=2
和C=1
时,将删除您在先前迭代中分配的V(1,2)
和V(1,3)
。你想要实现什么?最终你的数组将是3x4大,那么为什么…?酷,我没有意识到你可以在excel IDE中单步执行代码,我会查一下:)事实上这很简单。在代码的左侧有一个空的“条”。在特定代码行上单击它将设置一个“断点”(红点和红线将标记为红色),调试器将在此处停止。然后可以使用F8单步执行代码。请参见屏幕截图;)
ReDim Preserve V(1 To 1, 1 To 1)
For R = 1 To 3
V = application.Transpose(V)
ReDim Preserve V(LBound(V, 1) To UBound(V, 1), LBound(V, 2) To R)
V = application.Transpose(V)
For C = 1 To 4
N = N + 1
ReDim Preserve V(LBound(V, 1) To UBound(V, 1), LBound(V, 2) To C)
V(R, C) = N
Next C
Next R