2016-01-28 4 views
1

В течение последних нескольких дней я изучал это, не нахожу ответа. У меня есть список транзакций, из которых я фильтрую подмножество. Для подмножества я храню дату и сумму в массиве для использования в расчете XIRR.Хранение дат в массиве в Libreoffice Basic

Входной столбец проверен на «IsDate» и считается True. Кроме того, я использую «ReDim Preserve (от 0 до n) в качестве даты» при хранении дат. Однако при тестировании результата массив не содержит дат, а парный разряд.

См. Приведенный ниже код.

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 в новую. Но не повезло, удваивается снова ...

Любая помощь будет оценена.

+0

Если вы поместите результирующий массив двойников в электронную таблицу и отформатируйте ячейки как даты, они отображаются правильно? (Если удвоение - это дни с 31 декабря 1899 года - то, как электронные таблицы хранят внутренние даты независимо от настройки отображения - это должно работать.) – Lyrl

+0

Да, они корректно отображают, когда я помещаю результирующий массив в лист и отформатируем их как даты , Но я ищу способ подачи этого ad-hoc массива дат к функции XIRR, и это та часть, которая, похоже, не работает (поскольку массив содержит числовые эквиваленты дат, но не хранится как даты) , – ArubaCalc

+0

Будет ли функция XIRR принимать строковые данные в качестве входных данных? – Lyrl

ответ

0

Номер is дата. Вызов UNO FunctionAccess не принимает тип OpenOffice Basic Date и ожидает вместо него тип номера.

Здесь работает пример кода:

Function FundXIRRTotal(ByVal FundISIN As String, ByVal KiesDatum As Date) As Variant 
    Dim wshT As Object 
    Dim i As Long 
    Dim arrValues(0, 2) As Double 
    Dim unoDates(0, 2) As Double 
    Dim theDate As Double 
    Dim oFA As Object 
    Dim args(2) As Variant 
    Dim result As Variant 

    Set wshT = ThisComponent.Sheets.getByName("Transacties") 
    For i = 0 To 2 
     arrValues(0, i) = wshT.getCellByPosition(3, i).Value 
     'The date value will be a number, for example 42020 for 2015-01-16. 
     theDate = wshT.getCellByPosition(2, i).Value 
     unoDates(0, i) = theDate 
    Next i 
    oFA = createUNOService("com.sun.star.sheet.FunctionAccess") 
    args = Array(arrValues, unoDates) 
    result = oFA.callFunction("XIRR", args) 
    FundXIRRTotal = result 
End Function 

Смотрите также https://forum.openoffice.org/en/forum/viewtopic.php?f=20&t=67996.

Кстати, я также пробовал использовать com.sun.star.util.Date, но это, похоже, не сработало.

+0

Спасибо, Джим, это решило это. – ArubaCalc

0

Как обходной путь, создайте лист под названием «TempSheet». Он может быть скрыт, потому что он будет использоваться только для временной обработки.

В документе FundXIRRTotal напишите arrDates в колонку TempSheet A. Затем передайте этот диапазон ячеек в oFA.callFunction().

Ниже приведен рабочий код, который я использовал для проверки этой концепции. Измените «C1: C3» на диапазон в TempSheet, который содержит содержимое arrDates, например "TempSheet.A1:A" & Ubound(arrDates).

Function FundXIRRTotal(ByVal FundISIN As String, ByVal KiesDatum As Date) As Double 
    Dim wshT As Object 
    Dim i As Long 
    Dim arrValues(2, 0) As Double 
    Dim arrDates(2, 0) As Date 
    Dim args as Array 
    Dim oFA As Object 

    Set wshT = ThisComponent.Sheets.getByName("Transacties") 
    For i = 0 To 2 
     arrDates(i, 0) = wshT.getCellByPosition(2, i).Value 
     arrValues(i, 0) = wshT.getCellByPosition(3, i).Value  
    Next i 
    oFA = createUNOService("com.sun.star.sheet.FunctionAccess") 
    args = Array(arrValues, wshT.getCellRangeByName("C1:C3")) 
    FundXIRRTotal = oFA.callFunction("XIRR", args) 
End Function 

Примечание: Я рекомендую использовать другой ответ вместо этого.

 Смежные вопросы

  • Нет связанных вопросов^_^