Calc: "Speichern unter..." als CSV für mehrere Tab

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

Moderator: Moderatoren

famo
*****
Beiträge: 275
Registriert: Do, 06.01.2005 00:15
Wohnort: Berlin

Calc: "Speichern unter..." als CSV für mehrere Tab

Beitrag von famo »

Hallo,
ich bin gerade dabei mir mein erstes Makro zu basteln. Und zwar brauch ich eins welches mir alle Tabellen des aktuellen Dokuments als CSV speichert mit folgenden Optionen:
1. die Dateien sollen nach folgenden Schema benannt werden: "DateinameTabellenname.prn" (Dateiname ohne Endung)
2. die Dateien sollen im selben Ordner wie die Ursprungsdatei gespeichert werden
3. die Dateien sollen als Text (CSV) mit fester Spaltenbreite gespeichert werden
4. In der CSV Datei müssen die Kommas durch Punkte ersetzt sein.
5. und es wär schön schön, wenn nach ausführen des Skripts, wieder die Ursprungsdatei in OO offen wäre.

Soweit bin ich bisher gekommen:

Code: Alles auswählen

REM  *****  BASIC  *****
Sub Main
End Sub
sub export
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(3) as new com.sun.star.beans.PropertyValue
args1(0).Name = "URL"
args1(0).Value =  "file:///F:/richard/Eigene%20Dateien/test/Datsheet1.prn"
args1(1).Name = "FilterName"
args1(1).Value = "Text - txt - csv (StarCalc)"
args1(2).Name = "FilterOptions"
args1(2).Value = "FIX,34,ANSI,1"
args1(3).Name = "SelectionOnly"
args1(3).Value = true
dispatcher.executeDispatch(document, ".uno:SaveAs", "", 0, args1())
end sub
Zu 1. Dachte ich mir dass ich den Dateinamen und Tabellename auslese und diese dann als String an die Save funktion übergebe.

Code: Alles auswählen

dim docname    as string
dim sheetname  as string
docname    = ThisComponent.CurrentController.Frame
sheetname  = Document.CurrentController.Activesheet.Name
Aber dass funktioniert leider noch nicht, warum?
Zu 2. so ähnlich:

Code: Alles auswählen

dim directory  as string
dirname  = CurDir
Dass dann eben einsetzen:

Code: Alles auswählen

args1(0).Value =  "dirname/docnamesheetname.prn"
Und da ich dass ja für mehrere Tabellen machen will, muss ich das Programm auch noch davon abhalten das Dokument zu schließen, wie mache ich das?
Zu. 4. Muss ich dafür einen zusätzlichen Befehl schreiben oder gibt es da eine andere Lösung?

Danke für alle Antworten,
Richard
Toxitom
********
Beiträge: 3769
Registriert: Di, 12.08.2003 18:07
Wohnort: Wiesbaden
Kontaktdaten:

Beitrag von Toxitom »

Hey Richard,

warum postest du doppelt? Den gleichen Thread hast du doch schon im Calc-Forum geöffent? So etwas verwirrt doch nur....

Zu deinen vielfältigen Fragen:
1. die Dateien sollen nach folgenden Schema benannt werden: "DateinameTabellenname.prn" (Dateiname ohne Endung)
Lösbar solange deine Datei bereits eine qualifizeirte URL besitzt (Speichername).
2. die Dateien sollen im selben Ordner wie die Ursprungsdatei gespeichert werden
Lösbar, siehe oben.
3. die Dateien sollen als Text (CSV) mit fester Spaltenbreite gespeichert werden
Musst du wahrscheinlich selbst zusammenbauen!
3. die Dateien sollen als Text (CSV) mit fester Spaltenbreite gespeichert werden
?? Welche Kommas? Meist du Zahlen nach amerikanischen Schema speichern? (Tausendertrenner = Komma, Dezimaltrenner = Punkt) oder die Wertetrennung?
5. und es wär schön schön, wenn nach ausführen des Skripts, wieder die Ursprungsdatei in OO offen wäre.
Nutze "StoreToURL()" und deine akteulle Datei bleibt erhalten.

Das in Kurzform. Deine geposteten Codeschnipsel solltest du am besten wieder vergessen - die helfen wenig. Der Dispatcher ist für die Aufgabe wenig bis gar nicht geeignet.
Andererseits ist das Projekt nicht "mal eben so" zu schreiben oder zu lösen, erwarte also keine fertige Lösung hier.
Gehe mal auf die Suche, hier im Forum oder auch im internationalen forum (http://www.oooforum.org) - einmal nach Calc-Export CSV, Calc-Filter "Text - txt - csv (StarCalc)" oder ähnlichem, dann nach der Methode "StoreToURL()". Mit den dann gefundenen Infos kommst du schon ein gutes Stück weiter.

den Dateinamen deines akltuellen Dokumentes bekommst du übrigens einfach über die URL Funktion raus:

Code: Alles auswählen

msgbox thiscomponent.URL
schneidest du nun nach dem letzten "/" alles ab, dann hast du den aktuellen Pfad....und gleich in URL Schreibweise.
Oder du nutzt eben Curdir, das musst du dann aber noch in eine URL-Schreibweise umwandeln! (convertToURL() )
Die Tabellennamen bekommst du über die Eigenschaft "name" einfach heraus, die Tabellen sprichst du entweder mit de Namen an oder über die Indexnummer ;-)
also:

Code: Alles auswählen

msgbox thisComponent.sheets(0).name
liefert dir den Namen des ersten Tabellenbalttes.
Das ganze löst du später über Schleifen - Blatt für Blatt :-)

So, und nun viel Spass. Bei Codeteilen, wo du nicht weiterkommst: hier posten, dann schaun wir und helfen.

Viele Grüße
Thomas
Unterstützer LibreOffice, zertifizierter Trainer und Berater
Bücher: LibreOffice 6- Einstieg und Umstieg
Makros Grundlagen - LibreOffice / OpenOffice Basic
famo
*****
Beiträge: 275
Registriert: Do, 06.01.2005 00:15
Wohnort: Berlin

Beitrag von famo »

Hallo Thomas,
Danke für deine Antwort und sorry wegen dem Doppelpost war nicht beabsichtigt, hab diesen Forumbreich aber erst nachher entdeckt und mir erschien er eindeutig passender als "OO Calc". (Wenn ich den Post hätte verschieben können, hätte ich dass sonst gemacht).

Den dispatcher hab ich "genommen", da ich die Funktion Makro aufzeichnen benutzt habe.

Zu 4. Damit meine ich das amerikanische Format.

Dass mit der Suche war ein guter Tipp, ich hab auf http://www.oooforum.org gleich ein "fast fertiges" Skripte gefunden:
Das hier liest .xls Dateien und speichert sie dann als .csv:
http://www.oooforum.org/forum/viewtopic.phtml?t=50170
Nur leider hat dieses Skript zuviele Funktionen für mich und beim Versuch sie rauszuschneiden, funktioniert es nicht mehr :cry: . Vielleicht könnte mir da jmd. von euch behilflich sein? :roll:

Code: Alles auswählen

Sub Main
   ' This is the hardcoded pathname to a folder containing Excel files.
   cFolder = "/Users/Shared/Jobs"

   ' Get the pathname of each file within the folder.
   cFile = Dir$( cFolder + "/*.*" )
   Do While cFile <> ""
      ' If it is not a directory...
      If cFile <> "."  And  cFile <> ".." Then
         ' If it has the right suffix...
         If LCase( Right( cFile, 4 ) ) = ".xls" Then
            ' Open the document.
            oDoc = StarDesktop.loadComponentFromURL( ConvertToUrl( cFolder + "/" + cFile ), "_blank", 0, Array() )
            '=========
            ' Options for delimiters in CVS
            cFieldDelimiters = Chr(9)
            cTextDelimiter = ""
            cFieldTypes = ""
            ' options....
            '   cFieldDelimiters = ",;" ' for either commas or semicolons
            '   cFieldDelimiters = Chr(9) ' for tab
            '   cTextDelimiter = Chr(34) ' for double quote
            '   cTextDelimiter = Chr(39) ' for single quote
            ' Suppose you want your first field to be numeric, then two text fields, and then a date field....
            '   cFieldTypes = "1/2/2/3"
            ' Use 1=Num, 2=Text, 3=MM/DD/YY, 4=DD/MM/YY, 5=YY/MM/DD, 9=ignore field (do not import)
            '----------
            ' Build up the Filter Options string
            ' From the Developer's Guide
            '   http://api.openoffice.org/docs/DevelopersGuide/DevelopersGuide.htm
            ' See section 8.2.2 under Filter Options
            '   http://api.openoffice.org/docs/DevelopersGuide/Spreadsheet/Spreadsheet.htm#1+2+2+3+Filter+Options
            cFieldDelims = ""
            For i = 1 To Len( cFieldDelimiters )
               c = Mid( cFieldDelimiters, i, 1 )
               If Len( cFieldDelims ) > 0 Then
                  cFieldDelims = cFieldDelims + "/"
               EndIf
               cFieldDelims = cFieldDelims + CStr(Asc( c ))
            Next
   
            If Len( cTextDelimiter ) > 0 Then
               cTextDelim = CStr(Asc( cTextDelimiter ))
            Else
               cTextDelim = "0"
            EndIf

            cFilterOptions = cFieldDelims + "," + cTextDelim + ",0,1," + cFieldTypes

            '=========
            ' Prepare new filename
            cNewName = Left( cFile, Len( cFile ) - 4 )
            
            ' Save it in OOo format.
            'oDoc.storeToURL( ConvertToUrl( cFolder + "/" + cNewName + ".sxc" ), Array() )
            
            ' Loop and selects sheets to save as csv
            oSheets = oDoc.Sheets()
            aSheetNames = oSheets.getElementNames()
               For index=0 to oSheets.getCount() -1
                  oSheet = oSheets.getByIndex(index)
                  
                  ' Define prefix or suffix to append to filename
                  appendName = aSheetNames(index) 'define prefix/suffix as the name of the sheet
                  appendNum = index + 1 ' define prefix/suffix as the number of the sheet                  
                  ' Choose new filename, with prefix or suffix
                  'cNewFileName = appendName + "_" + cNewName 'prefix name
                  'cNewFileName = appendNum + "_" + cNewName ' prefix number
                  'cNewFileName = cNewName + "_" + appendName ' suffix name
                  cNewFileName = cNewName +  "_" + appendNum ' suffix number
                  
               oController = oDoc.GetCurrentController()  'view controller
               oController.SetActiveSheet(oSheet) 'switches view to sheet object
               
               ' Export it using a filter.
               oDoc.StoreToURL( ConvertToUrl( cFolder + "/" + cNewFileName + ".csv" ),_
                  Array( MakePropertyValue( "FilterName", "Text - txt - csv (StarCalc)" ),_
                  MakePropertyValue( "FilterOptions", cFilterOptions ),_
                  MakePropertyValue( "SelectionOnly", true ) ) )
               Next index
            ' Close the document.
            oDoc.dispose()
         EndIf
      EndIf
      cFile = Dir$
   Loop
End Sub
Das mit den Filter Optionen kriege ich dann hoffentlich von alleine hin, habe auch schon in der Dokumentation die Filter Option für "US-English" gefunden. Nur ist mir noch nicht ganz klar muss ich dann für jede Spalte das Format angeben? Weil in der Datei sind mehrere Tab, die alle verschiedene Anzahl von Spalten haben. Und wie verhält es sich dann mit den Zeilen. Meine Tab sind generell so aufgebaut:
1. Zeile & Spalte Text, Rest sind zahlen (US-english), aber manchmal ist auch noch eine weitere Zeile mit Text.
Naja das werde ich dann schon austüfteln. Erstmal vielen Dank fürs Lesen & Antworten,
Gruß
Richard
Antworten