setFormulaArray 太慢了

Posted

技术标签:

【中文标题】setFormulaArray 太慢了【英文标题】:setFormulaArray too slow 【发布时间】:2021-06-08 07:02:33 【问题描述】:

我正在尝试编写一个 python 包装器,该包装器旨在从 csv(或 mysql)读取多个记录并更新工作表预定义范围的值,该范围由值单元格和公式单元格组成,我的目的是仅更新值单元格并保持范围内的公式单元格不变。

为了做到这一点,我首先尝试逐个设置单元格值,使用if跳过公式单元格,但是由于单元格超过10000个所以速度很慢,然后我尝试了setDataArray这是足够快但公式被值覆盖,然后我创建了一个数组并将值和公式设置到数组中并使用setFormulaArray 将值和公式放入范围内,该函数是我需要的,因为它需要多个分钟完成

我知道setFormulaArray 会更新公式,但我不需要这样做,但是由于 API 中没有选项可以跳过公式,我只能使用相同的公式来更新特定的原始公式细胞。

在使用setFormulaArry 时是否有任何解决方案可以提高性能,或者是否有任何解决方案可以仅更新值单元格并跳过某个范围内的公式单元格? 下面是我的代码

import uno
import time


#to open the libreoffice calc file
local_ctx = uno.getComponentContext()
smgr_local = local_ctx.ServiceManager
resolver = smgr_local.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", local_ctx)
url = "uno:socket,host=localhost,port=2083,tcpNoDalay=1;urp;StarOffice.ComponentContext"

uno_ctx = resolver.resolve(url)
uno_smgr = uno_ctx.ServiceManager
desktop = uno_smgr.createInstanceWithContext("com.sun.star.frame.Desktop", uno_ctx )
PropertyValue = uno.getClass('com.sun.star.beans.PropertyValue')
inProps = PropertyValue( "Hidden" , 0 , True, 0 )
document = desktop.loadComponentFromURL("file:///D:/salse.ods", "_blank", 0, inProps )


# get the sheet and read original data and formula from the sheet
sheets = document.getSheets()
xs = sheets["salse"]
cursor=xs.createCursor()
cursor.gotoStartOfUsedArea(False)
cursor.gotoEndOfUsedArea(True)
cra=cursor.getRangeAddress()


rng=xs.getCellRangeByPosition(cra.StartColumn,cra.StartRow,cra.EndColumn,cra.EndRow)
ft=rng.getFormulaArray()

#some code here to change values in ft.... 


# bellow took more than one minutes
rng.setFormulaArray(ft)

这只是对 setFormulaArray 性能的测试

【问题讨论】:

欢迎来到 SO!为什么您认为“API 中没有选项可以跳过公式”? crngs=cursor.queryContentCells(7) 呢?然后.getCells().createEnumeration().hasMoreElements().nextElement()... 见herehere... 或只使用MRI 感谢您的回答,我的意思是 "there is no option to skip formula"setting values 时,理想情况下,我期待像@ 987654335@,遇到公式单元格时会自动跳转到下一个数值单元格。但是它对您的建议很有帮助,我测试了queryContentCells(7),它返回了分割的范围,然后我可以在每个子范围上调用setDataArray,它不是那么完美,但可以提高性能。谢谢。 【参考方案1】:

更新1:

我仍然找不到理想的解决方案,但是,我的解决方案是为工作簿中的每个工作表创建一个相同的工作表,并在原始工作表中添加对完全相同单元格上新创建工作表的引用,例如:

example

sheetA 是原始工作表

sheetA-1 是新创建的

然后修改 sheetA 中的数据单元格以引用 sheetA-1

然后setDataArray更新sheetA-1中的整个范围,sheetA中对应单元格中的数据会自动变化

【讨论】:

以上是关于setFormulaArray 太慢了的主要内容,如果未能解决你的问题,请参考以下文章

sqlmap太慢了

for循环太慢了

InAppReview : SKStoreReviewController 太慢了

为啥使用 information_schema 太慢了?

插入 WStandardItemModel 太慢了

Ucanaccess 太慢了