电子表格函数中返回数组

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

下面的代码返回一个数组。我想在电子表格中使用它作为 Excel 公式来返回数组。但是,当我这样做时,它只将第一个值返回到单元格。无论如何,是否可以返回与数组大小相同的范围内的数组?

Function LoadNumbers(Low As Long, High As Long) As Long()
'''''''''''''''''''''''''''''''''''''''
' Returns an array of Longs, containing
' the numbers from Low to High. The
' number of elements in the returned
' array will vary depending on the
' values of Low and High.
''''''''''''''''''''''''''''''''''''''''

'''''''''''''''''''''''''''''''''''''''''
' Declare ResultArray as a dynamic array
' to be resized based on the values of
' Low and High.
'''''''''''''''''''''''''''''''''''''''''
Dim ResultArray() As Long
Dim Ndx As Long
Dim Val As Long
'''''''''''''''''''''''''''''''''''''''''
' Ensure Low <= High
'''''''''''''''''''''''''''''''''''''''''
If Low > High Then
    Exit Function
End If
'''''''''''''''''''''''''''''''''''''''''
' Resize the array
'''''''''''''''''''''''''''''''''''''''''
ReDim ResultArray(1 To (High - Low + 1))
''''''''''''''''''''''''''''''''''''''''
' Fill the array with values.
''''''''''''''''''''''''''''''''''''''''
Val = Low
For Ndx = LBound(ResultArray) To UBound(ResultArray)
    ResultArray(Ndx) = Val
    Val = Val + 1
Next Ndx
''''''''''''''''''''''''''''''''''''''''
' Return the array.
''''''''''''''''''''''''''''''''''''''''
LoadNumbers = ResultArray()

End Function
arrays excel return spreadsheet vba
5个回答
7
投票

UDF 当然可以返回一个数组,并且您的函数可以正常工作。只需选择范围 B2:D2,将

=LoadNumbers(1, 3)
放入公式栏中,然后按 Ctrl+Shift+Enter 告诉 Excel 这是一个数组函数。

现在,你不能让 UDF 根据其输入自动调整范围的大小 它是从 调用的(至少不是没有一些丑陋的

Application.OnTime
hack),但你无论如何都不需要这样做。只需将函数放在 1000 个单元格宽度的范围内,然后让 UDF 用空白单元格填充未使用的空间,如下所示:

Function LoadNumbers(ByVal Low As Long, ByVal High As Long) As Variant()
    Dim ResultArray() As Variant
    Dim Ndx As Long
    Dim Val As Long
    Dim SourceCols As Long

    SourceCols = Application.Caller.Columns.Count

    If Low > High Then
        Exit Function
    End If
    If High - Low + 1 > SourceCols Then High = Low + SourceCols - 1

    ReDim ResultArray(1 To SourceCols)

    Val = Low
    For Ndx = LBound(ResultArray) To (High - Low + 1)
        ResultArray(Ndx) = Val
        Val = Val + 1
    Next Ndx
    For Ndx = (High - Low + 2) To UBound(ResultArray)
        ResultArray(Ndx) = vbNullString
    Next Ndx
    LoadNumbers = ResultArray()
End Function

3
投票

工作表公式只能将值输出到写入公式的同一单元格。就目前情况而言,代码已经生成了一个数组。如果您希望在向下复制公式时显示值,请使用这样的公式(在您想要的任何单元格中),然后向下复制:

=INDEX(LoadNumbers(1,10),ROWS($A$1:$A1))

如果你复制太多,你会得到#REF!错误,因为 LoadNumbers 的数字用完了。


1
投票

我一直在寻找类似的东西(在宏中创建一个函数,从工作表中获取输入,输出一个多维数组),我希望下面的用例有助于回答。如果没有,我很抱歉:

用例: 创建并应用众所周知的数值期权估值函数,并将股票价格、估值和收益输出为函数中指定的 #rows 的 3 维数组(3 列)(在本例中为 20,作为 NAS 变量)。代码被复制 - 但想法是将输出放入工作表中......

a) 这些输入在工作表中是静态的。 b)我通过我想要开始的输出单元格中的“fx”函数列表调用宏公式“optval”,并将起始输入放入公式中。 b) 输出将根据代码使用 20 行的 NAS 边界传播到单元格。微不足道,但有效。 c) 您可以自动执行此操作并将其输出到工作表 - 但无论如何,我希望这种方式有帮助。

模块功能如下(复制!) - 但只需将启动器输入放入即中即可 Vol=.2,Int 汇率 = 0.05,Strike=120,Exp = 1,P type = C(或 P),US?= N,即欧洲,,NAS=20(或者您想查看的任意行数,以及它影响数值方法的粒度)

Function optval(Vol, Intrate, Strike, Expn, Ptype, Etype, NAS)

ReDim S(0 To NAS) As Double
ReDim VOld(0 To NAS) As Double
ReDim VNew(0 To NAS) As Double
ReDim dummy(0 To NAS, 1 To 3)

dS = 2 * Strike / NAS
dt = 0.9 / NAS / NAS / Vol / Vol
NTS = Int(Expn / dt) + 1
dt = Expn / NTS

q = 1
If Ptype = "P" Then q = -1
For i = 0 To NAS
    S(i) = i * dS
    VOld(i) = Application.Max(q * (S(i) - Strike), 0)
    dummy(i, 1) = S(i)
    dummy(i, 2) = VOld(i) 'Payoff
Next i

For k = 1 To NTS
    For i = 1 To NAS - 1
        Delta = (VOld(i + 1) - VOld(i - 1)) / 2 / dS
        Gamma = (VOld(i + 1) - 2 * VOld(i) + VOld(i - 1)) / dS / dS
        Theta = -0.5 * Vol * Vol * S(i) * S(i) * Gamma - _
            Intrate * S(i) * Delta + Intrate * VOld(i)
        VNew(i) = VOld(i) - Theta * dt 'BSE
    Next i

    VNew(0) = VOld(0) * (1 - Intrate * dt) 'S=0
    VNew(NAS) = 2 * VNew(NAS - 1) - VNew(NAS - 2) 'Infty
    
    For i = 0 To NAS
        VOld(i) = VNew(i)
    Next i
    
    If Etype = "Y" Then
        For i = 0 To NAS
            VOld(i) = Application.Max(VOld(i), dummy(i, 2))
        Next i
    End If
    
Next k

For i = 0 To NAS
    dummy(i, 3) = VOld(i)
Next i

optval = dummy
End Function

0
投票
=INDEX(LoadNumbers(1,10),ROWS($A$1:$A1),COLUMNS($B$1,B$1))

0
投票

您可以添加一个参数作为输出的索引,类似于聚合函数中的键

Function LoadNumbers(Low As Long, High As Long, index As Integer) As Long()


Dim ResultArray() As Long
Dim Ndx As Long
Dim Val As Long

If Low > High Then
    Exit Function
End If

ReDim ResultArray(1 To (High - Low + 1))

Val = Low
For Ndx = LBound(ResultArray) To UBound(ResultArray)
    ResultArray(Ndx) = Val
    Val = Val + 1
Next Ndx

LoadNumbers = ResultArray(index)

End Function

© www.soinside.com 2019 - 2024. All rights reserved.