Formularfelder in Basic modifizieren

Ich möchte einem Writer Dokument beim laden einen Stammdatenblock (Name, Vorname, etc) zufügen. Die Stammdaten sind als Textdatei in einem lokalen Verzeichnis verfügbar. Ein Basic-Scribt das die Datei öffnet und die Datem in entsprechende Variablen extrahiert habe ich schon, bin in VBA (Access) eher versiert, alles easy soweit.

  1. Wie weise ich die Variablen Formularfeldern in Write zu? Textfelder als Formular-Steuerelement definiert erscheinen nicht im Objektkatalog. Gibt es eine Standard-Objekthierarchie über die ich die Referenzen für alle Formularfelder im Dokument auslesen kann
  2. Wenn das dann geht: Wie kann ich im Dokument festlegen daß das Skript beim Öffnen des Dokuments automatisch ausgeführt wird?

Aktuell ruft die Ursprungssoftware ein Word-Dokument auf und übergibt die Inhalte als Platzhalter. Da wir weg von MS Office wollen geht nur ein Workaround über Stammdatensatz als Textfile ins User-Home schreiben und dann ein beliebiges Programm aufrufen. Das Programm wäre eben dann die ODT-Dokumentvorlage die beliebigen Text enthält und die Kundendaten aus dem Textfile extrahiert und einsetzt.
Merci vom Noob

Du brauchst doch auch im Writer nur die Platzhalter. Formularfelder benötigst Du nur, wenn Du Daten aus einer Datenquelle einlesen, bearbeiten und speichern willst. Außerdem haben Formularfelder die Eigenart, dass sie eine feste Breite haben - auch nicht hilfreich für ein Textdokument.
.
Formularfelder siehst Du nur in dem Formularnavigator. Die Dinger sind eine komplett eigene Konstruktion auf der Drawpage.
.
Wie so etwas in der Praxis aussieht kannst Du z.B. bei meiner Konstruktion zu den XRechnungen sehen: XRechnungen mit LibreOffice. Da ist die Datengrundlage natürlich in einer Datenbank. Lasse ich das ausdrucken, dann erscheinen die Inhalte einiger Felder (alles, was nicht als Rechnungsposten auftaucht) in den gleichnamigen Platzhaltern. Nur die Rechnungsposten selbst werden in eine Tabelle geschrieben.

Problem gelöst:
Das Objektmodell gibt eine Liste aller Textfelder her mit:
Dim oDoc as Object ’ Objektvariable für Zeiger auf das aktuelle Dokument
Dim oDPage as Object ’ Objektvariable für Zeiger für die Drawpage
Dim oShape as Object ’ Objektvariable für Zeiger auf das Shape (Textfeld = Zeichnungsobjekt)
Dim Inhalt as String
oDoc=ThisComponent ’ Das ist der Zeiger aufs Aktuelle Dokument
oDPage=oDoc.DrawPage ’ Das ist der Overlay, der die Shapes enthält

Innerhalb der Shapes kann man durchiterieren:
for icounter = 0 to oDPage.count-1
sPlaceHolder = “” 'Platzhalter löschen
oShape = oDPage.getByIndex(iCounter)
sclass = oshape.getImplementationName ’ Die Art des Rahmens.
if sclass = “SwXShape” then ’ Wenn Textfeld den Inhalte holen
sPlaceholder = oShape.getString
if left$(sPlaceholder, 2) = “$$” and right$(sPlaceholder, 2) = “$$” then ’ Ist ein Platzhalter, soll ersetzt werden
select case sPlaceholder
case “$$Name$$”
oShape.setString sNeuerInhalt

Wichtig ist die Klasse des Shapes. Nicht für jede Klasse gibt es jeden Get-Befehl. In diesem Fall halt Textrahmen → Inhalt auslesen, eingebundene Grafiken z.b. → getString gibt Fehler Methode nicht unterstützt.
Wenn man im normalen Writer-Dokumentenfenster unter Extras auf Entwicklungswerkzeuge klickt, bekommt man am unteren Rand eine Objekthierarchie eingeblendet. Wenn das entsprechende Objekt im Text angeklickt wird, kann man die Properties, Methoden und Inhalte der Properties sehen. Das hilft schon mal weiter.
Über Extras-> Anpassen kann man verschiedenen Ereignissen im Dokument Makros zuordnen, damit das dann auch rundläuft muss man die Makros entweder signieren oder, für den Heimgebrauch sicher auch ausreichend, ein sicheres Herkunftsverzeichnis eintragen. Vielen Dank für euren Input, das hat mich auch die richtige Spur gebracht.

Hallo Robert,
vielen Dank für deinen Input. Ich arbeite natürlich auch lieber mit Platzhaltern, wenn das einfacher ist.
Mein Problem liegt aber tiefer: Wie referenziere ich Elemente in einem Writer-Dokument in einem Basic-Makro. Wie erwähnt komme ich mit reichlich Wissen aus der MS-Office-Welt, da ist mir die Objekthierarchie geläufig (und oft reicht ein Me…). Wenn ich jetzt einen Platzhalter definiere und ihm als Wert eine Variable zuweise, hat diese Variable einen im Dokument eindeutigen Namen (var_for_Nachname). Wie weise ich jetzt var_for_nachname per basic einen Wert zu?
Der von dir gezeigte Weg über eine Rechnungserstellung mit einer Datenbank die die Feldinhalte bereitstellt ist für mich nicht gangbar. Ich bekomme aus der Anwendung nur einen Stammdatensatz zur Laufzeit in eine Textdatei geliefert. Aus der extrahiere ich die jeweiligen Feldinhalte (läuft schon) so dass mir diese als Variablen in meinem Basic-Makro zur Verfügung stehen. Was schreibe ich in mein Makro, damit statt “Nachname” Hurzlmeier im Dokument steht?
Merci, Stefan

Da wäre ich nicht so sicher. Man braucht nämlich keine Datenbank, sondern eine Datenquelle. Das kann auch eine Calc/Excel-Datei oder eine csv-Datei sein. Falls Deine Textdatei keine csv/tsv sein sollte kannst Du sie sicher problemlos umformen.
(Wenn man mit registeierten Namen fur Datenquellen arbeitet kann man sogar das Format ändern, solange die Verbindung und Fald/Spaltennamen gleich bleiben.)

Wenn Du das alles selbst programmierst, warum nicht einfach Suchen und ersetzen? Schreib in Deine Vorlage was eindeutiges wie %%NAME%%, wenn es an Windows Batch erinnern soll. Ich habe ein paar html-Templates mit Datum und Name fur Projekte. Das geht ohne komplexe Strukturen.
.
Der Witz bei der Datenquellen-Methode ist halt, dass eigentlich kein Code benotigt wird.

PS: Nutze fur Antworten hier am besten die Sprechblase (kommentieren). Der grosse Knopf “suggest a solution” ist eigentlich nur für (verschiedene) Lösungen da.

@gws_bavaria : Hier ein zusammengekürzter Code aus der besagten Datenbank:

SUB FillTextfields(oNewDoc AS OBJECT, oForm AS OBJECT) AS LONG
	DIM oColumns AS OBJECT, oTextfields AS OBJECT, oTextfield AS OBJECT
	DIM stColumnname AS STRING
	DIM inIndex AS INTEGER
	oColumns = oForm.Columns
	oTextfields = oNewDoc.Textfields.createEnumeration
	DO WHILE oTextfields.hasMoreElements
		oTextfield = oTextfields.nextElement  
		IF oTextfield.supportsService("com.sun.star.text.TextField.JumpEdit") THEN
			stColumnname = oTextfield.PlaceHolder	'Placeholder ist Bennennung für das Textfeld
			IF oColumns.hasByName(stColumnname) THEN	'Wenn der Name des Textfeldes gleich dem Spaltennamen der Daten ist, die dem Formular zugrunde liegen ...
				inIndex = oForm.findColumn(stColumnname)
				oTextfield.Anchor.String = TRIM(oForm.getString(inIndex))
			END IF
		END IF
	LOOP
END SUB

Der Zugang da erfolgt über den Vergleich von Spaltennamen in der Datenquelle und den Benennungen der Textfelder. Sind die Namen gleich, dann wird der Inhalt in den Platzhalter geschrieben. Wie Du das mit Deiner “Datenquelle” machen kannst kann ich nicht sagen. Ich würde die Writer-Datei als Datenquelle ansprechen (über Base…).

1 Like

Wäre die Datenbank dieser Anwendung mit LibreOffice verbunden, könntest Du diesen Datensatz mit einem Klick im Datenquellenfenster übernehmen.

Das ist richtig und hilft leider gar nicht, weil die Datenbank in einer anderen Software steckt und für mich nicht transparent ist. Alles was ich kriege ist besagte Textdatei mit den von mir benötigten Informationen aus einer Standard-Exportfunkktionalität. Das ganze ist eine Arztpraxisverwaltungssoftware, darunter liegt eine Maria-DB, ich kriege aber das Datenbankpasswort nicht und möchte auch tatsächlich nicht auf eine Produktivdatenbank hart zugreifen, auch wenn das rein lesend ist. Wenn die Bank irgendwie korrupt wird habe ich dann extrem schlechte Karten wenn die meinen Zugriff finden. Und API’s gibt es keine. Leider.

Das Problem habe ich auch. Ich mach mit dem nächtlichen Backup eine Kopie der Datenbank und verwende diese dann für meine Zwecke. Aber wenn Du gar keinen Zugriff darauf hast, dann ist das natürlich blöd. Meine ist eine vollkommen ungeschützte Sammlung von hunderten dBase-Dateien.

Wenn besagte csv-Datei immer unter demselben Pfadnamen abgelegt wird, dann gibt es eine komplett Makrofreie Lösung, indem Du ein Base-Dokument mit dem Verzeichnis verbindest. Textdatenbank = Sammlung von ähnlich strukturierten Textdateien im selben Verzeichnes, wo jede Datei durch eine Tabelle repräsetiert wird.
Datei>Neu>Datenbank…
Verbinde mit existierender DB vom Typ “Text”.
Gib den Pfad, die Dateiendung, Codierung und die Trennzeichen an.
Ja, registriere die DB.
Speicher die DB, schließe sie, vergiss sie, aber lösche sie nicht.
Nun sollte die Textdatei über das Datenquellenfenster von Calc und Writer zu sehen sein (Strg+Umsch+F4).
Ziehe die Spaltenköpfe in aus dem Datenquellenfenster in Dein Writer-Document, und fertig ist die Laube.
Falls sich der Name der Tabelle ändert, kann man die korrekte Tabelle auswählen mit Writer-Menü:Bearbeiten>Datenbank wechseln (oder so ähnlich).