我有以下vba功能。它目前是NPV函数,但我需要将其转换为IRR函数,该函数返回NPV = 0时的速率(换句话说,速率是什么,以使得下面的函数的总和= 0)
我知道你可以在VBA中使用求解器,但是我所做的任何研究都让我在语法方面迷失了方向。
有没有办法在没有求解器的情况下做到这一点(或许和IF语句,或类似的东西)。我对VBA并不熟悉所有可用的论证操作。
我更喜欢书面回答什么是最好的方法,反对为我做这件事(所以我可以学习VBA)...如果我必须使用求解器,那么我确实需要帮助的语法它
Public Function myIRR(cashFlows As Range) As Double
Dim myArray(50) As Double
Dim i As Integer
Dim sum As Double
Dim rate As Single
i = 0
For Each elem In cashFlows
myArray(i) = elem.Value
sum = sum + myArray(i) / (1 + rate) ^ i
i = i + 1
Next Elem
End Function
答案 0 :(得分:1)
好的,今天下午我有点无聊(等待计算的东西)。所以这是我快速而肮脏的方法。它使用二分法,效率不高,但应该得到答案。除了使用维基百科(http://en.wikipedia.org/wiki/Internal_rate_of_return)中的小例子确认它与Excel中的IRR功能相同时,我还没有测试过这个,所以一定要彻底测试它。
Public Function MyIRR(cashflows As Range) As Double
'doing a binary search - there are way more efficient ways of solving this
Dim rate As Double, rateLow As Double, rateHigh As Double, npv As Double
Dim counter As Long
rateLow = 0
rateHigh = 1
rate = 0.5
Do Until counter > 100
npv = MyNPV(cashflows, rate)
If Abs(npv) < 10^ - 9 Then
MyIRR = rate
Exit Function
End If
If npv < 0 Then
rateHigh = rate
Else
rateLow = rate
End If
rate = (rateHigh - rateLow) / 2 + rateLow
counter = counter + 1
Loop
'if it gets here then something has gone wrong
MyIRR = xlErrNum
End Function
Public Function MyNPV(cashflows As Range, rate As Double) As Double
'assumes the cashflows are stored vertically in a range, and the first one happens at period 0
Dim i As Long
For i = 1 To cashflows.Rows.Count
MyNPV = MyNPV + cashflows(i, 1) * (1 + rate) ^ -(i - 1)
Next
End Function