Imagine, you can have a huge table with various keys PARID/PARVA similar to USR05 but defined for plant specific parameters (see below table structure). There is an application working with BIG STRUCTURE receiving data from this database table. But how to do the conversion from table PAR(ID)/PAR(VAlue) into a structure? If you would do that manually, it would be huge list of IF ITAB-PARID = 'SOME_STRUCTURE_FIELD1' ELSE IF ITAB-PARID = 'SOME_STRUCTURE_FIELD2' etc. - long list of checks made within a loop over ITAB. You would need to write down all the structure components one by one. Yes, it is nicely easily readable , but its ugly programming at all.
Let's look at the dynamic approach, it saves lots of manual coding here. The below code snippet is, I hope, well commented to grasp the idea.
Source database table structure:
Target filled flat structure:
*&---------------------------------------------------------------------*
REPORT z_dynamic_prg
.
* Some huge flat target stucture receiving PARID/PARVA data from ITAB
TYPES:
BEGIN OF tls_plant_specifics
,
delete_aufnr
TYPE abap_bool
,
use_screen_202
TYPE abap_bool
,
global_selection
TYPE abap_bool
,
run_co04
TYPE abap_bool
,
not_use_opr_num
TYPE abap_bool
,
export_9_31
TYPE string
,
export_9_4
TYPE string
,
export_9_5
TYPE string
,
export_special
TYPE string
,
screen_907_clear
TYPE string
,
not_use_fstau
TYPE abap_bool
,
blank_staging
TYPE abap_bool
,
filter_version
TYPE c LENGTH
1,
export_plan_in
TYPE abap_bool
,
staging_blank
TYPE abap_bool
,
remove_routines
TYPE abap_bool
,
panning_rmw_e3
TYPE abap_bool
,
schedule_old
TYPE abap_bool
,
free_time
TYPE c LENGTH
1,
set_subrc
TYPE abap_bool
,
zroh_1
TYPE string
,
zroh_2
TYPE abap_bool
,
fevor_set_bu
TYPE abap_bool
,
component_active
TYPE abap_bool
,
sel_reservations
TYPE string
,
mode_3_lgort
TYPE lgort_d
,
change_profil
TYPE abap_bool
,
set_user_attrib
TYPE abap_bool
,
import_check_lr
TYPE abap_bool
,
read_marc_as_1
TYPE werks_d
,
read_marc_as_2
TYPE werks_d
,
read_marc_as_3
TYPE werks_d
,
default_lgort
TYPE lgort_d
,
select_days
TYPE abap_bool
,
use_zmet_zroh
TYPE abap_bool
,
set_fevor_icon
TYPE string
,
read_marc_as_4
TYPE werks_d
,
set_fstad_fstau
TYPE abap_bool
,
set_okcode
TYPE string
,
set_affree
TYPE abap_bool
,
set_time
TYPE abap_bool
,
userexit_lgnum
TYPE lgnum
,
get_mto_mts_by
TYPE string
,
END OF tls_plant_specifics
,
BEGIN OF tls_plant_specifics_parva_parid
,
parid
TYPE memoryid
,
parva
TYPE xuvalue
,
END OF tls_plant_specifics_parva_parid
.
DATA: lt_plant_specifics_parva_parid
TYPE STANDARD TABLE OF tls_plant_specifics_parva_parid
,
ls_plant_specifics_parva_parid
LIKE LINE OF lt_plant_specifics_parva_parid
,
lo_structdescr
TYPE REF TO cl_abap_structdescr
,
lt_components
TYPE cl_abap_structdescr
=>component_table
,
ls_component
LIKE LINE OF lt_components
,
lv_element_name
TYPE string
,
lv_element_content
TYPE string
.
DATA: lv_werks
TYPE werks_d
VALUE '9999', " some plant - hardcoded for test
lv_plant_table
TYPE tabname
VALUE 'SOME_YOUR_PARAM_TABLE_NAME',
ls_plant_specifics
TYPE tls_plant_specifics
. " target structure
FIELD-SYMBOLS <fs_element>
TYPE simple
.
" Get all plant parameters into itab
SELECT parid parva
FROM (lv_plant_table
)
INTO TABLE lt_plant_specifics_parva_parid
WHERE werks
= lv_werks
.
IF ( sy
-subrc
EQ 0 ) AND ( lt_plant_specifics_parva_parid
IS NOT INITIAL ).
" Get the values out of table (parid/parva) into class public structure
lo_structdescr ?= cl_abap_structdescr
=>describe_by_data
( ls_plant_specifics
).
lt_components
= lo_structdescr
->get_components
( ).
" Loop at parid x parva itab (comming from database)
LOOP AT lt_plant_specifics_parva_parid
INTO ls_plant_specifics_parva_parid
.
" Loop over components of target structure
LOOP AT lt_components
INTO ls_component
.
" Read component name out of table
lv_element_name
= ls_plant_specifics_parva_parid
-parid
.
" If PARAM name is equal to STRUCTURE component name => assign the value to the structure for this field
IF ls_component
-name
EQ lv_element_name
.
CONCATENATE 'ls_plant_specifics-' lv_element_name
INTO lv_element_name
.
ASSIGN (lv_element_name
) TO <fs_element>
.
IF ( <fs_element>
IS ASSIGNED ) AND ( ls_plant_specifics_parva_parid
-parva
IS NOT INITIAL ).
" You can assign data based on its type...
IF ls_component
-type->absolute_name
CS 'ABAP_BOOL'.
" just one char
<fs_element>
= ls_plant_specifics_parva_parid
-parva+0
(1).
ELSE.
" strings, etc.
lv_element_content
= ls_plant_specifics_parva_parid
-parva
.
CONDENSE lv_element_content
NO-GAPS
.
<fs_element>
= lv_element_content
.
ENDIF.
ENDIF.
ENDIF.
ENDLOOP.
ENDLOOP.
FREE lo_structdescr
.
ENDIF.