Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 如何调整循环中数组的大小?_Vba_Excel - Fatal编程技术网

Vba 如何调整循环中数组的大小?

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

我正在尝试返回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 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