CalcTabellenblatt per Macro als .csv speichern

ich versuche seit Tagen dieses Problem zu lösen. Viele Beispiele im Netz haben mich leider nicht weitergeführt, da sie meistens auf VBA basieren. Letztendlich habe ich es mit dem Macrorecorder versucht. Hier konnte ich punkten aber leider sind da noch zwei Haken. Erstens: nach Ende des Makros erscheint immer die MsgBox: “Es wurde nur die aktuelle Tabelle gespeichert” Zweitens: Der Desktop springt von “Projekt.ods” auf “Projekt.csv”. Beide Sachen stören und verlangen nach Handeingriff, der aber vermieden werden muss. Hier mein Code:
Kann mir jemand helfen?
Vielen Dank

rem ----------------------------------------------------------------------



dim args57(2) as new com.sun.star.beans.PropertyValue
args57(0).Name = "URL"
args57(0).Value = "file:///C:/Boule/Testversion/MeldelisteDiagrammTest.csv"
args57(1).Name = "FilterName"
args57(1).Value = "Text - txt - csv (StarCalc)"
args57(2).Name = "FilterOptions"
args57(2).Value = "59,34,76,1,,0,false,true,true,false,false"

dispatcher.executeDispatch(document, ".uno:SaveAs", "", 0, args57())


end sub

[Edit - Opaque] Code als vorformatierter Text formatiert.

Erstens: nach Ende des Makros erscheint immer die MsgBox: “Es wurde nur die aktuelle Tabelle gespeichert”

Dann musst aber dazu sagen, welche(s) Sheet(s) Deiner Datei als .csv gespeichert werden soll. Es gilt die Regel “1 Tabelle ergibt 1 .csv Datei”. Hast Du mehrere Tabellen in einer einzigen Datei, benötigst Du mehrere .csv Dateien - wie sollen die gegebenenfalls heißen, wenn alle Tabellen eines Calc Dokuments in jeweils eine .csv Datei exportiert werden sollen?

Vielleicht habe ich mich falsch ausgedrückt. Das mit der einen Tabelle ist schon ok. Nur die MsgBox stört mich. Es handelt sich hier um Teil eines größeren Projektes, bei dem möglichst wenig Bedienereingriffe gefragt sind (aufgrund der Qualifikation der Bediener). Der zweite Haken ist noch schlimmer: Die geöffnete Arbeitsmappe wird umbenannt in …csv statt …ods. und funktioniert auch nicht mehr wie gewohnt. Ich muß also die …csv-Mappe schließen und die …ods-Mappe wieder neu öffnen um weiter arbeiten zu können.

Hallo Opaque,
vielen Dank für die schnelle Reaktion. Dein Makro funktioniert auch schon fast wie es soll, nur leider wird die falsche Tabelle gespeichert. Vorher springe ich zu der Tabelle hin, die ich speichern möchte und die aktuelle wurde gespeichert. Bei deiner Version wird immer eine ganz bestimmte gespeichert. Ich habe leider nicht erkannt, ob und wo ich die Tabellennr. oder -Name einstellen kann.

Ich habe leider nicht erkannt, ob und wo ich die Tabellennr. oder -Name einstellen kann.

Das kannst Du auch nicht einstellen und das habe ich auch in den Anmerkungen geschrieben.


> Vorher springe ich zu der Tabelle hin, die ich speichern möchte und die aktuelle wurde gespeichert.

Das verstehe ich nicht. Bei mir wird die aktuelle Tabelle (die, die den Focus hat() als CSV Datei gespeichert. Auch das hatte ich in meinen Anmerkungen geschrieben.


> Bei deiner Version wird immer eine ganz bestimmte gespeichert.

Ist beim mir nicht so. Und was ist “eine ganz bestimmte” Tabelle? Damit kann ich wenig anfangen. Heißt “bestimmt”: "immer die 1. Tabelle, " “*immer die 5. Tabelle”, ": “immer die zuletzt geänderte Tabelle” oder was auch sonst immer (wie gesagt: Bei mir ist das nicht so; aber ich habe das auch nur mit einer meiner LibreOffice Versionen und openSUSE Leap 15.2 getestet, da Du keine Angaben zu Deiner Umgebung gemacht hattest).

Sorry,
ich hatte in meiner Begeisterung die Anmerkungen gar nicht gelesen. Meine LO-Version ist 7.0.5.2 und läuft unter Win10. Gespeichert wird bei deiner Version immer die Tabelle 9, die bei Start des Programms als erste öffnet (Programmbeschreibung). Es sollte, und da springe ich vor Ausführung des Makros immer hin, die Tabelle 12 gespeichert werden. Hier sind dann Namen gespeichert, die von einem externen Parser gelesen werden, der nur ASCII-Texte erkennt. Wenn das ganze mit Tab.12 klappen würde wäre ich schon einen Riesenschritt weiter.

Gespeichert wird bei deiner Version immer die Tabelle 9, die bei Start des Programms als erste öffnet (Programmbeschreibung).

Ich versuche immer noch zu verstehen warum Du Tabelle 9 als .csv gespeichert bekommst, wenn doch Tabelle 12 die aktive Tabelle ist. Daher frage ich mich:

Wie öffnest Du die Datei? Klickst Du auf ein Attachment in einer E-Mail (womit die .csv Datei dann auch evtl. in einem temporären Verzeichnis Deines E-Mail-Programms erzeugt werden würde) oder ist die Datei schon irgendwo in Deiner Verzeichnisstruktur gelandet.

Heureka,
ich habe die beiden “Save-Zweige” rausgeschmissen und schon funzt es.
Vielen Dank für deine Hilfe

Die Frage ist damit beantwortet.

Um nun deine Frage zu beantworten: Das Programm öffnet immer mit Tabelle9 und ich vermute, durch das Saven hatten wir diesen Effekt.

Heureka, ich habe die beiden “Save-Zweige” rausgeschmissen und schon funzt es.

Das verstehe ich gar nicht, ergibt für mich auch keinen Sinn und ist in der Regel deshalb gefährlich, da .ods Datei (Inhalt der betreffenden Tabelle) und .csv Datei im Zweifel nicht mehr übereinstimmen müssen.

Für die richtigen FilterOptions:
Speicher die csv-Datei oder öffne eine bestehende mit allen erforderlichen und korrekten Einstellungen im Ex/Import-Dialog. Mit der Textdatei im aktiven Fenster starte das folgende Makro.

Sub showFilterOptions()
Dim args(),i%
   args() = thisComponent.getArgs
   for i = 0 to uBound(Args())
      if args(i).Name = "FilterOptions" then inputbox args(i).Name,"",cStr(args(i).value)
   next
End Sub

Du kannst die FilterOptions für Dein Makro aus der Inputbox kopieren.

Hallo,

vielleicht hilft Dir das hier:

sub ExportToCSV
    
   dim sDocURL      as string
   dim sDocPath     as string
   dim sDocName     as string
   dim sDocExt      as string
   dim sBackURL     as string
   dim oDoc         as object
   dim oDisp        as object
   dim oFrame       as object
if (Not GlobalScope.BasicLibraries.isLibraryLoaded("Tools")) then
    GlobalScope.BasicLibraries.LoadLibrary("Tools")
end if
    
oDoc = Thiscomponent
    
if oDoc.hasLocation() then
    
        '--------------------------------------------------
        ' Save the file, if it has been opened from storage
        '--------------------------------------------------
oDoc.store()
    
else
    
   '-------------------------------------------
   ' Show a save dialog if it is a new document
   '-------------------------------------------
        oFrame = ThisComponent.CurrentController.Frame
        oDisp  = createUnoService("com.sun.star.frame.DispatchHelper")
        oDisp.executeDispatch(oFrame, ".uno:Save", "", 0, Array())
    
 end if
    
 if oDoc.hasLocation() then
    
    sDocURL      = oDoc.getURL()
    sDocPath     = DirectoryNameoutofPath(sDocURL, "/")
    sDocName     = GetFileNameWithoutExtension(sDocURL, "/")
    sDocExt      = GetFileNameExtension(sDocURL, "/")
        
    '--------------------------------------------------------------
    ' Create CSV only, if working on a Calc Document in ODF Format
    '--------------------------------------------------------------
    if sDocExt = "ods" then
        
      sBackURL = sDocPath & "/" & sDocName & ".csv"
          
      dim sArgs(2) as new com.sun.star.beans.PropertyValue
      sArgs(0).Name = "FilterName"
      sArgs(0).Value = "Text - txt - csv (StarCalc)"
      sArgs(1).Name = "FilterOptions"
      sArgs(1).Value = "59,34,76,1,,0,false,true,true,false,false"
      oDoc.storeToURL(sBackURL, sArgs())
          
   end if  
    
end if
end sub

Anmerkungen

[1] Der erste Zweig in if oDoc.hasLocation stellt lediglich sicher, dass Änderungen an der Datei auch gespeichert werden, falls es sich um eine bestehende Datei handelt

[2] Der else Zweig erzwing eine Sicherung, falls es sich um eine neue Datei handelt, die noch nie gesichert wurde.

[3] Es wird eine CSV Datei erzeugt, die denselben Name hat, wie die geöffnete Datei

[4] Es wird die jeweils aktive Tabelle als .csv exportiert und ein eventuell vorhandener Export einer anderen Tabelle wird überschrieben. Wenn der Dateiname des Exports noch um Tabellennummer/Tabellenname erweitert werden soll, bitte einen entsprechenden Kommentar hinterlassen.

[5] Die CSV Datei wird im gleichen Verzeichnis, in dem die .ods Datei speichert ist, erzeugt.

[6] Es bleibt die .ods Datei geöffnet

Getested mit LibreOffice

    Version: 7.0.5.2, Build ID: 64390860c6cd0aca4beafafcfd84613dd9dfb63a
    CPU threads: 8; OS: Linux 5.3; UI render: GL; VCL: kf5
    Locale: de-DE (de_DE.UTF-8); UI: de-DE, Calc: threaded

Update - Erweiterte Makroversion

Siehe folgendes erweiterte Makro: ExportCSVMakro-Erweitert.txt.odt - Die Erweiterung .odt bitte entfernen. Die Datei ist eine reine Textdatei und hat diese Endung nur erhalten, um sie hier mit einer erlaubten Erweiterung hochladen zu können.

Anmerkungen

[1] Diese Version exportiert alle Tabellen oder die mit Nummer übergebene Tabelle (Diese Verwendung zeigt beispielhaft die zusätzlich Subroutine ExportSheet12

[2] Es wird dem originalen Dateinamen noch ein -sheet-# hinzugefügt, um die verschiedenen Tabellen zu im exportierten CSV Namen unterscheiden zu können. Will man das nicht für den Fall, dass eine Tabllennummer angegeben wurde, könnten man unmittelbar nach der Zeile sBackURL=... ein

        if iStart = iStop then
          sBackURL = sDocPath & "/" & sDocName & ".csv"
        end fi 

einfügen.

[3] Dieses Makro wurde nun gesteted unter Windows mit

    Version: 7.0.5.2 (x64), Build ID: 64390860c6cd0aca4beafafcfd84613dd9dfb63a
    CPU threads: 1; OS: Windows 10.0 Build 19042; UI render: Skia/Raster; VCL: win
    Locale: en-US (en_DE); UI: en-US, Calc: threaded

Das Macro wurde kommentarlos von Dritten editiert und ich habe keine Lust nun die Differenz zum Original zu suchen (Die Diff-Funktion ist relativ unbrauchbar, da sie den gesamten Codeblock markiert). Fragen daher bitte ab nun an den Editor.

Das liegt daran, dass Editor:in die Code-Blöcke als solche gekennzeichnet hat, damit sie hypsch dargestellt werden (mittels vor- und nachgestellten ``` Zeilen, leider aber die dann überflüssige Einrückung von 4 spaces nicht entfernt). Die simple Einrückung formatiert nämlich einfach nur als <pre>-Block.

Nu hab dich mal nicht so… Nett von Editor wäre allerdings gewesen, wenn ein Kommentar am Ende des Posts hinterlassen worden wäre, was geändert wurde.

Hallo
wenn ich überall kommentieren würde wo ich unleserliche Codeblöcke geraderücke käme ich ja zu gar nichts mehr ;-(

Wie kann man denn das Trennzeichen ändern? Ich habe bereits probiert die Kommas in der Zeile sArgs(1).Value gegen das gewünschte “|” zu tauschen - aber leider ohne Erfolg.

Das kann ja nicht klappen, sArgs(1).Value beschreibt ja die zu verwendenen Optionen, des Export Filters. Das , trennt also die einzelnen Optionen des Export Filters. Das verwendete Trennzeichen versteckt sich in einem der durch , (Komma) separierten Werte der Optionen. Wenn ich richtig getestet habe ist es die erste Option, die das Trennzeichen beschreibt:

Ersetze die 59 durch 124 also:

sArgs(1).Value = "59,34,76,1,,0,false,true,true,false,false" durch

sArgs(1).Value = "124,34,76,1,,0,false,true,true,false,false"

ersetzen.

PS: Deine Frage hast Du als Antwort auf die eigentliche Frage geschrieben. Bitte schreibe in Zukunft eine eigene Frage und beziehe Dich dabei auf eine existierende Frage und deren Lösung. Sonst werden hier Lösungen zu Problemen so versteckt, dass diese am Ende niemand mehr findet and der Sinn und Zweck dieser Seite wird nicht mehr erfüllt.