【发布时间】:2016-01-28 17:59:36
【问题描述】:
在过去的几天里,我一直在研究这个问题,但没有找到答案。我有一个交易列表,我从中过滤一个子集。对于子集,我将日期和金额存储在一个数组中,以用于 XIRR 计算。
使用“IsDate”测试输入列,结果为 True。此外,我在存储日期时使用“ReDim Preserve (0 to n) As Date”。但是,在测试结果时,该数组不包含 Dates 而是 Doubles。
请参考下面的代码。
Function FundXIRRTotal(ByVal FundISIN As String, ByVal KiesDatum As Date) As Double
Dim wshT As Object
Dim wshS As Object
Dim wshP As Object
Dim wsh As Object
Dim LastRow As Long
Dim i As Long
Dim NumberOfTrans As Long
Dim Guess As Double
Dim arrValues() As Double
Dim arrDates() As Date
Dim oFA As Object
Set wshT = ThisComponent.Sheets.getByName("Transacties")
Set wshP = ThisComponent.Sheets.getByName("Portefeuille")
Set wshS = ThisComponent.Sheets.getByName("Instellingen")
'Find Last Used Row
wsh = wshT.createCursor
wsh.gotoEndOfUsedArea( False )
LastRow = wsh.getRangeAddress().EndRow
NumberOfTrans = 0
'Create Transaction Array
For i = 1 To LastRow
If wshT.getCellByPosition(3, i).String = FundISIN And CDate(wshT.getCellByPosition(0, i).Value) <= KiesDatum Then
ReDim Preserve arrValues(0 To NumberOfTrans) As Double
ReDim Preserve arrDates(0 To NumberOfTrans) As Date
arrDates(NumberOfTrans) = CDate(wshT.getCellByPosition(0, i).Value)
If wshT.getCellByPosition(1, i).String = wshS.getCellRangeByName("FundBuy").String Then
arrValues(NumberOfTrans) = -CDbl(wshT.getCellByPosition(9, i).Value / wshT.getCellByPosition(10, i).Value)
End If
If wshT.getCellByPosition(1, i).String = wshS.getCellRangeByName("FundSell").String Then
arrValues(NumberOfTrans) = CDbl(wshT.getCellByPosition(9, i).Value / wshT.getCellByPosition(10, i).Value)
End If
If wshT.getCellByPosition(1, i).String = wshS.getCellRangeByName("FundDeposit").String Then
arrValues(NumberOfTrans) = CDbl(wshT.getCellByPosition(9, i).Value / wshT.getCellByPosition(10, i).Value)
End If
If wshT.getCellByPosition(1, i).String = wshS.getCellRangeByName("FundDivCash").String Then
arrValues(NumberOfTrans) = CDbl(wshT.getCellByPosition(9, i).Value / wshT.getCellByPosition(10, i).Value)
End If
If wshT.getCellByPosition(1, i).String = wshS.getCellRangeByName("FundDivShares").String Then
arrValues(NumberOfTrans) = CDbl(wshT.getCellByPosition(9, i).Value / wshT.getCellByPosition(10, i).Value)
End If
If wshT.getCellByPosition(1, i).String = wshS.getCellRangeByName("FundSplit").String Then
arrValues(NumberOfTrans) = -CDbl(wshT.getCellByPosition(9, i).Value / wshT.getCellByPosition(10, i).Value)
End If
If wshT.getCellByPosition(1, i).String = wshS.getCellRangeByName("FundFee").String Then
arrValues(NumberOfTrans) = -CDbl(wshT.getCellByPosition(9, i).Value / wshT.getCellByPosition(10, i).Value)
End If
If wshT.getCellByPosition(1, i).String = wshS.getCellRangeByName("FundWarUit").String Then
arrValues(NumberOfTrans) = -CDbl(wshT.getCellByPosition(9, i).Value / wshT.getCellByPosition(10, i).Value)
End If
NumberOfTrans = NumberOfTrans + 1
End If
Next i
'Add current value to Array
'NumberOfTrans = NumberOfTrans + 1
ReDim Preserve arrValues(0 To NumberOfTrans) As Double
ReDim Preserve arrDates(0 To NumberOfTrans) As Date
arrValues(NumberOfTrans) = CDbl(Waarde(FundISIN, KiesDatum))
arrDates(NumberOfTrans) = CDate(KiesDatum)
If Portfolio(FundISIN, KiesDatum) = 0 Then
FundXIRRTotal = 0
Exit Function
End If
'Calculate XIRR
oFA = createUNOService("com.sun.star.sheet.FunctionAccess")
FundXIRRTotal = oFA.callFunction("XIRR", Array(arrValues()), Array(arrDates()))
End Function
我知道 Array 函数存在数据类型丢失的问题。我试图通过创建一个新的 Array As Date 并从 arrDates 复制到新的来克服这个问题。但是运气不好,又双打了……
任何帮助将不胜感激。
【问题讨论】:
-
如果将生成的双精度数组放入电子表格,并将单元格格式设置为日期,它们是否正确显示? (如果双打是自 1899 年 12 月 31 日以来的天数 - 电子表格内部存储日期的方式与显示设置无关 - 这应该有效。)
-
是的,当我将结果数组放入工作表并将它们格式化为日期时,它们确实显示正确。但我正在寻找一种方法将这个特别的日期数组提供给 XIRR 函数,而这部分似乎不起作用(因为该数组包含日期的等值数,但不存储为日期) .
-
XIRR 函数是否将字符串日期作为输入?
-
好问题!据我所知,XIRR 需要数值和日期。但我试图将日期作为字符串“输入”它,这给出了同样的错误。
标签: arrays date macros libreoffice basic