简体   繁体   中英

How to pass list of values to user defined function (UDF) in Excel

---------------------------------------
A                   B       C   D
---------------------------------------
Timestamp           Stock   Qty Price
---------------------------------------
01 February 2011    ST1     100 10
02 March 2013       ST1     900 11
01 February 2011    ST2     200 121
04 May 2014         ST1     250 15
02 March 2016       ST2     150 130
04 May 2018         ST2     250 140
08 September 2016   ST1     300 19
01 February 2012    ST3     400 190
11 November 2017    ST1    -400 20

I am looking to create a function in excel by the name MyXIRR(Dates as Range, Values as Range, Balance as Double, BalanceAsOn Date)

To this function I need to pass data from Timestamp column as Dates, Qty X Price as Values for each Stock. Balance and BalanceAsOn is something I will determine separately.

For example for ST1

the Dates will be below

01 February 2011    
02 March 2013       
04 May 2014     
08 September 2016
11 November 2017

the values will be below

100
900
250
300
-400

The problem I am facing is how to pass on list of values based on filter on Stock code.

I am not expert on INDEX or MATCH etc but when I tried something like

=MyXIRR(INDEX(A1:A9,MATCH("ST1",B1:B9,0)), INDEX(C1:C9*D1:D9,MATCH("ST1",B1:B9,0)), 100.00, TODAY())

OR use this as Array by pressing Ctrl + Shift + Enter ie

{=MyXIRR(INDEX(A1:A9,MATCH("ST1",B1:B9,0)), INDEX(C1:C9*D1:D9,MATCH("ST1",B1:B9,0)), 100.00, TODAY())}

Then on debugging the MyXIRR I get just one value in Dates and one value in Values ie 01 February 2011 and 100. I expect the MyXIRR to get list not just first value.

Suspecting I am misusing INDEX I tried IF and SUMPRODUCT but I get #VALUE! Error for both of below two cases

=MyXIRR(IF(B1:B9="ST1",A1:A9,0), IF(B1:B9="ST1",C1:C9*D1:D9,0), 100.00, TODAY())

OR

= MyXIRR(SUMPRODUCT((B1:B9="ST1"),A1:A9), SUMPRODUCT((B1:B9="ST1"),C1:C9*D1:D9), 100.00, TODAY() )

Can someone suggest what wrong I am doing and/or suggest way forward?

I am using Excel for Mac version 16.16.2

Below is how my function looks like

Public Function MyXIRR(Dates As Range, Trans As Range, Balance As Double,  BalanceAsOn As Date) As Double

Dim Cell As Range
 For Each Cell In Dates
    MsgBox Cell.Value
 Next Cell

MyXIRR = Dates.Count
End Function

This just loops in only once and display 01/02/2011 when I call it for ST1

[Note that the following solution has not been tested on a Mac version of Excel.]

To pass only the values that correspond to "ST1", first you'll need to declare Dates and Trans as a Variant, as Scott has already mentioned, and then change the body of your function accordingly...

Public Function MyXIRR(Dates As Variant, Trans As Variant, Balance As Double, BalanceAsOn As Date) As Double

     Dim currentDate As Variant

     For Each currentDate In Dates
         MsgBox currentDate
     Next currentDate

     MyXIRR = UBound(Dates)

End Function

Then you can use the following formula, which needs to be confirmed with CONTROL+SHIFT+ENTER, not just ENTER...

=MyXIRR(INDEX(A2:A10,N(IF(1,SMALL(IF(B2:B10="ST1",ROW(B2:B10)-ROW(B2)+1),ROW(INDIRECT("1:"&COUNTIF(B2:B10,"ST1"))))))),INDEX(C2:C10*D2:D10,N(IF(1,SMALL(IF(B2:B10="ST1",ROW(B2:B10)-ROW(B2)+1),ROW(INDIRECT("1:"&COUNTIF(B2:B10,"ST1"))))))),100,TODAY())

If done correctly, Excel will automatically place curly braces {...} around the formula.

Try this:

Public Function MyXIRR(Dates As Range, Trans As Range, Balance As Double, BalanceAsOn As Date) As Double

    Dim Area as Range    
    Dim Cell As Range

    For Each Area in Dates.Areas
        For Each Cell In Area
            MsgBox Cell.Value
        Next Cell
    Next Area

    MyXIRR = Dates.Count
End Function

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM