【问题标题】:Applying a predefined excel function to a VBA for loop array to create a new function将预定义的 excel 函数应用于 VBA for 循环数组以创建新函数
【发布时间】:2018-08-17 08:00:48
【问题描述】:

我曾使用过另一种编程语言,但 VBA 对我来说是一个相对较新的平台。我知道我想要执行的算法,但是我遇到了一些问题。

我一直在尝试为债券的市场收益率创建一个财务模型,由于在事物的自然过程中,我需要使用求解器,所以我决定使用工作表函数 IRR,其数组定义为FOR 循环和案例结构如图所示。我之前只是在 VBA 中使用 IRR 函数,它显示了错误-“类型不匹配:需要数组或用户定义的类型”。

但是,现在我没有看到任何错误,但我的函数说其中一个参数是错误的数据类型。如果有人能告诉我我在这里做错了什么,我将不胜感激。

Function Market_Yield(Clean_Price As Variant, Number_of_Payments As Integer, Coupon As Variant, Face As Variant, AccIn As Variant) As Variant

    Dim Payment As Variant

    For i = 0 To Number_of_Payments

        Select Case i
        Case Is = 0
            Payment(i) = -Clean_Price

        Case Is = Number_of_Payments - 1
            Payment(i) = (AccIn / Coupon) + (Coupon * Face)

        Case Is = Number_of_Payments
            Payment(i) = ((Coupon * Face) - (AccIn)) + (((Coupon * Face) - (AccIn)) / Coupon)

        Case Else
            Payment(i) = Coupon * Face
        End Select

    Next i

    Market_Yield = Application.WorksheetFunction.IRR(Payment(), 0.1)

End Function

【问题讨论】:

  • 你能举个例子吗?
  • 我们不习惯你的金融词汇。你能避免如果,解释它或参考解释吗?
  • 并根据需要将 () 从 Payment() 中删除。
  • 你好 QHarr。您是指输出的快照吗?
  • 我的意思是一些重现错误的测试值。这样做所需的最低金额。

标签: vba excel for-loop switch-statement


【解决方案1】:

我对您的代码进行了一些更改,现在似乎可以工作了?

Function Market_Yield(Clean_Price As Variant, Number_of_Payments As Integer, Coupon As Variant, Face As Variant, AccIn As Variant) As Variant
    Dim Payment() As Variant
    ReDim Payment(0 To Number_of_Payments) As Variant
    Dim i As Integer
    For i = 0 To Number_of_Payments
        Select Case i
            Case 0
            Payment(i) = -Clean_Price

            Case Number_of_Payments - 1
            Payment(i) = (AccIn / Coupon) + (Coupon * Face)

            Case Number_of_Payments
            Payment(i) = ((Coupon * Face) - (AccIn)) + (((Coupon * Face) - (AccIn)) / Coupon)

            Case Else
            Payment(i) = Coupon * Face
        End Select
    Next i
    Market_Yield = Application.WorksheetFunction.IRR(Payment(), 0.1)
End Function

好的,为什么这行得通而你的宏却行不通?

  1. 您已将Payment() 声明为数组,但Excel 不喜欢动态数组,它需要有一个上限。所以我在ReDim数组中添加了一行代码到必要的边界;
  2. 您从未声明过i,您只是开始循环使用它。在大多数语言中,这会很好,因为你会做类似for (int i = 0; i < Number_of_Payments; i++) 的事情,其中​​声明是循环的一部分。但是 Excel VBA 不是这样的,所以你必须显式添加Dim i As Integer;
  3. 您的Case 语句不正确,因为您使用的是Is 语句,而这不是它们在VBA 中的工作方式。因为您在顶部使用Case i,所以您只需要Case 以及语句其余部分中的值或关键字Else,例如Case 1 表示“i = 1 的情况”。

我认为是这样?

【讨论】:

  • 对于您的示例数据,我得到 0.014037。这是正确的吗?
  • 是的!这确实是我需要的。谢谢理查德汉塞尔!你能告诉我我做错了什么吗?
  • 是的。我现在明白了。谢谢!:-)
【解决方案2】:

您的 Payments 数组未初始化为数组。 这就是您收到错误的原因。

要正确创建数组,您应该这样做:

Dim Payment() As Variant
ReDim Payment(0 To Number_of_Payments) As Variant

否则,它不会被识别为数组,编译器也不知道数组应该有多大

【讨论】:

  • 另外i根本没有声明,case语句有点奇怪等等
  • 我试过了,我得到了一个错误,说支付指数应该是一个常数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-14
  • 2013-06-18
  • 2021-04-14
  • 2018-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多