Umwandlung Struktur <-> CSV

Für den Datenaustausch werden CSV-Dateien immer noch gerne verwendet, weil sie einfach zu erstellen und zu verwenden sind. Bei der Erstellung und beim Einlesen gibt es jedoch Tücken, die man am besten umgeht, in dem man Standardfunktionen verwendet.

Eine unkomplizierte Standardbibliothek ist die Klasse CL_RSDA_CSV_CONVERTER.

Folgend ein kleines Verwendungsbeispiel

Code

REPORT.

DATA gr_conv TYPE REF TO cl_rsda_csv_converter.
DATA gs_t000 TYPE t000.
DATA gv_csv TYPE c LENGTH 1000.

START-OF-SELECTION.

 SELECT SINGLE * FROM t000 INTO gs_t000 WHERE mandt = '066'.

 gr_conv = cl_rsda_csv_converter=>create( i_delimiter = '"' i_separator = ';' ).

 gr_conv->structure_to_csv( EXPORTING i_s_data = gs_t000
 IMPORTING e_data = gv_csv ).

 WRITE / gv_csv.

Nachtrag

Ebenfalls einfach nutzbar ist die Klasse CL_ICF_CSV.  Mit der Methode REQUEST_FOR_WRITE_INTO_CSV kann man eine Tabelle inclusive Spaltenüberschriften ins CSV-Format konvertieren und gleichzeitig speichern. Die Methoden zum Umwandeln der Daten sind leider als PRIVATE deklariert, so dass die Klasse wirklich nur zum Umwandeln und direkten Speichern der Daten genutzt werden kann.

Allerdings werden die Spaltenüberschriften hinzugelesen und als erste Zeile der CSV-Datei gespeichert.

DATA IT_DATA TYPE STANDARD TABLE OF t005.
cl_icf_csv=>request_for_write_into_csv(
 it_data = it_data
 iv_hdr_struct_name = 'T000'
 iv_init_dir = 'd:\temp'
 iv_file_name = 'testcsv.txt' ).
Enno Wulff

COMMENTS

  • <cite class="fn">helwie</cite>

    Hallo Enno,

    mal angenommen, ich würde in einer Query die o.g. Methode zur Erzeugung der csv-Daten nutzen wollen.
    Ist es möglich, die Query dann per Batch-Job einzustellen, damit die csv-Datei nach einem noch anzugebenen Pfad lokal auf meinem Laufwerk abgelegt werden kann?
    Falls ja, wie genau müsste ich dann vorgehen?

    Gruß
    Helwie

    • <cite class="fn">Enno Wulff</cite>

      “Batch” und “PC” schliessen sich aus. Nicht zwingend, aber das ist nur mit viel Aufwand zu realisieren.
      Verwende ein Gruppenlaufwerk oder lasse den Job dir die Datei per Mail schicken.
      Gruß
      Enno

  • <cite class="fn">bdegel</cite>

    Hallo Enno,

    nach einer Klasse wie CL_ICF_CSV habe ich schon eine Weil gesucht, klasse !
    Jetzt habe ich bei folgendendem Beispiel im CSV eine unpassende Headerzeile (bin noch ABAP-Anfänger, sorry für den Lieschen-Müller-Ansatz):

    TYPES: BEGIN OF TY_CUSTOMER_LIST,
    BUKRS TYPE KNB1-BUKRS,
    KUNNR TYPE KNA1-KUNNR,
    ALTKN TYPE KNB1-ALTKN,
    NAME1 TYPE KNA1-NAME1,
    NAME2 TYPE KNA1-NAME2,
    PSTLZ TYPE KNA1-PSTLZ,
    ORT01 TYPE KNA1-ORT01,
    STRAS TYPE KNA1-STRAS,
    MAHNS TYPE KNB5-MAHNS,
    MADAT TYPE KNB5-MADAT,
    EIKTO TYPE KNVV-EIKTO,
    END OF TY_CUSTOMER_LIST.

    DATA: lt_customerlist TYPE TABLE OF TY_CUSTOMER_LIST, msg TYPE string.

    SELECT
    KNB1~BUKRS,
    KNA1~KUNNR,
    KNB1~ALTKN,
    KNA1~NAME1,
    KNA1~NAME2,
    KNA1~PSTLZ,
    KNA1~ORT01,
    KNA1~STRAS,
    KNB5~MAHNS,
    KNB5~MADAT,
    KNVV~EIKTO
    FROM KNA1
    LEFT OUTER JOIN KNB1 ON KNB1~KUNNR = KNA1~KUNNR
    LEFT OUTER JOIN KNB5 ON KNB5~KUNNR = KNA1~KUNNR
    LEFT OUTER JOIN KNVV ON KNVV~KUNNR = KNA1~KUNNR
    INTO TABLE @lt_customerlist
    WHERE KNB1~BUKRS = ‘2100’.

    * Tabelle ausgeben, wenn Datensätze vorhanden
    IF sy-dbcnt > 0.
    msg = sy-dbcnt.
    CONCATENATE msg ‘Datensätze gefunden’ INTO msg.
    MESSAGE msg TYPE ‘I’.

    * CSV-Klasse
    cl_icf_csv=>request_for_write_into_csv(
    it_data = tbCustomerList
    iv_hdr_struct_name = ‘T000’
    iv_init_dir = ‘d:\temp’
    iv_file_name = ‘CustomerList.txt’ ).
    ENDIF.

    In der ausgegebenen CSV steht dann folgender, so gar nicht passender Header:

    MANDT;MTEXT;ORT01;MWAER;ADRNR;CCCATEGORY;CCCORACTIV;CCNOCLIIND;CCCOPYLOCK;CCNOCASCAD;CCSOFTLOCK;CCORIGCONT;CCIMAILDIS;CCTEMPLOCK;CHANGEUSER;CHANGEDATE;LOGSYS

    Was mache ich da falsch bzw. wie mache ich es richtig ?

    Grüße,
    Bernd

  • <cite class="fn">greutter</cite>

    Hallo zusammen,

    Klasse CL_RSDA_CSV_CONVERTER habe ich schon einmal verwendet. Sie hat leider einen kleinen Haken. Leere Felder werden mit space gefüllt, also z. B. ” “.

    Im Constructor wird dafür ein Attribut gesetzt: CONCATENATE me->delimiter me->delimiter INTO me->initial_char SEPARATED BY space.

    Leider ist me->initial_char als privat definiert, sodass man diese Einstellung nicht ändern kann. BO Data Services erwartet für leere Felder “”, somit muss man hier ein bisschen tricksen.

    Grüße,
    Markus

Comments are closed.