从函数VBA返回动态数组

时间:2017-03-05 22:22:29

标签: vba

我正在尝试创建一个输出数组的函数。 但是,我在左侧的函数调用必须返回Variant或 宾语。如何从此函数返回动态数组?

Public Function Fibonacci_Array(max As Integer) As Integer


    Dim result()   As Variant
    ReDim result(0 To max)

    '' Array indices.
    Dim i1         As Integer
    Dim i2         As Integer
    Dim i          As Integer

    i1 = 0
    i2 = 1


    '' Array values.
    Dim newVal     As Long
    Dim prev2      As Long
    Dim prev       As Long

    prev2 = 0
    prev = 1

    '' Loop through
    While prev <= max

            result(i1) = prev2
            result(i2) = prev


            newVal = prev + prev2
            ''Debug.Print newVal

            prev2 = prev
            prev = newVal

            i1 = i1 + 1
            i2 = i2 + 1
    Wend

    '' Problem here.
    Fibonacci_Array() = result

End Function

2 个答案:

答案 0 :(得分:3)

在将数组传递给函数或从函数传递数组时,

Variant是最灵活的类型。

替换

Public Function Fibonacci_Array(max As Integer) As Integer

通过

Public Function Fibonacci_Array(max As Integer) As Variant

替换

Dim result() As Variant

通过

Dim result As Variant

并替换

Fibonacci_Array() = result

通过

Fibonacci_Array = result

这将使它编译,但你似乎需要一些调试,因为当我输入

?Join(Fibonacci_Array(10),", ")

在立即窗口中,我得到:

0, 1, 1, 2, 3, 5, 8, , , , 

(如果您希望Fibonacci数小于max,这可能是您想要的,但是在返回之前您可能希望使用ReDim Preserve将数组缩小到适当大小。如果您打算获得第一个max斐波那契数字,那么罪魁祸首就是行While prev <= max - 您想要与prev进行比较不是max

On Edit 我认为编写一个VBA函数会很有趣,该函数返回所有Fibonacci数字的数组,其大小为&lt; =给定的最大值。由于Fibonacci数字迅速增长,我决定使用Long而不是Integer,并且在填充数组之前还使用Binet's formula来计算数组的大小(可能为安全性+1) ,所以我们不分配一个太大的数组:

Function FibNums(max As Long) As Variant
    'returns array consisting of all Fibonacci numbers <= max
    'max is assumed to be >= 1

    Dim i As Long, n As Long, F As Long
    Dim Fibs As Variant

    'come up with an upper bound on size of array:
    n = 1 + Int(Log(Sqr(5) * max) / Log((1 + Sqr(5)) / 2))
    ReDim Fibs(1 To n)
    Fibs(1) = 1
    Fibs(2) = 1
    i = 2
    Do While Fibs(i) <= max
        F = Fibs(i - 1) + Fibs(i)
        If F <= max Then
            i = i + 1
            Fibs(i) = F
        Else
            Exit Do 'loop is finished
        End If
    Loop
    'at this stage, Fibs contains i numbers
    If i < n Then ReDim Preserve Fibs(1 To i)
    FibNums = Fibs
End Function

例如:

?Join(Fibnums(100000),", ")
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025

答案 1 :(得分:1)

您的返回类型应该相同,并且在分配函数值时不需要括号:

Public Function Fibonacci_Array(max As Integer) As Long()


    Dim result()   As Long
    ReDim result(0 To max)

    '' Array indices.
    Dim i1         As Integer
    Dim i2         As Integer
    Dim i          As Integer

    i1 = 0
    i2 = 1


    '' Array values.
    Dim newVal     As Long
    Dim prev2      As Long
    Dim prev       As Long

    prev2 = 0
    prev = 1

    '' Loop through
    While prev <= max

            result(i1) = prev2
            result(i2) = prev


            newVal = prev + prev2
            ''Debug.Print newVal

            prev2 = prev
            prev = newVal

            i1 = i1 + 1
            i2 = i2 + 1
    Wend

    '' Problem here.
    Fibonacci_Array = result

End Function

Sub a()

Dim b() As Long

b() = Fibonacci_Array(100)
End Sub