优化 PyUno 中的公式复制

Posted

技术标签:

【中文标题】优化 PyUno 中的公式复制【英文标题】:Optimizing formula copying in PyUno 【发布时间】:2016-12-20 22:35:40 【问题描述】:

LibreOffice 5.2.3.3

我正在尝试将 Excel VBScript 程序移植到 PyUno。该逻辑有效,但它的运行速度比在 Excel 中慢得多。

我制作了两张纸,Sheet1 和 Sheet2。参考下面的脚本,我在 Sheet1 中添加了一个按钮来调用create,在 Sheet2 中添加了一个按钮来调用copy。在运行create 并等待它完成后,我运行copy

有没有办法进一步优化copy 当它在单独的线程中运行时,我可以看到每一行都被填满,而我希望它对人眼来说是即时的。移除线程只会让图形等待更新。

(我的原始代码从一个不可见的 CSV 文件复制数据,由于某种原因,这需要更长的时间,以至于它在没有单独线程的情况下锁定了 Calc。我认为这会体现这个问题,但显然我需要另一个测试用例。或者也许这些单元格有更多的文本很重要。)

编辑 1: 回应 @Jim K 的评论:“单独线程”意味着一个附加函数为业务逻辑生成一个线程,如下所示:

import threading


def _create():
    # ...
    pass


def create(clickEvent):
    t = threading.Thread(target=_create)
    t.start()


g_exportedScripts = create,

test.py(这是有问题的代码。)

import msgbox
import os
import uno


def copyFormula(a, b):
    formula = a.getFormula()
    b.setFormula(formula)

    return formula != ''


doc = XSCRIPTCONTEXT.getDocument()


def copy(clickEvent):
    sheet1 = doc.Sheets.getByName('Sheet1')
    sheet2 = doc.Sheets.getByName('Sheet2')

    for y in range(0, 5):
        for x in range(0, 150):
            source = sheet1.getCellByPosition(x, y)
            target = sheet2.getCellByPosition(x, y)
            copyFormula(source, target)


def create(clickEvent):
    sheet1 = doc.Sheets.getByName('Sheet1')
    sheet2 = doc.Sheets.getByName('Sheet2')

    for y in range(0, 5):
        for x in range(0, 150):
            target = sheet1.getCellByPosition(x, y)
            target.setFormula('(, )'.format(x, y))


g_exportedScripts = create, copy

【问题讨论】:

LibreOffice 是否仍试图重绘 GUI?我想知道在 wxpython 中是否可能有类似于“冻结”和“解冻”的东西,你告诉 GUI“停止绘图,直到我告诉你这样做” 我在一台速度很快的机器上运行了这段代码,每个函数用时不到一秒。在一台速度较慢的机器上(大约 11 岁),大约需要 4 秒。这是你发现的,还是它在你的机器上运行得慢得多?另外,我不明白您在单独的线程中运行是什么意思。这是否意味着与仅按下每张纸上的按钮不同?注意:如果 LibreOffice 在listening mode 中打开,运行会慢很多。 @alex314159:是的,有doc.lockControllers()doc.unlockControllers() [openoffice.org/api/docs/common/ref/com/sun/star/frame/… @Grault:编辑后,问题的线程部分更清晰了;谢谢。 @JimK ~1 秒是我从上面的代码中得到的——足够我观看它的时间,但不如我的应用程序代码多。我在您的答案中应用了第一种技术,并为我的目的获得了足够的速度。我有点尴尬,我需要的功能就在我在文档中使用的功能旁边。 【参考方案1】:

这些函数中的任何一个都应该更快:

def copy2(clickEvent=None):
    sheet1 = doc.Sheets.getByName('Sheet1')
    sheet2 = doc.Sheets.getByName('Sheet2')
    range1 = sheet1.getCellRangeByPosition(0,0,150,5)
    range2 = sheet2.getCellRangeByPosition(0,0,150,5)
    range2.setDataArray(range1.getDataArray())

def copy3(clickEvent=None):
    sheet1 = doc.Sheets.getByName('Sheet1')
    sheet2 = doc.Sheets.getByName('Sheet2')
    range1 = sheet1.getCellRangeByPosition(0,0,150,5).RangeAddress
    range2 = sheet2.getCellRangeByPosition(0,0,150,5).RangeAddress
    cell2 = sheet2.getCellByPosition(
        range2.StartColumn, range2.StartRow).CellAddress
    sheet1.copyRange(cell2, range1)

或者,使用调度程序通过剪贴板进行复制和粘贴。

有关复制和粘贴单元格的更多信息,请参阅Andrew Pitonyak's macro document 中的第 5.23 节。

【讨论】:

谢谢,我明天去看看。另外,我认为我对您的引用不起作用,因此请参阅我对问题的编辑。

以上是关于优化 PyUno 中的公式复制的主要内容,如果未能解决你的问题,请参考以下文章

Azure synapse 中的两次复制(暂存复制 + 普通复制)如何比普通复制更优化

使用 pyuno 对 calc 文档中的单元格范围进行排序

什么是索引以及如何使用它们来优化数据库中的查询? [复制]

《Hexo: 从零开始编写自己的主题》4. fancybox优化图片展示效果代码高亮以及数学公式

SQL优化万能公式:5 大步骤 + 10 个案例

优化公式排版和Beamer相关知识