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

Dynamic Internal table Problem

Former Member
0 Likes
1,682

Hi Friends,

My requirement is to build a dynamic internal table. I have already used the approach of using

CALL METHOD cl_alv_table_create=>create_dynamic_table..But its constraint of not running more than 36 times is making it inappropriate for my requirement.I got to know about the below mentioned method from Forums and its really suiting my requirement as it has no limitations but as you can see below in code that it is using a DDIC Structure from where it fetches the name of the fields of structure and hence make it dynamic.

Let us assume my structure looks somewhat like this :

COMPONENT Dtyp Size Decimals

COL01 INT1 3 0

COL02 INT1 3 0

COL03 INT1 3 0

COL04 INT1 3 0

COL05 INT1 3 0

COL06 INT1 3 0

COL07 INT1 3 0

COL08 INT1 3 0

Now my dynamic internal table's column contains:

COL01 COL02 COL03 COL04 COL05 COL06 COL07 COL08

But i want to make these columns dynamic.In other words,

CREATE DATA gv_ref TYPE STANDARD TABLE OF (STRUCTNAME).
ASSIGN gv_ref->* TO <t_dyntable>.

Here it is bringing all the fields of STRUCTNAME into the columns of Dynamic Internal table.Can we bring our desired number of fields out of these 8 fields ranging from COL01 TO COL08.

For ex : from COL01 to COL04.

from COL01 to COL03.

from COL01 to COL06.

from COL01 to COL08.

This modification will actually make the table a dynamic internal table.

Please throw some light upon this idea.Code is pasted below for reference.

Thanks and Regards,

Gaurav

REPORT zdyntable .
DATA : t_newtable TYPE REF TO data,t_newline  TYPE REF TO data,t_fldcat TYPE lvc_t_fcat.
DATA : STRUCTNAME(15) value 'ZSTRUCTCOL'.
DATA : gv_ref TYPE REF TO data.
DATA : gv_area TYPE REF TO data.
DATA : gv_val TYPE REF TO data.

FIELD-SYMBOLS: <fs_table> TYPE STANDARD TABLE,
<fs_update> TYPE STANDARD TABLE,
<fs_data> TYPE ANY.
FIELD-SYMBOLS: <t_dyntable> TYPE STANDARD TABLE,
             <t_dyntable1> TYPE STANDARD TABLE,
             <fs_dyntable>,
             <fs_fldval> TYPE ANY,
             <fs_col1>,<fs_col2>.


CREATE DATA gv_ref TYPE STANDARD TABLE OF (STRUCTNAME).
ASSIGN gv_ref->* TO <t_dyntable>.
CREATE DATA t_newline LIKE LINE OF <t_dyntable>.

10 REPLIES 10
Read only

venkat_o
Active Contributor
0 Likes
1,221

Hello Gaurav,

Have a look at this sample program and execute the program . On selection-screen give some number.

<pre>

REPORT ztest_notepad.

&----


*& Declarations

&----


*Type-pools

TYPE-POOLS:

slis.

*Types

TYPES:

ty_fcat TYPE lvc_s_fcat,

ty_fcatalog TYPE slis_fieldcat_alv.

*Work areas

DATA:

wa_fcat TYPE ty_fcat,

wa_fcatalog TYPE ty_fcatalog.

*Internal tables

DATA:

it_fcat TYPE STANDARD TABLE OF ty_fcat,

it_fcatalog TYPE STANDARD TABLE OF ty_fcatalog.

*Type reference

DATA:

it_dyn_tab TYPE REF TO data,

wa_newline TYPE REF TO data.

*Filed symbols

FIELD-SYMBOLS:

<gt_table> TYPE STANDARD TABLE,

<fs_dyntable>,

<fs_fldval> TYPE ANY,

<l_field> TYPE ANY.

*Variables

DATA:

l_fieldname TYPE lvc_s_fcat-fieldname,

l_tabname TYPE lvc_s_fcat-tabname,

l_fieldtext TYPE lvc_s_fcat-seltext,

l_index TYPE char2.

"Selection-screen

PARAMETERS:

p_colms TYPE i.

&----


*& start-of-selection.

&----


START-OF-SELECTION.

PERFORM build_fieldcat.

PERFORM create_dynamic_table.

DO 20 TIMES.

DO p_colms TIMES.

l_index = sy-index.

CONCATENATE 'FIELD' l_index INTO l_fieldname.

ASSIGN COMPONENT l_fieldname OF STRUCTURE <fs_dyntable> TO <l_field>.

<l_field> = sy-index.

ENDDO.

INSERT <fs_dyntable> INTO TABLE <gt_table>.

ENDDO.

LOOP AT it_fcat INTO wa_fcat.

PERFORM fieldcatalog1 USING: wa_fcat-fieldname

wa_fcat-tabname

wa_fcat-seltext.

ENDLOOP.

CALL FUNCTION 'REUSE_ALV_LIST_DISPLAY'

EXPORTING

i_callback_program = 'ZTEST_NOTEPAD'

it_fieldcat = it_fcatalog

TABLES

t_outtab = <gt_table>.

&----


*& Form BUILD_FIELDCAT

&----


FORM build_fieldcat .

CLEAR: l_fieldname,

l_tabname,

l_fieldtext,

l_index.

DO p_colms TIMES.

CLEAR l_index.

l_index = sy-index.

CONCATENATE 'FIELD' l_index INTO l_fieldname.

CONCATENATE 'Field' l_index INTO l_fieldtext.

l_tabname = '<GT_TABLE>'.

PERFORM fieldcatalog USING: l_fieldname

l_tabname

l_fieldtext.

ENDDO.

ENDFORM. " BUILD_FIELDCAT

&----


*& Form CREATE_DYNAMIC_TABLE

&----


FORM create_dynamic_table .

CALL METHOD cl_alv_table_create=>create_dynamic_table

EXPORTING

it_fieldcatalog = it_fcat

IMPORTING

ep_table = it_dyn_tab.

ASSIGN it_dyn_tab->* TO <gt_table>.

  • Create dynamic work area and assign to FS

CREATE DATA wa_newline LIKE LINE OF <gt_table>.

ASSIGN wa_newline->* TO <fs_dyntable>.

ENDFORM. " CREATE_DYNAMIC_TABLE

&----


*& Form FIELDCATALOG

&----


FORM fieldcatalog USING field table f_txt.

wa_fcat-fieldname = field.

wa_fcat-tabname = table.

wa_fcat-seltext = f_txt.

APPEND wa_fcat TO it_fcat.

CLEAR wa_fcat.

ENDFORM. " FIELDCATALOG

&----


*& Form FIELDCATALOG1

&----


FORM fieldcatalog1 USING field table f_txt.

wa_fcatalog-fieldname = field.

wa_fcatalog-tabname = table.

wa_fcatalog-seltext_m = f_txt.

APPEND wa_fcatalog TO it_fcatalog.

CLEAR wa_fcatalog.

ENDFORM. " FIELDCATALOG1</pre>

Thanks

Venkat.O

Read only

Former Member
0 Likes
1,221

Hi venkat,

Thanks for the reply.But i have stated my limitation that i cannot use this method as it is not running more than 36 times.

Thanks,

Gaurav

Read only

Former Member
0 Likes
1,221

Hi,

I had created a dynamic internal table making use of a dynamic program within my current program.

You can try on the similar lines.

The reference code is as follows:-

PERFORM y_f_build_table USING y_li_fcat_tbl
                            CHANGING y_v_tmpprgm.
    PERFORM table_create IN PROGRAM (y_v_tmpprgm)
                          CHANGING y_lv_new_table .
    ASSIGN  y_lv_new_table->* TO  <y_lf_table>.

Here Y_LI_FCAT_TABLE is basically a fieldcatalog table with the fieldname; reference field name; reference table name and other such details

The perform Y_F_BUILD_TABLE basically creates a dynamic internal table.

FORM y_f_build_table  USING    y_li_fcat  TYPE lvc_t_fcat
                      CHANGING y_lv_repid TYPE syrepid.

  DATA : y_lv_message  TYPE char255,
         y_lv_line     TYPE i,
         y_lv_word     TYPE char72.

  DATA : y_lwa_fcat     TYPE lvc_s_fcat,
         y_lwa_source   TYPE string.

  DATA : y_li_source    LIKE STANDARD TABLE OF y_lwa_source
         WITH HEADER LINE.

  CONSTANTS : y_lk_dyn_rptname TYPE char70 VALUE
              'REPORT GENENERATED_SUBROUTINE_POOL.',

              y_lk_dyn_formname TYPE char70 VALUE
              'FORM  TABLE_CREATE CHANGING NEW_TABLE.',

              y_lk_dyn_begin TYPE char70 VALUE
              'DATA: BEGIN OF LT_GENTAB OCCURS 0.',

              y_lk_dyn_end TYPE char70 VALUE
              'DATA: END OF LT_GENTAB.',

              y_lk_dyn_reference TYPE char70 VALUE
              'DATA: POINTER TYPE REF TO DATA.',

              y_lk_dyn_create TYPE char70 VALUE
              'CREATE DATA POINTER LIKE STANDARD TABLE OF LT_GENTAB.',

              y_lk_dyn_move   TYPE    char70 VALUE
              'NEW_TABLE = POINTER.',

              y_lk_dyn_endform TYPE char70 VALUE
              'ENDFORM.',

              y_lk_data TYPE char5  VALUE 'DATA:',
              y_lk_type TYPE char4  VALUE 'TYPE'.

y_lwa_source = y_lk_dyn_rptname.
  APPEND y_lwa_source TO y_li_source.

  y_lwa_source = y_lk_dyn_formname.
  APPEND y_lwa_source TO y_li_source.

  y_lwa_source = y_lk_dyn_begin.
  APPEND y_lwa_source TO y_li_source.

LOOP AT y_li_fcat INTO y_lwa_fcat.

cASE y_lwa_fcat-sp_group.
      WHEN y_k_cell OR y_k_color.

CONCATENATE y_lk_data  y_lwa_fcat-fieldname

y_lk_type

Read only

0 Likes
1,221

continuin with the code.

y_lwa_fcat-ref_table   y_k_dot   INTO y_lwa_source  SEPARATED BY space.

WHEN OTHERS.

        CONCATENATE y_lk_data
              y_lwa_fcat-fieldname
              y_lk_type
              y_lwa_fcat-ref_table
              INTO y_lwa_source
              SEPARATED BY space.

        CONCATENATE y_lwa_source
                    y_k_minus
                    y_lwa_fcat-ref_field
                    y_k_dot
                    INTO y_lwa_source.

    ENDCASE.

APPEND y_lwa_source TO y_li_source.
    CLEAR : y_lwa_source, y_wa_fcat.

  ENDLOOP.

y_lwa_source = y_lk_dyn_end.
  APPEND y_lwa_source TO y_li_source.

  y_lwa_source = y_lk_dyn_reference.
  APPEND y_lwa_source TO y_li_source.

  y_lwa_source = y_lk_dyn_create.
  APPEND y_lwa_source TO y_li_source.

  y_lwa_source = y_lk_dyn_move.
  APPEND y_lwa_source TO y_li_source.

  y_lwa_source = y_lk_dyn_endform.
  APPEND y_lwa_source TO y_li_source.


  CLEAR: y_lwa_source.

  y_lv_repid = sy-repid.

CATCH SYSTEM-EXCEPTIONS generate_subpool_dir_full = y_k_9.
    GENERATE SUBROUTINE POOL y_li_source NAME y_lv_repid
    MESSAGE y_lv_message LINE y_lv_line WORD y_lv_word.
  ENDCATCH.

  CASE sy-subrc.
    WHEN y_k_0.
    WHEN y_k_9.
      RAISE generate_subpool_dir_full.
    WHEN OTHERS.
      MESSAGE x999 WITH y_lv_message y_lv_line y_lv_word.
  ENDCASE.

IF NOT y_v_message IS INITIAL.
    MESSAGE e999 WITH y_lv_message y_lv_line y_lv_word.
  ENDIF.   "IF NOT y_v_message IS INITIAL.


ENDFORM

So in this way i am creating a dynamic program and in that i am creating a internal table and then taking reference of that internal table.

This may not be a best of the method but it can serve your purpose.

Try to understand the concept.

Regards,

Ankur Parab

Read only

0 Likes
1,221

Hi Ankur,

Thanks for the reply..but the approach you are using here is nothing but it is using subroutine buffer which has also got the same limitation of 36 times execution.

GENERATE SUBROUTINE POOL y_li_source NAME y_lv_repid
    MESSAGE y_lv_message LINE y_lv_line WORD y_lv_word.
  ENDCATCH.

Notes from the system for your information:

1.Temporary subroutine pools belong to the runtime context of the generating program, i.e. to the roll area of the internal mode from which the generation is performed. They may therefore be addressed only within this context, i.e. the generated FORM routines can only be called from within the generating mode.

2.Up to 36 temporary subroutine pools can currently be managed for each roll area.

3.You must carry out the necessary authorization and system checks before calling GENERATE SUBROUTINE POOL.

Thats why I am looking for an alternative..

Thanks and Regards,

Gaurav

Edited by: Gaurav Kumar on Jul 6, 2009 1:26 PM

Read only

0 Likes
1,221

Hi Gaurav,

All approaches posted here finally use generate subroutine pool which also does a COMMIT WORK implicitly.

There is a clear alternative: RTTI dynamic Type services.

Look at this sample, it creates a dynamic table for a range tyble of any type:

METHOD FACTORY.
* take RSDSSELOPT, exchange LOW/HIGH characteristics
  DATA:
    lv_sign        TYPE tvarv_sign,
    lv_opti        TYPE tvarv_opti,
    lt_components  TYPE cl_abap_structdescr=>component_table,
    lo_range_descr TYPE REF TO cl_abap_structdescr,
    lo_tdescr      TYPE REF TO cl_abap_tabledescr,
    lr_range       TYPE REF TO data,
    lv_i           TYPE i.
  FIELD-SYMBOLS:
    <component>   TYPE LINE OF abap_component_tab,
    <range_tab>   TYPE STANDARD TABLE..
  APPEND INITIAL LINE TO lt_components ASSIGNING <component>.
  <component>-type ?= cl_abap_datadescr=>describe_by_data( lv_sign ).
  <component>-name = 'SIGN'.
  APPEND INITIAL LINE TO lt_components ASSIGNING <component>.
  <component>-type ?= cl_abap_datadescr=>describe_by_data( lv_opti ).
  <component>-name = 'OPTION'.
  APPEND INITIAL LINE TO lt_components ASSIGNING <component>.
  <component>-type ?= cl_abap_datadescr=>describe_by_data( iv_any ).
  <component>-name = 'LOW'.
  APPEND INITIAL LINE TO lt_components ASSIGNING <component>.
  <component>-type ?= cl_abap_datadescr=>describe_by_data( iv_any ).
  <component>-name = 'HIGH'.
  lo_range_descr   ?= cl_abap_structdescr=>create( lt_components ).
  lo_tdescr        = cl_abap_tabledescr=>create( lo_range_descr ).
  CREATE OBJECT ro_range.
  CREATE DATA ro_range->mr_rangetab TYPE HANDLE lo_tdescr.
ENDMETHOD.

The Code posted is part of a class for creation and use of dynamically created ranges for fields of any types - passed as parameter iv_any.

I tried to construct tables with many fields and found a bug in the ABAP system: You should never create fields refering to dictionary table or structure or data elements without domain. Some lazy developers do not create a domain but use direct built-in type entry for the data element. Those fields may show wrong behavior in the table created dynamically; i.e. F1/F4 and the missing negative values / lowercase characters flag may be misinterpreted.

You can not use the above code directly but you will have to adapt it to you needs.

Please let me know if you have trouble using the idea, I may help you further.

Kind regards,

Clemens

Read only

0 Likes
1,221

Hi clemens,

Thanks for the valuabele input..But i think this method cannot be used in 4.7 version and i am using SAP 4.7.

Thanks and Regards,

Guarav

Read only

0 Likes
1,221

Hi Gaurav,

There is no other way in 4.7. You have cl_salv_table=>factory in ECC version.

But in 4.7 you have to live with this limitation

Cheers,

Kothand

Read only

0 Likes
1,221

message was irrelevant.. sorry.

Edited by: Gavin Jones on Sep 9, 2009 9:48 PM

Edited by: Gavin Jones on Sep 9, 2009 9:49 PM

Read only

Clemenss
Active Contributor
0 Likes
1,221

Hi Gaurav,

in 4.7 you still have the way of creating a distionary structure with the absolute maximum of columns ever required. The in the code, you define a table of <dictionry structure>.

The create the full field catalog using the LVC or ALV FIELDCATALOG_MERGE function modules.

In the fieldcatalog, set all fields to TECH = 'X' except the ones you need dynamically.

The rest should be clear, you may close the thread if no further questions remain.

Regards,

Clemens