Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 如何在VBA中将不确定数组传递给函数并循环?_Arrays_Vba_Excel_Function - Fatal编程技术网

Arrays 如何在VBA中将不确定数组传递给函数并循环?

Arrays 如何在VBA中将不确定数组传递给函数并循环?,arrays,vba,excel,function,Arrays,Vba,Excel,Function,我的函数接受一个范围,比如无风险利率,并产生一系列贴现因子。这个问题似乎有三个方面: (a) 在数组上调用fn, (b) 指定阵列点, (c) 使用循环i作为fn参数 是围绕每个数组(点i)使用循环的最佳方法,还是可以通过简单地调用函数来填充整个数组 Function CreateDiscArray(RFR_array As Range) Dim MyArray() As Variant MyArray = RFR_array Dim xDimRate As Inte

我的函数接受一个范围,比如无风险利率,并产生一系列贴现因子。这个问题似乎有三个方面:

(a) 在数组上调用fn,
(b) 指定阵列点,
(c) 使用循环i作为fn参数

是围绕每个数组(点i)使用循环的最佳方法,还是可以通过简单地调用函数来填充整个数组

Function CreateDiscArray(RFR_array As Range)

    Dim MyArray() As Variant
    MyArray = RFR_array

    Dim xDimRate As Integer
    xDimRate = UBound(MyArray, 1)

    Dim TempArray() As Variant
    For i = 1 To xDimRate Step 1
        TempArray(i, 1) = DiscFact(MyArray(i), i)
    Next i

    CreateDiscArray() = TempArray()
End Function


您的原始代码存在一些问题

  • 您没有使用
    选项Explicit
    ,因此您不知道
    i
    是未声明的

  • 您没有对
    TempArray
    进行尺寸标注,因此代码无法分配给其索引

  • 您正在引用的
    myArray(i)
    将失败,因为有两个维度,因此必须使用
    myArray(i,1)

  • 您正在使用
    i
    计数器(基于1)作为期限。这是一个糟糕的设计选择,因为你的男高音并不总是一致的长度,你可以期待有许多短期男高音。此外,这是一个bug,因为
    i>=1
    将始终是
    TRUE

因此,要使原始函数在代码中可行,请执行以下操作:


而且,如果将命名范围命名为Tenor和Rate,则可以将数组公式重新定义为
=if(TenorIn一句话,不是。看起来你在寻找类似lambda函数的东西,VBA不提供。更好的办法是将tenors定义为月份,并将测试更改为
Tenor<12
。这适用于从短期到月份的粒度,以及从长期到25年的费率。但是……生成VBA代码和execu的元代码动态测试是如此的有趣!但是…但是,创建VBA过程的元代码创建了一个Python脚本,并将其作为json发送到PHP服务器进行评估,然后使用BAT文件中编写的自定义解析器将其转换回数组?我不能尝试,但我认为类似的操作也应该有效
CreateDiscArray=[DiscFact(A1:A3,B1:B3)]
,我将替换
应用程序。使用
费率.工作表评估
。评估
@Slai-是的,类似的方法可以工作,但您必须将地址硬编码到VBA文本中。您无法使用提供范围的地址。
Function DiscFact(Rate, Tenor)
    If Tenor < 1 Then DiscFact = (1 + Tenor * Rate)
    If Tenor >= 1 Then DiscFact = (1 + Rate) ^ (-Tenor)
End Function
CreateDiscArray = DiscFact(MyArray(,1), 1 to xDimRate)
Option Explicit

Function CreateDiscArray(RFR_array As Range)

    Dim MyArray() As Variant
    MyArray = RFR_array.Value

    Dim xDimRate As Integer
    xDimRate = UBound(MyArray, 1)

    ReDim TempArray(LBound(MyArray) To UBound(MyArray), LBound(MyArray, 2) To UBound(MyArray, 2)) As Variant
    Dim i As Long
    For i = 1 To xDimRate Step 1
        TempArray(i, 1) = DiscFact(MyArray(i, 1), i)
    Next i

    CreateDiscArray = TempArray
End Function

Function DiscFact(Rate, Tenor)
    'BUG: Tenor will always be >= 1
    If Tenor < 1 Then DiscFact = (1 + Tenor * Rate)
    If Tenor >= 1 Then DiscFact = (1 + Rate) ^ (-Tenor)
End Function
    A   |   B  |   C
--+-----|------|-------------------------------------------------
1 | .5  | 99   | {=IF(A1:A3<1,1+A1:A3*B1:B3,(1+B1:B3)^(-A1:A3))}
2 | 1   | 97   | 
3 | 2   | 95   | 
Public Function DiscFactor(rates As Range, tenors As Range) As Variant

  Dim Rate As String
  Dim Tenor As String
  Rate = rates.Address
  Tenor = tenors.Address

  DiscFactor = Application.Evaluate("=IF(" & Tenor & "<1,1+" & Tenor & "*" & Rate & ",(1+" & Rate & ")^(-" & Tenor & "))")

End Function