In this article I’d like to present different possible approaches on accessing data and working with it dynamically.
Your table name is initially unknown and is determined during runtime:
DATA:
* This will be global variable holding the selected
* table data
lo_data TYPE REF TO data,
lv_tabname TYPE tabname16 DEFAULT 'MARA',
lv_component TYPE fieldname DEFAULT 'MSTAE',
lv_value TYPE string.
FIELD-SYMBOLS:
* This will be used to access the table data
* dynamically:
<lt_data> TYPE ANY TABLE, " Table data
<ls_data_line> TYPE ANY, " Table line structure
<lv_data_field> TYPE ANY. " Field of the structure
START-OF-SELECTION.
* Create variable of given type dynamically
CREATE DATA lo_data TYPE TABLE OF (lv_tabname).
* Assign contents of the variable to field symbol
* so you can manipulate the data
ASSIGN lo_data->* TO <lt_data>.
* Get data from selected table
SELECT * FROM (p_tabnam)
INTO TABLE <lt_data>.
Assign components (fields) of a structure dynamically
LOOP AT <lt_data> ASSIGNING <ls_data_line>.
ASSIGN COMPONENT p_comp
OF STRUCTURE <ls_data_line>
TO <lv_data_field>.
CHECK sy-subrc = 0.
IF <lv_data_field> IS INITIAL.
<lv_data_field> = p_value.
ENDIF.
ENDLOOP.
If you need to access more components of a structure in the loop, it might be a good idea to create a MACRO definition. In that case you can modify the above code snippet as the following:
DEFINE assign_value.
ASSIGN COMPONENT &1 OF STRUCTURE <ls_data_line> TO <lv_data_field>.
IF sy-subrc = 0.
<lv_data_field> = &2.
ENDIF.
END-OF-DEFINITION.
LOOP AT <lt_data> ASSIGNING <ls_data_line>.
assign_value 'MSTAE' 'ZX'.
assign_value 'MHDHB' '365'.
assign_value 'KZKFG' 'X'.
* ...
ENDLOOP.
Append fields to your ITAB during runtime
DATA:
lo_data_line TYPE REF TO DATA,
lo_sdescr TYPE REF TO cl_abap_structdescr,
lo_tdescr TYPE REF TO cl_abap_tabledescr,
lt_components TYPE abap_component_tab.
FIELD-SYMBOLS:
<ls_component> TYPE abap_componentdescr.
* Create dynamic line of our itab
ASSIGN lo_data->* TO <lt_data>.
CREATE DATA lo_data_line LIKE LINE OF <lt_data>.
* We are creating components of the new/updated ITAB
APPEND INITIAL LINE TO lt_components ASSIGNING <ls_component>.
* We get description of the current itab
<ls_component>-type ?= cl_abap_structdescr=>describe_by_data_ref( lo_data_line ).
* We assign some dummy name (will not be used anyhow)
<ls_component>-name = 'DATA'.
* Include all fields
* If 'as_include' = abap_false, then all fields of the structure
* would be added in our new itab as one field of type
* "structure" with name 'DATA'
<ls_component>-as_include = abap_true.
* Now we're adding new component of type
* LVC_T_SCOL - Internal table
APPEND INITIAL LINE TO lt_components ASSIGNING <ls_component>.
<ls_component>-type ?= cl_abap_structdescr=>describe_by_data( l_lvc_t_scol ).
<ls_component>-name = 'CELL_COLORS'.
* We create reference to a line description of the new itab
lo_sdescr = cl_abap_structdescr=>create( lt_components ).
* ...we create reference to the new ITAB description
lo_tdescr = cl_abap_tabledescr=>create( lo_sdescr ).
* Finally we create our new ITAB, where
* 1. all fields from fieldcat are included
* 2. New field of type LCV_T_SCOL is appended
CREATE DATA lo_data TYPE HANDLE lo_tdescr.
Call FORMs of other programs
Let’s assume you have a report called Z_REPORT and you want to call its FORM get_data which e.g. reads data from VBEP.
PERFORM get_data(Z_REPORT).
Access variables from other programs
Your previous call caused required data to be loaded but the data is available in the Z_REPORT’s global variable ‘gt_vbep’ only – how to access it?
DATA:
lv_variable(40) TYPE c.
FIELD-SYMBOLS:
<lt_vbep> TYPE TABLE OF vbep,
<ls_vbep> TYPE VBEP.
lv_variable = ‘(Z_REPORT)gt_vbep’.
ASSIGN (lv_variable) TO <lt_vbep>.
LOOP AT <lt_vbep> ASSIGNING <ls_vbep>.
<ls_vbep>-TDUHR = ‘235959’.
ENDLOOP.