Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

how to extend structures at runtime

Former Member
0 Likes
1,868

hello,

is there any chance to

extend a data structure at runtime?

normally you define a structure with

data: begin of x,

field1 type c,

field2 type n.

data: end of x.

this structure is the basis for your internal tables etc.

it would be definitely nice to add a third field at runtime if it is needed.

in other programming languages it would also be possible to add elements to an array. the question ist: how can i add fields to the structure dynamically?

it could be useful for a lot of situations.

dynamically generated fieldcatalogue for example.

i think i could succeed in changing the structure by using field symbols in combination with dynamically creating data objects by the "CREATE DATA" statement.

has anyone already done something similar?

1 ACCEPTED SOLUTION
Read only

MauricioMiao
Contributor
0 Likes
983

Hello Gideon,

It is possible using ABAP runtime program generation like in code below.

This program generate a dinamic ALV with N fields. There is a parameter where the user type how many fields he wants to display (or generate).

Then form f_create_dynamic_table generate an internal table with N fields according to the number in the parameter.

You can change the program to generate a dinamic structure if you want, in fact it already does it.

Just cut and paste the program and execute in your system.

Regards,

Mauricio

REPORT zasmm008.

$$ Declarações -

-


TYPE-POOLS:

kkblo. "Tipos para lista especial

FIELD-SYMBOLS:

TYPE table.

PARAMETERS p_qtd TYPE i OBLIGATORY DEFAULT 10.

$$ Eventos -

-


INITIALIZATION.

%_p_qtd_%_app_%-text = 'Dinamic fields quantity'.

START-OF-SELECTION.

CHECK p_qtd > 0 AND p_qtd < 100.

PERFORM f_create_dynamic_table.

PERFORM f_fill_dynamic_table.

PERFORM f_create_alv.

$$ Forms -

-


*&----


*

*& Form f_create_dynamic_table

*&----


*

FORM f_create_dynamic_table.

DATA:

lv_line TYPE i,

lv_word(72) TYPE c,

lv_form(30) TYPE c VALUE 'TABLE_CREATE',

lv_message(240) TYPE c,

lp_table TYPE REF TO data,

lp_struc TYPE REF TO data,

lv_name LIKE sy-repid,

lv_cont(02) TYPE n,

lv_lng TYPE i,

lv_typesrting(6) TYPE c.

  • The dynamic internal table stucture

DATA: BEGIN OF lt_struct OCCURS 0,

fildname(8) TYPE c,

abptype TYPE c,

length TYPE i,

END OF lt_struct.

  • The dynamic program source table

DATA: BEGIN OF lt_inctabl OCCURS 0,

line(72),

END OF lt_inctabl.

  • Sample dynamic internal table stucture

DO p_qtd TIMES.

ADD 1 TO lv_cont.

CONCATENATE 'FIELD' lv_cont INTO lt_struct-fildname.

lt_struct-abptype = 'C'.

lt_struct-length = '4'.

APPEND lt_struct.

ENDDO.

  • Create the dynamic internal table definition in the dyn. program

lt_inctabl-line = 'PROGRAM ZDYNPRO.'.

APPEND lt_inctabl.

lt_inctabl-line = 'FORM TABLE_CREATE CHANGING P_TABLE P_STRUC.'.

APPEND lt_inctabl.

lt_inctabl-line = 'DATA: BEGIN OF DYNTAB OCCURS 0,'.

APPEND lt_inctabl.

LOOP AT lt_struct.

lt_inctabl-line = lt_struct-fildname.

lv_lng = strlen( lt_struct-fildname ).

IF NOT lt_struct-length IS INITIAL .

lv_typesrting(1) = '('.

lv_typesrting+1 = lt_struct-length.

lv_typesrting+5 = ')'.

CONDENSE lv_typesrting NO-GAPS.

lt_inctabl-line+lv_lng = lv_typesrting.

ENDIF.

lt_inctabl-line+15 = 'TYPE'.

lt_inctabl-line+21 = lt_struct-abptype.

lt_inctabl-line+22 = ','.

APPEND lt_inctabl.

ENDLOOP.

lt_inctabl-line = 'END OF DYNTAB.'.

APPEND lt_inctabl.

lt_inctabl-line = 'DATA: POINTER TYPE REF TO DATA.'.

APPEND lt_inctabl.

lt_inctabl-line = 'CREATE DATA POINTER LIKE DYNTAB[].'.

APPEND lt_inctabl.

lt_inctabl-line = 'P_TABLE = POINTER.'.

APPEND lt_inctabl.

lt_inctabl-line = 'CREATE DATA POINTER LIKE LINE OF DYNTAB.'.

APPEND lt_inctabl.

lt_inctabl-line = 'P_STRUC = POINTER.'.

APPEND lt_inctabl.

lt_inctabl-line = 'ENDFORM.'.

APPEND lt_inctabl.

CATCH SYSTEM-EXCEPTIONS generate_subpool_dir_full = 9.

GENERATE SUBROUTINE POOL lt_inctabl[] NAME lv_name

MESSAGE lv_message LINE lv_line WORD lv_word.

ENDCATCH.

PERFORM (lv_form) IN PROGRAM (lv_name) CHANGING lp_table lp_struc.

  • Dynamic table in <tb> and its header line in <st>

ASSIGN lp_table->* TO .

ENDFORM. " f_create_dynamic_table

*&----


*

*& Form f_create_alv

*&----


*

FORM f_create_alv.

DATA:

ls_layout TYPE slis_layout_alv,

lv_cont(02) TYPE n,

lt_fieldcat TYPE slis_t_fieldcat_alv WITH HEADER LINE.

DO p_qtd TIMES.

CLEAR lt_fieldcat.

ADD 1 TO lv_cont.

CONCATENATE 'FIELD' lv_cont INTO lt_fieldcat-fieldname.

CONCATENATE 'Campo' lv_cont INTO lt_fieldcat-seltext_s

SEPARATED BY space.

lt_fieldcat-seltext_m = lt_fieldcat-seltext_s.

lt_fieldcat-seltext_l = lt_fieldcat-seltext_s.

lt_fieldcat-outputlen = 10.

APPEND lt_fieldcat.

ENDDO.

ls_layout-zebra = 'X'.

CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'

EXPORTING

is_layout = ls_layout

it_fieldcat = lt_fieldcat[]

TABLES

t_outtab =

EXCEPTIONS

program_error = 1

OTHERS = 2.

ENDFORM. " f_create_alv

*&----


*

*& Form f_fill_dynamic_table

*&----


*

FORM f_fill_dynamic_table.

DATA:

lv_line(2) TYPE n,

lv_field(2) TYPE n.

DO 20 TIMES.

ADD 1 TO lv_line.

CLEAR lv_field.

DO p_qtd TIMES.

ADD 1 TO lv_field.

ASSIGN COMPONENT lv_field OF STRUCTURE .

ENDDO.

ENDFORM. " f_fill_dynamic_table

2 REPLIES 2
Read only

MauricioMiao
Contributor
0 Likes
984

Hello Gideon,

It is possible using ABAP runtime program generation like in code below.

This program generate a dinamic ALV with N fields. There is a parameter where the user type how many fields he wants to display (or generate).

Then form f_create_dynamic_table generate an internal table with N fields according to the number in the parameter.

You can change the program to generate a dinamic structure if you want, in fact it already does it.

Just cut and paste the program and execute in your system.

Regards,

Mauricio

REPORT zasmm008.

$$ Declarações -

-


TYPE-POOLS:

kkblo. "Tipos para lista especial

FIELD-SYMBOLS:

TYPE table.

PARAMETERS p_qtd TYPE i OBLIGATORY DEFAULT 10.

$$ Eventos -

-


INITIALIZATION.

%_p_qtd_%_app_%-text = 'Dinamic fields quantity'.

START-OF-SELECTION.

CHECK p_qtd > 0 AND p_qtd < 100.

PERFORM f_create_dynamic_table.

PERFORM f_fill_dynamic_table.

PERFORM f_create_alv.

$$ Forms -

-


*&----


*

*& Form f_create_dynamic_table

*&----


*

FORM f_create_dynamic_table.

DATA:

lv_line TYPE i,

lv_word(72) TYPE c,

lv_form(30) TYPE c VALUE 'TABLE_CREATE',

lv_message(240) TYPE c,

lp_table TYPE REF TO data,

lp_struc TYPE REF TO data,

lv_name LIKE sy-repid,

lv_cont(02) TYPE n,

lv_lng TYPE i,

lv_typesrting(6) TYPE c.

  • The dynamic internal table stucture

DATA: BEGIN OF lt_struct OCCURS 0,

fildname(8) TYPE c,

abptype TYPE c,

length TYPE i,

END OF lt_struct.

  • The dynamic program source table

DATA: BEGIN OF lt_inctabl OCCURS 0,

line(72),

END OF lt_inctabl.

  • Sample dynamic internal table stucture

DO p_qtd TIMES.

ADD 1 TO lv_cont.

CONCATENATE 'FIELD' lv_cont INTO lt_struct-fildname.

lt_struct-abptype = 'C'.

lt_struct-length = '4'.

APPEND lt_struct.

ENDDO.

  • Create the dynamic internal table definition in the dyn. program

lt_inctabl-line = 'PROGRAM ZDYNPRO.'.

APPEND lt_inctabl.

lt_inctabl-line = 'FORM TABLE_CREATE CHANGING P_TABLE P_STRUC.'.

APPEND lt_inctabl.

lt_inctabl-line = 'DATA: BEGIN OF DYNTAB OCCURS 0,'.

APPEND lt_inctabl.

LOOP AT lt_struct.

lt_inctabl-line = lt_struct-fildname.

lv_lng = strlen( lt_struct-fildname ).

IF NOT lt_struct-length IS INITIAL .

lv_typesrting(1) = '('.

lv_typesrting+1 = lt_struct-length.

lv_typesrting+5 = ')'.

CONDENSE lv_typesrting NO-GAPS.

lt_inctabl-line+lv_lng = lv_typesrting.

ENDIF.

lt_inctabl-line+15 = 'TYPE'.

lt_inctabl-line+21 = lt_struct-abptype.

lt_inctabl-line+22 = ','.

APPEND lt_inctabl.

ENDLOOP.

lt_inctabl-line = 'END OF DYNTAB.'.

APPEND lt_inctabl.

lt_inctabl-line = 'DATA: POINTER TYPE REF TO DATA.'.

APPEND lt_inctabl.

lt_inctabl-line = 'CREATE DATA POINTER LIKE DYNTAB[].'.

APPEND lt_inctabl.

lt_inctabl-line = 'P_TABLE = POINTER.'.

APPEND lt_inctabl.

lt_inctabl-line = 'CREATE DATA POINTER LIKE LINE OF DYNTAB.'.

APPEND lt_inctabl.

lt_inctabl-line = 'P_STRUC = POINTER.'.

APPEND lt_inctabl.

lt_inctabl-line = 'ENDFORM.'.

APPEND lt_inctabl.

CATCH SYSTEM-EXCEPTIONS generate_subpool_dir_full = 9.

GENERATE SUBROUTINE POOL lt_inctabl[] NAME lv_name

MESSAGE lv_message LINE lv_line WORD lv_word.

ENDCATCH.

PERFORM (lv_form) IN PROGRAM (lv_name) CHANGING lp_table lp_struc.

  • Dynamic table in <tb> and its header line in <st>

ASSIGN lp_table->* TO .

ENDFORM. " f_create_dynamic_table

*&----


*

*& Form f_create_alv

*&----


*

FORM f_create_alv.

DATA:

ls_layout TYPE slis_layout_alv,

lv_cont(02) TYPE n,

lt_fieldcat TYPE slis_t_fieldcat_alv WITH HEADER LINE.

DO p_qtd TIMES.

CLEAR lt_fieldcat.

ADD 1 TO lv_cont.

CONCATENATE 'FIELD' lv_cont INTO lt_fieldcat-fieldname.

CONCATENATE 'Campo' lv_cont INTO lt_fieldcat-seltext_s

SEPARATED BY space.

lt_fieldcat-seltext_m = lt_fieldcat-seltext_s.

lt_fieldcat-seltext_l = lt_fieldcat-seltext_s.

lt_fieldcat-outputlen = 10.

APPEND lt_fieldcat.

ENDDO.

ls_layout-zebra = 'X'.

CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'

EXPORTING

is_layout = ls_layout

it_fieldcat = lt_fieldcat[]

TABLES

t_outtab =

EXCEPTIONS

program_error = 1

OTHERS = 2.

ENDFORM. " f_create_alv

*&----


*

*& Form f_fill_dynamic_table

*&----


*

FORM f_fill_dynamic_table.

DATA:

lv_line(2) TYPE n,

lv_field(2) TYPE n.

DO 20 TIMES.

ADD 1 TO lv_line.

CLEAR lv_field.

DO p_qtd TIMES.

ADD 1 TO lv_field.

ASSIGN COMPONENT lv_field OF STRUCTURE .

ENDDO.

ENDFORM. " f_fill_dynamic_table

Read only

Former Member
0 Likes
983

hey mauricio, thanks for your quick and useful answer.

all problems are solved.

i didn´t know

the statement

"GENERATE SUBROUTINE POOL" before.

have a nice weekend!