Hello community,

files with comma separated values (CSV) are a good and easy way for exchanging data. Also you have the possibility to manipulate the data e.g. via Microsoft Access, Microsoft Excel or Open Office Calc easily. But for the last step, to upload the file in an SAP system, I can’t find an easy way. So I create a class with three methods to upload a CSV file. Here a code example how to do that:

"-Begin-----------------------------------------------------------------
Report  Z_CSV_LOAD.

  "-Variables-----------------------------------------------------------
    Data CSV Type Ref To Z_CSV_IMPORT.

  "-Main----------------------------------------------------------------
    Delete From SFLIGHT.
    Commit Work.

    Create Object CSV.
    CSV->Load_CSV_File( 'C:\Dummy\sflight.csv' ).
    CSV->Transform_CSV_Data( 'SFLIGHT' ).
    CSV->Get_CSV_Data( 'SFLIGHT' ).

"-End-------------------------------------------------------------------

With three lines of code you can upload the content of a CSV file into an SAP table.

  1. Load_CSV_File
    Loads the CSV file from the presentation server.
  2. Transform_CSV_Data
    With this method you have the possibility to manipulate the head line and the CSV data. Often it is necessary to add the field MANDT and the correct content. Also it is often necessary to correct date fields.
  3. Get_CSV_Data
    Copies the data into the SAP table. It is not necessary that the column of the CSV file must have the same position as the field in the SAP table. It is only necessary that the column and field names are equal.
"-Begin-----------------------------------------------------------------

Class Z_CSV_IMPORT Definition Public Final Create Public .

Public Section.

  Methods Constructor.

  Methods LOAD_CSV_FILE
    Importing
      Value(I_FILENAME) Type String.

  Methods TRANSFORM_CSV_DATA
    Importing
      Value(I_TABLENAME) Type String.

  Methods GET_CSV_DATA
    Importing
      Value(I_TABLENAME) Type String.

Protected Section.

  Data G_CSV_DATA type STRINGTAB .
  Data G_ERROR_FLAG type ABAP_BOOL value ABAP_FALSE.
  Data G_TAB_FIELDS Type Standard Table Of String .

Private Section.

EndClass.



Class Z_CSV_IMPORT Implementation.


Method Constructor.
"-Begin-----------------------------------------------------------------

  Clear G_CSV_DATA.

"-End-------------------------------------------------------------------
EndMethod.


Method GET_CSV_DATA.
"-Begin-----------------------------------------------------------------

  "-Structures----------------------------------------------------------
    Types: Begin Of l_typ_Confrontation,
             IntFieldName Type String,
             IntFieldPos Type i,
             IntFieldTyp Type String,
             CSVFieldPos Type i,
             CSVFieldName Type String,
           End Of l_typ_Confrontation.

  "-Variables-----------------------------------------------------------
    Data l_rda_data Type Ref To Data.
    Data l_rda_wa Type Ref To Data.
    Data l_rcl_descr_tab Type Ref To cl_abap_tabledescr.
    Data l_rcl_descr_struc Type Ref To cl_abap_structdescr.
    Data l_comp_descr Type abap_compdescr.
    Data l_tab_content Type Standard Table Of String.
    Data l_Line Type String Value ''.
    Data l_tab_confrontation Type Standard Table Of l_typ_Confrontation
      With Key CSVFieldPos.
    Data l_FieldName Type String Value ''.
    Data l_Content Type String Value ''.
    Data l_Conf Type l_typ_Confrontation.

    Field-Symbols  <l_Table> Type Standard Table.
    Field-Symbols  <l_comp> Type Any.
    Field-Symbols  <l_wa> Type Any.

  "-Main----------------------------------------------------------------
    If G_CSV_DATA Is Not Initial And G_ERROR_FLAG = ABAP_FALSE.

      "-Reference to Table----------------------------------------------
        Create Data l_rda_data Type Standard Table Of (I_TABLENAME).
        Assign l_rda_data- >* To  <l_Table>.
      "-Get Structure of Table------------------------------------------
        l_rcl_descr_tab ?= cl_abap_typedescr= >describe_by_data(  <l_Table> ).
        l_rcl_descr_struc ?= l_rcl_descr_tab- >get_table_line_type( ).
      "-Define Line of Table--------------------------------------------
        Create Data l_rda_wa Like Line Of  <l_Table>.
        Assign l_rda_wa- >* To  <l_wa>.

      "-Compare Field Names of the Table with Headline of CSV-----------
      "-
      "- With this step is the position of the column indifferent. It
      "- is only necessary that the field of the table and the column
      "- of the CSV file must have the same name.
      "-
      "-----------------------------------------------------------------
        Loop At l_rcl_descr_struc- >components Into l_comp_descr.
          l_Conf-INTFIELDNAME = l_comp_descr-NAME.
          l_Conf-INTFIELDPOS = sy-tabix.
          l_Conf-INTFIELDTYP = l_comp_descr-TYPE_KIND.
          Loop At g_tab_fields Into l_FieldName.
            l_Conf-CSVFIELDPOS = -1.
            l_Conf-CSVFIELDNAME = 'UNKNOWN'.
            If l_comp_descr-NAME = l_FieldName.
              l_Conf-CSVFIELDNAME = l_FieldName.
              l_Conf-CSVFIELDPOS = sy-tabix.
              Exit.
            EndIf.
          EndLoop.
          Append l_Conf To l_tab_confrontation.
        EndLoop.
        Delete l_tab_confrontation Where CSVFIELDPOS = -1.
        Sort l_tab_confrontation By CSVFIELDPOS.

      "-Copy Data-------------------------------------------------------
        Loop At G_CSV_DATA Into l_Line From 2.
          Split l_Line At ';' Into Table l_tab_content.
          Loop At l_tab_content Into l_Content.
            Condense l_Content.
            Read Table l_tab_confrontation With Key CSVFieldPos = sy-tabix
              Into l_Conf.
            If sy-subrc = 0.
              Assign Component l_Conf-INTFIELDNAME Of Structure  <l_wa>
                To  <l_comp>.
              If l_Conf-INTFIELDTYP = 'P'.
                Replace All Occurrences Of '.' In l_Content With ''.
                Replace ',' In l_Content With '.'.
                 <l_comp> = l_Content.
              Else.
                 <l_comp> = l_Content.
              EndIf.
            EndIf.
          EndLoop.
          Append  <l_wa> To  <l_Table>.
          Clear  <l_wa>.
        EndLoop.

      "-Write Data into Table-------------------------------------------
        Insert (I_TABLENAME) From Table  <l_Table>.
        If sy-subrc  <> 0.
          G_ERROR_FLAG = ABAP_TRUE.
        EndIf.

    EndIf.

"-End-------------------------------------------------------------------
EndMethod.


Method LOAD_CSV_FILE.
"-Begin-----------------------------------------------------------------

  Call Function 'GUI_UPLOAD'
    Exporting
      FILENAME = i_FileName
      FILETYPE = 'ASC'
    Tables
      DATA_TAB = g_csv_data
    Exceptions
     OTHERS = 1.
   If sy-subrc  <> 0.
     G_ERROR_FLAG = ABAP_TRUE.
   EndIf.

"-End-------------------------------------------------------------------
EndMethod.


Method TRANSFORM_CSV_DATA.
"-Begin-----------------------------------------------------------------

  "-Variables-----------------------------------------------------------
    Data l_Fld1 Type String Value ''.
    Data l_Fld2 Type String Value ''.
    Data l_Fld3 Type String Value ''.
    Data l_FldRest Type String Value ''.

    Field-Symbols  <Line> Type String.

  "-Main----------------------------------------------------------------
    If G_CSV_DATA Is Not Initial And G_ERROR_FLAG = ABAP_FALSE.

      "-Manipulate Headline---------------------------------------------
        Read Table G_CSV_DATA Index 1 Assigning  <Line>.
         <Line> = 'MANDT;' &&  <Line>.

      Condense  <Line> No-Gaps.
      Split  <Line> At ';' Into Table g_tab_fields.

    EndIf.

    "-Transformation----------------------------------------------------
      Loop At G_CSV_DATA From 2 Assigning  <Line>.
         <Line> = sy-mandt && ';' &&  <Line>.
      EndLoop.

"-End-------------------------------------------------------------------
EndMethod.

EndClass.

"-End-------------------------------------------------------------------

Enjoy it.

Cheers

Stefan

To report this post you need to login first.

5 Comments

You must be Logged on to comment or reply to a post.

  1. Richard Harper

    Hi,

    A couple of things that probably need a bit more work because unfortunately I can’t see where you handle them.

    Where a string in a CSV file contains a comma it is delimited with quotes.  You need to handle this.

    Number formats – you seem to assume that the decimal format is comma.  Don’t forget that you could be receiving files with a variety of different number formats.  This includes UK/US,  European, etc etc which need to be translated into sap internal format,  or if the output is to be used for a BDC session the external format of the user.

    Date formats.  You need to handle the various date formats that can com in from external files and convert that to internal or external format of the current user.

    You assume that the file will have column headers.  In a lot of cases this is not so,  especially when coming from external systems.  Using sy-index you can assign components of a structure to a field symbol.  You can then use SPLIT to get the columns into an itab and associate each record with a column.

    Oh!! And also make the delimiter an optional parameter to the Constructor method that defaults to a comma.  Then the user can pass in other delimiters such as TAB or ~ etc etc

    Add these things in and make it even more generic! 😉

    Rich

    (0) 

Leave a Reply