[gelöst] Argumente einer gegebenen Funktion bekommen

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

darka
Beiträge: 9
Registriert: So, 24.05.2015 13:57

[gelöst] Argumente einer gegebenen Funktion bekommen

Beitrag von darka »

Hallo,

ich schreibe in Java ein Add-On für OpenOffice Calc.
Dabei habe ich folgendes Problem:
Wenn eine Zelle ausgewählt ist, die eine Formel enthält, brauche ich den lokalen Namen dieser Funktion/Formel und den Wert der Funktion. Außerdem brauche ich die Argumente der Funktion. Hier ein paar Beispiele:

1. Bei "=SUM(4;5)" brauche ich folgende Informationen: lokaler Name der Funktion: "SUMME", Argumente der Funktion: 4 (int), 5 (int).

2. Sieht die Formel aber komplizierter aus: "=SUM(PRODUCT(B4;C3);8)" muss das auch funktionieren.
In diesem Bsp brauche ich den Namen der äußeren Funktion: "SUMME", deren Argumente: PRODUKT(B4;C3) (Formel), 8 (int) und das gleiche für die innere Funktion.
Also Name: "PRODUKT", Argumente: B4 (Zellverweis), C3 (Zellverweis) und dann folge ich noch den Zellverweisen und werte aus was darin steht (das klappt aber schon).

3. Auch bei Text-Formeln soll das funktionieren: "=CONCATENATE("Programmier";"sprache")" -> Name: VERKETTEN, Argumente: "Programmier" (String), "sprache" (String).

4. auch bei allen anderen Formeln, die in Calc zur Verfügung stehen, mit allen denkbaren Kombinationen und Spezialfällen, soll das funktionieren.

Am Ende soll also das Ergebnis der kompletten Formel ausgegeben werden, die einzelnen Namen aller Funktionen, die daran beteiligt waren, sowie die Argumente der Funktionen (im Bsp 2 wären die Argumente, die ich als Ausgabe benötige: der Wert aus B4, der Wert aus C3 und 8).

Die lokalen Namen der Funktionen bekomme ich über die Cell-Properties "FormulaLocal".

Wenn die Argumente der Funktionen nur Verweise auf andere Zellen sind, in denen dann die Werte stehen, bekomme ich das alles mit "com.sun.star.sheet.XFormulaQuery, queryPrecedents()" hin. Aber es sollen eben auch so Funktionen wie im Beispiel verarbeitet werden, die gar nicht oder nur teilweise auf andere Zellen verweisen.

Im Beispiel 2 kann ich mit "com.sun.star.sheet.XFunctionAccess, callFunction()" den Wert der inneren Funktion (PRODUKT) berechnen.
Aber wie bekomme ich überhaupt die Argumente der äußeren Funktion (SUMME), sodass ich die innere Funktion auswerten kann?
Kennt jemand eine Methode, die mir die Argumente der Funktionen ausgibt?

Ich wäre sehr dankbar, wenn mir dabei jemand helfen könnte!

darka
Zuletzt geändert von darka am Do, 28.05.2015 16:31, insgesamt 1-mal geändert.
F3K Total
********
Beiträge: 3724
Registriert: Mo, 28.02.2011 17:49

Re: Argumente einer gegebenen Funktion bekommen

Beitrag von F3K Total »

Moin,
CROSSPOSTING ohne Referenz ist unhöflich :(
darka
Beiträge: 9
Registriert: So, 24.05.2015 13:57

Re: Argumente einer gegebenen Funktion bekommen

Beitrag von darka »

Danke für den Hinweis!
Und entschuldigt bitte meinen Fauxpas!
Stephan
********
Beiträge: 12368
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: Argumente einer gegebenen Funktion bekommen

Beitrag von Stephan »

ich kann Dir leider nicht weiterhelfen, einerseits weil ich kein Java kann, andererseits weil ich keine inhaltliche Lösung für das Problem ansich habe.

Mit "com.sun.star.sheet.XFormulaQuery, queryPrecedents()" habe ich noch nie gearbeitet bzw. wusste garnicht von dessen Existenz.

Ich würde versuchen die Formelausdrücke durch Stringbearbeitung aufzulösen, wie aufwändig das wird kann ich schwer einschätzen, andererseits ist aber durchaus überschaubar was alles auftreten kann und auch die Klammersetzung ist eindeutig aufzulösen.

Der erste Schritt wäre beispielsweise von links beginnend den Formelstring zeichenweise zu lesen und alle öffnenden Klammern zu registrieren und auf das Auftauchen der ersten schließenden Klammer zu achten, sobald diese auftritt ist alles zwischen Dieser und dem davor letzten Auftreten einer öffnenden Klammer der 'Gesamt-Parameter-Inhalt' einer Funktion.
Im Beispiel 2 kann ich mit "com.sun.star.sheet.XFunctionAccess, callFunction()" den Wert der inneren Funktion (PRODUKT) berechnen.
Aber wie bekomme ich überhaupt die Argumente der äußeren Funktion (SUMME), sodass ich die innere Funktion auswerten kann?
Na das ist doch einfach, WENN Du bereits das Produkt berechnen kannst ist das Ergebnis dieser Berechnung einer der Parameter von SUM und der zweite Parameter/Summand ist die 8 - oder ich verstehe die Frage falsch.
Kennt jemand eine Methode, die mir die Argumente der Funktionen ausgibt?
Ich nicht, aber das ist doch durch Stringverarbeitung lösbar, indem Du den Formelstring von links beginnend zeichenweise liest und dabei auf öffnende Klammern, Funktionsnamen und schließende Klammern achtest, die erste schließende Klammer liefert gemeinsam mit der davor aufgetretenen öffnenden Klammer das was ich obenstehend schon "'Gesamt-Parameter-Inhalt' einer Funktion" nannte und die zugehörige Funktion ist die letzte davor identifizierte Funktion.
Damit hast Du eine Funktion und ihre Parameter und alle anderen Funktionen muss Du in gleicher Art und Weise rekursiv auflösen.



Gruß
Stephan
darka
Beiträge: 9
Registriert: So, 24.05.2015 13:57

Re: Argumente einer gegebenen Funktion bekommen

Beitrag von darka »

Danke für deine Antwort, Stephan!
Stephan hat geschrieben: Ich würde versuchen die Formelausdrücke durch Stringbearbeitung aufzulösen, wie aufwändig das wird kann ich schwer einschätzen, andererseits ist aber durchaus überschaubar was alles auftreten kann und auch die Klammersetzung ist eindeutig aufzulösen.
An die Stringauswertung hatte ich auch schon gedacht, aber ich würde das eher als Notlösung sehen.
Stephan hat geschrieben:
Im Beispiel 2 kann ich mit "com.sun.star.sheet.XFunctionAccess, callFunction()" den Wert der inneren Funktion (PRODUKT) berechnen.
Aber wie bekomme ich überhaupt die Argumente der äußeren Funktion (SUMME), sodass ich die innere Funktion auswerten kann?
Na das ist doch einfach, WENN Du bereits das Produkt berechnen kannst ist das Ergebnis dieser Berechnung einer der Parameter von SUM und der zweite Parameter/Summand ist die 8 - oder ich verstehe die Frage falsch.
Jein. Der Folgepfeil geht in die andere Richtung: WENN ich das Argument habe und es ist eine Formel (also im Bsp PRODUKT), DANN kann ich sie berechnen, da ich die Funktion zum Berechnen kenne (callFunction()). Aber dazu muss ich das Argument erst auswerten können oder überhaupt erst mal bekommen. Die Antwort dazu hast du mir quasi damit gegeben:
Stephan hat geschrieben: [...] indem Du den Formelstring von links beginnend zeichenweise liest und dabei auf öffnende Klammern, Funktionsnamen und schließende Klammern achtest, die erste schließende Klammer liefert gemeinsam mit der davor aufgetretenen öffnenden Klammer das was ich obenstehend schon "'Gesamt-Parameter-Inhalt' einer Funktion" nannte und die zugehörige Funktion ist die letzte davor identifizierte Funktion.
Damit hast Du eine Funktion und ihre Parameter und alle anderen Funktionen muss Du in gleicher Art und Weise rekursiv auflösen.
Wie gesagt, empfinde ich die Stringauswertung als Notlösung und ich hatte gehofft es gebe eine elegantere Lösung.
Die Gefahr einen Fall zu vergessen sehe ich ziemlich groß, da ich ja die Benutzung der Calc-Formeln und die Schreibweisen nicht einschränken möchte.
Ich denke auch, dass die Performance darunter leiden wird.
Und ist dann nicht auch die Nutzung meines Programmes an die bestehenden Versionen von OOCalc geknüpft, da es wenig flexibel auf Änderung reagieren kann?
Mittlerweile ziehe ich es immer mehr in Betracht. Auch weil ich an der Antwortzahl im Forum merke, dass es wohl kein "kleines", schnell zu lösendes Problem ist.

Dann gibt es allerdings einige Fälle zu beachten:

1. Argumente sind:
a) int -> String beginnt mit Zahl und enthält kein Komma
b) double -> String beginnt mit Zahl und enthält ein Komma
c) String -> String beginnt mit Anführungszeichen
d) boolean ? (Kommt der Fall überhaupt vor?)
e) Verweise -> String beginnt mit Buchstabe
f) Bereichsverweise -> String beginnt mit Buchstabe und enthält einen Doppelpunkt
g) Formeln -> String beginnt mit Buchstabe und enthält eine öffnende Klammer und eine schließende Klammer

Bei 1.e) und folglich auch 1.f) ist noch zu beachten, dass der String die absolute Adresse des Verweises enthält -> Absolute Adresse des Verweises (zB "B4") muss in "com.sun.star.CellAddress" umgewandelt werden (also in "Sheet 0, Column 1, Row 3"). Dazu kenne ich keine Methode. Kennt jemand dazu eine Methode? Ansonsten müsste ich das auch noch "händisch" machen.
Außerdem kann die Adresse auch mit Tabellenblatt angezeigt werden "Tabelle1.B4". Wenn also ein Punkt in dem Verweisstring enthalten ist, ist in dem Wort vor dem Punkt nur die Ziffer interessant und die Adresse nach dem Punkt muss wieder, wie im vorherigen Satz angedeutet, ausgewertet werden.

2. Zeichen in der Formel:
a) Formel enthält mehrere Argumente -> Formel enthält Semikolon, die Argumente von einander trennen
b) Formel enthält nur ein Argument oder Bereichsverweise -> Formel enthält kein Semikolon

Das sind ziemlich viele verschachtelte Bedingungen. Aber das sind jetzt nur die Fälle, die mir einfallen. Und es sind bestimmt nur die üblichsten Fälle. Dabei habe ich jetzt beispielsweise "named ranges" keine Beachtung geschenkt.

Verstehst du meine Bedenken?
Stephan
********
Beiträge: 12368
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: Argumente einer gegebenen Funktion bekommen

Beitrag von Stephan »

Absolute Adresse des Verweises (zB "B4") muss in "com.sun.star.CellAddress" umgewandelt werden (also in "Sheet 0, Column 1, Row 3"). Dazu kenne ich keine Methode. Kennt jemand dazu eine Methode? Ansonsten müsste ich das auch noch "händisch" machen.
Außerdem kann die Adresse auch mit Tabellenblatt angezeigt werden "Tabelle1.B4". Wenn also ein Punkt in dem Verweisstring enthalten ist, ist in dem Wort vor dem Punkt nur die Ziffer interessant und die Adresse nach dem Punkt muss wieder, wie im vorherigen Satz angedeutet, ausgewertet werden.
Also da bist Du jetzt unaufmerksam.

Jenseits dessen das es (zumindest) in StarBasic ausgearbeitete Lösungen im Netz gibt um Zelladressen der Form "B4" in (1, 3) umzuwandeln (was hier nicht direkt hilft, da es Dir um Java geht) ist doch jederzeit möglich das Zell- oder Zellbereichsobjekt mit der namentlichen Adresse anzusprechen und dann die Rangeadresse auszulesen.

In StarBasic skizziert also ungefähr so:

Code: Alles auswählen

x = ThisComponent.Sheets().GetByIndex(0).getCellrangeByName("B4")
With x.RangeAddress 
	Msgbox .StartRow
	Msgbox .StartColumn
	Msgbox .Sheet
End With
Bei den Tabelle-Zelle-Adressen analog also z.B.:

Code: Alles auswählen

k = Split("Tabelle1.B4", ".")
x = ThisComponent.Sheets().GetByName(k(0)).getCellrangeByName(k(1))
With x.RangeAddress 
	Msgbox .StartRow
	Msgbox .StartColumn
	Msgbox .Sheet
End With
Verstehst du meine Bedenken?
Meine (ursprüngliche) Antwort hatte vor allem zum Ziel Dir deutlich zu machen das Deine Frage hier auch Beachtung findet (nur das Dir die Forumssoftware sagt wie oft Deine Frage angeklickt wurde, sagt ja nichts ob sie jemand gelesen hat der sie versteht) und Dir indirekt zu sagen das es wohl keine 'direkte' Lösung gibt. ("wohl" weil ich mich ja auch irren könnte, aber ich bin mir ziemlich sicher)

Natürlich ist es aufwändig das Ganze per 'Stringzerlegung' zu programmieren, andererseits aber wohl programmierungstechnisch nicht wirklich schwierig, die Herausforderung ist nur nichts zu übersehen.
Ich kann Dir dabei wegen der Sprache (Java) nicht weiterhelfen und es wäre mir zu aufwändig jetzt eine quasi Gesamtroutine in Basic zu entwerfen nur um zu illustrieren wie es geht.


Gruß
Stephan
mikeleb
*******
Beiträge: 1427
Registriert: Fr, 09.12.2011 16:50

Re: Argumente einer gegebenen Funktion bekommen

Beitrag von mikeleb »

Hallo,

anbei mal ein Anfang für eine Stringanalyse.
Das Ganze ist, wie schon festgestellt, mordskomplex, da alle Arten von Verknüpfungen, alle Argumenttypen, ... erfasst werden müssten.
In meinem Beispiel wird eine Funktion in Funktionsname, Argumentliste und abschließende Klammer zerlegt. Das allein ist schon nicht trivial.

Ganz am Rande: Wozu brauchst du diese Zerlegung eigentlich? Im Prinzip musst du damit ja die interne Berechnung nachbauen ...
Dateianhänge
makro_formelargumente.ods
(11.21 KiB) 110-mal heruntergeladen
Gruß,
mikeleb
Benutzeravatar
balu
********
Beiträge: 3812
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: Argumente einer gegebenen Funktion bekommen

Beitrag von balu »

Hallo darka,
ich schreibe in Java ein Add-On für OpenOffice Calc.

[...]

4. auch bei allen anderen Formeln, die in Calc zur Verfügung stehen, mit allen denkbaren Kombinationen und Spezialfällen, soll das funktionieren.

Am Ende soll also das Ergebnis der kompletten Formel ausgegeben werden, die einzelnen Namen aller Funktionen, die daran beteiligt waren, ...
Helf mir (uns) etwas auf die Sprünge, wozu soll das ganze gut sein?
Irgendwie kann ich momentan keinen Sinn darin sehen. Deshalb erzähl mal etwas mehr über dein Projekt.

Mir ist wohl schon klar was Du am Ende haben willst, z.B. das Ergebnis der kompletten Formel, (wir hatten hier so etwas ähnliches schon mal für StarBasic behandelt Ergebnis beliebiger Calc-Tabellenformel in Script ausrechnen), aber ob der Aufwand in Java wesentlich weniger ist als in StarBasic weiß ich nicht da ich mit Java nix am Hute habe.

Und ich weiß auch nicht ob dir wirklich bewusst ist auf was Du dich da einlässt. Deine genannten Formeln sind zu einfach, da beispielsweise nur 2 Funktionen direkt im Bezug stehen "=SUM(PRODUCT(B4;C3);8)".

Interessanter wird es dann, wenn nebst der Funktionen auch noch diverse Operatoren eingebunden sind (z.B. >=). Mal ein minimales Beispiel.

Code: Alles auswählen

=WENN(A8*C3>=SUMME(((0,300+0,260+0,300)*1,740)*12.000);"GRÖSSER";"KLEINER")
Sieht doch so einfach aus. Okay, hier stehen jetzt feste Werte drin, das kann man aber auch ändern. Und gleichzeitig erhöhen wir den Schwierigkeitsgrad.

Code: Alles auswählen

=WENN(A8*C3>=SUMME(((X1+Y1+Z1)*Basis)*Steuersatz);"GRÖSSER";"KLEINER")
Ja Upps!! Jetzt stehen da nicht nur Zellbezüge sondern auch noch Namen für Formeln oder für Zellbereiche drin; Basis und Steuersatz.
Und wie gedenkst Du die Namen aufzulösen? Hast Du dir darüber schon mal Gedanken gemacht?
Die Namen können fest auf eine bestimmte Zelle verweisen, oder einen feststehenden Wert beinhalten, oder aber im schlimmsten Fall komplexe Formeln beinhalten. Und hinter dem Namen könnte dann zum Beispiel folgendes stehen.

Code: Alles auswählen

WENN(ISTFEHLER(SUCHEN("DATE:";AA1));WENN(ISTFEHLER(SUCHEN("SUMMARY:";AA1));"";RECHTS(AA1;LÄNGE(AA1)-8));DATUM(TEIL(AA1;LÄNGE(AA1)-7;4);TEIL(AA1;LÄNGE(AA1)-3;2);TEIL(AA1;LÄNGE(AA1)-1;2)-WENN(ISTFEHLER(SUCHEN("DTEND";AA1));0;1)))
Und wenn Du jetzt vielleicht denkst "Ach das kriege ich schon irgendwie hin!", dann überleg dir mal folgendes.
Wenn ein Name ein komplette Formel beinhaltet, so kann auch der Name einen weiteren Namen zu einer Formel beinhalten. Es findet also eine Verschachtelung von verschiedenen Namen statt. Ich will dir das mal an einem relativ leichten Beispiel verdeutlichen.

Name: Apfel
Zugeordnet zu:

Code: Alles auswählen

X1+Y1+Z1
Name: Basis
Zugeordnet zu:

Code: Alles auswählen

1,740
Name: Steuersatz
Zugeordnet zu:

Code: Alles auswählen

12.000
Name: Tomate
Zugeordnet zu:

Code: Alles auswählen

A8*C3
Name: IstWahr
Zugeordnet zu:

Code: Alles auswählen

"GRÖSSER"
Name: IstFalsch
Zugeordnet zu:

Code: Alles auswählen

"KLEINER"
Und nun die erste Formel.
Name: Gurke
Zugeordnet zu:

Code: Alles auswählen

SUMME(((Apfel)*Basis)*Steuersatz)
Und nun die zweite Formel.
Name: Gemüse
Zugeordnet zu:

Code: Alles auswählen

WENN(Tomate>=Gurke;IstWahr;IstFalsch)
Und das Ende vom Lied ist, statt dieser Formel

Code: Alles auswählen

=WENN(A8*C3>=SUMME(((X1+Y1+Z1)*Basis)*Steuersatz);"GRÖSSER";"KLEINER")
steht jetzt nur noch

Code: Alles auswählen

=Gemüse
in einer Tabellenzelle.

Das ist jetzt wie gesagt nur ein relativ leichtes Beispiel, und du musst dich nicht fragen "Wer macht denn so etwas?", denn dann müsste ich sagen das ich so was mache. Und nein, ich bin nicht verrückt! Ich weiß nämlich durchaus wie man eine sehr lange Formel in einer Tabellenzelle mit Namen übersichtlicher gestalten kann, und dennoch die Formel lesen und verstehen kann.

Aber nicht nur die Übersichtlichkeit kann man durch Namen für Formeln erhöhen, sondern, und das ist eigentlich der Hauptgrund dafür, bei sehr umfangreichen und großen Tabellen hat man eine zentrale Stelle wo man einmal eine Formel ändert, und überall dort wo diese Formel steht wird sie automatisch angepasst. Das fällt dann unter die Rubrik: Wartungs- und Pflegeleichter.

So, und nun überleg dir dein Vorhaben noch mal ganz genau. Willst Du es noch immer in die Tat umsetzen, egal in welcher Programmiersprache? Denn wer ein Add-On für OpenOffice Calc programmieren will, muss auch an so etwas denken.



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D
darka
Beiträge: 9
Registriert: So, 24.05.2015 13:57

Re: Argumente einer gegebenen Funktion bekommen

Beitrag von darka »

Stephan hat geschrieben: Also da bist Du jetzt unaufmerksam.

[...] ist doch jederzeit möglich das Zell- oder Zellbereichsobjekt mit der namentlichen Adresse anzusprechen und dann die Rangeadresse auszulesen.
Da hast du Recht! :oops: "com.sun.star.table.XCellRange, getCellRangeByName()". Damit habe ich dann sogar schon meine Fälle 1.e), 1.f), 2.b) zweiter Teil und den Fall mit den "named Ranges" abgedeckt.
Stephan hat geschrieben: Ich kann Dir dabei wegen der Sprache (Java) nicht weiterhelfen und es wäre mir zu aufwändig jetzt eine quasi Gesamtroutine in Basic zu entwerfen nur um zu illustrieren wie es geht.
Das verstehe ich und das will und erwarte ich auch nicht. Das Ziel meiner Anfrage im Forum war nicht ausgearbeiteten Code zu bekommen, sondern ich hatte auf Denkanstöße in eine andere Richtung gehofft. Ich hatte gehofft, dass sich irgendwo in der API ein struct "Formula" versteckt, das gesammelte Informationen über Formeln enthält (vereinfacht und naiv gesagt) oder dass es zumindest eine Methode gibt, die mir das ganze leichter macht und die ich nur übersehen oder nicht gefunden habe.
Es gibt nämlich durchaus services, structs und Methoden, die mir generell Informationen über Funktionen geben:
The services com.sun.star.sheet.FunctionDescriptions and com.sun.star.sheet.FunctionDescription provide help texts about the available spreadsheet cell functions, including add-in functions and their arguments. This is the same information that OpenOffice.org API Calc displays in the function AutoPilot. (https://wiki.openoffice.org/wiki/Docume ... _Functions)
Aber sie geben mir keine Informationen über Instanzen von Funktionen.

Es gibt auch Infos über Recently Used Functions "com.sun.star.sheet.RecentFunctions", aber da bekomme ich auch nur ein Array mit Funktionen. Die Verschachtelung ergibt sich daraus wieder nicht.

@mikeleb: Danke für deinen Code! Genau das ist der Anfang der Auswertung.
Die Auswertung des Namens der Formel wird bei mir allerdings um ein Zeichen verschoben angezeigt. Ich hab die main geändert zu:

Code: Alles auswählen

if ozelle.gettype()=com.sun.star.table.CellContentType.FORMULA then
	argumente(mid(ozelle.formulalocal,1),args())
	temp=join(args(),chr(13))
	msgbox temp		
end if
Dann würde jetzt die Auswertung der einzelnen Argumente folgen und die Betrachtung der Fälle, die ich oben schon angedeutet habe.
mikeleb hat geschrieben: Ganz am Rande: Wozu brauchst du diese Zerlegung eigentlich? Im Prinzip musst du damit ja die interne Berechnung nachbauen ...
balu hat geschrieben: Helf mir (uns) etwas auf die Sprünge, wozu soll das ganze gut sein?
Irgendwie kann ich momentan keinen Sinn darin sehen. Deshalb erzähl mal etwas mehr über dein Projekt.
Im Rahmen einer Studentenarbeit soll eine Formel in Präfix/Infix-Schreibweise ausgewertet werden und in einem Datenflussdiagramm dargestellt werden. Zielgruppe sind Schüler der 9.Klasse Gymnasium.

Hier ein Beispiel:

Code: Alles auswählen

=PRODUKT(QUOTIENT(SUMME(a;b);2);h)
soll als Datenflussdiagramm angezeigt werden:
Hubwieser et al.: Informatik 2, Tabellenkalkulationssysteme und Datenbanken. Klett Verlag, 2007, S. 43, Fig.1
Hubwieser et al.: Informatik 2, Tabellenkalkulationssysteme und Datenbanken. Klett Verlag, 2007, S. 43, Fig.1
BspDatenflussdiagramm.png (135.07 KiB) 5931 mal betrachtet
balu hat geschrieben: Interessanter wird es dann, wenn nebst der Funktionen auch noch diverse Operatoren eingebunden sind (z.B. >=).
Richtig! Den Fall hätte ich jetzt erst mal weggelassen und wäre ihn als nächstes angegangen. Ganz im Sinn "eins nach dem anderen" :-D

Deine Beispiele, balu, sind perfekt! Denn genau da kommen auch meine Bedenken für die Stringauswertung her. Aber die Unterscheidungen, die du gemacht hast, verstehe ich noch nicht ganz:
balu hat geschrieben:Jetzt stehen da nicht nur Zellbezüge sondern auch noch Namen für Formeln oder für Zellbereiche drin; Basis und Steuersatz.
Und wie gedenkst Du die Namen aufzulösen? Hast Du dir darüber schon mal Gedanken gemacht?
Die Namen können fest auf eine bestimmte Zelle verweisen, oder einen feststehenden Wert beinhalten, oder aber im schlimmsten Fall komplexe Formeln beinhalten.
Mit der Methode "getCellRangeByName()" in "com.sun.star.table.XCellRange" kann ich sowohl Zellbezüge, Zellbereiche als auch Namen für Zellbezüge/Zellbereiche auswerten.
Wie kann man Formeln einen Namen zuordnen ohne den Namen einer bestimmten Zelle/einem bestimmten Zellbereich zuzuordnen? Ist der Name nicht immer auch an eine Zelle/einen Zellbereich geknüpft? Oder verstehe ich dein Bsp falsch?
balu hat geschrieben: So, und nun überleg dir dein Vorhaben noch mal ganz genau. Willst Du es noch immer in die Tat umsetzen, egal in welcher Programmiersprache? Denn wer ein Add-On für OpenOffice Calc programmieren will, muss auch an so etwas denken.
Da gibt es kein Zurück mehr.. Das Projekt steht und das Programm läuft auch schon, wenn jede Zelle NUR Verweise enthält. Aber eben NUR dann. Enthält eine Formel keine Verweise, also sind die Argumente der Formel nicht auf verschiedene Zellen aufgeteilt, wird das eben nicht ausgewertet.
Das muss ich jetzt noch ergänzen.... und kann hoffentlich alle Fälle abdecken...

Gruß darka
Benutzeravatar
balu
********
Beiträge: 3812
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: Argumente einer gegebenen Funktion bekommen

Beitrag von balu »

Hallo darka,
Deine Beispiele, balu, sind perfekt!
Freut mich zu hören.

darka hat geschrieben: Denn genau da kommen auch meine Bedenken für die Stringauswertung her. Aber die Unterscheidungen, die du gemacht hast, verstehe ich noch nicht ganz:
balu hat geschrieben: Jetzt stehen da nicht nur Zellbezüge sondern auch noch Namen für Formeln oder für Zellbereiche drin; Basis und Steuersatz.
Und wie gedenkst Du die Namen aufzulösen? Hast Du dir darüber schon mal Gedanken gemacht?
Die Namen können fest auf eine bestimmte Zelle verweisen, oder einen feststehenden Wert beinhalten, oder aber im schlimmsten Fall komplexe Formeln beinhalten.
Ich wollte darauf hinweisen, dass wenn Zellbezüge angegeben sind eine Auswertung wohl noch relativ einfach ist, wenn aber auch noch Namen angegeben sind die mit zu der Formel gehören, es schon schwieriger wird. Denn die Namen müssen ja auch untersucht und auseinandergenommen werden. Und dieser Prozess kann sich unter Umständen als sehr mühsam herausstellen, da irgendwie der Name rückwärts untersucht werden muss.

Wie kann man Formeln einen Namen zuordnen ohne den Namen einer bestimmten Zelle/einem bestimmten Zellbereich zuzuordnen? Ist der Name nicht immer auch an eine Zelle/einen Zellbereich geknüpft? Oder verstehe ich dein Bsp falsch?
Gar nicht so einfach, wenn man wohl noch nicht selber damit gearbeitet hat. :wink:
Der Name kann eine bestimmte Zelle sein.
Der Name kann ein bestimmter Zellbereich sein.
Der Name kann einen festen Wert beinhalten.
Der Name kann einen Text beinhalten.
Der Name kann kann eine Formel sein.
Der Name kann kann eine Formel sein, die Namen für die eben genannten beinhalten.
Der Name kann kann eine Formel sein, die wiederum auch nur ein Name für eine Formel ist.

Wie Du siehst kann ein Name vieles sein. Er kann also nicht nur mit einer bestimmten Zelle verknüpft sein, es kann genau so gut auch einfach nur einen Wert oder einen Text zugeordnet worden sein.

Aber eins ist dabei immer wichtig! Wenn man mit Namen arbeitet, und besonders mit Namen die auf Namen zugreifen, so müssen die Namen strukturiert (also der Reihe nach) einzeln eingegeben werden, denn sonst hagelts Fehlermeldungen.
Also eine Namenformel a-la

Code: Alles auswählen

SUMME(((Apfel)*Basis)*Steuersatz)
funktioniert nur dann, wenn vorher schon Apfel, Basis und Steuersatz definiert wurden. Das aber nur so am Rande, da dies nix mit deinem eigentlichen Problem zu tun hat. Denn wir gehen ja einfach davon aus, das die Namen schon existieren. Und folglich tritt folgendes Problem auf:

Was verbirgt sich hinter dem Namen und wieviele Namen gehören noch dazu?

Mit anderen Worten: Der Name in der Zelle

Code: Alles auswählen

=Gemüse
beinhaltet noch weitere Namen (siehe meinen ersten Beitrag). Und wie kommt man nun an die einzelnen Namen ran?
Hier ist die Übersicht aller Namen die zusammengesetzt den Namen: Gemüse ergeben (inklusive Gemüse selber).

Code: Alles auswählen

Apfel
Basis
Gemüse
Gurke
IstFalsch
IstWahr
Steuersatz
Tomate
Und hier was den einzelnen Namen zugeordnet ist.

Code: Alles auswählen

Apfel	=X1+Y1+Z1
Basis	=1,74
Gemüse	=WENN(Tomate>=Gurke;IstWahr;IstFalsch)
Gurke	=SUMME(((Apfel)*Basis)*Steuersatz)
IstFalsch	="KLEINER"
IstWahr	="GRÖSSER"
Steuersatz	=12
Tomate	=A8*C3
Du müsstest jetzt also nach folgendem Schema vorgehen.
Frage: Was ist Gemüse zugeordnet?
Antwort: Die folgende Formel

Code: Alles auswählen

=WENN(Tomate>=Gurke;IstWahr;IstFalsch)
Was ist Tomate zugeordnet, dann Gurke usw. etc.
Du müsstest also in der WENN-Formel jeden Namen durch die zugeordneten Formeln, Werte und Texte ersetzen, damit Du dann in deinem Java-Makro diese Formel stehen hast

Code: Alles auswählen

=WENN(A8*C3>=SUMME(((X1+Y1+Z1)*1,740)*12.000);"GRÖSSER";"KLEINER")
und dann könntest du wohl den "normalen" Weg gehen die Formel wie gewünscht aufzudröseln.


ABER!!!
Nach dem Du ja jetzt gesagt hast das dies quasi mehr ein Schulinternes Projekt ist, frage ich mich (dich) "Meinst Du die Schüler werden mit Namen arbeiten?"
Da gibt es kein Zurück mehr.
Na dann wünsche ich dir sehr viel Glück und Erfolg :D



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D
darka
Beiträge: 9
Registriert: So, 24.05.2015 13:57

Re: Argumente einer gegebenen Funktion bekommen

Beitrag von darka »

Hallo balu,

Jetzt hab ichs verstanden! Hab auch gleich mal nachgelesen... soweit ich das verstanden habe, behandelt OO die Namen und die Beispiele, die du genannt hast, intern alle gleich. Also intern ist es nicht relevant ob der Name über eine Formel oder über Zellen oder über Namen definiert wurde.
https://wiki.openoffice.org/wiki/Docume ... med_Ranges
Das würde meinen Ansprüchen wieder entgegen kommen :wink:
Dann gibt es aber anscheinend einen Unterschied zwischen label range und named range. Den muss ich mir noch anschauen, aber wie du sagst, ist das jetzt erst mal dritt-rangig.
Für ein perfektes Programm ist es notwendig, finde ich. Aber den Zweck erfüllt es wohl auch ohne diese Funktion.

So, jetzt erst mal die "normalen" Fälle auf die Reihe kriegen, dann die Operatoren und dann evtl noch label ranges.
Wenn ich so weit bin, werde ich hier für Java-interessierte nochmal schreiben wie ich die Stringauswertung gelöst habe.

Stephan, mikeleb, balu, vielen Dank, dass ihr euch meines Problemes angenommen habt!!

Gruß, darka
Karolus
********
Beiträge: 7533
Registriert: Mo, 02.01.2006 19:48

Re: Argumente einer gegebenen Funktion bekommen

Beitrag von Karolus »

Hallo

Hast du eigentlich in dem Kontext mal geschaut was die Methoden .getArrayTokens() bzw. .getTokens() hergeben?

Zumindest den selbstgestrickten Formelparser solltest du damit nicht benötigen.
LO7.4.7.2 debian 12(bookworm) auf Raspberry5 8GB (ARM64)
LO25.2.3.2 flatpak debian 12(bookworm) auf Raspberry5 8GB (ARM64)
darka
Beiträge: 9
Registriert: So, 24.05.2015 13:57

Re: Argumente einer gegebenen Funktion bekommen

Beitrag von darka »

Hallo Karolus,

ja, die Methoden habe ich gesehen, aber ich verstehe nicht, was sie tun. :(
Im Developer's Guide habe ich keine Beschreibungen dazu gefunden und über die Suchmaschine auch nicht.
Die Beschreibungen in der API doc hat mir auch nicht geholfen. Weißt du was die Methoden machen?

Hier, was ich verstanden hab:
anscheinend kann man mit "com.sun.star.sheet.XFormulaTokens, getTokens()" eine bestehende Formel in Zeichen (token) umwandeln. Die Zeichen erhält man in Form von "FormulaToken", die aus "OpCode" und "Data" bestehen. "OpCode" könnte die Vorschrift sein mit der die Formel in Zeichen umgewandelt wird, bin mir aber nicht sicher. "Data" kann wohl sowas wie ein zugewiesener Name sein.

Vermutlich hat auch "com.sun.star.sheet.XFormulaOpCodeMapper, getMappings()" eine ähnliche Funktion, aber da versteh ich genauso wenig.
Es gibt dann in dem Zusammenhang noch den XFormulaParser, aber der is vermutlich für nicht vordefinierte Funktionen gedacht?! und die constant group "FormulaMapGroup".

Aber ich versteh ja nicht mal die getTokens()-Funktion...
Was kann ich mit den Tokens machen wenn ich sie habe?
Karolus
********
Beiträge: 7533
Registriert: Mo, 02.01.2006 19:48

Re: Argumente einer gegebenen Funktion bekommen

Beitrag von Karolus »

Hallo

Du bist einigermassen auf dem richtigen Pfad, würde es dir helfen wenn versuche die Zusammenhänge auf `python`isch zu erklären?? -- in Java wäre ich absolut überfordert!
LO7.4.7.2 debian 12(bookworm) auf Raspberry5 8GB (ARM64)
LO25.2.3.2 flatpak debian 12(bookworm) auf Raspberry5 8GB (ARM64)
darka
Beiträge: 9
Registriert: So, 24.05.2015 13:57

Re: Argumente einer gegebenen Funktion bekommen

Beitrag von darka »

Ja sehr gerne!

Wichtig wäre auch, von welchem service oder Objekt ich ....XFormulaTokens anfordern muss.
Antworten