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
CodePudding user response:
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.
CodePudding user response:
Actually I like Philips solution more, it is more error-proof and comprehensive in terms of type-handling, but just for the sake of diversity I will add this fast&dirty solution.
You can use methods methods of cl_rsda_csv_converter
auxiliary class:
DATA: input TYPE TABLE OF string.
TYPES t_itab TYPE TABLE OF pa0009 WITH EMPTY KEY.
DATA(dref) = NEW t_itab( ).
APPEND ` 800;90051099;0;;;99991231;20080501;000;20100312;HORVATLU;;;;;;;;;;;;;;;46456.89;HUF;0.00;;0;;;;;HU;;;;;;;;;;;;;;;;00;;;;00000000;;;;; ` TO input.
APPEND ` 800;99000005;0;;;99991231;20170101;000;20170220;GUNASHMA;;;;;;;;;;;;;;;5564665.00;EUR;0.00;;0;;;;;DE;28511111;123;;;;;;;;;;;;;;00;;;;00000000;;;;; ` TO input.
DATA: ls_line TYPE LINE OF t_itab.
LOOP AT input ASSIGNING FIELD-SYMBOL(<fs_s>).
* creating converter
DATA(lo_csv) = cl_rsda_csv_converter=>create( i_separator = ';' ).
* Process records
lo_csv->csv_to_structure( EXPORTING i_data = <fs_s> IMPORTING e_s_data = ls_line ).
* inserting into itab
INSERT ls_line INTO TABLE dref->*.
ENDLOOP.