Author: David Pietroniro
Submitted: 10/15/2008
Related Links:
- Concept of Runtime Type Creation
- Advanced and Generic Programming in ABAP
- Dynamic Internal Tables and Structures
Description
Some days ago I saw the following scenario in the ABAP General Forum:
I have an internal table with the following fields and values:
Keyfield1 |
Keyfield2 |
Keyfield3 |
KeyfieldWeek |
Cost |
---|---|---|---|---|
A |
B |
C |
01 |
100 |
A |
B |
C |
02 |
200 |
A |
B |
C |
03 |
300 |
B |
D |
E |
01 |
400 |
B |
D |
F |
02 |
500 |
And I have to create a final dynamic internal table like this:
A |
B |
C |
100 |
200 |
300 |
B |
D |
E |
400 |
|
|
B |
D |
F |
500 |
|
|
If only the week field is changing, I have to add a new field to the result internal table.
Here my solution suggestion:
CONSTANTS: gco_cost TYPE c LENGTH 4 VALUE 'COST'. TYPES: BEGIN OF gty_line, key1 TYPE c LENGTH 1, key2 TYPE c LENGTH 1, key3 TYPE c LENGTH 1, keywk TYPE n LENGTH 2, cost TYPE n LENGTH 3, END OF gty_line, gty_t_table TYPE STANDARD TABLE OF gty_line WITH NON-UNIQUE KEY key1 key2 key3. DATA: gt_table TYPE gty_t_table, gs_table LIKE LINE OF gt_table, gr_table TYPE REF TO gty_line, gr_struct_typ TYPE REF TO cl_abap_datadescr, gr_dyntable_typ TYPE REF TO cl_abap_tabledescr, gt_dyntable TYPE REF TO data, gs_dyntable TYPE REF TO data, gt_component TYPE cl_abap_structdescr=>component_table, gv_field TYPE cl_abap_structdescr=>component-name, gv_i TYPE n VALUE 1. FIELD-SYMBOLS: <fs_table> TYPE INDEX TABLE, <fs_line> TYPE ANY, <fs_field> TYPE ANY. PERFORM fill_table USING: 'A' 'B' 'C' 01 100, 'A' 'B' 'C' 02 200, 'A' 'B' 'C' 03 300, 'B' 'D' 'E' 01 400, 'B' 'D' 'F' 01 500. PERFORM add_component USING: 'KEY1' gs_table-key1, 'KEY2' gs_table-key2, 'KEY3' gs_table-key3, 'COST1' gs_table-cost. READ TABLE gt_table INDEX 1 INTO gs_table. LOOP AT gt_table REFERENCE INTO gr_table FROM 2. IF gs_table-key1 = gr_table->key1 AND gs_table-key2 = gr_table->key2 AND gs_table-key3 = gr_table->key3. gs_table = gr_table->*. gv_i = gv_i + 1. CONCATENATE gco_cost gv_i INTO gv_field. PERFORM add_component USING gv_field gs_table-cost. ENDIF. ENDLOOP. gr_struct_typ ?= cl_abap_structdescr=>create( p_components = gt_component ). gr_dyntable_typ = cl_abap_tabledescr=>create( p_line_type = gr_struct_typ ). CREATE DATA: gt_dyntable TYPE HANDLE gr_dyntable_typ, gs_dyntable TYPE HANDLE gr_struct_typ. ASSIGN: gs_dyntable->* TO <fs_line>, gt_dyntable->* TO <fs_table>. CLEAR gv_i. SORT gt_table BY key1 key2 key3. READ TABLE gt_table INDEX 1 INTO gs_table. LOOP AT gt_table REFERENCE INTO gr_table. IF gs_table-key1 NE gr_table->key1 OR gs_table-key2 NE gr_table->key2 OR gs_table-key3 NE gr_table->key3. gs_table = gr_table->*. APPEND <fs_line> TO <fs_table>. CLEAR: <fs_line>, gv_i. ENDIF. IF gv_i = 0. gv_i = 1. ASSIGN COMPONENT 'KEY1' OF STRUCTURE <fs_line> TO <fs_field>. <fs_field> = gr_table->key1. ASSIGN COMPONENT 'KEY2' OF STRUCTURE <fs_line> TO <fs_field>. <fs_field> = gr_table->key2. ASSIGN COMPONENT 'KEY3' OF STRUCTURE <fs_line> TO <fs_field>. <fs_field> = gr_table->key3. ASSIGN COMPONENT 'COST1' OF STRUCTURE <fs_line> TO <fs_field>. <fs_field> = gr_table->cost. ELSE. gv_i = gv_i + 1. CONCATENATE gco_cost gv_i INTO gv_field. ASSIGN COMPONENT gv_field OF STRUCTURE <fs_line> TO <fs_field>. <fs_field> = gr_table->cost. ENDIF. ENDLOOP. APPEND <fs_line> TO <fs_table>. *&---------------------------------------------------------------------* *& Form FILL_TABLE *&---------------------------------------------------------------------* FORM fill_table USING p_key1 TYPE gty_line-key1 p_key2 TYPE gty_line-key2 p_key3 TYPE gty_line-key3 p_keywk TYPE gty_line-keywk p_cost TYPE gty_line-cost. DATA ls_line LIKE LINE OF gt_table. ls_line-key1 = p_key1. ls_line-key2 = p_key2. ls_line-key3 = p_key3. ls_line-keywk = p_keywk. ls_line-cost = p_cost. APPEND ls_line TO gt_table. ENDFORM. "FILL_TABLE *&---------------------------------------------------------------------* *& Form ADD_COMPONENT *&---------------------------------------------------------------------* FORM add_component USING p_field TYPE cl_abap_structdescr=>component-name p_type TYPE any. DATA ls_component TYPE cl_abap_structdescr=>component. ls_component-name = p_field. ls_component-type ?= cl_abap_datadescr=>describe_by_data( p_type ). APPEND ls_component TO gt_component. ENDFORM. "add_component
The FILL_TABLE form was created just to fill data like in the scenario.