【问题标题】:Basic Wrapper for LibreOffice Calc Python UDFLibreOffice Calc Python UDF 的基本包装器
【发布时间】:2021-08-18 13:36:14
【问题描述】:

Basic 包装器调用是如何形成的以使用非整数电子表格范围运行 LibreOffice Calc Python 用户定义函数?

我不清楚如何为 valuesexcel_date 数组正确声明函数,这两个数组都是实数数组,请在我理解的基本术语中输入 Variant。

我关注Calling a python function from within LibreCalc,范围可以作为整数参数传递而不定义它们,但这些是真实值。两个数组都是一维的,所以多维数组的问题不适用,正如How can I call a Python macro in a cell formula in OpenOffice.Org Calc?中所讨论的那样

基本代码是:

Function xnpv_helper(rate as Double, values() as Variant, excel_date() as Variant) as Double
    Dim scriptPro As Object, myScript As Object
    scriptPro = ThisComponent.getScriptProvider()
    myScript = scriptPro.getScript("vnd.sun.star.script:MyPythonLibrary/Develop/math.py$xnpv_helper?language=Python&location=user")
    xnpv_helper = myScript.invoke(Array(rate, values, excel_date), Array(), Array() )
end function

电子表格数据:

Date    Amount  Rate    xnpv
31/12/19    100 -0.1    
31/12/20    -110

xnpv_helper 在底部。实际的python脚本是基于https://github.com/tarioch/xirr from financial python library that has xirr and xnpv function?

# Demo will run in python REPL - uncomment last line
import scipy.optimize

DAYS_PER_YEAR = 365.0

def xnpv(valuesPerDate, rate):
    '''Calculate the irregular net present value.

    >>> from datetime import date
    >>> valuesPerDate = {date(2019, 12, 31): -100, date(2020, 12, 31): 110}
    >>> xnpv(valuesPerDate, -0.10)
    22.257507852701295
    '''
    if rate == -1.0:
        return float('inf')
    t0 = min(valuesPerDate.keys())
    if rate <= -1.0:
        return sum([-abs(vi) / (-1.0 - rate)**((ti - t0).days / DAYS_PER_YEAR) for ti, vi in valuesPerDate.items()])
    return sum([vi / (1.0 + rate)**((ti - t0).days / DAYS_PER_YEAR) for ti, vi in valuesPerDate.items()])


from datetime import date
def excel2date(excel_date):
    return date.fromordinal(date(1900, 1, 1).toordinal() + int(excel_date) - 2)

def xnpv_helper(rate, values, excel_date):
    dates = [excel2date(i) for i in excel_date]
    valuesPerDate = dict(zip(dates, values))
    return xnpv(valuesPerDate, rate)

# valuesPerDate = {date(2019, 12, 31): -100, date(2020, 12, 31): 110}
# xnpv_helper(-0.10, [-100, 110], [43830.0, 44196.0])

【问题讨论】:

  • 如果您只想使用 XNPV 函数,为什么不直接使用 Calc 的 built-in function 名称呢?还有一个内置的XIRR
  • https://github.com/tarioch/xirr/blob/master/src/xirr/math.py 中 Python XIRR 函数的行为与 Calc 的内置函数有何不同?据我所见,它们完全相同。它们都接受一个日期数组和一个值数组并输出一个值。在 Python 版本中,将两个数组组合成一个二维数组这一事实并不会改变函数的作用。
  • 是的,数学计算是相同的,但是您不能使用ask.libreoffice.org/t/… 中演示的内置函数对正常数据布局进行多次计算。

标签: python libreoffice openoffice.org libreoffice-calc libreoffice-basic


【解决方案1】:

感谢 @arturaz 解释 Basic 数组作为元组来到 python 并需要转换为列表(python 中数组的最佳匹配)。他在https://stackoverflow.com/a/8978435/4539999 的回答中提供了更多详细信息,该回答基于问题和其他答案。

APSO python 控制台显示:

  1. 从 Basic 解析到 python 的内容
  2. 需要什么
  3. 带日期格式的必需数据
APSO python console [LibreOffice]
3.8.10 (default, Aug 10 2021, 19:39:20) [MSC v.1928 64 bit (AMD64)]
>>> 
1: ((43830.0,), (44196.0,)) ((100.0,), (-110.0,)) -0.1
2: [43830.0, 44196.0] [-100, 110] -0.1
3: {datetime.date(2019, 12, 31): -100, datetime.date(2020, 12, 31): 110} -0.1

这两个数组在用于 python 辅助函数之前被重新格式化:

def xnpv_helper(rate, values, excel_date):
    excel_date0 = [a for b in excel_date for a in b]
    values0 = [a for b in values for a in b]
    dates = [excel2date(i) for i in excel_date0]
    valuesPerDate = dict(zip(dates, values0))
    return xnpv(valuesPerDate, rate)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多