[gelöst] Können Makros dateiübergreifend aufgezeichnet werden?

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

kilix
****
Beiträge: 128
Registriert: So, 09.04.2023 11:27

[gelöst] Können Makros dateiübergreifend aufgezeichnet werden?

Beitrag von kilix »

Moderatorenhinweis: Thema verschoben in den Bereich "Makros und allgemeine Programmierung" , Toxitom


Hallo,
ich arbeite an eine Calc-Applikation die Daten als CSV-Dateien aus einem großen Vorsystem bezieht. Die CSV-Datei kann ich leicht in eine CALC-Tabelle konvertieren. Dann muss ich sie selektiv in eine andere Calc-Tabelle (die Verknüfungen und Formeln enthält) übernehmen. Selektiv heißt, dass ich inaktive Zeilen (Datensätze) entfernen muss und dann einzelne Spalten der CSV-Tabelle in meine Calc-Tabelle kopieren muss.
Das ganze sollte, für den Anwender einfach, mitteles eines Makros erfolgen.
Ich habe nun probiert so einen Makro mitzuschreiben, was an sich kein Problem darstellt solange ich nur Bereiche, Zellen usw. der Calc-Tabelle anspreche. Sobald ich aber von der Calc-Tabelle aus auf Zellen der aus der CSV-Datei konvertierten Tabelle zugreifen will geht es nicht mehr (solche Aktionen werden nicht mitaufgezeichnet).
Gibt es eine Möglichkeit mit einem Makro der Calc-Tabelle z.B. auch Zellen der CSV-Tabelle in die Calc-Tabelle zu kopieren?
Zuletzt geändert von kilix am Sa, 06.05.2023 18:45, insgesamt 1-mal geändert.
Grüße
kilix
kilix
****
Beiträge: 128
Registriert: So, 09.04.2023 11:27

Re: Können Makros dateiübergreifend aufgezeichnet werden?

Beitrag von kilix »

Hallo,
ich kann mir gleich selbst antworten, zumindest kann ich berichten was mir gelungen ist:
ich habe die aus der CSV-Textdatei konvertierte CSV-Tabelle als Calc Tabelle, also mit Extension ODS gespeichert und dann einen kleinen Makro generiert, der in meiner Calc-Tabelle gespeichert ist und der eine Spalte aus der konvertierten ODS-Tabell in meine Calc-Tabelle kopiert. Das hat jetzt einwandfrei funktioniert.
Es ist also, dass Makros nur funktionieren wenn beide Tabellen im ODS-Format vorhanden sind. Aus CSV-Dateien konvertierte Tabellen müssen zuerst als ODS-Tabellen gespeichert werden.
Ich weiß nicht ob das die Frage komplett beantwortet odr ob es noch weiteres dazu zu wissen gibt, aber für's erste passt das.

Da schließt sich eine weitere Frage an: als ich diesen Makro zur Ausführung aufrief erhielt ich (obwohl ich heute schon andere Makros laufen ließ, die Meldung, dass meine Java-Umgebung einen Fehler hätte. Ich habe darauf die bestehende (und auch schon veraltete Jave-Version) deinstalliert und die neuen Verionen jre-8u371-windows-x64 und jre-8u371-windows-i586 geholt und installiert. Ich habe beide installiert weil in den BASE-Tutorial (das ich hier fand) gesagt wurde, dass OO die 32bit-Version braucht und diese daher auch installiert werden muss. Dann habe ich die neue Version mit Extras-Einstellungen eingestellt. Trotzdem bekomme ich die oben genannte Fehlermeldung wieder. Allerdings funktioniert das Makro nach Quittierung der Meldung trotzdem.

Edit:
da habe ich mich doch zu früh gefreut! Nach einem Neustart des Systems bekam ich zwar die Java-Fehlermeldung nicht mehr aber das Makro funktioniert auch nicht mehr. Ich kann zwar die Makrosprache von OO nicht aber es sieht so aus also ob im Code die andere Tabelle gar nicht adressiert wird.
Es funktioniert also doch nicht - oder hab ich was falsch gemacht?
Grüße
kilix
Hiker
******
Beiträge: 590
Registriert: Mo, 08.09.2014 21:34
Wohnort: Berlin

Re: Können Makros dateiübergreifend aufgezeichnet werden?

Beitrag von Hiker »

kilix hat geschrieben: Mo, 01.05.2023 14:08 ...
Es ist also, dass Makros nur funktionieren wenn beide Tabellen im ODS-Format vorhanden sind. Aus CSV-Dateien konvertierte Tabellen müssen zuerst als ODS-Tabellen gespeichert werden.
Ich weiß nicht ob das die Frage komplett beantwortet odr ob es noch weiteres dazu zu wissen gibt, aber für's erste passt das.
Ist aber leider falsch. Es mag ja sein, dass Du manches nicht aufzeichnen kannst (der MakroRecorder macht durchaus Fehler und bekommt manches nicht mit) und Du kannst definitiv kein Macro funktionsfähig in einer csv-Datei unterbringen, aber Macros, die auf andere Dateien zugreifen sind definitiv möglich.
... . Ich kann zwar die Makrosprache von OO nicht aber es sieht so aus also ob im Code die andere Tabelle gar nicht adressiert wird.
Es funktioniert also doch nicht - oder hab ich was falsch gemacht?
Der wesentliche Fehler ist den Code hier nicht zur Verfügung zu stellen. Wenn Du vorher hier die Schaltfläche </> verwendest bleibt er sogar lesbar.

Evtl. interessant:
https://forum.openoffice.org/en/forum/v ... hp?t=23727

https://forum.openoffice.org/en/forum/v ... p?t=108073
Libre Office 6.3.1 (Win 10 Pro) / Libre Office 6.0.7 (Win8.1 Pro, Win 7 Pro) / AOO (Win 7)
kilix
****
Beiträge: 128
Registriert: So, 09.04.2023 11:27

Re: Können Makros dateiübergreifend aufgezeichnet werden?

Beitrag von kilix »

Danke für die Antwort! Ich habe jetzt 2 Tests gemacht:
1) die CSV-Datei aufgerufen
2) ODS-Datei aufgerufen und mit Makro aufzeichnen den Inhalt der CSV-Datei in die ODS-Datei kopiert (beginnednd an einer definierten Stelle)
3) die ODS-Datei gespeichert
4) den Makro unter Meine Makros gespeichert.
5) OO heruntergefahren und neu gestartet
6) die CSV-Datei und die ODS-Datei aufgerufen
7) den Makro aus der ODS-Datei gestartet.
Ergebnis:
Makro1.jpg
Makro1.jpg (6.75 KiB) 2446 mal betrachtet
Daten wurden keine eingefügt, nur der einzufügende Bereich mit einem Rahmen versehen

Im 2. Test habe ich das gleiche gemacht aber die Zellen aus einer ODS-Datei kopiert.
Ergebnis:
Makro2.jpg
Makro2.jpg (5.81 KiB) 2446 mal betrachtet
Auch diesmal wurden keine Daten kopiert.

Hier ist das Makro1 zum ersten Test:

Code: Alles auswählen

sub Test1
rem ----------------------------------------------------------------------
rem define variables
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

rem ----------------------------------------------------------------------
dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "ToPoint"
args1(0).Value = "$X$2"

dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args1())

rem ----------------------------------------------------------------------
dispatcher.executeDispatch(document, ".uno:Paste", "", 0, Array())

rem ----------------------------------------------------------------------
dim args3(0) as new com.sun.star.beans.PropertyValue
args3(0).Name = "ToPoint"
args3(0).Value = "$A$3"

dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args3())

end sub
und hier das Makro zum 2. Test:

Code: Alles auswählen

sub Test2
rem ----------------------------------------------------------------------
rem define variables
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

rem ----------------------------------------------------------------------
dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "ToPoint"
args1(0).Value = "$X$2"

dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args1())

rem ----------------------------------------------------------------------
dispatcher.executeDispatch(document, ".uno:Paste", "", 0, Array())

rem ----------------------------------------------------------------------
dim args3(0) as new com.sun.star.beans.PropertyValue
args3(0).Name = "ToPoint"
args3(0).Value = "$R$12"

dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args3())

end sub
Ich möchte mich schon im Vorhinein für eure Hilfe bedanken!
Grüße
kilix
mikeleb
*******
Beiträge: 1316
Registriert: Fr, 09.12.2011 16:50

Re: Können Makros dateiübergreifend aufgezeichnet werden?

Beitrag von mikeleb »

Hallo,
das aufgezeichnet Makro mach tnichts anderes als in der ods-Datei in die Zelle X2 zu gehen und dort den Inhalt der Zwischenablage einzufügen.
Beim ersten Versuch klappt das, weil die kopierten Zellen der csv noch in der Zwischenablage sind.
Kurz: mit dem Makrorekorder wirst du keine Erfolg haben.
Gruß,
mikeleb
kilix
****
Beiträge: 128
Registriert: So, 09.04.2023 11:27

Re: Können Makros dateiübergreifend aufgezeichnet werden?

Beitrag von kilix »

Ja, mikeleb, genau das habe ich mir nach weiteren Versuchen gedacht. Denn erstens hat es nur funktioniert solange OO nicht geschlossen wurde. D.h. es wurde immer der selbe Inhalte der Zwischenablage vom Erstellen des Makro mit dem Makrorecorder eingelesen. Sobald ich aber OO beendet und wieder aufgerufen hatte wurde nichts kopiert. Zum Zweiten fehlt mir jeder Hinweise auf die Datei aus der ich den Bereich kopieren will (soweit hab ich den Code schon verstanden, wenn ich ihn auch sonst kaum verstehe).
D.h., um dieses Aufgabe mit einem Makro lösen zu können müsste ich den Code für den Makro erstellen. Ich habe zwar schon Basic programmiert (zuletzt FreeBasic) aber das hier verwendete Basic verstehe ich ohne Anleitung nicht. Ich habe zwar schon Im Internet nach einer Anleitung gesucht aber noch nicht gefunden.
Ich habe zwar hier https://users.de.openoffice.narkive.com ... i-kopieren einen Code gefunden, der einen Bereich einer Datei in die Zwischenablage kopieren soll und einen zweiten Code der die Zwischenablage in die andere Datei speichern soll. Aber auch hier finde ich keine Dateinamen etc.
Grüße
kilix
mikeleb
*******
Beiträge: 1316
Registriert: Fr, 09.12.2011 16:50

Re: Können Makros dateiübergreifend aufgezeichnet werden?

Beitrag von mikeleb »

Hallo,
da ich gerade so ein ähnliches Makro da hatte, mal ein Beispiel, wie es aussehen könnte.
Wenn du die Sub csv_import aufrufst, öffnet sich ein Dialog zum Auswählen und Öffnen der cvs-Datei. Aus dieser werden die Daten aus der 1. Tabelle Zellen B1:B20 ausgelesen und in die odt-Datei, 1.Tabelle Zellen D11:D30 geschrieben.

Code: Alles auswählen

Sub csv_import

	'Zugriff auf die aktuelle Datei
	oDoc=ThisComponent
	
	'Öffnen der csv-Datei
	Dim args(1) as New com.sun.star.beans.PropertyValue
	args(0).Name= "FilterName"
	args(0).Value = "Text - txt - csv (StarCalc)"
	
	'ASCII-Codes 44 (Komma), 32 (Leerzeichen), 9 (Tabulator)
	'Mehrfachauswahl durch / trennen, z. B. 44/9
	sFeldSeparator="44"
	'ASCII-Codes 34 (doppelte Hochkomma), 39 (einfache Hochkomma)
	sTextBegrenzer="34"
	'Systemzeichensatz 0
	sZeichensatz="0"
	'erste einzulesende Zeile
	sErste="1"
	'Spaltenformat für jede Spalte festlegen
	'Spalte/Format/Spalte/Format/...
	'Formate: 1 Standard, 2 Text, 3 Datum (MTJ), 4 Datum (TMJ), 5 Datum (JMT), 9 nicht importieren, 10 US-englisch
	'nicht aufgeführte Spalten werden als Standard importiert
	sSpaltenFormate="1/1/2/1/3/1/4/1"
	args(1).Name="FilterOptions"
	args(1).Value =sFeldSeparator & "," & sTextBegrenzer & "," & sZeichensatz & "," & sErste & "," & sSpaltenformate
	'Dialog zur Dateiauswahl
	'ein Startverzeichnis kann optional vorgegeben werden
	sUrl= FileOpenDialog("csv-Datei auswählen","")
	if isarray(sUrl) then
			oCSV=StarDesktop.LoadComponentFromURL(sUrl(0), "_blank",0,args())
	end if
	'Auslesen der Daten in ein Array der Daten
	aDaten=oCSV.Sheets(0).getCellRangeByName("B1:B20").getDataArray
	'Schreiben der Daten in die aktuelle Datei
	oDoc.Sheets(0).getCellRangeByName("D11:D30").setDataArray(aDaten)
	
End Sub

function FileOpenDialog(sTitle as String, optional sStartverzeichnis as string) 
    if ismissing(sStartverzeichnis) then
    	oPS=CreateUnoService("com.sun.star.util.PathSettings")
    	sStartverzeichnis=oPS.work
    end if
    oFilepicker = createUnoService("com.sun.star.ui.dialogs.FilePicker")
    oFilepicker.Title = sTitle  
    oFilepicker.appendFilter("Alle Dateien", "*.*")
    oFilepicker.appendFilter("csv-Dateien", "*.csv")
    oFilepicker.setCurrentFilter("csv-Dateien")
	oFilepicker.setMultiSelectionMode(true)
	oFilepicker.setDisplayDirectory(converttourl(sStartverzeichnis)) 	
	if oFilepicker.execute()=1 then
		FileOpenDialog = oFilepicker.getSelectedFiles()
	else
		FileOpenDialog=""
	end if
End function
Dateianhänge
beispiel_csv_auslesen.ods
(8.92 KiB) 82-mal heruntergeladen
Gruß,
mikeleb
Hiker
******
Beiträge: 590
Registriert: Mo, 08.09.2014 21:34
Wohnort: Berlin

Re: Können Makros dateiübergreifend aufgezeichnet werden?

Beitrag von Hiker »

kilix hat geschrieben: Di, 02.05.2023 18:44 ... Ich habe zwar schon Basic programmiert (zuletzt FreeBasic) aber das hier verwendete Basic verstehe ich ohne Anleitung nicht. Ich habe zwar schon Im Internet nach einer Anleitung gesucht aber noch nicht gefunden.
...
Basic dürfte Dir kaum Probleme machen, aber die Library (UNO) in der LibreOffice/ OpenOffice/ StarOffice den Zugang zu den Dokumenten und Strukturen verpackt ist "etwas" unübersichtlich. Ausserdem sind Ansätze wie Objektorientierung, Unicode, Modularisierung bei BASIC nicht gerade systemimmanent...

Startpunkte:
Dannenhöfer:
http://www.dannenhoefer.de/faqstarbasic/index.html

Pitonyak
https://www.pitonyak.org/oo.php
(es gibt auch eine deutsche Übersetzung)

und eine "Sammelfrage":
https://ask.libreoffice.org/t/libreoffi ... ning/74539
Libre Office 6.3.1 (Win 10 Pro) / Libre Office 6.0.7 (Win8.1 Pro, Win 7 Pro) / AOO (Win 7)
kilix
****
Beiträge: 128
Registriert: So, 09.04.2023 11:27

Re: Können Makros dateiübergreifend aufgezeichnet werden?

Beitrag von kilix »

@ mikeleb
danke für dieses Beispiel! Nachdem ich die Daten aus einem Vorsysten als CSV-Datei erhalte könnte mir das eine Zwischentabelle ersparen. Ich werde mir das Beispiel genau ansehen.

@Hiker
ja, mit der Aussage zu Basic und die Library (UNO) etc. hast du recht! Die Dokumente von Dannenhöfer und Pitoniak habe ich mir schon etwas angesehen aber da durchzukommen wird etwas dauern.

Auf jeden Fall ein herzliches Dankeschön für eure Hilfe! Auch wenn ich mich jetzt länger nicht melde, ich bleibe dran!
Grüße
kilix
kilix
****
Beiträge: 128
Registriert: So, 09.04.2023 11:27

Re: Können Makros dateiübergreifend aufgezeichnet werden?

Beitrag von kilix »

@ mikeleb
nochmals herzlichen Dank für dieses Makro! ich habe es leicht modifiziert weil ich von den 18 Spalten der CSV-Datei nur 5 benötige. Dazu habe ich die Zeilen für Ein- und Auslesen kopiert und in jede Zeile den entsprechenden Bereich eingetragen. Und das funktioniert auch wenn die Ausgabe auf eine Tabelle erfolgt, die im vorderen Bereich schon Daten enthält. Den Rest der noch notwendig ist, nämlich das Löschen der gerade eingelesenen Zeilen wenn in der Spalte Inaktivdatum ein Datum eingetragen ist. Das hatte ich schon mit Makroaufzeichnen gelöst oder ginge das auch schon beim Übernehmen der Bereiche wobei ich allerdings die Schwierigkeit sehe weil ich in mehreren Teilbereichen einlese in denen diese Spalte gar nicht vorkommt.
Ein echtes Problem ist, dass bei Übernehmen der Texte die Umlaute nicht richtig angezeigt werden sondern Sonderzeichen zeigen. Bei der manuellen Konvertierung hatte ich den Zeichensatz auf Unicode (UTF-8) gesetzt.

Edit: das Problem mit dem Zeichensatz konnte ich lösen, habe eine Internetseite zu LibreOffice gefunden, die eine Liste der Codes enthält.
https://help.libreoffice.org/latest/de/ ... arams.html
Grüße
kilix
kilix
****
Beiträge: 128
Registriert: So, 09.04.2023 11:27

Re: Können Makros dateiübergreifend aufgezeichnet werden?

Beitrag von kilix »

Mit Hilfe des Codes von mikeleb konnte ich die aus der CSV-Datei zu holenden Spalten problemlos in die ODS-Tabelle übertragen. Die im folgenden benötigten Verarbeitungen kann ich aufzeichnen und in dieses Makro integrieren. Da sehe ich kein Problem weil ich diese Verarbeitungen schon mit einem aufgezeichneten Makro gelöst habe.
Was die Aufzeichnung allerdings stört ist, dass nach der Übernahme der Daten aus der CSV-Datei die Tabelle datei.csv am Schirm zu sehen ist und nicht die Datei datei.ods, die die Daten empfangen hat. Ich habe versucht diesen Wechsel mit Fenster und Auswahl der anderen Tabelle aufzuzeichnen. Das habe ich testweise zwischen zwei ods-Dateien gemacht weil man in der csv-datei keine Macros aufzeichnen kann. Leider wurde dabei gar nichts aufgezeichnet. Offenbar lässt sich dieser Vorgang nicht aufzeichnen.
In diesem Fall würde es mir schon genügen wenn die Datei datei.csv geschlossen würde weil ich sie nicht mehr benötige.
Ich habe zwar einen Code gefunden mit dem man eine Datei schließen kann aber zu diesem Zeitpunkt wird im Macro die ODS-Datei referenziert und daher diese geschlossen. Ich weiß nicht wie ich den Bezug wieder auf die CSV-Datei legen kann.
Grüße
kilix
Hiker
******
Beiträge: 590
Registriert: Mo, 08.09.2014 21:34
Wohnort: Berlin

Re: Können Makros dateiübergreifend aufgezeichnet werden?

Beitrag von Hiker »

Da Du Deinen Code nicht hier eingesetzt hast, kommentiere ich mikeles...

Der Code kennt 2 referenzen, einmal oDoc, abgeleitet aus ThisDocument am Anfang und oCSV, der beim Öffnen des zweiten documents zurückgegeben wurde. Mit diesen kannst Du sie auch schliessen.

Falls Du natürlich einen Code gefunden hast, mit dem das "aktive" Dokument, das den Eingabefokus hat, geschlossen wird, müsstest Du den Fokus entsprechend anpassen, oder anderen Code suchen/finden.
Libre Office 6.3.1 (Win 10 Pro) / Libre Office 6.0.7 (Win8.1 Pro, Win 7 Pro) / AOO (Win 7)
mikeleb
*******
Beiträge: 1316
Registriert: Fr, 09.12.2011 16:50

Re: Können Makros dateiübergreifend aufgezeichnet werden?

Beitrag von mikeleb »

Hallo,

Code: Alles auswählen

oCSV.close(false)
Gruß,
mikeleb
kilix
****
Beiträge: 128
Registriert: So, 09.04.2023 11:27

Re: Können Makros dateiübergreifend aufgezeichnet werden?

Beitrag von kilix »

@mikeleb und Hiker,
dank eurer Hilfe funktioniert das Makro jetzt gut. Nach dem Kopieren der Bereiche aus der csv-Datei in die entsprechenden Bereiche der ods-Datei wird die csv-Datei geschlossen. Jetzt kann ich den Rest des "Zellenschaufelns", wie schon früher gemacht, als Makro aufzeichnen.
Allerdings wäre es für den Anwender gut wenn er die csv-Datei nicht aus der Liste wählen muss sondern die csv-Datei von selbst geöffnet wird, da es immer die gleiche Datei ist (wenn sich auch der Inhalt ändert).
D.h. der im folgenden Code (der nur eine Anpassung des Codes von Mikeleb ist) soll der mit ************ markierte Code durch ein "open file" ersetzt werden. D.h. die csv-Datei wird geöffnet, ohne dass der Anwender es merkt.
Ich habe zwar versucht das aus verschiedenen Beispielen, die ich im Netz gefunden habe "zusammenzubauen" hatte aber keinen Erfolg.

Wenn dieses Makro so funktioniert dürfte es für mich kein Problen sein es für andere Bereichsübertragungen zwischen 2 ods-Dateien zu adaptieren (nehme ich zumindest an).

Nochmals vielen Dank für eure Hilfe und ich hoffe, dass ihr mir mit dem oben genannten auch weiterhelft, danke!
Grüße
kilix
kilix
****
Beiträge: 128
Registriert: So, 09.04.2023 11:27

Re: Können Makros dateiübergreifend aufgezeichnet werden?

Beitrag von kilix »

Ich hab es gefunden!
Im Internet habe ich den Code gefunden, der nach wenigen Adaptionen funktioniert hat. Im folgenden Code ist der Originalcode von mikeleb mit ' auf REM gesetzt und der von mir an seiner Stelle eingesetzte darunter geschrieben.

Code: Alles auswählen

'*****************************************************************
	'Dialog zur Dateiauswahl
	'ein Startverzeichnis kann optional vorgegeben werden
'	sUrl= FileOpenDialog("csv-Datei auswählen","")
'	if isarray(sUrl) then
'			oCSV=StarDesktop.LoadComponentFromURL(sUrl(0), "_blank",0,args())
'	end if
'*******************************************************************
    sURL = convertToURL("f:\SVSTST\Daten.csv")
    oCSV = StarDesktop.LoadComponentFromURL(sURL(0), "_blank", 0, args())
 '*******************************************************************
Das einzige was jetzt stört ist, dass man das komplette Verzeichnis in den Code schreiben muss. Das bedeutet, dass der Anwender diese Applikation auch auf diese Partition und in dieses Verzeichnis speichern muss. Die zu öffnende Datei liegt im gleichen Verzeichnis wie die geöffnete. Wenn man im Macro die Angabe der Partion und des Verzeichnissen umgehen könnte wäre das ein Hit!
Grüße
kilix
Antworten