locked
SELECT SQL und Export im CSV-Format RRS feed

  • Frage

  • Hallo NG,

    habe ein kleines Problem:

    Mit

    USE mitglieder
    SELECT titel, name, vorname, stranum, plz, ort FROM mitglieder INTO CURSOR cur_export
    COPY TO D:\mitgliederexport.csv TYPE DELIMITED WITH CHARACTER ";"

    ... möchte ich Tabellendaten in eine CSV-Datei setzen. Dabei werden Textfelder in Hochkommas gesetzt.

    "";"Strobel";"Jürgen";"Im Grund 17";"74889";"Sinsheim-Hoffenheim";01.01.1974

    Frage: kann man die Hochkommas irgendwie unterdrücken? Das Programm, dem ich diese daten übergeben will, weiß anhand der Datensatznummer, um welches Format es sich handelt und möchte keine Hochkommas o. ä. , um Textfelder, numerische Felder oder Datumsfelder unterscheiden zu können.

    Das Ergebnis sollte also so aussehen:

    ;Strobel;Jürgen;Im Grund 17;74889;"Sinsheim-Hoffenheim;01.01.1974

    Danke und Gruß

    Jürgen


    <--------(nur Fliegen sind schöner!)-------->

    Samstag, 1. Juli 2017 13:26

Antworten

  • Danke für Eure Ideen und Hilfe. Beide Lösungen klappen. Auch meine auf Lowlevelbasis.

    Schönes WE

    Jürgen


    <--------(nur Fliegen sind schöner!)-------->

    Freitag, 7. Juli 2017 09:20

Alle Antworten

  • probier mal ob dir das hilft:

    COPY TO D:\mitgliederexport.csv TYPE DELIMITED WITH ";"

    Viele Grüße

    Joachim

    Montag, 3. Juli 2017 12:13
  • So wie Joachim das zu probieren vorschllägt geht es nicht.

    CREATE CURSOR crsTest (iid i autoinc, cText C(30) DEFAULT "foo", tDatetime T DEFAULT DATETIME())
    APPEND BLANK
    COPY TO mitgliederexport.csv TYPE DELIMITED WITH ";"

    Das erzeugt ein File dieser Art:

    1,;foo;,04.07.2017 21:09:39
    Sieht nur auf den ersten Blick gut aus, aber die Kommas sind weiterhin die Separatoren und statt mit Anführungszeichen ist der String foo mit Semikoli begrenzt.


    Siehe in der Hilfe:

    "Because character data can include commas, character fields are additionally delimited with double quotation marks."

    Das ist die Hauptbedeutung von Delimited, die Abgrenzung von Strings, im stringenten CSV Format gehört das alleine schon deswegen dazu, um auch Texte mit Komas und Zeilenumbrüchen innerhalb der Anführungszeichen noch zum selben Datensatz zählen zu lassen.

    Excel kann damit auch umgehen, es besteht also kein Grund, das abzuändern.

    Für das Trennzeichen, den Sparator (CSV = Comma Separated Values) ist im Befehl die WITH CHARACTER Klause zuständig.

    Die Hilfe hat ein Bespiel, dass die verquerte Natur dieses Kommandos aufzeigt: 
    COPY TO mytxt.txt DELIMITED WITH _ WITH CHARACTER ';'

    Das Semikolon als Alternative zum Komma ist in Quotes. Der Unterstrich als der alternative Stringbegrenzer nicht. Es ist sogar noch verwirrender, weil bei fehlender Angabe von WITH CHARACTER die Klausel DELIMITED WITH ';' interpretiert wird wie DELIMITED WITH " WITH CHARACTER ';', was man so wiederum gar nicht schreiben kann.

    Es ist nicht vorgesehen gar keinen Stringbegrenzer zu haben. Deswegen bietet sich dann an die Arbeit selbst zu übernehmen, sei es mit STRTOFILE oder Textmerge und \\

    Nimm das als Basis:

    https://support.microsoft.com/de-de/help/241424/how-to-export-memo-fields-with-other-field-types-to-a-text-file-with-v

    Eine Konvention für echtes CSV ist nicht nur Anführungszeichen als Stringbegrenzer zu nehmen, sondern innerhalb der Texte vorkommende Anführungszeichen per verdoppelung zu "escapen", ein abschließendes Anführungszeichen steht also immer allein und wird dann von Komma (nächstes Feld), Zeilenumbruch (nächster Satz) oder Dateiende (Tabellenende) gefolgt. Auch das macht VFP nicht, selbst mit dem einfachsten COPY TO TYPE CSV nicht. Die Ecken und Kanten sind nie ausgebügelt worden.

    Tschüß, Olaf.


    Olaf Doschke - http://www.doschke.name

    Dienstag, 4. Juli 2017 19:13
  • Scheint nicht so einfach zu sein. Hmmmm

    Ich probier es mal mit FOPEN(), FPUTS() usw. "zusammenzubasteln".

    Danke und Grüße

    Jürgen


    <--------(nur Fliegen sind schöner!)-------->

    Mittwoch, 5. Juli 2017 14:45
  • Wie gesagt...https://support.microsoft.com/de-de/help/241424/how-to-export-memo-fields-with-other-field-types-to-a-text-file-with-v

    Das einzige Problem ist in dem Abschnitt:

          IF lnCount < lnFieldCount && Determines if the last field was
    && processed and sets the closing quote.
    lcFieldString = lcFieldString + '"' + lcString + '"' + ','
    ELSE
    lcFieldString = lcFieldString + '"' + lcString + '"'
    ENDif

    Das setzt jeden Feldtyp in Anführungszeichen. Die willst Du aber ja nicht, also nimmst Du die sowieso raus und ergänzt nur das Komma bzw. Semikolon an dieser Stelle, wenn es nicht das letzte Feld ist.

    Wenn Du zu faul bist, den Code zu lesen, zu verstehen und anzupassen, dann mußt Du halt Deine eigene Routine schreiben...

    Tschüß, Olaf.


    Olaf Doschke - http://www.doschke.name

    Mittwoch, 5. Juli 2017 15:45
  • Hi Jürgen,

    bevor Du jetzt tatsächlich mit LowLevel Funktionen anfängst...

    Über das _VFP Objekt steht eine Funktion .DataToClip zur Verfügung. Diese bekommt als Parameter Deinen Cursor mit den Selekt-Ergebnissen (der zuvor noch am Anfang positioniert werden sollte (-> GO TOP IN cur_export).

    Anschliessend steht der Cursor als TAB (Chr(9) ) getrennter Datenstring im _cliptext und mit CHRTRAN() ersetzt Du nun die TABs durch ein Semikolon und hustest die nun korrigierte Zwischenablage mit STRTOFILE() auf die Festplatte.

    GO TOP in cur_export
    _vfp.DataToClip( [cur_export] , , 3 )
    SET MEMOWIDTH TO 8000
    _cliptext = CHRTRAN( _cliptext , CHR(9) , [;] )
    =STRTOFILE(_cliptext,[c:\temp\MeinExport.csv])

    JM2C


    Gruss / Best regards
    -Tom
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible,
    you are, by definition, not smart enough to debug it. 010101100100011001010000011110000101001001101111011000110110101101110011



    • Bearbeitet Tom Borgmann Donnerstag, 6. Juli 2017 11:21 Tippfehler
    Donnerstag, 6. Juli 2017 11:20
  • Und wenn Du die Headerzeile nicht brauchst, dann suchst Du nach dem ersten CR/LF und schreibst mit SUBSTR() alles ab dem AT() + 2 nochmals nach _cliptext. Damit wäre auch der Header weg.

    Gruss / Best regards
    -Tom
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible,
    you are, by definition, not smart enough to debug it. 010101100100011001010000011110000101001001101111011000110110101101110011

    Donnerstag, 6. Juli 2017 11:26
  • Das mag weniger Code sein, aber MS Codebeispiel löst in der Hauptsache noch den Export von Memofeldern, deren Memlines alle per Space getrennt aneinandergebappt werden, um auf eine Zeile zu geraten und dann auch in VFP per IMPORT bzw APPEND brauchbares CSV ergeben.

    Die Performance wird auch gerne unterschätzt. Nur weil COPY TO oder STRTOFILE ein Einzelaufruf sind, bleibt der Flaschenhals in erster Linie die Festplattengeschwindigkeit. Ich habe sehr gute Erfahrungen mit CSV Exporten mit angepasstem MS Code gemacht, man kann vor allem sehr individuell die Formate selbst bestimmen, so wie die Zielanwendung/Datenbank die Datenexporte braucht, während das bei COPY TO oder auch DataToClip immer nur indirekt mit den aktuellen Einstellungen geht.  Das kann man dank der universellen TRNSFORM() Funktion genauso von SETtings abhängig machen oder sehr individuell mit Stringformatierungen in TEXTMERGE arbeiten. Und so riesig und unüberschaubar wird's auch nicht. 

    Der Fehler im MS Script, das Begrenzen aller Werte mit Anführungszeichen ist wahrlich ein grober Schnitzer, aber komm, wer nicht 20 Zeilen Code überblicken kann und spätestens per Single Stepping durch den Code sieht, wo die überflüssigen Anführungszeichen herkommen, der weiß sich dann wohl gar nicht mehr selbst zu helfen.

    Tschüß, Olaf.


    Olaf Doschke - http://www.doschke.name

    Donnerstag, 6. Juli 2017 15:00
  • Danke für Eure Ideen und Hilfe. Beide Lösungen klappen. Auch meine auf Lowlevelbasis.

    Schönes WE

    Jürgen


    <--------(nur Fliegen sind schöner!)-------->

    Freitag, 7. Juli 2017 09:20