Text in Textmarke per Makro ändern

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

Moderator: Moderatoren

Proma
**
Beiträge: 20
Registriert: So, 03.05.2020 10:04

Text in Textmarke per Makro ändern

Beitrag von Proma »

Hallo liebe Experten,

zunächst ein herzliches Grüß Gott an das Forum und alle Mitwirkenden! Ich habe mich heute hier angemeldet und gebe zum Einstand eine ViRu (virtuelle Runde) aus. Prost und auf ein gutes Miteinander! :lol:

Vorweg - mein Kenntnisstand in OpenOffice liegt etwa zwischen "Null" und "Erschreckend", Vorkenntnisse aus MS-Word, MS-Excel und VBA sind in eher bescheidenem Rahmen vorhanden. An den Writer, an Calc und an StaBasic taste ich mich gerade ein bisschen heran. Und da geht's schon los:

Im Writer möchte ich eine Art Rechnung schreiben, sehr vereinfacht dargestellt so:
Betrag1
Betrag2
Summe
Betrag1 und Betrag2 wie auch die Summe sollen durch das Makro ermittelt bzw. ausgerechnet und jeweils in eine schön formatierte Zeichenkette (Tausender-Punkt und 2 Nachkommastellen) umgewandelt werden. Das krieg' ich noch hin (ein herzliches Dankeschön an Michael Dannhäuser für seine hilfreichen Beispiel-Seiten!). Wie aber kann ich den Writer dazu bringen, dass er die Beträge und die Summe exakt dort platziert, wo ich sie haben möchte?

Versucht habe ich es schon mit Textmarken, das hat auch auf den ersten Blick funktioniert; wenn ich dann aber im selben Dokument andere Beträge einfügen möchte, dann werden die alten Beträge nicht etwa überschrieben, sondern die neuen Beträge werden vor die alten Beträge gesetzt. Das sieht dann etwa so aus

Nach dem ersten Durchlauf (perfekt)
23.200,00
14.300,00
37.500,00

Nach dem zweiten Durchlauf (der Schock)
15.100,0023.200,00
20.200,0014.300,00
35.300,0037.500,00

Wie kriege ich den Writer dazu, einen gegebenenfalls bei einer Textmarke vorhandenen Text zu entfernen, bevor ein neuer Text eingefügt wurde? Ich habe schon versucht, jeder Textmarke einen Leerstring ("") zuzuweisen, was naturgemäß nicht funktionieren konnte, weil ja dieser Leerstring auch wieder VOR eine vorhandene Zeichenkette geschrieben wird und diese dann nicht ersetzt.

Und noch eine Frage: Ist meine Vorgehensweise mit den Textmarken hier überhaupt der richtige Ansatz oder gibt es hierfür besser geeignete Methoden wie z.B. Rahmen oder noch andere Alternativen?

Meine Ausstattung:
Windows 10, Apache OpenOffice 4.1.5 (portable)

Für Eure Unterstützung danke ich Euch vorab schon recht herzlich!

Liebe Grüße
vom Martin
Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: Text in Textmarke per Makro ändern

Beitrag von Stephan »

z.B. sollte gehen:

Code: Alles auswählen

t_cur = ThisComponent.Text.CreateTextCursor
t_cur.gotoRange(thisComponent.getBookmarks().getByName("test").getAnchor, false)
t_cur.gotoEndOfParagraph(True)
t_cur.String = "23.200,00"
Und noch eine Frage: Ist meine Vorgehensweise mit den Textmarken hier überhaupt der richtige Ansatz oder gibt es hierfür besser geeignete Methoden wie z.B. Rahmen oder noch andere Alternativen?
Ein Feld (Einfügen-Feldbefehl) könnte eine besserre Alternative sein. Das Arbeiten mit Feldern ist etwas komplex, lies es in:
https://www.uni-due.de/~abi070/count.ph ... eutsch.pdf

in Kapitel "14.10 Textfelder" nach


Gruß
Stephan
Proma
**
Beiträge: 20
Registriert: So, 03.05.2020 10:04

Re: Text in Textmarke per Makro ändern

Beitrag von Proma »

Hallo Stephan,

vielen Dank für Deine Nachricht, den Code und den Link!
Das hilft mir schon mal sehr viel weiter. Ich sehe schon, mit diesem Forum habe ich eine wirklich gute Wahl getroffen!
Alle verfügbaren Daumen hoch! 8)

Kannst Du mir vielleicht noch eine Quelle benennen, wo ich Grundlagen zu StarBasic nachlesen kann? Die Dannhäuser-Seiten liefern zwar reihenweise tolle Beispiele zur Lösung konkreter Probleme, aber ich bräuchte zunächst einmal etwas fürs Grundlagenwissen (z.B. wie dimensioniere ich eine Cursor-Variable - Dim t_cur as Object oder gibt es da etwas spezielleres wie Dim t_cur as Cursor, ist der With-Block in StarBasic verfügbar oder nicht oder vielleicht unter einer anderen Bezeichnung etc.).

Vielen Dank und liebe Grüße
vom Martin
Proma
**
Beiträge: 20
Registriert: So, 03.05.2020 10:04

Re: Text in Textmarke per Makro ändern

Beitrag von Proma »

Hallo Stephan,

habe gerade ein bisschen mit Deinem Code herumgespielt. Nachdem ich in der ersten Code-Zeile

Code: Alles auswählen

ThisComponent.Text
ersetzt habe durch

Code: Alles auswählen

ThisComponent.getText
läuft jetzt alles genau so wie ich es wollte. Super!!!

Den Link zur Uni-due werde ich mir in den nächsten Tagen vornehmen. Interessiert mich wirklich sehr.

Vielen Dank nochmal, einen schönen Abend und für morgen einen guten Einstieg in die neue Woche!

Liebe Grüße
vom Martin
Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: Text in Textmarke per Makro ändern

Beitrag von Stephan »

Proma hat geschrieben: So, 03.05.2020 20:34 Hallo Stephan,

habe gerade ein bisschen mit Deinem Code herumgespielt. Nachdem ich in der ersten Code-Zeile

Code: Alles auswählen

ThisComponent.Text
ersetzt habe durch

Code: Alles auswählen

ThisComponent.getText
läuft jetzt alles genau so wie ich es wollte. Super!!!
Ich verstehe jetzt nicht welchen funktionalen UNteschied das machen soll. Ist denn bei Dir ein UNterschied bemerkbar? UNd wenn ja, bei welcher Programmversion?
Kannst Du mir vielleicht noch eine Quelle benennen, wo ich Grundlagen zu StarBasic nachlesen kann?
Das quasi Standardwerk wäre:
https://www.uni-due.de/~abi070/ooo.html

Das gibt es prinzipiell auch als gedrucktes Buch, aber gegenüber dem PDF ist das veraltet:
http://www.pitonyak.org/book/

Als deutsches Buch wäre das von Thomas Krumbein zu empfehlen:
https://www.tintal.de/index.php/compone ... Itemid=101
z.B. wie dimensioniere ich eine Cursor-Variable - Dim t_cur as Object oder gibt es da etwas spezielleres wie Dim t_cur as Cursor,
Das ist ein Objekt und wird als Solches deklariert, also Dim t_cur as Object, der Name der Objekt-Variablke (t_cur) ist natürlich beliebig.
ist der With-Block in StarBasic verfügbar
ja

Solcherart Sprach-Grundlagen kannst Du in der Hilfe nachlesen, bei OpenOffice im Menü über Hilfe-Openoffice und dann links im Dialog Makros und Programmierung-Befehle-Alphabetische LIste ... nachlesen.
Wenn Dir der Unterschied zwischen Sprache und API klar ist so sei gesagt das Starbasic als Sprache fast deckungsgleich ist mit VBA, das API natürlich recht unterschiedlich und somit die praxisrelevaten Makros (die ja fast alle das API nutzen) auch unterschiedlich.

Du kannst im Übrigen VBA-Code in OpenOffice/LibreOffice direkt ausführen (es läuft nicht alles aber eine ganze Menge), dazu musst Du nur in den Kopf des/der Module die sog Kompatibilitätsoption schreiben:

Code: Alles auswählen

Option VBASupport 1
wenn Du entsprechende MS Office Dateien mit Makros in OO/LO öffnest wird das auch automatisch eingetragen, wenn die Einstellungen unter Extras-Optionen/Einstellungen-Laden/Speichgern-VBA-Eigenschaften richtig gesetzt sind.


Gruß
Stephan
Proma
**
Beiträge: 20
Registriert: So, 03.05.2020 10:04

Re: Text in Textmarke per Makro ändern

Beitrag von Proma »

Hallo und guten Morgen Stephan,

vielen Dank für Deine Nachricht und die Infos!
Stephan hat geschrieben: Mo, 04.05.2020 07:04 Ich verstehe jetzt nicht welchen funktionalen UNteschied das machen soll. Ist denn bei Dir ein UNterschied bemerkbar? UNd wenn ja, bei welcher Programmversion?
Der Unterschied besteht darin, dass das Makro bei Verwendung von ".Text" mit der unten dargestellten Fehlermeldung abbricht (Apache OpenOffice 4.1.5 portable unter Windows 10)

Fehlermeldung.jpg
Fehlermeldung.jpg (20.43 KiB) 4559 mal betrachtet

Aber es ist noch ein kleines Problem aufgetaucht, das ich gestern in meiner Euphorie glatt übersehen habe. Mit dem Code werden nicht nur die vorhandenen Einträge entfernt sondern gleichzeitig auch die Textmarken selbst. Das heißt, der erste Durchlauf hat (rein optisch) noch das korrekte Ergebnis gebracht, denn die alten Beträge sind entfernt und die neuen an der richtigen Stelle platziert worden; aber mit den alten Beträgen ist dann auch die Textmarke verschwunden, was beim nächsten Durchlauf zwangsläufig zu einem Fehler führen musste, weil die angegebene Textmarke ja nicht mehr vorhanden war.

Vielleicht hast Du noch eine Idee, wo ich da ansetzen könnte?

Vielen Dank jedenfalls für die bisher geleistete großartige Unterstützung und liebe Grüße
vom Martin
Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: Text in Textmarke per Makro ändern

Beitrag von Stephan »

Der Unterschied besteht darin, dass das Makro bei Verwendung von ".Text" mit der unten dargestellten Fehlermeldung abbricht
Passiert bei mir nicht und darf auch nicht passieren.

Der Fehler deutet normalerweise auf einen falschen Objektbezug hin, aber bei .Text vs. .getText ist das eigentlich nicht denkbar.

Wenn der Fehler auftritt, dann schrreibe vor die fehler-auslösende Zeile iins Makro:

Code: Alles auswählen

Msgbox ThisComponent.dbg_properties
und poste hier die Msgbox, dann kann man Genaueres sagen.
Mit dem Code werden nicht nur die vorhandenen Einträge entfernt sondern gleichzeitig auch die Textmarken selbst
Dieses Problems war ich mir eigentlich bewusst, aber es trat (scheinbar?) bei mir gestern nicht auf und so habe ich es nicht weiter geprüft.
Lies im angehängten PDF Kapitel 7.3.1 und schaue ob Du damit selbst eine Lösung findest.

Es ist nichts Falsches an Deinem Anliegen, es ist nur ungewöhnlich eine Textmarke mehrfach zu nutzen und so bin ich spontan etwas überfragt.
Eigentlich würde ich dann jetzt doch raten: mach das mit einem Feldbefehl.


Gruß
Stephan
Dateianhänge
Makro_Kochbuch.pdf
(3.29 MiB) 124-mal heruntergeladen
Proma
**
Beiträge: 20
Registriert: So, 03.05.2020 10:04

Re: Text in Textmarke per Makro ändern

Beitrag von Proma »

Hallo Stephan,

erstmal vielen herzlichen Dank für Deine Unterstützung, Dein Verständnis und Deine Geduld mit mir!
Stephan hat geschrieben: Mo, 04.05.2020 08:44 es ist nur ungewöhnlich eine Textmarke mehrfach zu nutzen
Ja, da hast Du natürlich vollkommen recht, normal ist das nicht! :lol: Aber in diesem speziellen Fall sollen Daten (Zahlen) aus Kalk in den Writer
übernommen (das klappt auch schon) und in die Textmarken geschrieben werden und dann soll dem Anwender die Möglichkeit geboten werden, die Zahlen zu prüfen und bei Bedarf auch (per Makro, z.B. mittels InputBox) zu ändern.

Deine Links, insbesondere der zur Uni-Due, und Dein Makro-Kochbuch sind für mich einfach Gold wert! Sie waren mir eine große Hilfe beim Erstellen eines kleinen Demo-Programms, mit dem ich den Code zum Befüllen, Auslesen und Zurücksetzen der Textmarken-Inhalte testen kann. Der Knackpunkt bei der ganzen Sache ist, dass das Ändern von Textmarkeninhalten nur mit "expandierten" Textmarken funktioniert. Eine expandierte TM erhält man, indem man mindestens EIN beliebiges Zeichen markiert und an dieser Stelle über Einfügen/Textmarken... eine neue TM erstellt.

Deinen Cursor-basierten Code, den ich ursprünglich verwenden wollte, habe ich dann doch nicht genommen, weil ich es einfach nicht hinbekommen habe. Das erste Problem mit der Fehlermeldung bin ich mit Deinem Vorschlag (Msgbox ThisComponent.dbg_properties) angegangen, da ist der Fehler noch einmal aufgetreten; weil ich aber verpasst hatte, die MsgBox zu fotografieren, hab' ich es nach einmal versucht und - dann hat das AEG-Prinzip (auf einmal geht's) gegriffen. In der Folge sind aber dann noch weitere unerklärliche Dinge passiert und ich hab' dann einfach den Mut verloren und zur anderen Variante gegriffen. Ich hoffe, Du nimmst es mir nicht übel. Gibt es eigentlich funktional einen Unterschied zwischen Deiner Lösung und meiner (s. nachstehenden Code)? Kann man sagen, dass die eine oder die andere Lösung besser ist und wenn ja warum?

Momentan bin ich etwas knapp in der Zeit, aber wenn ich wieder ein bisschen mehr Luft habe, dann stelle ich noch ein Beispiel mit Dokument hier ein. Vorläufig sage ich Dir erstmal ein ganz großes dickes Dankeschön für Deine Mühen, die Du Dir mit mir gemacht hast und für die tolle Unterstützung, de ich hier erfahren durfte!

Vielen herzlichen Dank und liebe Grüße
vom Martin

Code: Alles auswählen

Sub pMain
'Demonstriert das Befüllen, Auslesen und Leeren von Textmarken

  dim strTxt as string

'Befüllen
  MsgBox "Die Textmarken werden befüllt."  
  Call pSchreibeInTM("tmGrund", "Fahrtkosten")
  Call pSchreibeInTM("tmSumme", 2345.67)

'Auslesen
  MsgBox "Der Inhalt der Textmarken wird gelesen."
  Call pLeseAusTM("tmGrund", strTxt)
  MsgBox "Inhalt von TM Grund:" & chr(13) & chr(10) & strTxt
  Call pLeseAusTM("tmSumme", strTxt)
  MsgBox "Inhalt von TM Summe:" & chr(13) & chr(10) & strTxt

'Leeren
  MsgBox "Die Inhalte der Textmarken werden gelöscht."
  Call pSchreibeInTM("tmGrund", "")
  Call pSchreibeInTM("tmSumme", "")
  MsgBox "Hoffentlich hat alles geklappt..."
  
End Sub



'=====< Einträge in TM schreiben >==============================

Private Sub pSchreibeInTM(ByVal strBmk As String, ByVal varTxt As Variant)

  Dim strTxt As String

'Zahl und Text unterscheiden
  If IsNumeric(varTxt) Then                                     'Wenn eine Zahl geschrieben werden soll
    strTxt = Format(Csng(varTxt), "#,##0.00")                   '  Formatiere die Zahl und wandle sie in Text um
  Else                                                          'Sonst
    strTxt = Cstr(varTxt)                                       '  Wandle den Inhalt der Variant-Variablen in Text um
  End If                                                        'Ende Wenn
  
'Den Text der Textmarke zuweisen
  With ThisComponent.getBookmarks().getByName(strBmk)           'Bezugsobjekt: Textmarke
    .getAnchor.setString(strTxt)                                '  Schreibe den Text in die Textmarke
  End With                                                      'Ende Bezugsobjekt (Textmarke)

End Sub


'=====< Einträge aus TM lesen >=================================

Private Sub pLeseAusTM(byval strBmk as string, ByRef strTxt)
  
  With ThisComponent.getBookmarks().getByName(strBmk)           'Bezugsobjekt: Die betreffende Textmarke
    strTxt = .getAnchor.getString                               '  Hole den Inhalt der Textmarke
  End With                                                      'Ende Bezugsobjekt (Die betreffende Textmarke)
  
End Sub
Ergänzt am 05.05.2020, 21:36 Uhr:
Demo-Programm Textmarken2.odt angefügt
Dateianhänge
Textmarken2.odt
Kleines Demo-Programm
(17.03 KiB) 127-mal heruntergeladen
Antworten