将预定义的excel函数应用于VBA for循环数组以创建新函数

时间:2018-08-17 08:00:49

标签: excel vba excel-vba for-loop switch-statement

我曾经使用另一种编程语言,但是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

2 个答案:

答案 0 :(得分:2)

我对您的代码进行了一些更改,现在看来可以正常工作吗?

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的情况”。

我认为是吗?

答案 1 :(得分:0)

您的Payments数组未初始化为数组。 这就是为什么您会收到错误消息。

要正确创建阵列,您应该执行以下操作:

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

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