【问题标题】:Return dynamic array from function VBA从函数 VBA 返回动态数组
【发布时间】:2017-03-07 01:54:48
【问题描述】:

我正在尝试创建一个输出数组的函数。 但是,我得到左侧的函数调用必须返回 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

【问题讨论】:

    标签: vba


    【解决方案1】:

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

    (如果您想要小于max 的斐波那契数,这可能是您想要的,但是您可能希望在返回之前使用ReDim Preserve 将数组缩小到大小。如果您的意图是要获得第一个 max 斐波那契数,罪魁祸首是线 While prev &lt;= max - 它不是 prev,您想与 max 进行比较。

    编辑时我认为编写一个 VBA 函数会很有趣,该函数返回大小为 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
    

    【讨论】:

    • 我希望我能给这个回复 3 upvotes!一种用于正确回答我的问题,一种用于提供另一种输出斐波那契数列的方式,一种用于提及比内特公式。
    【解决方案2】:

    你的返回类型应该是一样的,你在给函数赋值的时候不需要括号:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-25
      • 2015-10-12
      • 2021-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-22
      • 1970-01-01
      相关资源
      最近更新 更多