Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

How can I load a flat file into a ZTABLE dynamically

Former Member
0 Kudos

I need to create a program which can Load a ZTABLE from a flat file structure (delimited and fixed options required).  We have many ZTables where this will be required so I was hoping to do it dynamically somehow.  Otherwise I will have to create one ABAP for every ZTable we have to load.

       

My Inputs should be

 

PARAMETERSp_ztable TYPE ddobjname,         "Z Table Name
             p_infile
(132) LOWER CASE,        "File Name
             p_delim
(1).                      "Delimiter

  I know that I can read the file by using gui_upload

    CALL FUNCTION 'GUI_UPLOAD'
   
EXPORTING
      filename               
= c_infile
      has_field_separator    
= p_delim
   
TABLES
      data_tab               
= indata
   
EXCEPTIONS
      file_open_error        
= 1
      file_read_error        
= 2

        OTHERS                  = 9.

I know that  I can split the contents of this file (if a delimiter is used).  However I will not know the actual field names of the table until runtime as to what to fields to split it into.  In the example below I have the actual table (t_rec) and each of the fields (pernr, lgart, etc) in the code but each table I
need to load will be different – it will have a different # of fields as well.

    

FORM read_data_pc.
 
LOOP AT indata.
   
PERFORM splitdata USING indata.
   
APPEND t_rec.
   
CLEAR t_rec.
 
ENDLOOP.

ENDFORM.

    

FORM splitdata USING p_infile.

   SPLIT p_infile AT p_delim INTO
        t_rec-pernr                 "Employee #
        t_rec-lgart                 "Wage Type
        t_rec-begda                 "Effective date
        t_rec-endda.                 "End date

  ENDFORM.                       

Once I split the data into the fields then I can just look and insert the record.

    

Does anyone have any ideas?  Specific code examples would be great if you do.  Thx!!

1 ACCEPTED SOLUTION

jcutinho
Explorer
0 Kudos

Hi Janice,

You can also try this code

DATAI_TMP(100) OCCURS 0 WITH HEADER LINE"Split internal table

DATA : V_HEX TYPE X VALUE '09'. "Tab delimiter

FIELD-SYMBOLS: <FS1>"Points to Table work area

               <FS2>.    "Points to Table Field


*---Create a new data object of table specified in parameter (p_table)

*---Reference is stored in dref variable. dref now contains a pointer

*---to newly created object.

   CREATE DATA DREF TYPE (P_ZTABLE).

*--Asssign the reference to field-symbol

   ASSIGN DREF->* TO <FS1>.

   LOOP AT I_DATA.

     REFRESH I_TMP.

*--Split each input row data into tokens with Tab delimiter

     SPLIT P_INFILE AT V_HEX INTO TABLE I_TMP.

*    CLEAR .

*---Assign each field of table to field-symbol

     DO.

       ASSIGN COMPONENT SY-INDEX OF STRUCTURE  <FS1> TO <FS2>.

       IF SY-SUBRC NE 0.

         EXIT.

       ENDIF.

       READ TABLE I_TMP  INDEX SY-INDEX.

       IF SY-SUBRC EQ 0.

         <FS2>  = I_TMP.

       ENDIF.

     ENDDO.

*--Now  will have all the data - Modify the table

     MODIFY (P_ZTABLE) FROM <FS1>.

   ENDLOOP.

8 REPLIES 8

jcutinho
Explorer
0 Kudos

Hi Janice,

Pass the P_ZTABLE value to DDIF_FIELDINFO_GET Function Module and get all the fields (& their respective properties) of the table and now match that Field names of the flat structure file. So that you can map accordingly.

Thanks,

Joel Cutinho

Former Member
0 Kudos

thx for the response.  I did something similar to that

*Get Structure of Z table you want to load into the t_itab table

  CALL FUNCTION 'DDIF_NAMETAB_GET'
    EXPORTING
      tabname   = p_ztable
    TABLES
      dfies_tab = t_itab
    EXCEPTIONS
      not_found = 1
      OTHERS    = 2.

The t_itab table returned actually contains all of the fieldnames, but I am lost as to how to split the data at the demilter (see code in orginal question) without hardcoding the field names.  I am sure the amswer is simple, but I am a little lost right now. 

Can you help?

Former Member
0 Kudos

Hi janice,,

Try this sample code where you can upload data from a flat file into the internal table.

REPORT  z_test.

TABLES: mara.

FIELD-SYMBOLS : <fs> .

DATA : fldname(50) TYPE c.

DATA : col TYPE i.

DATA : cmp LIKE TABLE OF rstrucinfo WITH HEADER LINE.

DATA: progname LIKE sy-repid,

dynnum LIKE sy-dynnr.

DATA itab TYPE TABLE OF alsmex_tabline WITH HEADER LINE.

DATA: BEGIN OF ZUPLOAD1_T OCCURS 0 ,

         matnr like mara-matnr,

         ersda like mara-ersda,

         ernam like mara-ernam,

         laeda like mara-laeda,

      END OF ZUPLOAD1_T.

*DATA: ZUPLOAD1_T LIKE mara OCCURS 0 WITH HEADER LINE.

DATA: wa_data LIKE TABLE OF  ZUPLOAD1_T WITH HEADER LINE.

  • selection-screen

SELECTION-SCREEN: BEGIN OF BLOCK blk WITH FRAME TITLE text-001.SELECTION-SCREEN : SKIP 1. PARAMETERS : p_file LIKE rlgrap-filename.SELECTION-SCREEN : SKIP 1.SELECTION-SCREEN : END OF BLOCK blk


. AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.

    • F4 Value for File

  CALL FUNCTION 'KD_GET_FILENAME_ON_F4'   EXPORTING

  •                       PROGRAM_NAME        = SYST-REPID
  •                       DYNPRO_NUMBER       = SYST-DYNNR
  •                       FIELD_NAME          = ' '

     static              = 'X'

  •                       MASK                = ' '

    CHANGING      file_name           = p_file   EXCEPTIONS     mask_too_long       = 1     OTHERS              = 2 


          .  IF sy-subrc <> 0.

  • MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
  •         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

  ENDIF.

START-OF-SELECTION.

CALL FUNCTION 'ALSM_EXCEL_TO_INTERNAL_TABLE' 

EXPORTING    filename                      = P_FILE   

i_begin_col                   = 1   

i_begin_row                   = 1   

i_end_col                     = 5   

i_end_row                     = 12507 

     tables   

   intern                        = ITAB

EXCEPTIONS  

        INCONSISTENT_PARAMETERS       = 1  

        UPLOAD_OLE                    = 2  

       OTHERS                        = 3.          .

IF sy-subrc <> 0.

  • MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
  •         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

ENDIF.

CALL FUNCTION 'GET_COMPONENT_LIST' 

EXPORTING  

    program          = SY-REPID   

    fieldname        = 'ZMARA' 

       tables   

       components       = CMP.

LOOP AT itab.    AT NEW row.     

IF sy-tabix = 1.        APPEND ZUPLOAD1_T.     

ENDIF.   

ENDAT.   

col = itab-col.   

READ TABLE cmp INDEX col.  


CONCATENATE 'ZUPLOAD1_T-' cmp-compname INTO fldname.  

ASSIGN (fldname) TO <fs>.  

<fs> = itab-COL.  

  APPEND ZUPLOAD1_T.  ENDLOOP.

DELETE ZUPLOAD1_T where matnr eq space.

LOOP AT ZUPLOAD1_T INTO wa_data.

  • insert mara from  wa_data .

    WRITE: / ZUPLOAD1_T-matnr, 20 ZUPLOAD1_T-ersda , 45 ZUPLOAD1_T-ernam, 55 ZUPLOAD1_T-laeda.

*HERE IAM JUST CHECKING I NEED TO UPDATE A ZTABLE

  ENDLOOP.

insert ZMARA FROM table itab ACCEPTING DUPLICATE KEYS.

I have tried it for mara.Please let me know whether it was helful.

Regards,

Kannan

Florian
Active Contributor
0 Kudos

Hi Janice,

I do not get your problem at all. You have different files you want to load into a z_table ( in case fo the file, you want to save the input in different tables and you just want to create one report to handle all of them? Am I right?

Where's your problem. Just develop a report all your valid tables are declared and use dynamic programming. There is a lot of examples available here in SCN. Just use the search

Dynamic Internal table - ABAP Development - SCN Wiki

To split your file into a valid structure, you just could use the splitcommand itself. It pass everything you need in your direction.

DATA: gt_split type table of string.

SPLIT yourstring AT '/' INTO TABLE gt_split.

I can imagine a report you pass the file and the tablename you want to insert the stuff.

Afterwards you assign the dynamic variables and pass the content of your file to the correct fields in the internal table and now you just have to update the table.

This is the simple way, a bit more difficult is to let the system choose the table by the unique file-identifier. Perhaps the headerinformation, if passed.

But in case you didn't share anything about the incoming file and how many tables you have to fight with it is just a pure suggestion of mine

~Florian

Former Member
0 Kudos

Hi Florian,

I have flat file "A" that needs to be loaded into ZTABLE_A, Flat File "B" that needs to be loaded into ZTABLE_B, Flat File "C" that needs to be loaded into ZTABLE_C, and so on and so on.

I can dynamically determine the table and the fields ... I just don't know how to split the data by the delimiter without hard coding  the field names or the # of fields.  Each table is different

  LOOP AT indata.
       SPLIT p_infile AT p_delim INTO
        t_rec-pernr                 "Employee #
        t_rec-lgart                 "Wage Type
        t_rec-begda                 "Effective date
        t_rec-endda.                 "End date

    APPEND t_rec.
   
CLEAR t_rec.
 
ENDLOOP.

How can I do this dynamically?

Florian
Active Contributor
0 Kudos

Hi Janice,

there are two ways, by uploading the file you can modify your file in that way, that you know, the first character is delimiter.

You can deliver a fixed position ( Prhaps your first field in the flat file is always the same length)

or

You have a set of delimiters and which are always delimiter and you can prove the file which is in the current file passed.

You know with the keyword FIND first occuronce of....

But in any case, a cpu isn't smart enough, that it can identify a delimiter without anything knowing before

Hope this gives you a clue how to handle this issue.

IF you need further information, you might share two or three different example-files, so we can dive more into it.

Regards

Florian

jcutinho
Explorer
0 Kudos

Hi Janice,

You can also try this code

DATAI_TMP(100) OCCURS 0 WITH HEADER LINE"Split internal table

DATA : V_HEX TYPE X VALUE '09'. "Tab delimiter

FIELD-SYMBOLS: <FS1>"Points to Table work area

               <FS2>.    "Points to Table Field


*---Create a new data object of table specified in parameter (p_table)

*---Reference is stored in dref variable. dref now contains a pointer

*---to newly created object.

   CREATE DATA DREF TYPE (P_ZTABLE).

*--Asssign the reference to field-symbol

   ASSIGN DREF->* TO <FS1>.

   LOOP AT I_DATA.

     REFRESH I_TMP.

*--Split each input row data into tokens with Tab delimiter

     SPLIT P_INFILE AT V_HEX INTO TABLE I_TMP.

*    CLEAR .

*---Assign each field of table to field-symbol

     DO.

       ASSIGN COMPONENT SY-INDEX OF STRUCTURE  <FS1> TO <FS2>.

       IF SY-SUBRC NE 0.

         EXIT.

       ENDIF.

       READ TABLE I_TMP  INDEX SY-INDEX.

       IF SY-SUBRC EQ 0.

         <FS2>  = I_TMP.

       ENDIF.

     ENDDO.

*--Now  will have all the data - Modify the table

     MODIFY (P_ZTABLE) FROM <FS1>.

   ENDLOOP.

Former Member
0 Kudos

Thank-you Joel!

Your coding examples gave me the idea that perhaps I need to look at doing the gui_upload differently and load the data as tab delimitted.  The root of my problem was that I was not able to split the fields dynamically by using .csv.  I did some playing around and now have my solution.  I will show the code below in case anyone else comes across this same need in the future.  I still need to put the data into the internal table at the end of this, but that is simple.

*Get Structure of Z table you want to load into the t_itab table

  CALL FUNCTION 'DDIF_NAMETAB_GET'
    EXPORTING
      tabname   = p_ztable
    TABLES
      dfies_tab = t_itab
    EXCEPTIONS
      not_found = 1
      OTHERS    = 2.
  IF sy-subrc <> 0.
* Implement suitable error handling here
  ENDIF.

FIELD-SYMBOLS:
  <gw_wa>           TYPE ANY,
  <gt_itab>         TYPE STANDARD TABLE. "TYPE ANY TABLE.

data: gt_components     TYPE abap_component_tab,
      gw_component      TYPE LINE OF abap_component_tab,
      gr_wa             TYPE REF TO data,
      gr_itab           TYPE REF TO data,
      gr_tabledescr     TYPE REF TO cl_abap_tabledescr,
gt_keys           TYPE abap_keydescr_tab,
  gw_key            TYPE LINE OF abap_keydescr_tab,
      gr_structdescr    TYPE REF TO cl_abap_structdescr.

Loop at t_itab into s_itab.
   MOVE s_itab-fieldname TO gw_component-name.
  gw_component-type ?= cl_abap_elemdescr=>get_string( ).
  INSERT gw_component INTO TABLE gt_components.
endloop"t_itab

*get structure descriptor -> GR_STRUCTDESCR
  gr_structdescr ?= cl_abap_structdescr=>create( gt_components ).

* create work area of structure GR_STRUCTDESCR -> GR_WA
  CREATE DATA gr_wa TYPE HANDLE gr_structdescr.
  ASSIGN gr_wa->* TO <gw_wa>.

* create descriptor for internal table -> GR_TABLEDESCR
  gr_tabledescr ?= cl_abap_tabledescr=>create( p_line_type  = gr_structdescr
                                               p_table_kind = cl_abap_tabledescr=>tablekind_std ).

CREATE DATA gr_itab TYPE handle gr_tabledescr.
  ASSIGN gr_itab->* TO <gt_itab>.

c_infile = p_infile.              "Convert filename to string type

  CALL FUNCTION 'GUI_UPLOAD'
    EXPORTING
      filename                = c_infile
      has_field_separator     = p_delim
    TABLES
      data_tab                = <gt_itab> "<fs_table> "t_rec <gt_itab>
    EXCEPTIONS
      file_open_error         = 1
      file_read_error         = 2
      no_batch                = 3
      gui_refuse_filetransfer = 4
      invalid_type            = 5
      no_authority            = 6
      unknown_error           = 7
      bad_data_format         = 8
      OTHERS                  = 9.