Skip to end of metadata
Go to start of metadata

Author: David Pietroniro
Submitted: 10/15/2008
Related Links:

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.