Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/68.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
Excel 如何使用子元素填充(动态)数组的值_Excel_Vba - Fatal编程技术网

Excel 如何使用子元素填充(动态)数组的值

Excel 如何使用子元素填充(动态)数组的值,excel,vba,Excel,Vba,我想使用Sub读取excel工作簿中某列的值(从单元格(3,1))然后将数组传递给主函数,但Sub中获取的值不会返回到主函数中的数组 我目前在单元格(3,1)和(4,1)中有值,我知道子模块可以工作,因为我在子模块中放入了一个消息框,它可以读取这两个值 我试着将Sub转换成一个函数,将Sub参数的名称更改为与主函数(tru des)中的数组相同的名称,还有很多类似的东西 Option Explicit Private Sub cmd_openform_Click() '"Main" functi

我想使用Sub读取excel工作簿中某列的值(从
单元格(3,1)
)然后将数组传递给主函数,但Sub中获取的值不会返回到主函数中的数组

我目前在
单元格(3,1)
(4,1)
中有值,我知道子模块可以工作,因为我在子模块中放入了一个消息框,它可以读取这两个值

我试着将Sub转换成一个函数,将Sub参数的名称更改为与主函数(tru des)中的数组相同的名称,还有很多类似的东西

Option Explicit
Private Sub cmd_openform_Click() '"Main" function
    Dim tr_des() As String
        Call getDescriptions(tr_des)
    uf_TestSelector.Show vbModal    'shows properly
    MsgBox tr_des(1)    'shows empty MsgBox
End Sub
Sub-getdescription(ByRef des_array()作为字符串)
尺寸描述为字符串,尺寸描述为整数
作为整数的Dim i
i=0
尺寸=1
ReDim des_阵列(大小)
执行While单元格(i+3,1)。值“”
des_数组(i)=单元格(i+3,1).值
MsgBox des_array(i)'两次都以正确的值打开MsgBox
尺寸=尺寸+1
ReDim des_阵列(大小)
i=i+1
环
端接头

我希望
MsgBox tru des(1)
从excel工作表的列返回一个值,但它总是返回一个空的MsgBox

您需要使用
ReDim Preserve

如果在
ReDim
之后执行
MsgBox des_array(i)
,您将看到值消失了:)

(不带
Preserve
)将数组重新分配到指定的维度。使用
ReDim Preserve
可以在不删除数组内容的情况下增加数组的大小

如果使用
Preserve
关键字,则只能调整最后一个数组维度的大小,并且根本无法更改维度的数量。例如,如果数组只有一个维度,则可以调整该维度的大小,因为它是最后一个也是唯一的维度。但是,如果数组有两个或多个维度,则可以仅更改最后一个维度的大小,同时仍保留数组的内容


@DavidZemens引入了
ReDim Preserve
作为解决您的问题的一种方法。我推荐一种不同的编程方法,以避免昂贵的VBA
Preserve
操作(性能损失在大型阵列上可能很明显,但在您的情况下可能并不重要)

这种方法使用了一种功能范例,其中计算了一个新的数组。下面是基于代码的简单重写

Option Explicit
Private Sub cmd_openform_Click() '"Main" function
Dim tr_des As Variant
    tr_des = getDescriptions
    uf_TestSelector.Show vbModal    'shows properly
    MsgBox tr_des(1)    
End Sub

Function getDescriptions() as Variant
Dim tValidRange as Range
Dim i As Integer
    Set tValidRange = Nothing ' Not really required but nice to be explicit
    i = 0
    Do While Cells(i + 3, 1).Value <> ""
        If tValidRange is Nothing Then
            Set tValidRange  = Cells(i + 3, 1)
        Else
            Set tValidRange  = Union(tValidRange,Cells(i + 3, 1))
            'Set tValidRange  = tValidRange.Resize(tValidRange.Rows.COunt + 1,1) ' Alternate approach
        End If
        i = i + 1
    Loop
    getDescriptions = tValidRange.Value ' Places values into an array.
End Sub
选项显式
Private Sub cmd_openform_Click()'“Main”函数
作为变体的Dim tr_des
tr_des=getDescriptions
uf_TestSelector.Show vbModal'正确显示
MsgBox tr_des(1)
端接头
函数getDescriptions()作为变量
变暗tValidRange作为范围
作为整数的Dim i
Set tValidRange=Nothing“不是真正需要的,但是很好的明确
i=0
执行While单元格(i+3,1)。值“”
如果tValidRange什么都不是
设置tValidRange=单元格(i+3,1)
其他的
设置tValidRange=Union(tValidRange,单元格(i+3,1))
“设置tValidRange=tValidRange.Resize(tValidRange.Rows.COunt+1,1)”替代方法
如果结束
i=i+1
环
getDescriptions=tValidRange.Value'将值放入数组中。
端接头
当然,新的思维方式会导致代码的进一步细化

Function getDescriptions() as Variant
Dim tValidRange as Range
Dim tRangeToCheck as Range
Dim i As Integer
    Set tValidRange = Nothing ' Not really required but nice to be explicit
    Set tRangeToCheck = Cells(3,1) 'This really should be fully qualified but ...
        ' ... you have not provided enough information for an example.

    Do While tRangeToCheck.Value <> ""
        If tValidRange is Nothing Then
            Set tValidRange  = tRangeToCheck
        Else
            Set tValidRange  = tValidRange.Resize(tValidRange.Rows.Count + 1,1) ' expand range down by one row.
        End If
        Set tRangeToCheck = tRangeToCheck.Offset(1,0) ' move down one row
    Loop
    getDescriptions = tValidRange.Value ' Places values into an array.
End Sub
函数getDescriptions()作为变量 变暗tValidRange作为范围 Dim tRangeToCheck as范围 作为整数的Dim i Set tValidRange=Nothing“不是真正需要的,但是很好的明确 设置tRangeToCheck=Cells(3,1)'这确实应该是完全限定的,但是。。。 ' ... 您没有为示例提供足够的信息。 在TransGetOcheck.Value“”时执行此操作 如果tValidRange什么都不是 设置tValidRange=transgetocheck 其他的 设置tValidRange=tValidRange.Resize(tValidRange.Rows.Count+1,1)“将范围向下扩展一行。 如果结束 设置tRangeToCheck=tRangeToCheck.Offset(1,0)'向下移动一行 环 getDescriptions=tValidRange.Value'将值放入数组中。 端接头
Function getDescriptions() as Variant
Dim tValidRange as Range
Dim tRangeToCheck as Range
Dim i As Integer
    Set tValidRange = Nothing ' Not really required but nice to be explicit
    Set tRangeToCheck = Cells(3,1) 'This really should be fully qualified but ...
        ' ... you have not provided enough information for an example.

    Do While tRangeToCheck.Value <> ""
        If tValidRange is Nothing Then
            Set tValidRange  = tRangeToCheck
        Else
            Set tValidRange  = tValidRange.Resize(tValidRange.Rows.Count + 1,1) ' expand range down by one row.
        End If
        Set tRangeToCheck = tRangeToCheck.Offset(1,0) ' move down one row
    Loop
    getDescriptions = tValidRange.Value ' Places values into an array.
End Sub