迭代数组并将它们放入一个数组中

问题描述 投票:0回答:2

我正在尝试创建一个函数,该函数返回一个包含未指定数量的元素的数组。元素的数量取决于通过我的函数传递的元素的数量。

Public Function dekonstruer_update_statement(oppdateringsfelter As Variant, oppdateringsverdier As Variant, oppdateringsteller As Long, oppdateringstabell As String, oppdateringskriteriefelter As Variant, oppdateringskriterier As Variant, oppdateringskriterieteller As Long) As Variant 

函数中的所有“变体”都应该是 x 元素的数组,如下所示

(Array(value1, value2, value3...etc.))

我想迭代“数组”并将它们放入一个数组中。

Dim dekonstruerArray() As Variant
Dim i, j, k, l, m As Long

i = 0

For j = 0 To oppdateringsteller - 1
    dekonstruerArray(i) = oppdateringsfelter(j)
    i = i + 1
Next j

For k = 0 To oppdateringsteller - 1
    dekonstruerArray(i) = oppdateringsfelter(k)
    i = i + 1
Next k

dekonstruerArray(i) = oppdateringstabell
i = i + 1

For l = 0 To oppdateringskriterieteller - 1
    dekonstruerArray(i) = oppdateringskriteriefelter(l)
    i = i + 1
Next l

For m = 0 To oppdateringskriterieteller - 1
    dekonstruerArray(i) = oppdateringskriterier(m)
    i = i + 1
Next m

dekonstruer_update_statement = dekonstruerArray

我明白了

下标超出范围(错误9)

因为我无法访问数组中的 (i) 位置。

我尝试将变体

dekonstruerArray()
分配给
dekonstruerArray(0 to x)
,其中
x
是通过计算传递给函数的“数组”内的所有值来计算的变量。这个数字在我的整个计划中会有所不同。

我明白了

编译错误:需要常量表达式

我可以选择集合,但我想了解数组是如何工作的。

arrays vba ms-access ms-access-2016
2个回答
1
投票

正如评论中已经提到的

REDIM
就是答案。

假设数组下界为零(即数据不是从索引 1 开始):

FUNCTION Concat(X AS VARIANT, Y AS VARIANT, Z AS VARIANT) AS VARIANT
    CONST K = 2
    ' K= number of arrays-1
    DIM A AS VARIANT
    REDIM A(UBOUND(X) + UBOUND(Y) + UBOUND(Z)+ K)

    DIM i,j AS INTEGER

    j = 0
    FOR i= 0 TO UBOUND(X)
        A(j)= X(i)
        j= j + 1
    NEXT

    FOR i= 0 TO UBOUND(Y)
        A(j)= Y(i)
        j= j + 1
    NEXT

    FOR I = 0 TO UBOUND(Z)
        A(j)= Z(i)
        j= j + 1
    NEXT

    Concat= A
END FUNCTION

1
投票

有许多关于在 VBA 中使用数组的技巧。

  1. 如果您要迭代整个数组,请使用

    For myIndex = Lbound(myArray) to Ubound(myArray)
    ,因为这允许您在不知道其开始和结束索引是什么的情况下使用数组。

  2. 如果您的数组来自 Excel 范围,那么它将始终是二维数组(即使您只想要行或列)。

  3. 尝试将数组作为单个实体而不是逐项使用。

代码的一个大问题是需要创建一个正确大小的数组,这就是为什么其他注释指示您进行 redim。但是,redim 可能是一项昂贵的操作,因此最好编写可以避免 ReDim 的代码(如果可以的话)。

下面的代码展示了如何使用 Scripting.Dictionary 来实现您的目标。两个版本。一种是代码的“直接”翻译。第二个版本展示了如何以更灵活的方式编写,因为不再需要提前指定要合并的数组。

Option Explicit

Public Function dekonstruer_update_statement _
( _
    oppdateringsfelter As Variant, _
    oppdateringsverdier As Variant, _
    oppdateringsteller As Long, _
    oppdateringstabell As String, _
    oppdateringskriteriefelter As Variant, _
    oppdateringskriterier As Variant, _
    oppdateringskriterieteller As Long _
) As Variant

    Dim myD As Scripting.Dictionary
    Set myD = New Scripting.Dictionary
    
    Dim myItem As Variant
    With myD
        ' using only those parameters declared as Variant
        ' Using the .count method of the scripting.dictionary to provide the needed Key
        For Each myItem In oppdateringsfelter
            myD.Add .Count, myItem
        Next
        
        For Each myItem In oppdateringsverdier
            myD.Add .Count, myItem
        Next
           
        For Each myItem In oppdateringskriteriefelter
            .Add .Count, myItem
        Next
    
        For Each myItem In oppdateringskriterier
            .Add .Count, myItem
        Next
    End With
    
    ' Return the combined arrays by using the .Items method of  the scripting.dictionary
    dekonstruer_update_statement = myD.Items
    
End Function

' Which of course would be more flexible when written as

'in your code
dekonstruer_update_statement oppdateringsfelter, oppdateringsverdier, oppdateringskriteriefelter, oppdateringskriterier

Public Function dekonstruer_update_statement(ParamArray ipParamArray() As Variant) As Variant

    Dim myD As Scripting.Dictionary
    Set myD = New Scripting.Dictionary
    
    Dim myArray As Variant
    For Each myArray In ipParamArray
        If Not VBA.IsArray(myArray) Then
            Err.Raise 17 ' expand this line to the error you wish to return
            Exit Function
        End If
        ConsolidateArray myArray
    Next
    
    dekonstruer_update_statement = myD.Items
        
End Function

Public Sub ConsolidateArray(ByRef iopD As Scripting.Dictionary, ByRef ipArray As Variant)
    
    Dim myItem As Variant
    For Each myItem In ipArray
        iopD.Add iopD.Count, myItem
    Next
    
End Sub

只是为了好玩,如果我使用自己的 VBA 结构和函数库,则可以通过一行 VBA 代码实现上述内容。

Set dekonstruer_update_statement = SeqA.Deb _
    .AddRange(oppdateringsfelter) _
    .AddRange(oppdateringsverdier) _
    .AddRange(oppdateringskriteriefelter) _
    .AddRange(oppdateringskriterier)
© www.soinside.com 2019 - 2024. All rights reserved.