Arrays 如何在VBA中将不确定数组传递给函数并循环?
我的函数接受一个范围,比如无风险利率,并产生一系列贴现因子。这个问题似乎有三个方面: (a) 在数组上调用fn,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
(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)
- 您正在使用
计数器(基于1)作为期限。这是一个糟糕的设计选择,因为你的男高音并不总是一致的长度,你可以期待有许多短期男高音。此外,这是一个bug,因为i
将始终是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