我正在尝试在excel中返回一个数组。我一直在使用此网站作为参考:http://www.cpearson.com/excel/returningarraysfromvba.aspx
所以我开始使用这个基本的示例脚本,它返回一个值矩阵(取自上面的网站):
Function Test() As Variant
Dim V() As Variant
Dim N As Long
Dim R As Long
Dim C As Long
ReDim V(1 To 3, 1 To 4)
For R = 1 To 3
For C = 1 To 4
N = N + 1
V(R, C) = N
Next C
Next R
Test = V
End Function
当我使用=Test()
将ctrl+shift+enter
键入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时,我认为我没有办法诊断为什么以上只返回{{1}}。我做错了什么?
答案 0 :(得分:3)
来自ReDim statement上的MSDN页面:
- 使用Preserve调整大小。如果使用“保留”,则只能调整阵列的最后一个维度。对于每个其他维度,您必须指定现有数组的边界 例如,如果您的数组只有一个维度,则可以调整该维度的大小并保留数组的所有内容,因为您要更改最后一个维度。但是,如果您的数组有两个或更多维度,则可以在使用“保留”时更改最后一个维度的大小。
所以问题是试图重新开始第一个排名( R 或第一维)。你不能用Preserve做到这一点。但是,您可以使用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
我已经看到这个用在一个循环中以放置更多的行'转换成二维数组,但转置有限制,它是额外的处理,虽然在内存中。
答案 1 :(得分:2)
在我的测试中,在直接窗口中调用此方法会抛出并索引越界错误。然后我逐步完成了代码,问题是以下几行:
ReDim Preserve V(1 To R, 1 To C)
对于For R
循环中的第一次运行(当R为1时),这没有问题,当内部(1 to 1, 1 to 4)
循环结束时,数组的大小将为For C
。
但是只要For R
进入第二个循环(当R为2时),它就会调整为(1 to 2, 1 to 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
然后,您可以使用此公式在数组公式(ctrl+shift+enter
)中对3x4单元格范围使用该方法:
=Test(3; 4)