BITTE helfen Sie uns HEUTE mit einer SPENDE
Helfen Sie das LibreOffice Forum zu erhalten!

❤️ DANKE >><< DANKE ❤️

> KEINE WERBUNG FÜR REGISTRIERTE BENUTZER!<
Ihre Spende wird für die Deckung der laufenden Kosten sowie den Erhalt und Ausbau 🌱 des LibreOffice Forums verwendet.
🤗 Als Dankeschön werden Sie im Forum als LO-SUPPORTER gekennzeichnet. 🤗

(gelöst) Daten einer Calc/Exel-Tabelle per Makro importieren

Base ermöglicht es Ihnen, Ihre Daten in einer Datenbank direkt mit LibreOffice zu bearbeiten.
Stegull
Beiträge: 37
Registriert: Di 6. Dez 2022, 13:36

(gelöst) Daten einer Calc/Exel-Tabelle per Makro importieren

Beitrag von Stegull » Di 10. Jan 2023, 15:59

Es läuft, mein kleines Daten-Kontroll-Projekt und ich bin sehr glücklich darüber!

Werte Mitdenker, Mithelfer und Base-Fachleute, werter RobertG und werter F3K,

mit dem Handbuch "Base_09_Makros_V72" und der Beispieldatenbank "Beispiel_Daten_Import_Hsqldb" habe ich mir eine Datenimportmöglichkeit geschaffen, die mir eine Menge Arbeitsschritte und damit Zeit erspart.
Dazu habe ich einfach das Makro aus der Beispieldatenbank genommen und meine Lokalisationsparameter (von "CalcTabelle1" in "Base-Tabelle1") eingetragen. Am Makro wurde nichts weiter verändert.

Es funktioniert! Da mir bei diesem Schritt bis zu 5000 Datenzeilen in die "Tabelle1" eingetragen werden dauert das einige Sekunden. Anfangs wurde der Formularhintergrund schwarz. Dies konnte ich durch Recherchieren beseitigen (Lösung: Skia deaktivieren).

Ich sehe Parameter Dezimalzahl und Datum in diesem Makro. Mir reicht der richtige Import des Datumformats eigentlich vorerst aus. Einige Spalten meiner Calc Tabelle beinhalten Uhrzeiten und einige Währungsformat (€). Diese werden nicht ordentlich importiert. Im Moment ist das nicht wichtig.

Meine Frage diesbezüglich:
1. Kann ich das Makro so belassen? So, wie es in der Beispieldatenbank angegeben ist mit meinen beiden Änderungen "Startort Calc Tabelle1" und "Zielort Base Tabelle1"? Oder müssen da noch einige spezifische Dinge angepasst werden.

2. Wenn ich eine zweite Tabelle in derselben Datenbank genau so importieren möchte, packe ich das in ein gemeinsames Makro oder sollen zwei Makros gebaut werden? Die Daten dürfen ruhig parallel importiert werden.

3. Ist die Verzögerung der Anzeige der importierten Daten darauf zurückzuführen, dass ca 5000 Datenzeilen hereingeholt werden? Oder geht das in der Regel schnell?

Dennoch, das Makro funktioniert und erleichtert meine bisherige Prozedere um ein Vielfaches!
Zuletzt geändert von Stegull am Fr 13. Jan 2023, 08:32, insgesamt 2-mal geändert.

RobertG
Beiträge: 2732
Registriert: Sa 19. Mai 2012, 17:37
Kontaktdaten:

Re: Daten einer Calc-Tabelle per Makro importieren

Beitrag von RobertG » Di 10. Jan 2023, 16:58

Der Import von Uhrzeiten muss da wohl noch entsprechend mit rein. Bei dem Import von Währungen müsste eigentlich das Ganze als Dezimalzahl importiert werden. Währungen sind reine Formatierungselemente und werden in der Datenbank nicht gespeichert.

Solange der Import klappt würde ich dem Zeitfaktor nicht zu viel Bedeutung schenken. Verläuft der denn proportional zu den eingelesenen Datensätzen (doppelte Datensatzzahl - doppelte Zeit)? Kann ja auch sein, dass erst einmal das Auslesen der Struktur braucht, bevor das Ganze läuft.

Wenn Du ein zweite Paar Tabellen nutzen willst, dann ändere das Makro doch so, dass Du die betreffenden Tabellen entweder aus dem Importbutton löst oder dem Makro als Variablen direkt mit gibst. Du kannst ja so starten:

Code: Alles auswählen

SUB Import1(oEvent AS OBJECT)
	CalcDataImport(oEvent, "Tabelle1 aus Calc", "Tabelle1 in HSQLDB")
END SUB

SUB Import2(oEvent AS OBJECT)
	CalcDataImport(oEvent, "Tabelle2 aus Calc", "Tabelle2 in HSQLDB")
END SUB

Sub CalcDataImport(oEvent AS OBJECT, Tabelle1 AS STRING, Tabelle2 AS STRING)
…
Ich habe einmal das Ganze so in die Beispieldatenbank eingebaut, dass es funktioniert. Auch die Angabe von Zeiten funktioniert jetzt. Die Daten sind bereits eingelesen. Die Tabellen in der Datenbankdatei leeren und dann neu einlesen.
Dateianhänge
Datenimport.zip
Datenbank und Calc-Datei
(25.6 KiB) 52-mal heruntergeladen
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

Stegull
Beiträge: 37
Registriert: Di 6. Dez 2022, 13:36

Re: Daten einer Calc-Tabelle per Makro importieren

Beitrag von Stegull » Di 10. Jan 2023, 18:12

Robert,

nun muss ich mich kräftig konzentrieren, um deine Antwort zu verstehen. Ich versuche es mal:

Schritt A - Makro-A "Daten CalcTab1 in BaseTab1"
Schritt B - Makro-B "Daten CalcTab2 in BaseTab2"
Schritt C - Makro-C (Makro A und B hintereinander ausführen)

Das Beispiel-Makro aus der Beispieldatenbank "Beispiel_Daten_Import_Hsqldb" ist sehr lang und ich verstehe nicht wirklich was da steht.

Die Zeitangaben sind nicht proportional zu den Datensätzen. Die Zeitangaben beziehen sich auf einen Datensatz (Terminbeginn). Manche Datensätze gehören zusammen über eine Auftragsnummer. Das ausgegebene Roh-Format (Exel-Tabelle aus einem Anwenderprogramm) sieht so aus "02.02.2023 16:00:00" (Klick in Zelle und aus Eingabezeile kopiert), dieses wird über eine 1zu1-Verknüpfung in CalcTab1 übertragen und von dort aus soll es nach Base importiert werden.
Der Umweg über die CalcTabelle ist notwendig, weil mein Anwenderprogramm die Roh-Tabellen nur in DezimalFormat exportiert. In der CalcTabelle wird das Format bestimmt, womit die BaseTabelle dann gefüllt wird.

Jetzt vermute ich, es gibt bestimmt einen effektiveren Weg.

Update:
Gerade gesehen dass du nochmal editiert hast. Probier ich nachher mal aus. Vielen Dank im Vorraus.

RobertG
Beiträge: 2732
Registriert: Sa 19. Mai 2012, 17:37
Kontaktdaten:

Re: Daten einer Calc-Tabelle per Makro importieren

Beitrag von RobertG » Di 10. Jan 2023, 19:23

In meinem Beispiel ist die Zeit ein reines Zeitfeld. Da müsste also noch ein Feld dazu, das eine Datums-Zeit-Kombination ergibt. In der HSQLDB ist das der TIMESTAMP. Muss ich einmal schauen - dürfte aber kein Problem sein, da Calc das Datum sowieso als Dezimalzahl weiter gibt.

Die Formatierung in Calc spielt für den Import keine Rolle. Datum und Zeit werden immer als Dezimalzahl ausgedrückt und transportiert.

Habe den Import nicht hur der zeit sondern auch des Timesatmp-Feldes erstellt.
Dateianhänge
Datenimport.zip
Import auch von Timestamp
(25.59 KiB) 39-mal heruntergeladen
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

Stegull
Beiträge: 37
Registriert: Di 6. Dez 2022, 13:36

Re: Daten einer Calc-Tabelle per Makro importieren

Beitrag von Stegull » Do 12. Jan 2023, 21:34

Hallo Robert,

hab nun alles eingebaut und es funktioniert tadellos! Für meinen bisherigen Ablauf bedeutet das eine unglaubliche Einsparung an Arbeitsschritten und Zeit.
Auch habe ich erkannt, dass der Umweg der Konvertierung der Exeltabellen in das CalcFormat überflüssig war. Auch hier geht es jetzt sehr viel schneller.

Recht herzlichen Dank!

Stegull
Beiträge: 37
Registriert: Di 6. Dez 2022, 13:36

Re: (gelöst) Daten einer Calc/Exel-Tabelle per Makro importieren

Beitrag von Stegull » Fr 13. Jan 2023, 11:36

Ich muss jetzt doch noch einmal intervenieren.

Da das Makro von RobertG sich auf zwei Tabellen innerhalb einer Datei bezieht musste mein Projekt anders konfiguriert werden. Bei mir gibt es zwei Tabellen in zwei getrennten Dateien. Der Import erfolgt also aus zwei Exel-Dateien (Tabelle1 und Tabelle2). Beide Importe werden per Schaltfläche in einem Formular aktiviert, erfordern somit zwei Arbeitsschritte.

Ist es möglich, beide Makros miteinander zu verknüpfen, dass sie gemeinsam, oder auch hintereinander, ablaufen?

Aus zwei Arbeitsschritten einen zu machen?

RobertG
Beiträge: 2732
Registriert: Sa 19. Mai 2012, 17:37
Kontaktdaten:

Re: (gelöst) Daten einer Calc/Exel-Tabelle per Makro importieren

Beitrag von RobertG » Fr 13. Jan 2023, 17:21

Du musst jetzt lediglich den Namen der Tabellenkalkulationsdatei-Datei aus dem umfangreichen Code heraus auslagern:

Code: Alles auswählen

stDir = ConvertToUrl(stDir & "Daten_Calc.ods")
muss zu so etwas werden wie

Code: Alles auswählen

stDir = ConvertToUrl(stDir & stCalc)
Für den Aufruf muss dann auch diese Variable mit angegeben werden:

Code: Alles auswählen

Sub CalcDataImport(oEvent AS OBJECT, stBaseTab AS STRING, stCalcTab AS STRING, stCalc AS STRING)
Und das wird aufgerufen aus

Code: Alles auswählen

SUB Import1_Start(oEvent AS OBJECT)
	CalcDataImport(oEvent, "tbl_Dez_Dat_NULL", "Tab_Dez_Dat_NULL", "Daten_Calc.ods")
END SUB

SUB Import2_Start(oEvent AS OBJECT)
	CalcDataImport(oEvent, "tbl_Dat_Zeit", "Tab_Dat_Zeit", "Daten_Calc_2.ods")
END SUB
Also 2 Tabellenkalkulationsdateien als Ausgangspunkt.

Soll das alles über nur einen Button aufgerufen werden, so geht dann

Code: Alles auswählen

SUB Import1_Start(oEvent AS OBJECT)
	CalcDataImport(oEvent, "tbl_Dez_Dat_NULL", "Tab_Dez_Dat_NULL", "Daten_Calc.ods")
	CalcDataImport(oEvent, "tbl_Dat_Zeit", "Tab_Dat_Zeit", "Daten_Calc_2.ods")
END SUB
Wenn Dir das mit den Namen für die Tabellen in den Calc-Dateien zu kompliziert ist und die Tabelle wirklich immer auf dem ersten Blatt liegt, dann kannst Du natürlich wie vorher auch die Calc-Tabelle über

Code: Alles auswählen

oDoc.Sheets(0)
statt

Code: Alles auswählen

oDoc.Sheets.getByName(stCalcTab)
ermitteln.

Gruß

Robert
Dateianhänge
Datenimport_1.zip
Import aus 2 versch. Tabellenkalkulationsdateien
(34.99 KiB) 41-mal heruntergeladen
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

Stegull
Beiträge: 37
Registriert: Di 6. Dez 2022, 13:36

Re: (gelöst) Daten einer Calc/Exel-Tabelle per Makro importieren

Beitrag von Stegull » Di 17. Jan 2023, 20:44

Hallo Robert,

ich verstehe das nicht so recht.
Ich habe ein bisschen herumgefrickelt mit deinen obigen Informationen und dem Code aus der Beispieldatenbank. Dabei ist dieser "nicht funktionierende" Code herausgekommen.

Code: Alles auswählen

SUB Import1_Start(oEvent AS OBJECT)
        CalcDataImport(oEvent, "Auftragliste.xlsx")
        CalcDataImport(oEvent, "Auftragdetailliste.xlsx")
END SUB


Sub CalcDataImport(oEvent AS OBJECT, stBaseTab AS STRING, stCalcTab AS STRING, stCalc AS STRING)
	DIM oDatasource AS OBJECT
	DIM oConnection AS OBJECT
	DIM oSQL_Command AS OBJECT
	DIM oResult AS OBJECT
	DIM oDB AS OBJECT
	DIM oDoc AS OBJECT
	DIM oDocView AS OBJECT
	DIM oRange AS OBJECT
	DIM Arg()
	DIM aColumn()
	DIM aColumns()
	DIM aType()
	DIM stSql AS STRING
	DIM stRow AS STRING
	DIM stDir AS STRING
	DIM stColumns AS STRING
	DIM stStartCol AS STRING
	DIM stEndCol AS STRING
	DIM stStartRow AS STRING
	DIM stEndRow AS STRING
	DIM stRange AS STRING
	DIM inCounter AS INTEGER
	DIM loColumns AS LONG
	DIM loRows AS LONG
	DIM loID AS LONG
	oDatasource = ThisComponent.Parent.CurrentController
	If NOT (oDatasource.isConnected()) THEN
		oDatasource.connect()
	END IF
	oConnection = oDatasource.ActiveConnection()
	oSQL_Command = oConnection.createStatement()
	' Spaltennamen und Spaltentypen aus der Tabelle der Datenbank auslesen. "ID" ist als Primärschlüssel vorgesehen.
	stSql = "SELECT COLUMN_NAME, TYPE_NAME FROM INFORMATION_SCHEMA.SYSTEM_COLUMNS WHERE TABLE_NAME = '"+stBaseTab+"' AND NOT COLUMN_NAME = 'ID'"
	oResult = oSQL_Command.executeQuery(stSql)
	inCounter = 0
	stColumns = ""
	' Spaltennamen und Spaltentypen in getrennten Arrays speichern. Ginge auch in einem zweidimensionalen Array
	WHILE oResult.next
		ReDim Preserve aColumn(inCounter)
		ReDim Preserve aType(inCounter)
		aColumn(inCounter) = oResult.getString(1)
		aType(inCounter) = oResult.getString(2)
		inCounter = inCounter+1
	WEND
	stSql = "SELECT MAX(""ID"") FROM """+stBaseTab+""""
	oResult = oSQL_Command.executeQuery(stSql)
	WHILE oResult.next
		loID = oResult.getInt(1) + 1
	WEND
	' Pfad zur Calc-Datei ermitteln. Liegt hier im gleichen Verzeichnis wie die Datenbankdatei
	oDB = ThisComponent.Parent
	stDir = Left(oDB.Location,Len(oDB.Location)-Len(oDB.Title))
	stDir = ConvertToUrl(stDir & stCalc)
	' Calcdatei laden und auf unsichtbar schalten
	oDoc = StarDesktop.loadComponentFromURL(stDir,"_blank", 0, Arg() )
	oDocView = oDoc.CurrentController.Frame.ContainerWindow
	oDocView.Visible = False
	' Position des beschrifteten Bereichs im Tabellenblatt ermitteln
	loColumns = uBound(oDoc.Sheets(0).ColumnDescriptions)	' Anzahl der Spalten
	stStartCol = split(oDoc.Sheets(0).ColumnDescriptions(0))(1)
	stEndCol = split(oDoc.Sheets(0).ColumnDescriptions(loColumns))(1)
	loRows = uBound(oDoc.Sheets(0)).RowDescriptions)	' Anzahl der Zeilen
	stStartRow = split(oDoc.Sheets(0)).RowDescriptions(0))(1)
	stEndRow = split(oDoc.Sheets(0)).RowDescriptions(loRows))(1)
	stRange = stStartCol & stStartRow & ":" & stEndCol & StEndRow
	' Beschrifteten Bereich als Datenquelle nutzen. Dabei wird davon ausgegangen, dass in der ersten beschrifteten Zeile die Spaltennamen stehen
	oRange = oDoc.Sheets(0)).getCellRangeByName(stRange)
	aDat = oRange.getDataArray()
	' Spaltennamen stehen in der ersten Zeile und können eine andere Reihenfolge haben als in der Tabelle der Datenbank.
	aColumns = aDat(0)
	FOR i = 1 TO uBound(aDat)	'0 wären die Spaltenüberschriften
		aRow = aDat(i)
		stColumns = """ID"""
		stRow = loID
		FOR k = 0 TO loColumns
			FOR n = 0 TO uBound(aColumn)
				IF aColumns(k) = aColumn(n) THEN	' Nur Spalten, die in der Datenbank mit gleichem Namen vorhanden sind, werden auch eingelesen.
					IF aType(n) = "DECIMAL" THEN
						IF aRow(k) <> "" THEN
							aRow(k) = Str(CDbl(aRow(k)))
						END IF
					END IF
					IF aType(n) = "DATE" THEN 'Datumsfeld
						IF isDate(CDate(aRow(k))) AND aRow(k) <> "" THEN
							aRow(k) = Year(CDate(aRow(k))) & "-" & Right("0" & Month(CDate(aRow(k))), 2) & "-" & Right("0" & Day(CDate(aRow(k))), 2)
						ELSE
							aRow(k) = ""
						END IF
					END IF
					IF aType(n) = "TIME" THEN 'Zeitfeld
						IF isDate(CDate(aRow(k))) AND aRow(k) <> "" THEN
							aRow(k) = Right("0" & Hour(CDate(aRow(k))), 2) & ":" & Right("0" & Minute(CDate(aRow(k))), 2) & ":" & Right("0" & Second(CDate(aRow(k))), 2)
						ELSE						
							aRow(k) = ""
						END IF
					END IF
					IF aType(n) = "TIMESTAMP" THEN 'Datum und Zeit
						IF isDate(CDate(aRow(k))) AND aRow(k) <> "" THEN
							aRow(k) = Year(CDate(aRow(k))) & "-" & Right("0" & Month(CDate(aRow(k))), 2) & "-" & Right("0" & Day(CDate(aRow(k))), 2) & " " & Right("0" & Hour(CDate(aRow(k))), 2) & ":" & Right("0" & Minute(CDate(aRow(k))), 2) & ":" & Right("0" & Second(CDate(aRow(k))), 2)
						ELSE						
							aRow(k) = ""
						END IF
					END IF
					IF aRow(k) = "" THEN
						aRow(k) = "NULL"
					ELSE
						aRow(k) = "'" & aRow(k) & "'"
					END IF
					stRow = stRow & "," & aRow(k)
					stColumns = stColumns & ",""" & aColumns(k) & """"
				END IF
			NEXT
		NEXT
		stSql = "INSERT INTO """+stBaseTab+""" ("& stColumns &") VALUES ("& stRow &")"
		oSQL_Command.executeUpdate(stSql)
		loID = loID + 1
	NEXT
	oDoc.close(True)	' Schließen des Calc-Documentes
	oEvent.Source.Model.parent.reload()	' Neuladen des Formulars
End Sub
Die aus der Anwendersoftware exportierten Exeldateien "Auftragliste.xlsx" und "Auftragdetailliste" mit der Tabelle "Sheets", (erstes Blatt) liegen im selben Ordner wie die Datenbank.

Ich bekomme Fehlermeldungen, die ich nicht verstehe.

RobertG
Beiträge: 2732
Registriert: Sa 19. Mai 2012, 17:37
Kontaktdaten:

Re: (gelöst) Daten einer Calc/Exel-Tabelle per Makro importieren

Beitrag von RobertG » Di 17. Jan 2023, 21:24

Die Prozedur CalcDataImport erwartet 4 Parameter: Das auslösende Ereignis, den Namen der Tabelle in der Datenbank, den Namen der Tabelle in Calc und die Calc-Datei. Bei Dir fehlen der Tabellenname in der Datenbankdatei und der Tabellenname in der Calc-Datei.

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

Stegull
Beiträge: 37
Registriert: Di 6. Dez 2022, 13:36

Re: (gelöst) Daten einer Calc/Exel-Tabelle per Makro importieren

Beitrag von Stegull » Di 17. Jan 2023, 21:46

Robert,

meinst du so?
Dateianhänge
1.JPG
1.JPG (32.56 KiB) 837 mal betrachtet

An alle, die das LibreOffice-Forum nutzen:


Bitte beteiligen Sie sich mit 7 Euro pro Monat und helfen uns bei unserem Budget für das Jahr 2024.
Einfach per Kreditkarte oder PayPal.
Als Dankeschön werden Sie im Forum als LO-SUPPORTER gekennzeichnet.

❤️ Vielen lieben Dank für Ihre Unterstützung ❤️

Antworten