Seite 1 von 2

mit Python auf LO-eigene Funktionen verwenden?

Verfasst: Do 4. Jul 2024, 09:26
von StefKe
Hallo in die Runde, ist es möglich per Python eingebaute Funktionen von Calc (ANZAHL2(); ZÄHLENWENN()...etc.) zu verwenden?

Danke - Stefan

Re: mit Python auf LO-eigene Funktionen verwenden?

Verfasst: Do 4. Jul 2024, 09:55
von karolus
Hallo
Kurze Antwort… Im Prinzip geht das … aber nur mit vielen Einschränkungen, meistens ist es in python einfacher gleich die Funktionen zu simulieren! Beispiel kommt noch!

Re: mit Python auf LO-eigene Funktionen verwenden?

Verfasst: Do 4. Jul 2024, 10:17
von karolus
Hallo

1. du brauchst die englischen Funktionsnamen anstatt der lokalisierten Namen.
2. …DataArray wird in python zu einer Datenstruktur übersetzt mit der wiederum die »calc-funktion« nicht mag.

am Beispiel von »ANZAHL2« ⇒ wäre »COUNTA« die englische Funktion, die tut aber nicht, aber ?meistens? »COUNT«:

Code: Alles auswählen

from itertools.chain import from_iterable as flat

createUnoService = XSCRIPTCONTEXT.ctx.ServiceManager.createInstance

doc = XSCRIPTCONTEXT.getDocument()
sheet = doc.Sheets["Tabelle1"]
data = flat( sheet["E1:F30"].DataArray )
fa = createUnoService("com.sun.star.sheet.FunctionAccess")
result = fa.callFunction("COUNT", data )
print(result)
Versuche mit ZÄHLENWENN (COUNTIF) scheitern schon an der Übergabe des »Kriteriums«:

Code: Alles auswählen

data2 = flat( sheet["A1:B14"].DataArray )
result2 = fa.callFunction("COUNTIF", (data, ">=5.0") )
#result2  # peng # aber nativer pythoncode geht stattdessen:
result2 = sum( entry>=5 for entry in data2 if entry!='')

Re: mit Python auf LO-eigene Funktionen verwenden?

Verfasst: Do 4. Jul 2024, 12:37
von StefKe
Ups, da bleib ich bei Python. Ne einfache Schleife tut's auch für den Hausgebrauch.

Danke - Stefan

Re: mit Python auf LO-eigene Funktionen verwenden?

Verfasst: Fr 1. Nov 2024, 18:26
von preklov
Bei mir hilft es immer, die Wertargumente als Tuple anzugeben, auch wenn es nur ein einziger Wert ist. Funktionsnamen müssen in Englisch sein. Ein Tuple ist eine durch Komma getrennte Sequenz von Werten in runden Klammern. Nach dem letzten Element darf ein Komma stehen. Man kann also ein Tuple mit nur einem Element durch beispielsweise „(2,)“ er-
zeugen.
Zum Beispiel:

Code: Alles auswählen

doc = XSCRIPTCONTEXT.getDocument()
fAccess = uno.getComponentContext().ServiceManager.createInstance('com.sun.star.sheet.FunctionAccess')
sheet = doc.Sheets.getByIndex(0)
result = fAccess.callFunction('Min', (24, 6, 18, 234)) # 6
oder

Code: Alles auswählen

result = fAccess.callFunction('Abs', (-2,)) # 2
oder

Code: Alles auswählen

result = fAccess.callFunction('Upper', ('klein',)) # KLEIN
oder

Code: Alles auswählen

count = int(fAccess.callFunction('COUNTBLANK', (sheet.getCellRangeByPosition(0, 0, 0, 20),)))
Das Komma innerhalb des geklammerten Wertarguments erzeugt zwingend ein Tuple.

Viel Erfolg
Volker

Re: mit Python auf LO-eigene Funktionen verwenden?

Verfasst: Fr 1. Nov 2024, 20:15
von karolus
Ah … man lernt nie aus!

Die tuple-übergabe war mir schon klar, nicht jedoch die Zell(bereichs)-übergabe:

Code: Alles auswählen

doc = XSCRIPTCONTEXT.getDocument()
fa = createUnoService("com.sun.star.sheet.FunctionAccess") 
#cellrange = doc.CurrentSelection # funktioniert nicht mit selektiertem »F1:F30«…
cellrange = doc.Sheets.Sheet1["F1:F30"]  # … in der Form klappts
result = fa.callFunction('COUNTblank', (cellrange,)) # funktioniert
#result = fa.callFunction('COUNTIF', (cellrange,".*55")) #funktioniert nicht! regex?
print(result)
insbesondere die vorletzte Zeile mit »COUNTIF« scheitert anscheinend an der Übergabe des regulären Ausdrucks?!

Re: mit Python auf LO-eigene Funktionen verwenden?

Verfasst: Sa 2. Nov 2024, 15:24
von preklov
Tja, CurrentSelection ist halt kein CellRange-Typ. Es ist wohl ein wenig umständlich:

Code: Alles auswählen

sel = doc.CurrentSelection
sheet = sel.Spreadsheet
selAddress = sel.RangeAddress
range = sheet.getCellRangeByPosition(selAddress.StartColumn,
                                     selAddress.StartRow,
                                     selAddress.EndColumn,
                                     selAddress.EndRow)
count = int(fAccess.callFunction('COUNTBLANK', (range,)))
Beim Countif-Problem finde ich auf die Schnelle keine Lösung für ein Regex-Argument. Ansonsten scheint es zu funktionieren.
Es ist noch viel zu entdecken :)

Re: mit Python auf LO-eigene Funktionen verwenden?

Verfasst: Sa 2. Nov 2024, 18:18
von preklov
Nur zur Vollständigkeit:
Mein Vorschlag zur Behandlung der CurrentSelection ist natürlich nur ein Teilaspekt. Er gilt nur für die Selektion eines zusammenhängenden Zellbereichs, nicht für die Selektion nur einer Zelle oder mehrerer getrennter Zellbereiche.
Für eine Komplettlösung benötigt man eine Methode, die differenziert entsprechende Werte zurückgibt.
Falls die Zusammenhänge nicht klar sein sollten, will ich gerne die Informationen geben.

Re: mit Python auf LO-eigene Funktionen verwenden?

Verfasst: So 3. Nov 2024, 11:50
von karolus
Hallo
Tja, CurrentSelection ist halt kein CellRange-Typ
Einspruch … in …CurrentSelection war natürlich exakt der gleiche Object-Typ, wie per statischer Zuweisung, warum »FunctionAccess« mit dem durchgereichten Objekt selbst Probleme hat?? kA :|
zum Glück lässt sich das Problem mit einer »Kopie« von »CurrentSelection« erschlagen:

Code: Alles auswählen

doc = XSCRIPTCONTEXT.getDocument()
# »createUnoService« ist bereits anderswo definiert!
fa = createUnoService("com.sun.star.sheet.FunctionAccess") 
cellrange = doc.getCurrentSelection() # aktuell »EIN« Zell-Bereich
cellrange = cellrange[:,:] # quasi Kopie per slice-Syntax

result = fa.callFunction('xmatch', ("Dezember",cellrange,0,-1)) 

print(result)  # funktioniert!!

Re: mit Python auf LO-eigene Funktionen verwenden?

Verfasst: So 3. Nov 2024, 13:10
von preklov
Wow, klasse Idee! :P