Makro: Zugriff auf Datenbank-Felder
Moderator: Moderatoren
Makro: Zugriff auf Datenbank-Felder
Hallo,
zwar eine FAQ, aber eine Lösung habe ich nicht gefunden: Das Ausfüllen von Feldern eines Writer-Dokuments mit Daten aus einer Datenquelle soll per Basic-Makro automatisiert werden. Nach
dispatcher.executeDispatch(document,".uno:ViewDataSourceBrowser","",0,args1())
hört es bei mir auf...
Ich stelle es mir so vor:
- beim Öffnen des Dokuments wird das/ein Suchfenster geöffnet
- Eingabe Suchbegriff
- Makro sucht Datensatz und führt "Daten in Felder" durch
Das kann doch eigentlich nicht so schwierig sein - ein häufig benötigter Ablauf und nichts exotisches. Pmoegenb und Toxitom haben sich in anderen Threads geäußert aber leider die Lösung nicht verraten.
Danke schonmal
Carsten
zwar eine FAQ, aber eine Lösung habe ich nicht gefunden: Das Ausfüllen von Feldern eines Writer-Dokuments mit Daten aus einer Datenquelle soll per Basic-Makro automatisiert werden. Nach
dispatcher.executeDispatch(document,".uno:ViewDataSourceBrowser","",0,args1())
hört es bei mir auf...
Ich stelle es mir so vor:
- beim Öffnen des Dokuments wird das/ein Suchfenster geöffnet
- Eingabe Suchbegriff
- Makro sucht Datensatz und führt "Daten in Felder" durch
Das kann doch eigentlich nicht so schwierig sein - ein häufig benötigter Ablauf und nichts exotisches. Pmoegenb und Toxitom haben sich in anderen Threads geäußert aber leider die Lösung nicht verraten.
Danke schonmal
Carsten
Hey Carsten,
nein, so schwierig ist das nicht, nur eben auch Aufwand. Im Einzelfall ist es doch so, dass du jemanden siuchst, der dir das Makro schreibt. Und das ist Aufwand.
Es gibt durchaus Beispiele, wie man soetwas lösen kann - vielleicht nicht direkt deine Aufgabenstellung, sondern "nur" ähnliche, und mit ein bischen recherchieren - und das machen die meisten hier auch nur, die dir helfen, kommt man selbst darauf.
Schau dir beispielsweise mal das folgende Beispiel an:
Rechnungsvorlage_2.0
Das ist ein Beispiel, wie Felder eines Dokumentes über eine Dialogmaske gefüllt werden. Teile des Dialoginhaltes werden aus einer Textdatei entnommen - quasi wie aus einer Datenbank.
Eine Dokumentation liegt bei.
Und wenn du das ganze dann für dich angepasst hast, und es gibt Einzelfragen, so helfen wir dir gerne - aber das ganze Makro etc. ... Sorry, das geht wohl doch ein wenig zu weit.
Gruss
Thomas
PS: Dein Codeschnipsel ist Dispatcher-Code, entweder aus dem Markorecorder oder - wer weiss woher. Damit kannst du wenig anfangen, Dispatcher Code ist nicht geeignet, Makros zu lernen und es geht auch bei weitem nicht alles .
nein, so schwierig ist das nicht, nur eben auch Aufwand. Im Einzelfall ist es doch so, dass du jemanden siuchst, der dir das Makro schreibt. Und das ist Aufwand.
Es gibt durchaus Beispiele, wie man soetwas lösen kann - vielleicht nicht direkt deine Aufgabenstellung, sondern "nur" ähnliche, und mit ein bischen recherchieren - und das machen die meisten hier auch nur, die dir helfen, kommt man selbst darauf.
Schau dir beispielsweise mal das folgende Beispiel an:
Rechnungsvorlage_2.0
Das ist ein Beispiel, wie Felder eines Dokumentes über eine Dialogmaske gefüllt werden. Teile des Dialoginhaltes werden aus einer Textdatei entnommen - quasi wie aus einer Datenbank.
Eine Dokumentation liegt bei.
Und wenn du das ganze dann für dich angepasst hast, und es gibt Einzelfragen, so helfen wir dir gerne - aber das ganze Makro etc. ... Sorry, das geht wohl doch ein wenig zu weit.
Gruss
Thomas
PS: Dein Codeschnipsel ist Dispatcher-Code, entweder aus dem Markorecorder oder - wer weiss woher. Damit kannst du wenig anfangen, Dispatcher Code ist nicht geeignet, Makros zu lernen und es geht auch bei weitem nicht alles .
Unterstützer LibreOffice, zertifizierter Trainer und Berater
Bücher: LibreOffice 6- Einstieg und Umstieg
Makros Grundlagen - LibreOffice / OpenOffice Basic
Bücher: LibreOffice 6- Einstieg und Umstieg
Makros Grundlagen - LibreOffice / OpenOffice Basic
[quote="Toxitom"]
nein, so schwierig ist das nicht, nur eben auch Aufwand. Im Einzelfall ist es doch so, dass du jemanden siuchst, der dir das Makro schreibt. Und das ist Aufwand.
[/quote]
Nein, es ist nicht so, daß ich einen suche, der ein Makro schreibt. Das Makro existiert und es fehlt eben die angefragte Funktionalität. SDK und 817-3924.pdf geben dazu auch nichts her. Der gepostete Dispatcher-Code ist bis jetzt durchaus hilfreich, denn anders konnte ich per Makro bisher keinen Zugang zu den Daten finden. Die Antwort mit 1000 Makro-Zeilen ist letztlich auch nicht informativer als das, was ich im Archiv lesen durfte. Eine etwas zielgerichtetere Antwort würden Dir sicher auch andere danken. Die Anfrage kam ja schon öfter.
Wenn es den Befehl "Daten in Felder" per Makro nicht gibt (z.B. ähnlich obiger Dispatcher-Zeile, das war der Grund, die zu posten), was sehr schade wäre, weil es die Sache vereinfachen würde, ist die Frage eben: wie aktualisiere ich per Makro eine Adresse mit dem Inhalt einer Datenbank?
'Mal schnell einen personalisierten Brief ausdrucken' ist ja etwas weniger anspruchsvoll als eine komplette Rechnungsverwaltung. Auf die Frage nach RFC-Implementierungen sendet sicher auch niemand den kompletten Linux-Source, oder?
nein, so schwierig ist das nicht, nur eben auch Aufwand. Im Einzelfall ist es doch so, dass du jemanden siuchst, der dir das Makro schreibt. Und das ist Aufwand.
[/quote]
Nein, es ist nicht so, daß ich einen suche, der ein Makro schreibt. Das Makro existiert und es fehlt eben die angefragte Funktionalität. SDK und 817-3924.pdf geben dazu auch nichts her. Der gepostete Dispatcher-Code ist bis jetzt durchaus hilfreich, denn anders konnte ich per Makro bisher keinen Zugang zu den Daten finden. Die Antwort mit 1000 Makro-Zeilen ist letztlich auch nicht informativer als das, was ich im Archiv lesen durfte. Eine etwas zielgerichtetere Antwort würden Dir sicher auch andere danken. Die Anfrage kam ja schon öfter.
Wenn es den Befehl "Daten in Felder" per Makro nicht gibt (z.B. ähnlich obiger Dispatcher-Zeile, das war der Grund, die zu posten), was sehr schade wäre, weil es die Sache vereinfachen würde, ist die Frage eben: wie aktualisiere ich per Makro eine Adresse mit dem Inhalt einer Datenbank?
'Mal schnell einen personalisierten Brief ausdrucken' ist ja etwas weniger anspruchsvoll als eine komplette Rechnungsverwaltung. Auf die Frage nach RFC-Implementierungen sendet sicher auch niemand den kompletten Linux-Source, oder?
- komma4
- ********
- Beiträge: 5332
- Registriert: Mi, 03.05.2006 23:29
- Wohnort: Chon Buri Thailand Asia
- Kontaktdaten:
Re: Makro: Zugriff auf Datenbank-Felder
Ich löse dies mit:Carsten01 hat geschrieben:Ich stelle es mir so vor:
- beim Öffnen des Dokuments wird das/ein Suchfenster geöffnet
- Eingabe Suchbegriff
- Makro sucht Datensatz und führt "Daten in Felder" durch
a) einem Dialog, der den Suchbegriff entgegen nimmt,
b) einer SQL Abfrage mittels Basic
c) füllen von Textmarken in einer Vorlage.
Für a) bis c) habe ich an verschiedenen Stellen Code-Beispiele gefunden und angepasst. Die Verwendung von Dispatcher-Code war nicht nötig.
Der Schritt a) entlastet auch von irgendwelcher Datenquellen-Navigation.
Wäre das eine Lösung?
Cheers
Winfried
aktuell: LO 5.3.5.2 30m0(Build:2) SUSE rpm, unter Linux openSuSE Leap 42.3 x86_64/KDE5
DateTime2 Einfügen von Datum/Zeit/Zeitstempel (als OOo Extension)
Winfried
aktuell: LO 5.3.5.2 30m0(Build:2) SUSE rpm, unter Linux openSuSE Leap 42.3 x86_64/KDE5
DateTime2 Einfügen von Datum/Zeit/Zeitstempel (als OOo Extension)
Re: Makro: Zugriff auf Datenbank-Felder
[quote="komma4"]
Ich löse dies mit:
a) einem Dialog, der den Suchbegriff entgegen nimmt,
b) einer SQL Abfrage mittels Basic
c) füllen von Textmarken in einer Vorlage.
Wäre das eine Lösung?[/quote]
Danke, das hört sich doch vielversprechend an. Wäre schön, wenn Du es mal zur Verfügung stellen könntest. Funktioniert die SQL-Abfrage auch mit einer Datenquelle im dBase-Format?
Ich löse dies mit:
a) einem Dialog, der den Suchbegriff entgegen nimmt,
b) einer SQL Abfrage mittels Basic
c) füllen von Textmarken in einer Vorlage.
Wäre das eine Lösung?[/quote]
Danke, das hört sich doch vielversprechend an. Wäre schön, wenn Du es mal zur Verfügung stellen könntest. Funktioniert die SQL-Abfrage auch mit einer Datenquelle im dBase-Format?
- komma4
- ********
- Beiträge: 5332
- Registriert: Mi, 03.05.2006 23:29
- Wohnort: Chon Buri Thailand Asia
- Kontaktdaten:
Re: Makro: Zugriff auf Datenbank-Felder
Wie geschrieben:Carsten01 hat geschrieben:Danke, das hört sich doch vielversprechend an. Wäre schön, wenn Du es mal zur Verfügung stellen könntest. Funktioniert die SQL-Abfrage auch mit einer Datenquelle im dBase-Format?
habe alles aus anderen Beispielen....
Wo liegen Deine Schwierigkeiten (Fragen)?
Ob die Abfrage auch mit DBase geht? Warum nicht?
a) Dialog anzeigen
Code: Alles auswählen
' Laden der Bibliothek mit dem Dialog
DialogLibraries.LoadLibrary( "wr" )
' Dialog erzeugen
oDialog = _
createUnoDialog( _
DialogLibraries.GetByName( "wr" ).GetByName( "GUI_Rechnungsdruck" ) )
' Objekt der Listbox holen
oListe = oDialog.getControl("ListBox1")
' SQL erstellen, um Listbox zu füllen
' RechnungsNummer und der Kundenname werden aus der DB geholt
' verknüpfung ist die Kunden-ID im Rechnungs-Datensatz
' Ergebnis wird aufsteigend sortiert: älteste Daten zuerst
sSQL = "SELECT " & _
" r.nummer , " & _
" k.name " & _
" FROM " & _
" t091_rechnung as r, " & _
" t090_kunde as k " & _
" WHERE " & _
" r.t090_id = k.id "& _
" ORDER BY "& _
" r.nummer ASC ;"
' Statement erzeugen
oStatement = oVerbindung.createStatement
' Abfrage absetzen
oResultSet = oStatement.executeQuery( sSQL )
' Listbox mit Ergebnis füllen
' Ergebnis1 bis ErgebnisNNN
While oResultSet.Next()
' string zusammensetzen
sCombi = oResultSet.getString(1) & " " & _
TRIM( oResultSet.getString(2) )
' immer oben einfügen, dadurch kommt jüngster Datensatz nach oben
oListe.addItem(sCombi,0)
Wend
' obersten Eintrag markieren
oListe.SelectItemPos(0, TRUE)
' DB freigeben
oResultSet.close()
oStatement.close()
' Anzeigen
oDialog.Execute()
Code: Alles auswählen
sQuery = "SELECT t090_kunde.name, "_
& " t090_kunde.strasse, " _
& " t090_kunde.plzort, "_
& " t091_rechnung.jahr, " _
& " t091_rechnung.monat , " _
& " t091_rechnung.nummer, " _
& " to_char( t091_rechnung.datum , 'YYYY-MM-DD' ), " _
& " to_char( t091_rechnung.netto, '99G999D99 L' ), " _
& " to_char( t101_mwst.mwst_satz, '99' ), " _
& " to_char( ( t091_rechnung.netto * t101_mwst.mwst_satz / 100 ), '9G999D99 L' )," _
& " to_char( ( ( t091_rechnung.netto * t101_mwst.mwst_satz / 100 ) "_
& " + t091_rechnung.netto ), '99G999D99 L' ), " _
& " t093_vertrag.bezeichnung , " _
& " t093_vertrag.datum" _
& " FROM " _
& " t090_kunde t090_kunde, " _
& " t091_rechnung t091_rechnung, " _
& " t093_vertrag t093_vertrag, " _
& " t101_mwst t101_mwst " _
& "WHERE " _
& " ( t090_kunde.id = t091_rechnung.t090_id "_
& " AND t093_vertrag.id = t091_rechnung.t093_id " _
& " AND t101_mwst.id = t091_rechnung.t101_id " _
& " AND t091_rechnung.nummer = '"& sNr & "') "
' Abfrage absetzen
oResultSet2 = oStatement2.executeQuery( sQuery )
sStr = ""
' nur einen Treffer !
oResultSet2.Next()
Code: Alles auswählen
Dim DateiEigenschaft(0) As New com.sun.star.beans.PropertyValue
' aus einer Vorlage erstellen
DateiEigenschaft(0).Name = "AsTemplate"
DateiEigenschaft(0).Value = True
' Speicherort und Name der Vorlage
sURL = "file:///zentrale/firma/vorlagen/firma/Rechnung2005.stw"
sURL = "file:///zentrale/firma/vorlagen/firma/Rechnung2006.ott"
' Dokument erstellen
oDok = StarDesktop.loadComponentFromURL( sURL , "_blank", 0, DateiEigenschaft() )
' in der Vorlage sind die folgenden Textmarken (Bookmarks) gesetzt, die nun
' mit dem Inhalten des Abfrageergebnisses gefüllt werden
' wiederholen:
' Textmarke holen
oBM = oDok.getBookmarks().getByName("Anschrift1")
oBM.getAnchor().String = Trim( oResultSet2.getString(1) )
Hilft das?
Cheers
Winfried
aktuell: LO 5.3.5.2 30m0(Build:2) SUSE rpm, unter Linux openSuSE Leap 42.3 x86_64/KDE5
DateTime2 Einfügen von Datum/Zeit/Zeitstempel (als OOo Extension)
Winfried
aktuell: LO 5.3.5.2 30m0(Build:2) SUSE rpm, unter Linux openSuSE Leap 42.3 x86_64/KDE5
DateTime2 Einfügen von Datum/Zeit/Zeitstempel (als OOo Extension)
Danke Winfried, das hilft schon etwas weiter, auch wenn es schade ist, daß man auf die Feldbefehle verzichten muß. Im Moment hänge ich bei
oStatement = oVerbindung.createStatement
Wie wird oVerbindung erzeugt? Das SDK sagt zu createStatement leider auch nichts.
Die SQL-Syntax muß ich mir auch noch aneignen, mir ist nur dBase geläufig. Aber dazu gibt's ja genug Doku.
oStatement = oVerbindung.createStatement
Wie wird oVerbindung erzeugt? Das SDK sagt zu createStatement leider auch nichts.
Die SQL-Syntax muß ich mir auch noch aneignen, mir ist nur dBase geläufig. Aber dazu gibt's ja genug Doku.
- komma4
- ********
- Beiträge: 5332
- Registriert: Mi, 03.05.2006 23:29
- Wohnort: Chon Buri Thailand Asia
- Kontaktdaten:
Du "musst" nicht auf Feldbefehle verzichten, ich arbeite aber nicht damit und kann Dir deshalb kein Beispiel anbieten.
Verbindung herstellen?
openoffice.org2.0_sdk/docs/common/ref/com/sun/star/sdbc/XConnection.html#createStatement
Die zu verwendende SQL-Syntax, besser: -Dialekt, ist vom eingesetzten Datenbank-Treiber abhängig.
In meinem Beispiel nutze ich auch Währungs- und Datumsformatierungen, um unabhängig von (System- oder Office-Einstellungen, besser gesagt: deren Vorstellungen) *meine* gewünschte Formatierung zu erreichen. Auch wenn ich nicht viele Rechnungen schreibe: damit erhalte ich nach einem Update von Datenbank-Engine, ODBC-/JDBC-Treiber oder OpenOffice gleichartige Schreiben (Eurozeichen-Position und Datum-ISO-Format).
Passt ein solches Vorgehen bei Dir denn überhaupt?
Wieviele Rechnungen sollen von wie vielen Anwendern pro Tag erstellt werden?
Verbindung herstellen?
openoffice.org2.0_sdk/docs/common/ref/com/sun/star/sdbc/XConnection.html#createStatement
Code: Alles auswählen
oDatenbankKontext = CreateUnoService ( "com.sun.star.sdb.DatabaseContext" )
' Datenquelle auswählen
' hier: PostgreSQL-DB über JDBC-Treiber
oDatenquelle = oDatenbankKontext.getByName( "resolutions_jdbc" )
On Error GoTo errLogin
oDatenquelle.setLoginTimeout( 10 )
' Verbindung herstellen: benutzer und passwort übergeben !!!
On Error GoTo errConnection
oVerbindung = oDatenquelle.getConnection( "", "" )
In meinem Beispiel nutze ich auch Währungs- und Datumsformatierungen, um unabhängig von (System- oder Office-Einstellungen, besser gesagt: deren Vorstellungen) *meine* gewünschte Formatierung zu erreichen. Auch wenn ich nicht viele Rechnungen schreibe: damit erhalte ich nach einem Update von Datenbank-Engine, ODBC-/JDBC-Treiber oder OpenOffice gleichartige Schreiben (Eurozeichen-Position und Datum-ISO-Format).
Passt ein solches Vorgehen bei Dir denn überhaupt?
Wieviele Rechnungen sollen von wie vielen Anwendern pro Tag erstellt werden?
Cheers
Winfried
aktuell: LO 5.3.5.2 30m0(Build:2) SUSE rpm, unter Linux openSuSE Leap 42.3 x86_64/KDE5
DateTime2 Einfügen von Datum/Zeit/Zeitstempel (als OOo Extension)
Winfried
aktuell: LO 5.3.5.2 30m0(Build:2) SUSE rpm, unter Linux openSuSE Leap 42.3 x86_64/KDE5
DateTime2 Einfügen von Datum/Zeit/Zeitstempel (als OOo Extension)
Ja, das Vorgehen paßt, auch wenn es nicht besonders hübsch ist (Textmarken finde ich irgendwie doof) und jedes Feld einzeln befüllt werden muß und auch nicht so einfach zwischen Datensätzen gewechselt werden kann. Es ging wie gesagt auch nicht um Rechnungen sondern einfache personalisierte Briefe oder Faxe.
Ein Problem habe ich mit dem SQL-Befehl. Eigentlich sollte Groß-/Kleinschreibung doch keine Rolle spielen, oder? Lasse ich % weg, stimmt das zwar, aber dann findet er keine Teilstrings.
Für die Nachwelt hier das komplette Makro, welches beim Neuerstellen eines Dokuments gestartet wird. Jegliche Fehlerbehandlung habe ich erst mal weggelassen, damit man das Prinzip besser nachvollziehen kann. Das nächste wäre noch die Meldung, wenn kein Datensatz gefunden wurde bzw. eine Auswahlbox, wenn mehrere Datensätze gefunden wurden.
Danke nochmals.
sub AutoNew
' Laden der Bibliothek mit dem Dialog
DialogLibraries.LoadLibrary( "Standard" )
' Dialog erzeugen... Name: <Suchbegriff>
oDialog = createUnoDialog(DialogLibraries.GetByName( "Standard" ).GetByName( "dlg_name" ))
oDialog.Execute()
oListe = oDialog.getControl("TextField1")
oDoc=ThisComponent
' Datenquelle auswählen und Statement erzeugen
oDatenbankKontext = CreateUnoService ( "com.sun.star.sdb.DatabaseContext" )
oDatenquelle = oDatenbankKontext.getByName( "Adressen" )
oDatenquelle.setLoginTimeout( 10 )
' Verbindung herstellen: benutzer und passwort übergeben
oVerbindung = oDatenquelle.getConnection( "", "" )
oStatement = oVerbindung.createStatement
' Abfrage absetzen
sSQL = "SELECT * FROM PRIVAT WHERE NAME LIKE '"+oListe.text+"%'"
oResultSet = oStatement.executeQuery( sSQL )
oDoc.getBookmarks().getByName("adresse").getAnchor().String = oResultSet.getString(1)
oDoc.getBookmarks().getByName("strasse").getAnchor().String = oResultSet.getString(3)
oDoc.getBookmarks().getByName("plzort").getAnchor().String = oResultSet.getString(4)
oDoc.getBookmarks().getByName("faxname").getAnchor().String = oResultSet.getString(1)
oDoc.getBookmarks().getByName("faxnr").getAnchor().String = oResultSet.getString(9)
' DB freigeben
oResultSet.close()
oStatement.close()
oDoc.getBookmarks().getByName("datum").getAnchor().String = date
Ein Problem habe ich mit dem SQL-Befehl. Eigentlich sollte Groß-/Kleinschreibung doch keine Rolle spielen, oder? Lasse ich % weg, stimmt das zwar, aber dann findet er keine Teilstrings.
Für die Nachwelt hier das komplette Makro, welches beim Neuerstellen eines Dokuments gestartet wird. Jegliche Fehlerbehandlung habe ich erst mal weggelassen, damit man das Prinzip besser nachvollziehen kann. Das nächste wäre noch die Meldung, wenn kein Datensatz gefunden wurde bzw. eine Auswahlbox, wenn mehrere Datensätze gefunden wurden.
Danke nochmals.
sub AutoNew
' Laden der Bibliothek mit dem Dialog
DialogLibraries.LoadLibrary( "Standard" )
' Dialog erzeugen... Name: <Suchbegriff>
oDialog = createUnoDialog(DialogLibraries.GetByName( "Standard" ).GetByName( "dlg_name" ))
oDialog.Execute()
oListe = oDialog.getControl("TextField1")
oDoc=ThisComponent
' Datenquelle auswählen und Statement erzeugen
oDatenbankKontext = CreateUnoService ( "com.sun.star.sdb.DatabaseContext" )
oDatenquelle = oDatenbankKontext.getByName( "Adressen" )
oDatenquelle.setLoginTimeout( 10 )
' Verbindung herstellen: benutzer und passwort übergeben
oVerbindung = oDatenquelle.getConnection( "", "" )
oStatement = oVerbindung.createStatement
' Abfrage absetzen
sSQL = "SELECT * FROM PRIVAT WHERE NAME LIKE '"+oListe.text+"%'"
oResultSet = oStatement.executeQuery( sSQL )
oDoc.getBookmarks().getByName("adresse").getAnchor().String = oResultSet.getString(1)
oDoc.getBookmarks().getByName("strasse").getAnchor().String = oResultSet.getString(3)
oDoc.getBookmarks().getByName("plzort").getAnchor().String = oResultSet.getString(4)
oDoc.getBookmarks().getByName("faxname").getAnchor().String = oResultSet.getString(1)
oDoc.getBookmarks().getByName("faxnr").getAnchor().String = oResultSet.getString(9)
' DB freigeben
oResultSet.close()
oStatement.close()
oDoc.getBookmarks().getByName("datum").getAnchor().String = date