2016-12-20 4 views
0

LibreOffice 5.2.3.3Optimisation de la copie de formules dans PyUno

J'essaye de porter un programme Excel VBScript sur PyUno. La logique fonctionne, mais elle fonctionne beaucoup plus lentement qu'Excel.

J'ai fait deux feuilles, Sheet1 et Sheet2. En référence au script ci-dessous, j'ai ajouté un bouton à Sheet1 pour appeler create et un à Sheet2 pour appeler copy. Après avoir exécuté create et en attendant qu'il se termine, je cours copy.

Y a-t-il un moyen d'optimiser davantage copy? Quand il se déroule dans un fil séparé, je peux voir chaque ligne se remplir, alors que j'espérais que ce serait instantané à l'œil humain. Retrait du fil fait juste attendre les graphiques pour mettre à jour.

(Mon code original copie des données à partir d'un fichier CSV invisible, ce qui prend encore plus de temps pour une raison quelconque, au point qu'il verrouille Calc sans threads séparés.Je pensais que cela allait manifester ce problème, mais apparemment j'ai besoin . un autre cas de test Ou peut-être il importe que ces cellules ont plus de texte)

Edit 1:. en réponse au commentaire de @ Jim K: « fil séparé », une fonction supplémentaire engendre un fil pour la logique métier, comme si:

import threading 


def _create(): 
    # ... 
    pass 


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


g_exportedScripts = create, 

test.py (Ceci est le code en question.)

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 
+0

Est-ce que LibreOffice essaie de redessiner l'interface graphique de toute façon? Je me demande s'il peut y avoir quelque chose de similaire à "geler" et "décongeler" dans wxpython où vous dites à l'interface graphique "arrête de dessiner jusqu'à ce que je vous dise de le faire" – alex314159

+1

J'ai exécuté ce code sur une machine rapide, et chaque fonction moins d'une seconde. Sur une machine lente (environ 11 ans), il a fallu environ 4 secondes. Est-ce ce que vous avez trouvé, ou a-t-il fonctionné beaucoup plus lentement sur votre machine? Aussi, je n'ai pas compris ce que vous vouliez dire en courant dans un fil séparé. Est-ce que cela signifie quelque chose de différent de simplement appuyer sur le bouton sur chaque feuille? Note: Si LibreOffice est ouvert en [mode d'écoute] (https://wiki.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Starting_OpenOffice.org_in_Listening_Mode), il fonctionnera beaucoup plus lentement. –

+1

@ alex314159: oui, il y a 'doc.lockControllers()' et 'doc.unlockControllers()' [https://www.openoffice.org/api/docs/common/ref/com/sun/star/frame/ XModel.html] – ngulam

Répondre

1

Chacune de ces fonctions devrait être beaucoup plus rapide:

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) 

Vous pouvez également utiliser le répartiteur pour copier et coller avec le presse-papiers.

Voir la section 5.23 dans Andrew Pitonyak's macro document pour plus d'informations sur la copie et le collage de cellules.

+0

Merci, je vais jeter un coup d'oeil à ce demain. En outre, je ne pense pas que ma référence à vous a fonctionné, alors voyez mon edit à la question. – Grault