1

I want to write a function in which I can include an array. I imagine that the function will work like the function NPV, we have 3 ways of specifying the syntax in the formula bar:

1) NPV(0.5, A1:A5)
2) NPV(0.5, A1, A2, A3, A4, A5)
3) NPV(0.5, {10, 20, 23, 25, 27})

Where 10, 20, 23, 25, 27 are the value in range A1:A5.

And here is my function in VBA:

Function MyNpv(r As Double, Flows As Variant)

Dim i, n As Integer
Dim p As Double
n = Application.Count(Flows)
For i = 1 To n
 p = p + Flows(i) / (r + 1) ^ i
Next i

MyNpv = p

End Function

However, my own function can only work like:

MyNpv(0.5, A1:A5)

Is there anyway that I can declare my array so that it would work flexibly like the function NPV?

Thanks.

6
  • 1
    learn.microsoft.com/en-us/office/vba/language/concepts/… Commented Mar 26, 2020 at 13:36
  • 3
    look into Param Array Commented Mar 26, 2020 at 13:37
  • also see HERE for how I tested if it was a range or an array. Commented Mar 26, 2020 at 13:39
  • I tried Param Array and MyNpv(0.5, A1, A2, A3, A4, A5) works, but MyNpv(0.5, A1:A5) does not work anymore, and NPV(0.5, {10, 20, 23, 25, 27}) still does not work Commented Mar 26, 2020 at 13:54
  • You need to loop the param array and test whether each part is a range or an array, then loop that. Commented Mar 26, 2020 at 13:57

1 Answer 1

1

Use a ParamArray, Loop that to test what is in each part of the array and then adjust accordingly:

Function MyNpv(r As Double, ParamArray Flows() As Variant)

    Dim FlowsPart As Variant

    Dim p As Double
    p = 0#

    Dim k As Long
    k = 1

    For Each FlowsPart In Flows
        Dim arr As Variant
        arr = FlowsPart

        Dim x As Long
        x = -1

        Dim y As Long
        y = -1

        On Error Resume Next
            x = UBound(arr, 2)
            y = UBound(arr)
        On Error GoTo 0

        Dim j As Long
        Dim i As Long
        If x >= 0 And y >= 0 Then
            For i = LBound(arr, 1) To UBound(arr, 1)
                For j = LBound(arr, 2) To UBound(arr, 2)
                    p = p + arr(i, j) / (r + 1) ^ k
                    k = k + 1
                Next j
            Next i
        ElseIf y >= 0 Then
            For j = LBound(arr) To UBound(arr)
                p = p + arr(j) / (r + 1) ^ k
                k = k + 1
            Next j
        Else
            p = p + arr / (r + 1) ^ k
            k = k + 1
        End If
    Next FlowsPart

    MyNpv = p

End Function

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.