🙏 Helfen Sie jetzt mit, unser LibreOffice Forum zu erhalten! 🙏
Mit Ihrer Spende sichern Sie den Fortbestand, den Ausbau und die laufenden Kosten dieses Forums. 🌱

🍀 Jeder Beitrag zählt – vielen Dank für Ihre Unterstützung!🍀

❤️ 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. 🤗

VBscript: Export von Calc-Blättern in CSV speichert ODS?!

Alles zur Programmierung im LibreOffice.
Antworten
LO-User
Beiträge: 11
Registriert: Fr 27. Jan 2012, 13:07

VBscript: Export von Calc-Blättern in CSV speichert ODS?!

Beitrag von LO-User » Mi 16. Mai 2012, 18:34

Hallo Leute,

ich bin jetzt schon seit 2 Tagen am Schreiben eines einfachen Skripts und komme einfach nicht weiter, egal wo ich mir im Netz / in Foren noch Anregungen hole.

Situation: Ich möchte, dass ich ein VBS-Skript unter Windows (7 oder XP) auf der Kommandozeile starte und dieses sich dann eine xls-Datei nach der nächsten vornimmt, diese in LibreOffice lädt, alle Blätter der jeweiligen Dateien als CSV abspeichert und dann LibreOffice schließt.

Problem 1: Immer wenn Calc eine Datei speichert, dann enthält sie eigentlich ein ODS (!) (Zip-Container, etc., fängt mit

Code: Alles auswählen

PK    u‚°@…l9Š.   .      mimetypeapplication/vnd.oasis.opendocument.spreadsheet
an) statt CSV als Text.

Makro? Als Makro mittels Makrorekorder klappt das alles sehr gut:

Code: Alles auswählen

dim document   as object
dim dispatcher as object

document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

dim args1(2) as new com.sun.star.beans.PropertyValue
args1(0).Name = "URL"
args1(0).Value = "file:///C:/Users/lutz/Desktop/test.csv"
args1(1).Name = "FilterName"
args1(1).Value = "Text - txt - csv (StarCalc)"
args1(2).Name = "FilterOptions"
args1(2).Value = "9,0,76,1,,0,false,true,true"

dispatcher.executeDispatch(document, ".uno:SaveAs", "", 0, args1())
Dies schreibt eine echte CSV des offenen Blattes heraus, Zeichensatz UTF-8, Feldtrenner Tab, kein Texttrenner. So weit, so gut.

Problem 2: In VBS funktioniert das gar nicht. Oder ich bin zu blöd. Habe es stattdessen mit StoreToUrl gemacht. Dabei tritt aber Problem 1 auf. Hier der Code:

Code: Alles auswählen

	' Scripting Objekt
	Dim wshshell
	' Dateisystem Objekt
	Dim objFSO
	' OpenOffice / LibreOffice Service Manager
	Dim objServiceManager
	' OpenOffice / LibreOffice Desktop
	Dim objDesktop
	' Runcommand, falls nicht in Cscript aufgerufen
	Dim runcommand

	Dim Pfad
	Dim Speicherpfad
	Dim Dateiname

	Dim url
	Dim args0(0)
	Dim args1(3)

	' Dateisystemobjekt erstellen
	Set wshshell = CreateObject("Wscript.Shell")
	Set objFSO = CreateObject("Scripting.FileSystemObject")

	'Wenn nicht im Cscript aufgerufen, rufe über Cscript auf
	if instr(1, wscript.fullname, "cscript.exe")=0 then
		runcommand = "cscript //Nologo xls2csv_calc.vbs"
		wshshell.run runcommand, 1, true
    	wscript.quit
	end if

	' Wenn Dateien vorhanden, dann starte Calc
	If objFSO.GetFolder(".").Files.Count>0 then
		' Den Service-Manager abfragen
		' Falls kein LibreOffice offen -> starten
		Set objServiceManager = WScript.CreateObject("com.sun.star.ServiceManager")
		' Desktop aufbauen
		Set objDesktop = objServiceManager.createInstance("com.sun.star.frame.Desktop")
		else
		' Falls keine Dateien im Verzeichnis
		wscript.echo "Keine Dateien gefunden!"
		wscript.quit
	End If

	on error resume next

    bError=False
    For each Datei in objFSO.GetFolder(".").Files
		if lcase(right(Datei.Name,3))="xls" then

			' Zugriff auf Verzeichnisse
			url = ConvertToURL(Datei.Path)
			objDesktop = GlobalScope.BasicLibraries.loadLIbrary( "Tools" )
			Set args0(0) = objServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue") 
			Set objDocument = objDesktop.loadComponentFromURL(url, "_blank", 0, args0 )

				' Dateinamen ohne Erweiterung und Pfad einlesen
				Pfad = ConvertToURL( Datei.ParentFolder ) & "/"
				Dateiname = objFSO.GetBaseName( Datei.Path )
				Speicherpfad = ConvertToURL( Datei.ParentFolder )

				' Args festlegen
				Set args1(0) = objServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue")
				Set args1(1) = objServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue")
				Set args1(2) = objServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue")
				sFilterName = "Text - txt - csv (StarCalc)"
				sFilterOptions = "9,0,76,1,,0,false,true,true"
				sOverwrite = True
				Set args1(0) = MakePropertyValue( "FilterName", sFilterName )
				Set args1(1) = MakePropertyValue( "FilterOptions", sFilterOptions )
				Set args1(2) = MakePropertyValue( "Overwrite", sOverwrite )

				' Einzelne Arbeitsblätter in einzelne csv speichern
				objSheets = objDocument.Sheets
				For i = 0 to objDocument.Sheets.getcount -1
					objSheet = objDocument.Sheets.getByIndex(i)
					Call objDocument.CurrentController.setActiveSheet(objSheet)
					Call objDocument.storeToURL( ConvertToURL( Datei.ParentFolder & "\" & Dateiname & "_" & objDocument.sheets.getByIndex(i).Name & ".csv" ), args1 )
				Next

				' Dokument schließen
				objDocument.close(True)
				Set objDocument = Nothing
				Pfad = ""
				Speicherpfad = ""
				Dateiname = ""

		Else
		End If

Next

' LibreOffice schließen
objDesktop.terminate
Set objDesktop = nothing
Set objServiceManager = nothing
Die Funktion ConvertToURL habe ich hier nicht mit aufgeführt. Ist in VBScript geschrieben und wandelt Windows-Pfadnamen in URL (file:/// etc.) um. Ist getestet und funktioniert definitiv.


So... hat jemand eine Idee was ich falsch mache? Oder kann mir jemand sagen wie ich den Dispatcher richtig im VBS aufrufe?

Ich bin für jede Hilfe dankbar, da ich langsam etwas verzweifelt bin!
LibreOffice 3.4.5
OOO340m1 (Build:502)
Windows 7 / Mac OS X 10.6

Benutzeravatar
karolus
* LO-Experte *
Beiträge: 2536
Registriert: Fr 10. Dez 2010, 10:01

Re: VBscript: Export von Calc-Blättern in CSV speichert ODS?

Beitrag von karolus » Mi 16. Mai 2012, 19:54

Hallo
Arbeite dich ein wenig in Python ein...
http://docs.python.org/library/index.html
http://www.python-forum.de/index.php
http://tutorial.pocoo.org/
installiere dazu http://pypi.python.org/pypi/xlrd

und du brauchst dazu weder Excel noch LO

Karo
LO7.4.7.5 debian 12(bookworm) auf Raspberry4b 8GB (64bit)
LO24.8.0.3 flatpak debian 12(bookworm) auf Raspberry4b 8GB (64bit)

LO-User
Beiträge: 11
Registriert: Fr 27. Jan 2012, 13:07

Re: VBscript: Export von Calc-Blättern in CSV speichert ODS?

Beitrag von LO-User » Mi 16. Mai 2012, 20:37

Hi karolus,

das ist sicher sehr nett gemeint und Python steht noch auf meiner To-Do-Liste für das nächste Jahr, aber dieses Skript hier muss leider aufgrund des Einsatzortes, den ich nicht selbst festlegen kann, mittels VBS laufen. Genauer gesagt, es ist eine Bedingung, die ich nicht ändern kann.

Ich werde mir die Links zu gegebener Zeit mal anschauen. Danke dafür.
LibreOffice 3.4.5
OOO340m1 (Build:502)
Windows 7 / Mac OS X 10.6

Benutzeravatar
karolus
* LO-Experte *
Beiträge: 2536
Registriert: Fr 10. Dez 2010, 10:01

Re: VBscript: Export von Calc-Blättern in CSV speichert ODS?

Beitrag von karolus » Mi 16. Mai 2012, 22:09

LO7.4.7.5 debian 12(bookworm) auf Raspberry4b 8GB (64bit)
LO24.8.0.3 flatpak debian 12(bookworm) auf Raspberry4b 8GB (64bit)

LO-User
Beiträge: 11
Registriert: Fr 27. Jan 2012, 13:07

Re: VBscript: Export von Calc-Blättern in CSV speichert ODS?

Beitrag von LO-User » Do 17. Mai 2012, 20:02

Hm... muss ich mal testen. Entweder hängt das ganze am SelectionOnly-Property oder dem Umstand, dass die Datei erst als ODS gespeichert wird und dann als CSV. Ich schau mal ob oder was davon wirkt. Wenn nichts davon, dann wohl wieder weil von außen (VBS) wohl alles anders als drinnen (Makro) ist... Naja, schaun mer mal.

Danke für den Link!
LibreOffice 3.4.5
OOO340m1 (Build:502)
Windows 7 / Mac OS X 10.6

LO-User
Beiträge: 11
Registriert: Fr 27. Jan 2012, 13:07

Re: VBscript: Export von Calc-Blättern in CSV speichert ODS?

Beitrag von LO-User » Fr 18. Mai 2012, 17:41

Hm... scheint nicht zu klappen.

1. Erst habe ich das Speichern in ODS veranlasst und dann in CSV - Fehlanzeige.

2. MakePropertyValue( "SelectionOnly", true ) brachte auch keine Veränderung. Es wird immer in ODS gespeichert.

3. Es scheint ein generelles Problem mit dem StoreToUrl oder den properties zu sein:
Selbst FiterName writer_pdf_Export oder Calc MS Excel 2007 XML funktionieren nicht. Ich weiß allerdings nicht was ich anders machen soll. Die Angaben hat doch der Makrorekorder auch genauso gemacht und wenn man das Makro in LibreOffice direkt aufruft, dann geht's ja auch!?

Hat noch jemand eine Idee?
LibreOffice 3.4.5
OOO340m1 (Build:502)
Windows 7 / Mac OS X 10.6

LO-User
Beiträge: 11
Registriert: Fr 27. Jan 2012, 13:07

Re: VBscript: Export von Calc-Blättern in CSV speichert ODS?

Beitrag von LO-User » Mo 21. Mai 2012, 21:39

Ok, hab's jetzt nach langem Probieren selber hinbekommen. Da Infos im Netz sehr verstreut sind, oft nicht funktionieren und ich anderen die mühsame Suche ersparen möchte, hier der Code, der funktioniert:

Code: Alles auswählen

' Variablen
Dim wshshell		' Scripting Objekt
Dim oFSO			' Dateisystem Objekt
Dim runcommand	' Runcommand, falls nicht in Cscript aufgerufen

Dim oSM		' OpenOffice / LibreOffice Service Manager
Dim oDesk		' OpenOffice / LibreOffice Desktop
Dim oCRef		' OpenOffice / LibreOffice Core Reflections

Dim sFileName	' Nackter Dateiname ohne Erweiterung
Dim sLoadUrl	' Url von der geladen wird
Dim sSaveUrl	' Url in die gespeichert wird
Dim args0(0)	' Lade-Argumente

' Dateisystemobjekt erstellen
Set wshshell = CreateObject("Wscript.Shell")
Set oFSO = CreateObject("Scripting.FileSystemObject")

' Wenn nicht im Cscript aufgerufen, rufe über Cscript auf
if instr(1, wscript.fullname, "cscript.exe")=0 then
	runcommand = "cscript //Nologo xyz.vbs"
	wshshell.run runcommand, 1, true
	wscript.quit
end if

' Wenn Dateien vorhanden, dann Calc starten
If oFSO.GetFolder(".").Files.Count>0 then
	' Falls kein LibreOffice offen -> starten
		Set oSM = WScript.CreateObject("com.sun.star.ServiceManager")
	' Desktop aufbauen
		Set oDesk = oSM.createInstance("com.sun.star.frame.Desktop")
		Set oCRef = oSM.createInstance( "com.sun.star.reflection.CoreReflection" )
else
	' Falls keine Dateien im Verzeichnis
		wscript.quit
End If

' Fehlerbehandlung
on error resume next

' CSV-Einstellungen für das Speichern
sFilterName = "Text - txt - csv (StarCalc)"
sFilterOptions = "9,0,76,1,,0,false,true,true"
sOverwrite = True

' Komponente für Dateizugriff laden
oDesk = GlobalScope.BasicLibraries.loadLIbrary( "Tools" )

' Ladeargument "Versteckt"
Set args0(0) = oSM.Bridge_GetStruct("com.sun.star.beans.PropertyValue") 
Set args0(0) = MakePropertyValue("Hidden", True)

For each oFile in oFSO.GetFolder(".").Files
	if lcase(right(oFile.Name,3))="xls" then
		' Datei öffnen
			sLoadUrl = ConvertToURL(oFile.Path)
			Set oDoc = oDesk.loadComponentFromURL(sLoadUrl, "_blank", 0, args0 )
		' Dateinamen ohne Erweiterung und Pfad einlesen
			sFileName = oFSO.GetBaseName( oFile.Path )
		' Arbeitsblätter in csv speichern
			For i = 0 to oDoc.Sheets.getcount -1
				oActSheet = oDoc.CurrentController.setActiveSheet( oDoc.Sheets.getByIndex(i) )
				sSaveUrl = ConvertToURL( oFile.ParentFolder & "\" & sFileName & "_" & oDoc.sheets.getByIndex(i).Name & ".csv" )
				saveCSV oSM, oDoc, sSaveUrl, sFilterName, sFilterOptions, sOverwrite
			Next
		' Dokument schließen
		oDoc.close(True)
		Set oDoc = Nothing
		Set oActSheet = Nothing
		sFileName = ""
		sLoadUrl = ""
		sSaveUrl = ""
	Else
	End If
Next

' LibreOffice schließen
oDesk.terminate
Set oDesk = nothing
Set oSM = nothing


Function ConvertToURL(sFileName)
' Windows-Pfadnamen in URL konvertieren

Dim sTmpFile

If Left(sFileName, 7) = "file://" Then
	ConvertToURL = sFileName
	Exit Function
End If

ConvertToURL = "file:///"
sTmpFile = oFSO.GetAbsolutePathName(sFileName)

' jegliche "\" durch "/" ersetzen
	sTmpFile = Replace(sTmpFile,"\","/") 

' jegliche "%" durch "%25" ersetzen
	sTmpFile = Replace(sTmpFile,"%","%25") 

' jegliche " " durch "%20" ersetzen
	sTmpFile = Replace(sTmpFile," ","%20")

ConvertToURL = ConvertToURL & sTmpFile
End Function


Function saveCSV( oSM, oDoc, sSaveUrl, sFilterName, sFilterOptions, sOverwrite )
' Speichert ein offenes Dokument, bzw. das aktive Blatt in eine Datei

Dim aProps( 2 ), oProp0, oProp1, oProp2, vRet

' Filtername setzen & ins Property-Array schreiben
	Set oProp0      = oSM.Bridge_GetStruct( "com.sun.star.beans.PropertyValue" )
	oProp0.Name     = "FilterName"
	oProp0.Value    = sFilterName
	Set aProps( 0 ) = oProp0

' Filteroptionen setzen & ins Property-Array schreiben
	Set oProp1      = oSM.Bridge_GetStruct( "com.sun.star.beans.PropertyValue" )
	oProp1.Name     = "FilterOptions"
	oProp1.Value    = sFilterOptions
	Set aProps( 1 ) = oProp1

' Datei-Überschreiben festsetzen & ins Property-Array schreiben
	Set oProp2      = oSM.Bridge_GetStruct( "com.sun.star.beans.PropertyValue" )
	oProp2.Name     = "Overwrite"
	oProp2.Value    = sOverwrite
	Set aProps( 2 ) = oProp2

' Speichern ausführen
	vRet            = oDoc.storeToURL( sSaveUrl, aProps )

End Function
So, in der Hoffnung, dass das jemandem hilft und der ganze Stress erspart bleibt: Viel Spaß damit!
LibreOffice 3.4.5
OOO340m1 (Build:502)
Windows 7 / Mac OS X 10.6


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