❤️ Helfen Sie noch heute, unser LibreOffice Forum zu erhalten! ❤️
Unterstützen Sie das LibreOffice-Forum und helfen Sie uns, unser Ziel für 2025 zu erreichen!

🍀 Jeder Beitrag zählt – vielen Dank für Ihre Unterstützung!🍀
Mit Ihrer Spende sichern Sie den Fortbestand, den Ausbau und die laufenden Kosten dieses Forums. 🌱


❤️ DANKE >> << DANKE ❤️

>> Dank Ihrer Unterstützung -> Keine Werbung für alle registrierten LibreOffice-Forum User! <<
🤗 Als Dankeschön werden Sie im Forum als LO-SUPPORTER gekennzeichnet. 🤗

[gelöst]Daten von einer Datenbank in eine andere kopieren

Base ermöglicht es Ihnen, Ihre Daten in einer Datenbank direkt mit LibreOffice zu bearbeiten.
malt14
Beiträge: 125
Registriert: Fr 7. Nov 2014, 06:21

[gelöst]Daten von einer Datenbank in eine andere kopieren

Beitrag von malt14 » Sa 3. Okt 2015, 19:24

Guten Tag,

ausgehend vom Makro im Gesamtband V50 (S. 447f) versuchte ich, dies in einer Datenbank anzuwenden. Ich erhalte diese Fehlermeldung:
basic.PNG
basic.PNG (54.57 KiB) 4403 mal betrachtet
Liegt das an meiner Version: 4.4.5.2?

Sowohl die benutzte Datenbank als auch die Zieldatenbank sind angemeldet. Die Zieldatenbank befindet sich auf einer anderen Festplatte (D:\).

Wie könnte man ein Update der Tabelle in der Zieldatenbank erreichen, also auch geänderte und nicht nur neue Datensätze entsprechen der Ausgangsdatenbank oder alle bestehenden Datensätze der Tabelle in der Zieldatenbank werden gelöscht und alle Datensätze der Ausgangsdatenbank einfügt?


Falls man die Datensätze mehrerer Tabellen anfügen oder updaten will, geht dies, indem man in das Makro Kopien des ursprünglichen Makros mit den entsprechend geänderten Tabellen und Feldnamen einfügt?

Code: Alles auswählen

REM  *****  BASIC  *****

SUB Datenkopie
DIM oDatabaseContext AS OBJECT
DIM oDatenquelle AS OBJECT
DIM oDatenquelleZiel AS OBJECT
DIM oVerbindung AS OBJECT
DIM oVerbindungZiel AS OBJECT
DIM oDB AS OBJECT
DIM oSQL_Anweisung AS OBJECT
DIM oSQL_AnweisungZiel AS OBJECT
DIM oAbfrageergebnis AS OBJECT
DIM oAbfrageergebnisZiel AS OBJECT
DIM stSql AS String
DIM stSqlZiel AS String
DIM inID AS INTEGER
DIM inIDZiel AS INTEGER
DIM stName AS STRING
DIM stOrt AS STRING
oDB = ThisComponent.Parent
stDir = Left(oDB.Location,Len(oDB.Location)-Len(oDB.Title))
stDir = ConvertToUrl(stDir & "test.odb")
oDatenquelle = ThisComponent.Parent.CurrentController
If NOT (oDatenquelle.isConnected()) THEN
oDatenquelle.connect()
END IF
oVerbindung = oDatenquelle.ActiveConnection()
oDatabaseContext = createUnoService("com.sun.star.sdb.DatabaseContext")
oDatenquelleZiel = oDatabaseContext.getByName(stDir)
oVerbindungZiel = oDatenquelleZiel.GetConnection("","")
oSQL_Anweisung = oVerbindung.createStatement()
stSql = "SELECT * FROM ""Tabelle1"""
oAbfrageergebnis = oSQL_Anweisung.executeQuery(stSql)
WHILE oAbfrageergebnis.next
inID = oAbfrageergebnis.getInt(1)
stName = oAbfrageergebnis.getString(2)
stOrt = oAbfrageergebnis.getString(3)
oSQL_AnweisungZiel = oVerbindungZiel.createStatement()
stSqlZiel = "SELECT ""ID"" FROM ""Tabelle1"" WHERE ""ID"" = '"+inID+"'"
oAbfrageergebnisZiel = oSQL_AnweisungZiel.executeQuery(stSqlZiel)
inIDZiel = - 1
WHILE oAbfrageergebnisZiel.next
inIDZiel = oAbfrageergebnisZiel.getInt(1)
WEND
IF inIDZiel = - 1 THEN
stSqlZiel = "INSERT INTO ""Tabelle1"" (""ID"",""name"") VALUES 
('"+inID+"','"+stname+"')"
oSQL_AnweisungZiel.executeUpdate(stSqlZiel)
END IF
WEND

DIM oDatabaseContext AS OBJECT
DIM oDatenquelle AS OBJECT
DIM oDatenquelleZiel AS OBJECT
DIM oVerbindung AS OBJECT
DIM oVerbindungZiel AS OBJECT
DIM oDB AS OBJECT
DIM oSQL_Anweisung AS OBJECT
DIM oSQL_AnweisungZiel AS OBJECT
DIM oAbfrageergebnis AS OBJECT
DIM oAbfrageergebnisZiel AS OBJECT
DIM stSql AS String
DIM stSqlZiel AS String
DIM inID AS INTEGER
DIM inIDZiel AS INTEGER
DIM stName AS STRING
DIM stOrt AS STRING
oDB = ThisComponent.Parent
stDir = Left(oDB.Location,Len(oDB.Location)-Len(oDB.Title))
stDir = ConvertToUrl(stDir & "test.odb")
oDatenquelle = ThisComponent.Parent.CurrentController
If NOT (oDatenquelle.isConnected()) THEN
oDatenquelle.connect()
END IF
oVerbindung = oDatenquelle.ActiveConnection()
oDatabaseContext = createUnoService("com.sun.star.sdb.DatabaseContext")
oDatenquelleZiel = oDatabaseContext.getByName(stDir)
oVerbindungZiel = oDatenquelleZiel.GetConnection("","")
oSQL_Anweisung = oVerbindung.createStatement()
stSql = "SELECT * FROM ""Tabelle2"""
oAbfrageergebnis = oSQL_Anweisung.executeQuery(stSql)
WHILE oAbfrageergebnis.next
inID = oAbfrageergebnis.getInt(1)
stName = oAbfrageergebnis.getString(2)
stOrt = oAbfrageergebnis.getString(3)
oSQL_AnweisungZiel = oVerbindungZiel.createStatement()
stSqlZiel = "SELECT ""ID"" FROM ""Tabelle2"" WHERE ""ID"" = '"+inID+"'"
oAbfrageergebnisZiel = oSQL_AnweisungZiel.executeQuery(stSqlZiel)
inIDZiel = - 1
WHILE oAbfrageergebnisZiel.next
inIDZiel = oAbfrageergebnisZiel.getInt(1)
WEND
IF inIDZiel = - 1 THEN
stSqlZiel = "INSERT INTO ""Tabelle2"" (""ID"",""name2"") VALUES 
('"+inID+"','"+stname2+"')"
oSQL_AnweisungZiel.executeUpdate(stSqlZiel)
END IF
WEND

END SUB

Grüße
Malt

LibreOffice
Version: 4.4.5.2
Gebietsschema: de_DE
Microsoft Windows 8.1 Home 6.03.9600 x64
Zuletzt geändert von malt14 am Mo 5. Okt 2015, 18:23, insgesamt 1-mal geändert.

RobertG
* LO-Experte *
Beiträge: 2888
Registriert: Sa 19. Mai 2012, 17:37
Kontaktdaten:

Re: Daten von einer Datenbank in eine andere kopieren

Beitrag von RobertG » Sa 3. Okt 2015, 19:42

Hallo Malt,

schon der Screenshot macht mich stutzig. In der Folgezeile der angemerkten Codezeile steht Code in grauer Farbe. Das deutet darauf hin, dass der Editor von einem Kommentar ausgeht. Das erste Zeichen, die offne Klammer, ist dunkelblau - Code wie z.B. eine Zuweisung "=".

Hinter dem Begriff "VALUES" scheint ein Zeilenumbruch eingebaut zu sein. Dadurch wird der String unterbrochen. Nimm den Zeilenumbruch raus, dann hast Du damit mehr Erfolg.

------------------------------
Willst Du nicht nur neue Daten in die Zieltabelle übertragen, sondern auch gegebenenfalls Updates, so ist dies problemlos am Schluss der Makros möglich:

Code: Alles auswählen

WEND
IF inIDZiel = - 1 THEN
stSqlZiel = "INSERT INTO ""Tabelle"" (""ID"",""Name"") VALUES ('"+inID+"','"+stName+"')"
ELSE
stSqlZiel = "UPDATE ""Tabelle"" SET ""Name"" = '"+stName+"' WHERE ""ID"" = '"+inID+"'"
END IF
oSQL_AnweisungZiel.executeUpdate(stSqlZiel)
inIDZiel klärt ja vorher ab, ob der Datensatz schon existiert. Bei '-1' existiert der Datensatz noch nicht - ein neuer Datensatz wird geschrieben. Sonst wird ein alter Datensatz überschrieben.
--------------------------------

Gruß

Robert
https://de.libreoffice.org/get-help/documentation/
https://www.familiegrosskopf.de/robert/index.php?&Inhalt=base_handbuch
https://www.familiegrosskopf.de/robert/index.php?&Inhalt=xml_formulare

malt14
Beiträge: 125
Registriert: Fr 7. Nov 2014, 06:21

Re: Daten von einer Datenbank in eine andere kopieren

Beitrag von malt14 » Sa 3. Okt 2015, 22:44

Hallo Robert,

vielen Dank für Deine Hilfe! Entsprechend Deinem Hinweis entfernte ich den Zeilenumbruch.
Ich kopierte das Makro aus dem Handbuch und bearbeitete es in Writer. Beim Einfügen entsteht der Zeilenumbruch, der mir nicht auffiel.

Eine neue Fehlermeldung:
basic2.PNG
basic2.PNG (57.86 KiB) 4393 mal betrachtet
Makro:

Code: Alles auswählen

REM  *****  BASIC  *****

SUB Datenkopie
DIM oDatabaseContext AS OBJECT
DIM oDatenquelle AS OBJECT
DIM oDatenquelleZiel AS OBJECT
DIM oVerbindung AS OBJECT
DIM oVerbindungZiel AS OBJECT
DIM oDB AS OBJECT
DIM oSQL_Anweisung AS OBJECT
DIM oSQL_AnweisungZiel AS OBJECT
DIM oAbfrageergebnis AS OBJECT
DIM oAbfrageergebnisZiel AS OBJECT
DIM stSql AS String
DIM stSqlZiel AS String
DIM inID AS INTEGER
DIM inIDZiel AS INTEGER
DIM stName AS STRING
DIM stOrt AS STRING
oDB = ThisComponent.Parent
stDir = Left(oDB.Location,Len(oDB.Location)-Len(oDB.Title))
stDir = ConvertToUrl(stDir & "test.odb")
oDatenquelle = ThisComponent.Parent.CurrentController
If NOT (oDatenquelle.isConnected()) THEN
oDatenquelle.connect()
END IF
oVerbindung = oDatenquelle.ActiveConnection()
oDatabaseContext = createUnoService("com.sun.star.sdb.DatabaseContext")
oDatenquelleZiel = oDatabaseContext.getByName(stDir)
oVerbindungZiel = oDatenquelleZiel.GetConnection("","")
oSQL_Anweisung = oVerbindung.createStatement()
stSql = "SELECT * FROM ""Tabelle1"""
oAbfrageergebnis = oSQL_Anweisung.executeQuery(stSql)
WHILE oAbfrageergebnis.next
inID = oAbfrageergebnis.getInt(1)
stName = oAbfrageergebnis.getString(2)
stOrt = oAbfrageergebnis.getString(3)
oSQL_AnweisungZiel = oVerbindungZiel.createStatement()
stSqlZiel = "SELECT ""ID"" FROM ""Tabelle1"" WHERE ""ID"" = '"+inID+"'"
oAbfrageergebnisZiel = oSQL_AnweisungZiel.executeQuery(stSqlZiel)
inIDZiel = - 1
WHILE oAbfrageergebnisZiel.next
inIDZiel = oAbfrageergebnisZiel.getInt(1)
WEND
IF inIDZiel = - 1 THEN
stSqlZiel = "INSERT INTO ""Tabelle1"" (""ID"",""name"") VALUES ('"+inID+"','"+stname+"')"
oSQL_AnweisungZiel.executeUpdate(stSqlZiel)
END IF
WEND
END SUB
LibreOffice Version: 4.4.5.2


Grüße
Malt

RobertG
* LO-Experte *
Beiträge: 2888
Registriert: Sa 19. Mai 2012, 17:37
Kontaktdaten:

Re: Daten von einer Datenbank in eine andere kopieren

Beitrag von RobertG » So 4. Okt 2015, 08:38

Hallo Malt,

aus dem Handbuch, direkt über dem Code:
Der Kontakt zur Ausgangsdatenbank wird im Verhältnis zum Formular ermittelt, in dem der Button liegt: ThisComponent.Parent.CurrentController. Der Kontakt zur externen Datenbank wird über den DatabaseContext und den Pfad zur Datenbank erstellt.
Ich vermute, dass Du das Makro nicht aus einem Formular heraus mit einem Button starten willst, sondern z.B. direkt von der Base-Oberfläche. Da gibt es dann keinen 'Parent'. Weder bei oDB (wäre dann einfach oDB = ThisComponent) noch bei oDatenquelle (wäre dann oDatenquelle = ThisComponent.CurrentController).

Gruß

Robert
https://de.libreoffice.org/get-help/documentation/
https://www.familiegrosskopf.de/robert/index.php?&Inhalt=base_handbuch
https://www.familiegrosskopf.de/robert/index.php?&Inhalt=xml_formulare

malt14
Beiträge: 125
Registriert: Fr 7. Nov 2014, 06:21

Re: Daten von einer Datenbank in eine andere kopieren

Beitrag von malt14 » So 4. Okt 2015, 16:00

Hallo Robert,

den Grund für mein "Parent" Problem erkanntest Du richtig. Funktioniert jetzt mit Verweis in der Symbolleiste.
Herzlichen Dank!

Meine Zieldatenbank liegt in einem anderen Verzeichnis auf einer anderen Festplatte (D:\xx\xx\zdb), Quelldatenbank (C:\xx\xx\qdb). Beide sind bei LO angemeldet. Dann funktioniert das Makro nicht. Kann man in das Makro den jeweiligen Dateipfad der Datenbanken eintragen?

Einige Datensätze (Namen) enthalten das Zeichen ', dann stoppt das Makro.

Grüße
Malt

RobertG
* LO-Experte *
Beiträge: 2888
Registriert: Sa 19. Mai 2012, 17:37
Kontaktdaten:

Re: Daten von einer Datenbank in eine andere kopieren

Beitrag von RobertG » So 4. Okt 2015, 17:23

Hallo Malt,
malt14 hat geschrieben: Meine Zieldatenbank liegt in einem anderen Verzeichnis auf einer anderen Festplatte (D:\xx\xx\zdb), Quelldatenbank (C:\xx\xx\qdb). Beide sind bei LO angemeldet. Dann funktioniert das Makro nicht. Kann man in das Makro den jeweiligen Dateipfad der Datenbanken eintragen?
Die Datenbank, von der aus Du das Ganze aufrufst, ist die Quelldatenbank. Da kann vom Pfad her nichts schief gehen.
Der Pfad zur Zieldatenbank wird hier definiert:

Code: Alles auswählen

stDir = ConvertToUrl(stDir & "ZielDB.odb")
Es wird also der Pfad zur Quelldatenbank ausgelesen und statt der Quelldatenbank die Zieldatenbank eingefügt.
Du kannst jetzt folgendermaßen vorgehen:

Code: Alles auswählen

stDir = ConvertToUrl("D:\xx\xx\zdb")
Dann kannst Du Dir diese Zeilen sparen:

Code: Alles auswählen

oDB = ThisComponent.Parent
stDir = Left(oDB.Location,Len(oDB.Location)-Len(oDB.Title))
stDir = ConvertToUrl(stDir & "ZielDB.odb")
Ob die Datenbanken angemeldet sind oder nicht spielt hierbei keine Rolle. Bei den vielen Testdatenbanken habe ich auf Anmeldungen der Datenbanken verzichtet und nutze stattdessen immer den Pfad.
malt14 hat geschrieben: Einige Datensätze (Namen) enthalten das Zeichen ', dann stoppt das Makro.
Nutze diese Funktion:

Code: Alles auswählen

FUNCTION String_to_SQL(st AS STRING)
IF InStr(st,"'") THEN
st = Join(Split(st,"'"),"''")
END IF
String_to_SQL = st
END FUNCTION
Steht im Handbuch unter
Daten aus Textfeldern auf SQL-Tauglichkeit vorbereiten
Gruß

Robert
https://de.libreoffice.org/get-help/documentation/
https://www.familiegrosskopf.de/robert/index.php?&Inhalt=base_handbuch
https://www.familiegrosskopf.de/robert/index.php?&Inhalt=xml_formulare

malt14
Beiträge: 125
Registriert: Fr 7. Nov 2014, 06:21

Re: Daten von einer Datenbank in eine andere kopieren

Beitrag von malt14 » So 4. Okt 2015, 23:01

Hallo Robert,

vielen Dank für die Hilfe zur Zieldatenbank und den Hinweis zur Hochkomma Funktion.
Ich las den Abschnitt darüber im Handbuch. Wie man eine Funktion in ein Makro einbaut und diese dann z.B. für stname ("Datenkopie") aufruft, weiß ich nicht. Dazu fand ich im Internet und Handbüchern nichts; ich kenne zu wenig von Makros, um erfolgreich zu suchen.

In meinen Tabellen benutze ich Feldnamen mit Leerzeichen. Das Makro funktioniert damit nicht. Setze ich den Feldnamen mit Leerzeichen in eckige Klammern "DIM [stname ID] AS STRING", funktioniert das Makro bis oSQL_AnweisungZiel.executeUpdate(stSqlZiel). Dann folgt die Fehlermeldung: Column not found: [stname ID].
Gibt es eine Möglichkeit Feldnamen mit Leerzeichen in Makros zu benutzen?


Grüße

Malt

RobertG
* LO-Experte *
Beiträge: 2888
Registriert: Sa 19. Mai 2012, 17:37
Kontaktdaten:

Re: Daten von einer Datenbank in eine andere kopieren

Beitrag von RobertG » Mo 5. Okt 2015, 09:08

Hallo Malt,

die Feldnamen in Tabellen haben nichts mit Namensbezeichnungen innerhalb von Makros zu tun. In Makros solltest Du tunlichst Variablen ohne irgendwelche Sonderzeichen erstellen. Ich nutze als Trennung hier gegebenenfalls den Unterschied zwischen Klein- und Großschreibung (der keine weitere Auswirkungen hat) oder den Unterstrich.

Code: Alles auswählen

stSqlZiel = "INSERT INTO ""Tabelle1"" (""ID"",""name"") VALUES ('"+inID+"','"+stname+"')"
Die Bezeichner für das Tabellenfeld sind in der ersten Klammer enthalten. Hier kannst Du zwischen die doppelten Anführungszeichen genau Deine Feldnamen eintragen:

Code: Alles auswählen

stSqlZiel = "INSERT INTO ""Tabelle1"" (""stname ID"",""name"") VALUES ('"+inID+"','"+stname+"')"
Die Meldung
Column not found: [stname ID]
deutet darauf hin, dass Du dort jetzt eben

Code: Alles auswählen

stSqlZiel = "INSERT INTO ""Tabelle1"" (""[stname ID]"",""name"") VALUES ('"+inID+"','"+stname+"')"
stehen hast. Und die Feldbezeichnung hast Du doch wohl nicht gewollt, oder?

Zum Einsatz der Funktion, die Hochkommata richtig maskiert:

Code: Alles auswählen

stTextneu = String_to_SQL(stTextalt)
steht als Aufrufbeispiel im Handbuch.
Dann gibt es in dem Makro, das Du nutzt, diese Zeilen:

Code: Alles auswählen

WHILE oAbfrageergebnis.next
inID = oAbfrageergebnis.getInt(1)
stName = oAbfrageergebnis.getString(2)
stOrt = oAbfrageergebnis.getString(3)
....
Jetzt setzt Du die Funktion ein:

Code: Alles auswählen

WHILE oAbfrageergebnis.next
inID = oAbfrageergebnis.getInt(1)
stName = String_to_SQL(oAbfrageergebnis.getString(2))
stOrt = String_to_SQL(oAbfrageergebnis.getString(3))
....
Damit sind die Variablen entsprechend maskiert. inID brauchst Du nicht zu maskieren, da es sich um eine Integer-Variable handelt.

Gruß

Robert
https://de.libreoffice.org/get-help/documentation/
https://www.familiegrosskopf.de/robert/index.php?&Inhalt=base_handbuch
https://www.familiegrosskopf.de/robert/index.php?&Inhalt=xml_formulare

malt14
Beiträge: 125
Registriert: Fr 7. Nov 2014, 06:21

Re: Daten von einer Datenbank in eine andere kopieren

Beitrag von malt14 » Mo 5. Okt 2015, 18:22

Hallo Robert,

vielen Dank für Deine Erklärungen!
Die Feldnamen funktionieren.

Im Handbuch wird der Grund für und die Arbeitsweise der Funktion String_to_SQL gut erklärt.
Ich wusste bisher nicht, dass man eine Funktion am Ende eines Makros unter End Sub einfügt. Mit der Beispielsdatenbank Beispiel_PDFFormular_Import lernte ich das.

Beim Aufruf von Datenkopie erhalte ich die Meldung "Wrong data type":
type.PNG
type.PNG (23.48 KiB) 4330 mal betrachtet
Das geschieht gelegentlich auch, wenn ich Daten manuell in eine Datenbank kopiere, obwohl diese denselben Datentyp wie die Zielspalte besitzen.

Soweit wie ich das bisher feststellen konnte, werden mit dem Makro Datenkopie trotz o.g. Meldung alle Datensätze korrekt in die Tabelle der Zieldatenbank kopiert.

Nochmals herzlichen Dank für Deine Hilfe und Geduld.

Grüße
Malt

RobertG
* LO-Experte *
Beiträge: 2888
Registriert: Sa 19. Mai 2012, 17:37
Kontaktdaten:

Re: [gelöst]Daten von einer Datenbank in eine andere kopieren

Beitrag von RobertG » Mo 5. Okt 2015, 21:20

Hallo Malt,

anscheinend versuchst Du in ein Zahlenfeld ein leeren String zu kopieren. Das Makro selbst ist erst einmal auf ein einfaches Beispiel gestrickt: Lediglich das Feld "ID" besteht aus Zahlen. Die Zahlen müssen immer gefüllt sein, da es der Primärschlüssel ist. Alle anderen Felder sind Textfelder. Leere Textfelder werden als leerer String übergeben.

Das geht für Textfelder, aber eben nicht für Zahlenfelder. Hier müsste an dem Makro noch nachgebessert werden. Leere Felder sollten grundsätzlich als NULL weitergegeben werden. Da steht schließlich nichts drin.

Ich nehme mir in den nächsten Tage das Makro noch einmal vor.

Gruß

Robert
https://de.libreoffice.org/get-help/documentation/
https://www.familiegrosskopf.de/robert/index.php?&Inhalt=base_handbuch
https://www.familiegrosskopf.de/robert/index.php?&Inhalt=xml_formulare


An alle, die das LibreOffice-Forum gern nutzen und unterstützen wollen:


Bitte helfen Sie uns mit 7 Euro pro Monat.
Durch Ihren Beitrag tragen Sie dazu bei, unsere laufenden Kosten für die kommenden Monate zu decken.
Unkompliziert per Kreditkarte oder PayPal.
Als ein kleines Dankeschön werden Sie im LO-Forum als SUPPORTER gekennzeichnet.



Antworten