[gelöst] Routinenname mit Variablen starten

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

Moderator: Moderatoren

erikafuchs
******
Beiträge: 690
Registriert: Di, 13.02.2007 17:38
Wohnort: Büttelborn

[gelöst] Routinenname mit Variablen starten

Beitrag von erikafuchs »

Ich möchte meine Programm übersichtlicher machen und anstelle von

wenn a=1 dann führe Routine_1 aus und wenn b=2 dann starte Routine_2
also anstelle von:
select case a
case 1
routine_1
case 2
routine_2
case
...
end case
etwas wie:
routine_a
geht das?
Zuletzt geändert von erikafuchs am Sa, 28.11.2020 17:50, insgesamt 1-mal geändert.
Hiker
******
Beiträge: 591
Registriert: Mo, 08.09.2014 21:34
Wohnort: Berlin

Re: Routinenname mit Variablen starten

Beitrag von Hiker »

Hallo,

machen kann man fast alles. Aber BASIC ist nicht die modernste Sprache.
In C würde ich einfach entsprechende Pointer in einem Array speichern, vor allem, wenn der Index wie bei Deinem Beispiel numerisch ist.
Bei Objektorientierung könntest Du Klassen bilden.

In jedem Fall hättest Du aber an anderer Stelle dann fast denselben Code, da Du Array/Objekt ja erstmal initialisieren musst.

Mein Vorschlag wäre also einfach eine SUB-Routine der a übergeben wird und die den entsprechenden Code aufruft.

Mfg, Jörn
Libre Office 6.3.1 (Win 10 Pro) / Libre Office 6.0.7 (Win8.1 Pro, Win 7 Pro) / AOO (Win 7)
erikafuchs
******
Beiträge: 690
Registriert: Di, 13.02.2007 17:38
Wohnort: Büttelborn

Re: Routinenname mit Variablen starten

Beitrag von erikafuchs »

Vielen Dank für die Mühe - ich hatte befürchtet dass das nicht geht.
Also doch mit „select case ...“ - es sind dann aber halt 2 mal 35 „case ...“ :-|
craig22
****
Beiträge: 135
Registriert: Mi, 19.08.2020 13:47

Re: Routinenname mit Variablen starten

Beitrag von craig22 »

Hallo Pit,

die Frage welche ich mir hier stelle ist:
Unter welchen Bedingungen soll a ODER b ODER c, etc. gültig sein?

Wenn dies vor der Case-Anweisung verifiziert wurde, dann genügt eine Case-Anweisung.
Ggf. a, b, c, etc. in ein Array schreiben, durchlaufen und prüfen.
Wenn WAHR dann:
xxx = a
oder
xxx = b
usw.

Code: Alles auswählen

Select Case xxx
.
.
.
End Select
xxx steht dann variabel für a ODER b ODER c, etc.
Gruß

Craig
_____________________________________________________
WIN 10 Pro 64-Bit • LO 7.1.5.2 (x64) • AOO 4.1.8
erikafuchs
******
Beiträge: 690
Registriert: Di, 13.02.2007 17:38
Wohnort: Büttelborn

Re: Routinenname mit Variablen starten

Beitrag von erikafuchs »

Ja, so mache ich das jetzt:
Screenshot4.jpg
Screenshot4.jpg (85.25 KiB) 3421 mal betrachtet
Die Aufgaben werden durch Klick in die Zelle gestartet - z.B. "Kopfrechnen" in Zeile 9 und im Modul findet sich dann die Routine "Aufg_09".
Und das gibt es dann noch für die Kontrolle der eingegebenen Lösung. Das sind lange Listen, die hätte ich gerne kürzer gehabt - mit dem Aufruf von
Aufg_&zeile
- oder
Aufg_§zeile
oder so - wäre doch viel eleganter.
craig22
****
Beiträge: 135
Registriert: Mi, 19.08.2020 13:47

Re: Routinenname mit Variablen starten

Beitrag von craig22 »

Hallo Pit,
ich dachte mal eben einen kleinen Code schreiben… :(
Jetzt habe ich ein Problem mit dem ich selbst nicht klar komme, wahrscheinlich kann Basic dieses nicht.

Deshalb habe ich hier mal eine Frage gestellt:
Mit einer String-Variablen eine Prozedur aufrufen

Wenn ich eine positive Antwort erhalte, dann habe ich einen passenden Code für Dich.
Gruß

Craig
_____________________________________________________
WIN 10 Pro 64-Bit • LO 7.1.5.2 (x64) • AOO 4.1.8
craig22
****
Beiträge: 135
Registriert: Mi, 19.08.2020 13:47

Re: Routinenname mit Variablen starten

Beitrag von craig22 »

Hallo Pit,
gleich vorweg, mir ist der entscheidende Schritt nicht geglückt.
Trotzdem möchte ich Dir zeigen was ich bisher programmiert habe.
siehe Datei und beachte die Kommentare, auch die im Code.
Sub Routine per String starten_01.ods
Call-Anweisung funktioniert nicht
(94.81 KiB) 89-mal heruntergeladen
  1. Ein Tabellenblatt mit den Namen der Sub-Routinen für die Aufgaben.
    Das Blatt könntest Du entweder in Deiner Datei verstecken oder man greift per Code auf eine externe Datei zu.
  2. In meiner Beispieldatei fehlt das Doppelklick-Ereignis. Ist zum Testen aber auch egal.
    Markiere eine beschriebene Zelle in Blatt „Rechenarten“ und starte das Makro:
    modAuswahl.Auswahl
  3. Das Makro ermittelt die Zelladresse der markierten Zelle, speziell wird der Zeilenindex ausgelesen und in die Variable „nRow“ geschrieben. nRow wird später benötigt, um auf das passende Arrayfeld zu zugreifen.
  4. Das Makro ließt den Zellbereich (A1:A51) aus Blatt „Routinenname“ in ein Array ein. Durch diesen Vorgang wird das Makro auch gleichzeitig dimensioniert.
  5. Der Name des Array ist: mRoutine()()
  6. Zugriff auf das passende Arrayfeld= mRoutine(nRow)(0)
  7. Zum besseren Verständnis folgt nun eine Messagebox mit Info’s
  8. Zum Schluß die nicht funktionierende Call-Anweisung.
    die Call-Anweisung sollte nun, jenach Arrayfeld-Inhalt das passende Aufgabenmakro starten.
    dazu habe ich ein eigenes Modul angelegt:
    modAufgaben
    Die Messagbox zeigt auch an, welche Routine in modAufgaben gestartet werden sollte.
    Arrayfeld-Inhalt =
Auf diese Weise benötigst du keine Case-Anweisung zur Selektion der entsprechenden Aufgabe.
Wenn nur die Call-Anweisung funktionieren würde.
Gruß

Craig
_____________________________________________________
WIN 10 Pro 64-Bit • LO 7.1.5.2 (x64) • AOO 4.1.8
erikafuchs
******
Beiträge: 690
Registriert: Di, 13.02.2007 17:38
Wohnort: Büttelborn

Re: Routinenname mit Variablen starten

Beitrag von erikafuchs »

Wenn nur die Call-Anweisung funktionieren würde.
ja, genau, wenn das nur funktionieren würde!

Vielen Dank für deine Mühe!
craig22
****
Beiträge: 135
Registriert: Mi, 19.08.2020 13:47

Re: Routinenname mit Variablen starten

Beitrag von craig22 »

Hallo Pit,

ich habe die Lösung, ob Du diese nutzen kannst kann ich nicht beurteilen.

In meiner Beispieldatei gibt es zwei relevante Tabellenblätter:
  • Routinenname
  • Rechenarten
Damit mein Programm funktioniert, müssen in den jeweiligen Spalten (A) die gleiche Anzahl von Einträgen vorhanden sein.
Derzeit sind es je Tabelle 8 Einträge:
"Ergänzen" bezieht sich auf Routine "Aufg_01"
"Addieren" bezieht sich auf Routine "Aufg_02"
usw.

Stelle den Cursor in Tabelle "Rechenarten" in eine der befüllten Zellen der Spalte A und führe das Makro per Button aus.

Es ist auch eine kleine Fehlerroutine eingebaut, für den Fall dass der Cursor versehentlich
in Spalte B steht oder sich in einer leeren Zeile befindet.
Diese wäre noch ausbaufähig, um ggf. alle Bedienungsfehler abzufangen.

Naja, auf jeden Fall entfällt so die Case-Anweisung, da die passenden Routinen variabel per Zeilenindex gestartet werden.

Bei einem Doppelklick-Event wäre ja auch eine Zeile markiert und das Makro käme so an den erforderlichen Zeilenindex.
Sub Routine per String starten_02.ods
(94.29 KiB) 90-mal heruntergeladen
Gruß

Craig
_____________________________________________________
WIN 10 Pro 64-Bit • LO 7.1.5.2 (x64) • AOO 4.1.8
erikafuchs
******
Beiträge: 690
Registriert: Di, 13.02.2007 17:38
Wohnort: Büttelborn

Re: Routinenname mit Variablen starten

Beitrag von erikafuchs »

Ich erstarre in Erfurcht und fühle mich wieder mal ganz klein!
Ich traue mich jetzt noch nicht so recht das einzubauen weil ich nur Teile verstehe.
(Ich weiß nicht, ob ich hier gesteinigt werde, wenn ich zugebe, dass mich hier mal wieder die Befürchtung ereilt, dass ich nicht wirklich Ahnung habe, was "objektorientiertes Programmieren" heißt (mein Riesenprogramm funktioniert ja totzdem (... meistens)))
Hilf mir doch mal hiermit:

Sind das Varaiblen des Typs "object":
Dim oMSPF ' Service "MasterScriptProviderFactory"
Dim oSC ' Interface: "XScriptInvocationContext"
Dim script '

Wo findet mein Makro dieses Object(?) ? (zwei Fragezeichen weil ich nicht sicher bin ob das ein Objekt ist):
oMSPF = GetDefaultContext().getByName("/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory")

das hier ist wohl so ähnlich wie wenn ich einen meiner Dialoge aufrufe:
oSC = oMSPF.createScriptProvider(oDoc.ScriptContainer)

hier wird wohl der entsprechende Text reingepackt:
sScriptCall="vnd.sun.star.script:Standard.modAufgaben." & sAufgabe & "?language=Basic&location=document"
script = oSC.getScript(sScriptCall)

Warum sind jetzt hier drei Arrays:
script.invoke(array(), array(), array())
craig22
****
Beiträge: 135
Registriert: Mi, 19.08.2020 13:47

Re: Routinenname mit Variablen starten

Beitrag von craig22 »

Pit hat geschrieben:Ich erstarre in Erfurcht und fühle mich wieder mal ganz klein!
Der einzige Unterschied zwischen Dir und mir, ist nicht die Größe, sondern die Nutzung
von XRAY, gepaart mit einer ausdauernden Geduld bei der Suche im Netz.

Es war reiner Zufall, dass ich zuerst per

Code: Alles auswählen

XRAY oDoc

Code: Alles auswählen

getScriptProvider         (  )                             AS com.sun.star.script.provider.XScriptProvider             com.sun.star.script.provider.XScriptProviderSupplier 
gefunden habe.
Allerdings führten meine Test’s immer zu Fehlermeldungen.
Also im Netz suchen und ich fand zunächst nur etwas zum Thema Python, bis ich dann diesen Begriff fand „ MasterScriptProviderFactory“.

In der API nachgeschlagen, hartnäckig im Netz gesucht und im englischen Forum fündig geworden.
Du siehst, nur geklaut und etwas umgemodelt.
Pit hat geschrieben:Ich traue mich jetzt noch nicht so recht das einzubauen weil ich nur Teile verstehe.
Nun es wird Fleißarbeit sein, Deinen Code entsprechend anzupassen, zumal ich gemäß Deiner Aussagen nur erahnen kann, dass es ein größerer recht komplexer Code ist, welchen Du nutzt.
Ich vermute Du doppelklickst auch auf Zellen in anderen Spalten, um eine entsprechende Routine aufzurufen.
Dabei kann Dir das von mir erstellte „Array’s in Array“ gute Dienste leisten. Vorausgesetzt die Logik paßt.
Pit hat geschrieben:(Ich weiß nicht, ob ich hier gesteinigt werde, wenn ich zugebe, dass mich hier mal wieder die Befürchtung ereilt, dass ich nicht wirklich Ahnung habe, was "objektorientiertes Programmieren" heißt (mein Riesenprogramm funktioniert ja totzdem (... meistens)))
Foren sind doch dazu da Fragen zu stellen.
Aus meiner Sicht gibt es keine dummen Fragen, sondern ggf. nur dumme Antworten.
Und ein Profiprogrammierer bin ich auch nicht; habe mir alles selbst beigebracht.
Motto:
  1. XRAY
  2. API verstehen
  3. RTFM
  4. Verstehe das Gelesene
  5. Teste das Gelesene
  6. Nutze das Gelesene
  7. Dann versteht’s Du wie es läuft.
  8. Jede Fehlermeldung treibt einen u.U. in den Wahsinn, aber man lernt daraus.
    So auch in dem aktuellen Fall:
    String in Anweisung konvertieren.
  9. Stelle auch dumme Fragen in den Foren :lol: :mrgreen:
Pit hat geschrieben:Hilf mir doch mal hiermit:

Sind das Varaiblen des Typs "object":
Dim oMSPF ' Service "MasterScriptProviderFactory"
Dim oSC ' Interface: "XScriptInvocationContext"
Siehe den Kommentar hinter den Deklarationen:
  • ' Service "MasterScriptProviderFactory"
  • ' Interface: "XScriptInvocationContext"
Ich habe mir angewöhnt die AOO-Konventionen bei der Basic-Programmierungg zu nutzen, eben weil ich kein Profi mit, sind die Präfixe quasi selbstredend.
Siehe diese AOO Seite…
Hier erkennst Du dass ein vorangestelltes o dreierlei bedeuten kann:
  1. oObject
  2. oService
  3. oInterface
Daraus resultiert:
Wenn ich meine ggf. umfangreichen Code lese, dann weiß ich sofort, es muss sich bei der Variablen um eines der drei Dinge handeln. Wenn ich dann noch den eigentlichen Variablennamen z.B. Doc hinter o schreibe, dann kann ich auch in fünf Jahren noch erahnen dass es sich um ein Objekt handelt.

Bei Services könnte man das Präfix erweitern und so deklarieren:
oSrvMasterScript
Bei Interfaces:
oIntTitle

Code: Alles auswählen

Dim script '
Bei script bin ich mir iim Augenblick noch nicht sicher, um was es sich hierbei handelt.
Wenn ich script mit Xray inspiziere, dann vermute ich es handelt sich um ein Objekt.
Dazu recherchiere ich aber noch.
Pit hat geschrieben:Wo findet mein Makro dieses Object(?) ? (zwei Fragezeichen weil ich nicht sicher bin ob das ein Objekt ist):
oMSPF = GetDefaultContext().getByName("/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory")
Siehe hier:
http://ooo-site.apache.org/api/docs/com ... ctory.html
Daraus geht hervor, dass „MasterScriptProviderFactory“ ein Service ist. Ein Service stellt weitere Services, Interfaces, Eigenschaften und Methoden bereit. Dies hat aber nichts mit Vererrbung zu tun.
Es wird ein Zeiger auf den Service erstellt und dann greift man sich Eigenschaften und Methoden, usw. welche der Service bereitstellt.
Was dies im einzelffal ist, ließt man entweder mit XRAY aus oder man bemüht die API-Dokmentation.
Somit ist oMSPF lediglich ein Zeiger auf diesen Service.
Als würde man mit dem Finger auf ein Haus zeigen.

Übersetzen könnte man dieses in etwa so:
Lieber Interpreter ich möchte genau diesen Service nutzen.
Mehr sagt die Anweisung nicht aus.
Pit hat geschrieben:das hier ist wohl so ähnlich wie wenn ich einen meiner Dialoge aufrufe:
oSC = oMSPF.createScriptProvider(oDoc.ScriptContainer)
Nein, nicht ähnlich.

Mit meinen eigenen Worten. Beachte aber, dass ich auch kein Programmierer bin!
Dies ist der eigentliche Zugrif auf den Service.
Der Service soll einen neuen ScriptProvider erstellen, mit dem Zugriff auf die Scripts im Dokument.

Pit hat geschrieben:hier wird wohl der entsprechende Text reingepackt:
sScriptCall="vnd.sun.star.script:Standard.modAufgaben." & sAufgabe & "?language=Basic&location=document"
script = oSC.getScript(sScriptCall)
Ja. Genau dies ist der entscheidende Punkt.
Denn hier wird keine Call-Anweisung erwartet, sondern ein String.
Deshalb lasseen sich die Strings zusammenbauen:

Code: Alles auswählen

sScriptCall="vnd.sun.star.script:Standard.modAufgaben." & sAufgabe & "?language=Basic&location=document"
Die Bibliothek „ Standard“ im Dokument.
Das Modul „ modAufgaben“ in der Bibliothek „Standard“
Name der Routine im Modul „ modAufgaben“, welche aufgerufen werden soll: „sAufgabe“

Ich nehme an, dass dieser Part soviel bedeutet wie:

Code: Alles auswählen

?language=Basic&location=document
Lieber Interpreter, es handelt sich bei den Angaben um einen Basic_Code, welcher sich in diesem Dokument befindet.

Mit der nachfolgenden Zeile weiß ich auch nicht weiter.
Gemäß Xray ist dies auch ein Objekt und hätte erwartet, dass man den Inhalt von (sScriptCall)
hier irgendwo auslesen kann, aber Fehlanzeige.
Naja, muss nochmal forschen...

Code: Alles auswählen

oSC.getScript(sScriptCall)
Pit hat geschrieben:Warum sind jetzt hier drei Arrays:
script.invoke(array(), array(), array())
Das habe ich auch nur abgeschrieben und getestet.
Ich weiß „script.invoke“ führt letztendlich das zuvor angegebene Makro aus, aber die drei Arrays ???
http://ooo-site.apache.org/api/docs/com ... cript.html
Werde ich noch recherchieren.
Gruß

Craig
_____________________________________________________
WIN 10 Pro 64-Bit • LO 7.1.5.2 (x64) • AOO 4.1.8
Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: Routinenname mit Variablen starten

Beitrag von Stephan »

Es war reiner Zufall, dass ich
danke für die interessanten Ausführungen, nur weil ich das kenne, hatte ich gleich am Anfang darauf hinwiesen (im anderen Thread):

"1.
Erstelle zur Laufzeit eine Batchdatei (oder ein Script) welche den Makroaufruf enthält und starte diese Batchdatei. Beispiele dafür sollten sich im Forum finden lassen."


weil ich weiß das es z.B. von mir Lösungen mit dem Scriptprovider mit VBScript im Forum gibt, nur konnte ich diese auf die Schnelle selbst nicht finden.

Die von Dir ausgearbeitete Lösung ist aber interessanter, ich werde mir das einmal in Ruhe ansehen.


Gruß
Stephan
erikafuchs
******
Beiträge: 690
Registriert: Di, 13.02.2007 17:38
Wohnort: Büttelborn

Re: Routinenname mit Variablen starten

Beitrag von erikafuchs »

Hallo Craig,
da habe ich wieder viel gelernt.
ich habe mich aber mal hingesetzt und dein Script noch vereinfacht. Anstelle von den Strings auf einem extra Tabellenblatt erstelle ich die Strings mit einer Schleife und das Makro starte ich mit einem Tabellenblattereignis direkt durch Klick auf die entsprechende Zelle mit dem Namen des Themas:
Sub Routine per String starten_03.ods
(33.41 KiB) 117-mal heruntergeladen
craig22
****
Beiträge: 135
Registriert: Mi, 19.08.2020 13:47

Re: Routinenname mit Variablen starten

Beitrag von craig22 »

@Stephan
Stephan hat geschrieben:"1.
Erstelle zur Laufzeit eine Batchdatei (oder ein Script) welche den Makroaufruf enthält und starte diese Batchdatei. Beispiele dafür sollten sich im Forum finden lassen."
Ich habe auch in diese Richtung geforscht, auch wenn ich in meinen Antworten nicht explizit darauf eingegangen bin.
Letztendlich hat mich dieser Hinweis ja auf die Python-Programmierung
gebracht, wo ich dann auf Umwegen die jetzige Lösung gefunden habe.
Da ich mich mit Python auch nicht auskenne, bis auf ein paar kleine Übungen, war mir eine reine Basic-Lösung lieber.
Stephan hat geschrieben:Die von Dir ausgearbeitete Lösung ist aber interessanter, ich werde mir das einmal in Ruhe ansehen.

Ich freue mich auf eine Rückmeldung, auch Verbesserungvorschläge nehme ich gerne an.

@Pit
Pit hat geschrieben:da habe ich wieder viel gelernt.
Das freut mich :D
Pit hat geschrieben:ich habe mich aber mal hingesetzt und dein Script noch vereinfacht. Anstelle von den Strings auf einem extra Tabellenblatt erstelle ich die Strings mit einer Schleife und das Makro starte ich mit einem Tabellenblattereignis direkt durch Klick auf die entsprechende Zelle mit dem Namen des
Ja, so hatte ich es auch vor. Nur Du erwähntest, dass Du ca. 100 Sub's
damit aufrufen möchtest, habe ich eine flexible Tabelle angelegt.
Das unschöne daran ist, dass man diese Tabelle in der Originaldatei u.U. ausblenden
muss oder die Daten (Namen der Sub's) in eine externe Datei auslagern muss.
Der Vorteil ist: Wenn sich später Routinennamen ändern, dann ändert man diese in
der Tabelle und werden dann zur Laufzeit automatisch vom Array korrekt verarbeitet

Ein weiterer Nachteil ist die Benennung der Aufgaben in der Schleife:
  • Aufg_01
  • Aufg_20
  • Aufg-140
Da Du bei den ersten 9 Aufgaben eine Null vorangestellt hast, musst Du eine Abfrage starten:
WENN Aufg_0
DANN Aufg_0n
SONST
Aufg_n
Gruß

Craig
_____________________________________________________
WIN 10 Pro 64-Bit • LO 7.1.5.2 (x64) • AOO 4.1.8
Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: [gelöst] Routinenname mit Variablen starten

Beitrag von Stephan »

Ich habe auch in diese Richtung geforscht,
z.B. habe ich jetzt gefunden:
viewtopic.php?p=285617#p285617

das ist aber immer noch nicht das woran ich eigentlich dachte - aber egal, Dein Ansatz ist im DEtail interessanter.


GRuß
Stephan
Antworten