如何将值列表传递给Excel中的用户定义函数(UDF)

时间:2018-10-02 14:57:58

标签: excel excel-vba excel-udf xirr

---------------------------------------
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

我正在寻找在MyExcel中创建MyXIRR(日期作为范围,值作为范围,余额作为双精度,BalanceAsOn日期)的功能

要使用此功能,我需要将时间戳列中的数据作为日期传递,将数量X价格作为每种股票的值传递。我将分别确定Balance和BalanceAsOn。

例如ST1

日期将在下面

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

值将在下面

100
900
250
300
-400

我面临的问题是如何基于股票代码上的过滤器传递值列表。

我不是INDEX或MATCH等方面的专家,但是当我尝试类似

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

或通过按Ctrl + Shift +输入I来将其用作数组

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

然后在调试MyXIRR时,我在Dates中仅获得一个值,在Values中即获得一个值,即2011年2月1日和100。我希望MyXIRR获得的列表不仅是第一个值。

怀疑我在滥用INDEX,因此尝试了IF和SUMPRODUCT,但得到了#VALUE!以下两种情况均出现错误

=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() )

有人可以建议我在做什么错和/或建议前进的方向吗?

我正在使用Excel for Mac版本16.16.2

下面是我的函数的样子

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

这仅循环一次并在我为ST1调用时显示01/02/2011

2 个答案:

答案 0 :(得分:1)

[请注意,以下解决方案尚未在Mac版本的Excel上进行测试。]

要仅传递与“ ST1”相对应的值,首先需要将Dates和Trans声明为Variant(如Scott所述),然后相应地更改函数的主体...

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

然后,您可以使用以下公式,该公式需要通过CONTROL + SHIFT + ENTER进行确认,而不仅仅是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())

如果操作正确,Excel将自动在公式周围放置花括号{...}。

答案 1 :(得分:0)

尝试一下:

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