Application Development 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: 

Create internal table dynamically

stefan_kolev4
Participant
0 Kudos

Hi Gurus,

I'd like to create an internal table based on the contents of internal table. For example contents of itab is fieldname, fieldtext and I need to create internal table dynamically from these fields.

Please advice me !

Stefan

1 ACCEPTED SOLUTION

Former Member
0 Kudos

HI,

This program creates internal table dynamically and sort it too.


REPORT  zreport_SORT.

parameters:
  p_f1(15) obligatory,
  p_f2(15) obligatory,
  p_f3(15) obligatory,
  p_table(15).

data:
  w_tab type ref to data,
  fs_tab type ref to data,
  w_flag,
  w_count type i.


create data w_tab type table of  (p_table) .
create data fs_tab type (p_table).

data:
  t_tab type table of spfli,
  fs_tab1 like line of t_tab.

field-symbols:
  <fs> type any table,
  <fs1> type any,
  <fs2> type any,
  <fs3> type any,
  <fs4> type any.

at selection-screen.

select count(*)
  from dd03l
  into w_count
 where tabname eq p_table
   and fieldname eq p_f1.
if w_count eq 0.
  w_flag = 'Y'.
 endif.
select count(*)
  from dd03l
  into w_count
 where tabname eq p_table
   and fieldname eq p_f2.

if w_count eq 0.
  w_flag = 'Y'.
 endif.

select count(*)
  from dd03l
  into w_count
 where tabname eq p_table
   and fieldname eq p_f3.

if w_count eq 0.
  w_flag = 'Y'.
 endif.
if w_flag eq 'Y'.
 clear w_flag.
 Message 'Incorrect field name' type 'E'.
endif.

start-of-selection.
assign w_tab->* to <fs>.
assign fs_tab->* to <fs1>.

  select *
    from (p_table)
    into corresponding fields of
   table <fs> up to 10 rows.
   sort <fs> by (p_f1) ascending (p_f2) ascending (p_f3) ascending.

assign component p_f1 of structure <fs1> to <fs2>.
assign component p_f2 of structure <fs1> to <fs3>.
assign component p_f3 of structure <fs1> to <fs4>.


  loop at <fs> into <fs1>.
  write:/ <fs2>,
          <fs3>,
          <fs4>.
  endloop.

Regards and Best wishes.

8 REPLIES 8

Former Member
0 Kudos

HI,

This program creates internal table dynamically and sort it too.


REPORT  zreport_SORT.

parameters:
  p_f1(15) obligatory,
  p_f2(15) obligatory,
  p_f3(15) obligatory,
  p_table(15).

data:
  w_tab type ref to data,
  fs_tab type ref to data,
  w_flag,
  w_count type i.


create data w_tab type table of  (p_table) .
create data fs_tab type (p_table).

data:
  t_tab type table of spfli,
  fs_tab1 like line of t_tab.

field-symbols:
  <fs> type any table,
  <fs1> type any,
  <fs2> type any,
  <fs3> type any,
  <fs4> type any.

at selection-screen.

select count(*)
  from dd03l
  into w_count
 where tabname eq p_table
   and fieldname eq p_f1.
if w_count eq 0.
  w_flag = 'Y'.
 endif.
select count(*)
  from dd03l
  into w_count
 where tabname eq p_table
   and fieldname eq p_f2.

if w_count eq 0.
  w_flag = 'Y'.
 endif.

select count(*)
  from dd03l
  into w_count
 where tabname eq p_table
   and fieldname eq p_f3.

if w_count eq 0.
  w_flag = 'Y'.
 endif.
if w_flag eq 'Y'.
 clear w_flag.
 Message 'Incorrect field name' type 'E'.
endif.

start-of-selection.
assign w_tab->* to <fs>.
assign fs_tab->* to <fs1>.

  select *
    from (p_table)
    into corresponding fields of
   table <fs> up to 10 rows.
   sort <fs> by (p_f1) ascending (p_f2) ascending (p_f3) ascending.

assign component p_f1 of structure <fs1> to <fs2>.
assign component p_f2 of structure <fs1> to <fs3>.
assign component p_f3 of structure <fs1> to <fs4>.


  loop at <fs> into <fs1>.
  write:/ <fs2>,
          <fs3>,
          <fs4>.
  endloop.

Regards and Best wishes.

0 Kudos

Probably I wasn't clear. I'm sorry. The idead is as follows: I have an internal table and it have one field for ex. 'fld'. I have 3 rows with contents for ex.

1 - ClientID

2 - Name1

3 - Name2

I'd lie to create internal table dynamically with structure / fields / based on the contents of internal table mentioned above.

Stefan

0 Kudos

Hi Stefan,

you can do it this way.....

first fill the fieldcatalog by those fieldnames giving the data type, fieldname and stuff... which ever are required by you....

and then pass this field catalog as mentioned below....

* Creates the internal table dynamically with respect to the
* field catalog prepared in the above steps...
DATA: mr_tot_cap_res_tab TYPE REF TO data,
         mt_fcat TYPE lvc_t_fcat.
" fill the field catalog.... here..........
    CALL METHOD cl_alv_table_create=>create_dynamic_table
      EXPORTING
        it_fieldcatalog = mt_fcat
      IMPORTING
        ep_table        = mr_tot_cap_res_tab.

Thanks,

Sid

0 Kudos

Hi Stefan,

please avoid

cl_alv_table_create=>create_dynamic_table

This method uses statement GENERATE SUBROUTINE POOL which is limited to just a couple of calls in one LUW. Furthermore it creates an (unwanted) database COMMIT because the generated code is stored in the database.

See this factory method to create a range table. Note: For every field you should use an existing DDIC Data element.

METHOD FACTORY.
  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.

  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.

To use the table, you can not avoid using field-symbols. You may proceed like

FIELD-SYMBOLS:
  &LT;itab&GT; TYPE TABLE.   
ASSIGN  ro_range->mr_rangetab->* to &LT;itab&GT;.

Then the internal table may be used.

Because the structure is not known at compile time, you can not access the fields in the usual way as &LT;rec&GT;-&LT;fieldname&GT;. To get access, use ASSIGN COMPONENT &LT;fieldname&GT; OF STRUCTURE &LT;rec&GT; to &LT;any&GT;.

If you get stuck that way, feel free to ask.

Regards,

Clemens

Edited by: Clemens Li on May 6, 2010 12:44 PM

0 Kudos

Sorry, one addition that did not fit in the character limit:

If field-symbols are new to you, it will cause some trouble at the beginning. Just remember that a field-symbol is assigned to a data object and then is used the same way as the data object itself, the field-symbol is a replacement of the name of the original data object - anything you do with the field-symbol is done with the data object it is assigned to.

Regards,

Clemens

Former Member
0 Kudos
DATA: itab TYPE STANDARD TABLE OF <<tablename>>, 
              wa LIKE LINE OF itab. 

DATA: fieldname(120) TYPE c, 
            fieldtext LIKE TABLE OF fieldname(120). 

START-OF-SELECTION. 
fieldname = ' ABCD  XXXX'. 
fieldname = ' EFGH '. 
 APPEND fieldname TO fieldtext. 

SELECT DISTINCT (fieldname) 
       INTO CORRESPONDING FIELDS OF TABLE itab 
            FROM <tablename>. 

IF sy-subrc EQ 0. 
  LOOP AT itab INTO wa. 
      WRITE: / wa-ABCD, wa-XXXX. 
       WRITE 😕 wa-EFGH. 
  ENDLOOP. 
ENDIF

.

0 Kudos

Hi,

Thanks for help ! Very simple and understandable, but I'd like to clarify one more thing !

Ok in your example itab consist what I need, but it consist many other fields. I'd like to have let's say 'final' internal table which should have only those fields, which I already selected and later to show that internal table using ALV.

0 Kudos

Hi Stefan,

some more code line where we create an itab with dynamic numer of columns (see the loop)

APPEND INITIAL LINE TO lt_components ASSIGNING <component>.
  <component>-type ?= cl_abap_datadescr=>describe_by_data( lv_time ).
  <component>-name = mc_colname_prof_time.
* value columns
  lr_data = get_ref_2_t_column( ).
  ASSIGN lr_data->* TO <table>.
  LOOP AT <table> ASSIGNING <any>.
    APPEND INITIAL LINE TO lt_components ASSIGNING <component>.
    <component>-type ?=
      cl_abap_datadescr=>describe_by_data( lv_prof_value ).
    <component>-name = get_colname_4_column( <any> ).
  ENDLOOP.
* description for single record
  lo_structdescr   ?= cl_abap_structdescr=>create( lt_components ).
* description for table
  lo_tdescr        = cl_abap_tabledescr=>create( lo_structdescr ).
* create table object
  CREATE DATA rr_table TYPE HANDLE lo_tdescr.

Later we display it using SALV

DATA:
    lr_alvtab       TYPE REF TO data.
    lr_alvtab = get_data( ).
    salv_display( lr_alvtab ).
METHOD salv_display.
* MO_SALV	Instance Attribute	Private	Type Ref To	CL_SALV_TABLE
  FIELD-SYMBOLS:
    <alvtab>       TYPE table.
  DATA:
    lo_container   TYPE REF TO cl_gui_container.
  lo_container ?= get_container( ).

  ASSIGN ir_table->* TO <alvtab>.
  TRY.
      cl_salv_table=>factory(
       EXPORTING
         list_display    = if_salv_c_bool_sap=>false
         r_container     = lo_container
       IMPORTING
          r_salv_table   = mo_salv
        CHANGING
          t_table        = <alvtab> ).
    CATCH cx_salv_msg.                                  "#EC NO_HANDLER
  ENDTRY.
* set the columns headers according to selected function
  set_column_headers( ) .
  set_salv_functions( ).
  mo_salv->display( ).
  set_layout_properties( ) .
ENDMETHOD.

Try this way, see CL_SALV_TABLE blogs, Rich Heilman created good intro.

Regards,

Clemens