Ms Access“数组”功能出现问题

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

所以我在使用 MS Access 时遇到了问题。我想要实现的是创建一个返回未指定数量元素的数组的函数。元素的数量取决于通过我的函数传递的元素的数量。我的功能工作原理如下:

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 到 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

0
投票

有许多关于在 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
© www.soinside.com 2019 - 2024. All rights reserved.