csvdynamictype-conversionabap

Convert semicolon-separated string into table structure?


I need some help for converting a string into in ITAB.

  LOOP AT LT_0111_FILE INTO LV_STRING.
    SPLIT LV_STRING AT ';' INTO TABLE LT_0111.
    DO GV_COMP TIMES.
      READ TABLE LT_0111 ASSIGNING <LV> INDEX SY-INDEX.
      IF <LV> IS NOT INITIAL.
        ASSIGN COMPONENT SY-INDEX OF STRUCTURE <STRUCT> TO <LV_COMP>.
        IF <LV_COMP> IS ASSIGNED.
          <LV_COMP> = <LV>.
        ENDIF.
      ENDIF.
    ENDDO.
    INSERT <STRUCT> INTO TABLE <TABLE>.
  ENDLOOP.

In LT_0111_FILE is the table PA0111 as a string with separator ";". Now I need to assign every field of this stringtable into the fields of the structure from PA0111.

I don´t want to do this for every field separatly because the fields will be created dynamically.

This code works for character fields but not for numbers. In the txt-file there will be numbers like 0,00 and to move them to the fields of the structure will give an error because the number have to be 0.00.

Thanks for the help


Solution

  • When you have an unknown structure and want to know what fields it has and what properties those fields have, then you can use the runtime type information classes.

    First, get a type description of your target structure.

    DATA lo_struct_description TYPE REF TO cl_abap_structdescr.
    lo_struct_description ?= cl_abap_typedescr=>describe_by_data( <struct> ).
    

    The casting-operator ?= is required here, because the return value of describe_by_data is a generic cl_abap_typedescr. You know that it got to be a structure, but the class does not know that. It could just as well be a table, simple type or a reference to an object. But if you can guarantee that it got to be a structure, you can up-cast it to a cl_abap_structdescr.

    Now you can get a table describing all the fields of the structure with:

    DATA lt_components TYPE abap_component_tab.
    lt_components = lo_struct_description->get_components( ).
    

    This table contains the names and the types of those components. So instead of using a DO-loop and using ASSIGN COMPONENT by index, you can LOOP AT the component table and use ASSIGN COMPONENT by name. And then you can handle each field according to its type:

    LOOP AT lt_components INTO ls_component.
      READ TABLE lt_0111 ASSIGNING <lv_in> INDEX sy-tabix.
      IF sy-subrc = 0.
        ASSIGN COMPONENT ls_component-name OF STRUCTURE <struct> TO <lv_out>.
        IF sy-subrc = 0.
          CASE ls_component-type->type_kind.
            WHEN cl_abap_datadescr=>typekind_date.
              " Special handling for dates
            WHEN cl_abap_datadescr=>typekind_packed.
              " Special handling for decimal numbers
             
            " Check the other constants cl_abap_datadescr=>typekind_* for all the other types
            " you might encounter in your use-case and which might require special treatment.
            WHEN OTHERS.
              " Probably just copyable. If not, you will get a runtime error here and need 
              " to implement special handling for this particular type_kind.
              <lv_out> = <lv_in>.
          ENDCASE.
        ENDIF.
      ENDIF.
    ENDLOOP.