Libreoffice 基础:如何将 CellRange 变量传递给 python 脚本

问题描述 投票:0回答:1

我正在为 Libre Office calc 编写第一个 Python 脚本。

按照各种指南,我安装了 APSO 并成功创建了一个调用 python 脚本的基本包装器。
这是它的签名:

Function python(functionName As String, ParamArray params) As Variant

地点:
functionName
是要调用的 python 方法的名称。
params
是要传递的参数。
(注意:由于 python 方法根据
functionName
的不同而有所不同,因此
params
数组没有预定义的大小和元素类型)

除非参数是单元格范围,否则这种方法效果很好。在这种情况下,单元格范围作为元组传递给 python,缺少有关行和列引用的信息。

为什么基本将单元格范围转换为元组而不是 CellRange 对象?
有没有办法检测

params
元素的类型,以便我可以以不同的方式管理单元格范围? (我尝试使用
TypeName(params(0))
但它似乎只适用于“字符串”等基本类型,如果参数是单元格范围,它会返回
Variant()

编辑1

更多细节,因为我的问题不够清楚
这是我用 basic 编写的完整包装:

REM  *****  BASIC  *****
option compatible

Function python(functionName As String, ParamArray params) As Variant
    Dim scriptPro As Object, myScript As Object
    scriptPro = ThisComponent.getScriptProvider()
    scriptPath = "vnd.sun.star.script:development.py$" & functionName & "?language=Python&location=user"
    On Error GoTo ErrorHandler 
    
    myScript = scriptPro.getScript(scriptPath)
   
    Dim outResult As Variant

    outResult = myScript.invoke(params, Array(), Array())
    python = outResult(0)
    
    Exit Function
     
ErrorHandler:
    python = CVErr(xlErrName)
End Function 

我从计算公式栏中执行包装器,例如:

 =python("custom_concatenate", "Hello ", "world")  

调用 python 方法 custom_concatenate,向其传递 2 个字符串“Hello”和“world”,并在单元格“Hello world”中显示

 =python("sum_all", A1:A10)  

调用 python 方法 sum_all,传递从 A1 到 A10 的单元格中包含的TUPLE OF VALUES,并显示单元格中的总和。

到此为止一切正常。

现在,假设我想创建一个方法,该方法接受一个范围并返回其第一行号和最后一行号的总和。
例如

=python("sum_row_numbers", B13:C24)

该方法应该计算第一行号 13 和最后一个行号 24 的总和,并返回 37

这是python方法的签名:

def sum_row_numbers(range):

问题是包装器传递的
range
参数只是元组的元组,此时对行和列的任何引用都是未知的。

如何确保包装器将有关范围的所有信息(包括单元格引用)传递给 python 方法?

python libreoffice-calc libreoffice-basic
1个回答
0
投票

要获取电子表格公式中使用的行号和列号,我们可以从

getFormula()
中提取它们。包括具有公式的单元格的地址。

import re

def sum_row_numbers(*params):
    sCellAddress = params[-1]
    oDoc = XSCRIPTCONTEXT.getDocument()
    oSheet = oDoc.getCurrentController().getActiveSheet()
    oCell = oSheet.getCellRangeByName(sCellAddress)
    sFormula = oCell.getFormula()
    match = re.search(r'[A-Z]+(\d+):[A-Z]+(\d+)', sFormula)
    if match:
        rownum, colnum = map(int, match.groups())
        return rownum + colnum
    return 0

例如,在单元格 A1 中输入以下公式并向下填充。

=PYTHON("sum_row_numbers"; B13:C24; CELL("address"))

结果:

37 39 41 43 45 47 49 51 53 55 57 59
© www.soinside.com 2019 - 2024. All rights reserved.