[gelöst]Daten aus 2 DB-Backends in einem Formular?

Datenbanklösungen mit AOO/LO

Moderator: Moderatoren

JoCo
Beiträge: 7
Registriert: Fr, 16.01.2009 15:17
Wohnort: Bremen

[gelöst]Daten aus 2 DB-Backends in einem Formular?

Beitrag von JoCo »

Hallo an Alle,
seit einigen Tagen versuche ich ein Formular zu erstellen das mir Daten aus 2 unterschiedlichen DB's anzeigt.

Meine Ausgangs-Situation:
Ich benutze OOo 3.2.1 unter Linux.
Mit der integrierten HSQL-DB habe ich eine Datenbank zur Zeiterfassung und Rechnungsstellung für Subunternehmer erstellt (Montage.odb).
In einem Hauptformular ("Rechnungen") habe ich u.a. ein Unterformular ("UebrsOffen") das mir in einem Tabellenkontrollfeld
die noch nicht als bezahlt markierten Rechnungen auflistet. "UebersOffen" ist SQL-basiert da die Daten aus verschiedenen Tabellen stammen.
Mit Hilfe eines Makros lese ich den Inhalt eines nicht verknüpften Datumsfeld aus und schreibe es ins Feld "BezAm" der entspechenden Tabelle "eigRechn".

Als Onlinebanking-Programm nutze ich KMyMoney. Darin ordne ich den Konto-Buchungen u.a. die Kategorie "Ein19%" zu.
KMyMoney kann seine Daten in einer MySQL-Datenbank speichern. Für diese Datenbank habe ich (MySQL-jdbc) eine "kmysql.odb" erstellt
und bei OOo registriert. "kmysql.odb" enthält eine funktionierende Abfrage "SucheRechnungsEingänge".

Was ich erreichen möchte:
Ich möchte in "Montage.Rechnungen" die Daten von "kmysql.SucheRechnungsEingänge" anzeigen und per Makro das Konto-Buchungs-Datum als "BezAm"
in "Montage.eigRechn" eintragen.

Was ich versucht habe:
Im der Oberfläche von Base habe ich keine Möglichkeit gefunden in der bestehenden Montage.odb eine weitere Datenbank auszuwählen.
(Ich fürchte das hat seinen Grund)

Meine Versuche in Basic eine weitere DB als Verbindung unterzujubeln sind leider auch gescheitert:

Code: Alles auswählen

Sub KontoAuszug1
'***************
' holt die Zahlungseingänge vom Konto
globalscope.basiclibraries.loadlibrary("MRILib")

Dim oDoc
Dim oDraw
Dim oFormKonto
Dim oDrMan
Dim oDr
Dim oCon

oDoc = ThisComponent
oDraw = oDoc.Drawpage
oDrMan = CreateUnoService("com.sun.star.sdbc.DriverManager")
oDr = oDrMan.getDriverByUrl("sdbc:mysql:jdbc:localhost:3306/kmymoney)"
Dim oParms(1) As New com.sun.star.beans.PropertyValue
  oParms(0).name = "user"
  oParms(0).value = "root"
  oParms(1).Name = "password"
  oParms(1).value = "meinPasswort"
oCon = oDr.Connect("sdbc:mysql:jdbc:localhost:3306/kmymoney",oParms)
 
oFormKonto = oDoc.CreateInstance("com.sun.star.form.component.Form")
oFormKonto.ActiveConnection = oCon
oFormKonto.CommandType=com.sun.star.sdb.CommandType.COMMAND
oFormKonto.Command = "SELECT `kmmPayees`.`name`, `kmmSplits`.`valueFormatted`, `kmmSplits`.`postDate`, `kmmSplits`.`memo` " &_
			"FROM `kmymoney`.`kmmSplits` AS `kmmSplits`, `kmymoney`.`kmmPayees` AS `kmmPayees`, `kmymoney`.`kmmAccounts` AS `kmmAccounts` " &_
			"WHERE `kmmSplits`.`payeeId` = `kmmPayees`.`id` AND `kmmSplits`.`accountId` = `kmmAccounts`.`id` " &_
			"AND ( `kmmAccounts`.`accountName` LIKE 'Befr-ein' OR `kmmAccounts`.`accountName` LIKE '19%-ein' )" 
'kleiner Test
oFormKonto.execute()
oFormKonto.first()
print oFormKonto.getString(1)
'liefert Daten

oDraw.Forms.InsertByName ("Konto",oFormKonto)
	
Mri oFormKonto

End Sub
Das Makro erzeugt zwar das Formular "Konto", aber wenn ich diesem im Entwurfsmodus dann Konroll-Elemente zuordne, kann ich keine Datenfelder
auswählen (Auswahl-Liste in Eigenschaften/Daten/DatenFelder hat keine Einträge).

Desweiteren habe ich das Formular "Rechnungen" mal als eigenes .odt Dokument gespeichert. (Kopie speichern unter ...)
Jetzt kann ich zwar wie gewünscht die zweite Datenbank als Quelle hinzufügen und bekomme auch die Daten aus beiden DB's richtig angezeigt,
aber wenn ich versuche per Makro das Buchungs-Datum als "BezAm" zu speichern bleibt das updateRow() ohne Wirkung.
Um doppelte Verbindungen zur HSQL zu vermeiden, habe ich OOo erst komplett geschlossen und dann das eigenständige Formular geöffnet.

Code: Alles auswählen

' nur der Teil in dem ich speichern will

SQLstr = "SELECT * FROM eigRechn WHERE " + Teilstr			'den neuen SQL-String erstellen
Dim rsBezAm As Object											
rsBezAm = createUnoService("com.sun.star.sdb.RowSet")			
	With rsBezAm											
		.DataSourceName="Montage"						
		.CommandType=com.sun.star.sdb.CommandType.COMMAND
		.Command=SQLstr
		.execute()
	End With

While rsBezAm.next											
	rsBezAm.updateDate(4,Datumstruct)						'Datum in der aktuellen Reihe eintragen 
	rsBezAm.updateRow() 									'aktuelle Reihe speichern
Wend
Jetzt meine Frage an euch, welche Möglichkeiten habe ich?
Muss ich mir die Anzeige der Konto-Daten selbst zusammen basteln oder gibt es doch einen Weg ein Tabellen-Kontrollfeld zu benutzen.
Im Netz findet man zwar viele Beispiele wie man sich mit einer einzigen Datenbank verbindet,
zu meheren DB's gleichzeitig habe ich aber leider nichts gefunden.
Danke für's lesen und eventuelle Anregungen
Gruß aus Bremen
Jörn
Zuletzt geändert von JoCo am Do, 19.08.2010 09:32, insgesamt 1-mal geändert.
Benutzeravatar
komma4
********
Beiträge: 5332
Registriert: Mi, 03.05.2006 23:29
Wohnort: Chon Buri Thailand Asia
Kontaktdaten:

Re: Daten aus 2 unterschiedl. DB-Backends in einem Formular?

Beitrag von komma4 »

Auch Dir noch ein "Willkommen im Forum"


Ich kann Dir nicht sagen, wo Dein Problem liegt.

Du bekommst die Daten der 2. DB in die Liste... dann stehen sie Dir auch für das UPDATE zur Verfügung.
So die Theorie.

In der Praxis kann ich mich hier per BASIC mit 2 Datenbank-Backends verbinden und deren Daten nutzen (auch in einem Formular). Wie das bei Dir nun im speziellen Fall auszusehen hat... keine Ahnung.
Debugge Deinen Code und versuche die Schwachstelle zu identifizieren.


Viel Erfolg!
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)
JoCo
Beiträge: 7
Registriert: Fr, 16.01.2009 15:17
Wohnort: Bremen

Re: Daten aus 2 unterschiedl. DB-Backends in einem Formular?

Beitrag von JoCo »

Moin Winfried,
zuerst einmal ein herzliches Dankeschön an dich für deinen unermüdlichen Einsatz in diesem Forum. Ohne Leute wie dich würden die Foren im Netz einfach nicht funktionieren. Wenn ich für jedes deiner Postings mal 5 Minuten Zeitaufwand rechne, komme ich auf über 300 Stunden. Respekt!!
Debugge Deinen Code und versuche die Schwachstelle zu identifizieren.
Ich glaube die Schwachstelle liegt in der Tabelle ("eigRechn") in die ich speichern will. Beim Entwurf habe ich einen zusammengesetzten Primärschlüssel ("ID"und "JobID") definiert da es sich um eine m zu n Beziehung handelt. Eine Rechnung kann mehrere Jobs enthalten und ein Job kann in mehr als einer Rechnung abgerechnet werden.
Der erste Eintrag in "eigRechn" erfolgt bei Rechnungserstellung:

Code: Alles auswählen

'speichern
oRs.Command = "SELECT * FROM eigRechn " 
oRs.execute()
For i=0 To uBound(Jobs)                         'in Jobs() stehen die "JobID's"
	oRs.moveToInsertRow()
	oRS.updateString(1,ReNrTxt)
	oRs.updateInt(2,neueReNr)
	oRs.updateDate(3,ReDatum)
	oRs.updateInt(5,Jobs(i))
	oRs.insertRow()
Next i
hier funktionieren die Methoden des Rowsets.
Der zweite Eintrag erfolgt bei Zahlungseingang (Code siehe 1. Posting)
updateRow() bleibt ohne Wirkung.
Wenn ich aber ein Statement benutze wird das Datum korrekt in die Tabelle geschrieben

Code: Alles auswählen

Dim Datumstring As String
Dim oRsBezAm
Dim oStmnt
Dim SQLStmnt As String
							
Datumstring = Left(oFormKonto.getString(3),10)		'den Datum-Teil des TimeStamp als String einlesen ( = z.B. 2010-04-21 00:00:00)
									
oRsBezAm = createUnoService("com.sun.star.sdb.RowSet")			
	With oRsBezAm											
		.DataSourceName="Montage"						
		.CommandType=com.sun.star.sdb.CommandType.COMMAND
		.Command="SELECT * FROM ""eigRechn"" "
		.execute()
	End With
oStmnt = oRsBezAm.ActiveConnection.createStatement()

SQLStmnt ="UPDATE ""eigRechn"" SET ""BezAm"" = '" & Datumstring &_
		 "' WHERE ""ID"" IN ('" +  Join(aktuelleLoes(),"','")	 & "')"                  'aktuelleLoes() beinhaltet die "ReNrTxt"
			 
oStmnt.executeUpdate(SQLStmnt)
Wenn ich in Base die Tabelle öffne und Werte direkt eingebe oder lösche werden die Änderungen verworfen. Auch hier habe ich nur über SQL-Direkt Schreib-Zugriff auf "eigRechn". Da es bei anderen Tabellen mit einfachem Primärschlüssel keine Probleme gibt muss es wohl an der Tabelle liegen.
Obwohl ich eine funktionierende Lösung habe, würde es mich doch interessieren ob es nicht doch eine Möglichkeit gibt mit dem Rowset direkt zu arbeiten.
Ich muss allerdings gestehen, daß ich die Doku der API nicht wirklich verstanden habe.
service RowSet

Description
is a client side RowSet, which use retrieves is data based on a database table, a query or a SQL command or by a rowset reader, who mustn't support SQL. The connection of the rowset is typically a named DataSource or a DataAccess component or a previous instanciated connection.

Depending on the ::com::sun::star::sdbc::ResultSetConcurrency , the RowSet caches all data or uses an optimized way for retrieving the data, such as, refetching rows by their keys or if provided, by their bookmarks.

In addition, it provides events for RowSet navigation and RowSet modifications to approve the actions and to react on them.
Was bedeutet client side RowSet?
ResultSetConcurrency = 1008 habe ich übrigens überprüft.
Letzte Frage:
In der Praxis kann ich mich hier per BASIC mit 2 Datenbank-Backends verbinden und deren Daten nutzen (auch in einem Formular).
Gilt das für ein Formular innerhalb von Base oder nur für das separate Textdokument mit Formularen?

Ein schönes Restwochenende wüscht
Jörn
Benutzeravatar
komma4
********
Beiträge: 5332
Registriert: Mi, 03.05.2006 23:29
Wohnort: Chon Buri Thailand Asia
Kontaktdaten:

Re: Daten aus 2 unterschiedl. DB-Backends in einem Formular?

Beitrag von komma4 »

Danke für die anerkennenden Worte. Solange es mit Spass macht (auch mal was zu probieren) bin ich dabei :)
JoCo hat geschrieben:Wenn ich in Base die Tabelle öffne und Werte direkt eingebe oder lösche werden die Änderungen verworfen. Auch hier habe ich nur über SQL-Direkt Schreib-Zugriff auf "eigRechn". Da es bei anderen Tabellen mit einfachem Primärschlüssel keine Probleme gibt muss es wohl an der Tabelle liegen
Seltsam.
Erste Anmerkung deutet auf einen fehlenden Primärschlüssel hin.


JoCo hat geschrieben:.ResultSetConcurrency = 1008 habe ich übrigens überprüft.
Sehe ich in Deinem Code nicht... ?

Code: Alles auswählen

rsBezAm = createUnoService("com.sun.star.sdb.RowSet")         
   With rsBezAm                                 
      .DataSourceName="Montage"                  
      .CommandType=com.sun.star.sdb.CommandType.COMMAND
      .Command=SQLstr
      .execute()
   End With

While rsBezAm.next                                 
   rsBezAm.updateDate(4,Datumstruct)                  'Datum in der aktuellen Reihe eintragen
   rsBezAm.updateRow()                            'aktuelle Reihe speichern
Wend
Ich setze (ungebundene) Kontrollfelder per BASiC in ein BASE-Formular und der Update per Formularfunktion klappt....
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)
JoCo
Beiträge: 7
Registriert: Fr, 16.01.2009 15:17
Wohnort: Bremen

Re: Daten aus 2 unterschiedl. DB-Backends in einem Formular?

Beitrag von JoCo »

Ich wollte gerade ein screenshot von "eigRechn" im Entwurfsfenster anhängen aber:
Das Kontingent für Dateianhänge ist bereits vollständig ausgenutzt.
Also, nur zur Sicherheit, der Aufbau der Tabelle in Textform:
____Feldname____Feldtyp
PK__ID_________Text(VARCHAR)
____ReNr________Integer
____ReDatum____Datum
____BezAm______Datum
PK_JobID_______Integer
____MwStSatzID_Integer

Wahrscheinlich sollte ich die Verknüpfung "ID" zu "JobID" in eine eigene Tabelle auslagern. Aber das zusammenstellen von Daten ist bei meinem DB-Entwurf auch so schon kompliziert genug. Oder gibt es "zwingende Gründe" dafür?

Bei mir wurden bisher alle RowSets immer automatisch mit ResultSetConcurrency = 1008 erstellt (wenn ich mich auf die Angaben vom Mri-Tool verlassen kann).
Ich werde das gleich nochmal explizit mit angeben um zu sehen ob es einen Unterschied macht.

[quote = "komma4"]Ich setze (ungebundene) Kontrollfelder per BASiC in ein BASE-Formular und der Update per Formularfunktion klappt....[/quote]

Ich glaube da liegt der Unterschied. Ich versuche Daten aus einem Tabellenkontrollfeld der MySQL-DB in die Tabelle der HSQL-DB zu schreiben.
Das Tabellenkontrollfeld ist also gebunden. Ich müsste also erst per Makro eine tabellenartige Struktur von Datenfeldern erzeugen und diese dann mit den Werten aus der Abfrage von MySQL füllen. Das ist es mir nicht wert.
Auf lange Sicht werde meine Formulare wahrscheinlich sowieso außerhalb von Base benutzen, um nicht immer erst in Base das passende auswählen zu müssen.
Antworten