05-06-2010 9:01 AM
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
05-06-2010 9:06 AM
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.
05-06-2010 9:06 AM
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.
05-06-2010 9:52 AM
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
05-06-2010 9:59 AM
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
05-06-2010 11:44 AM
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:
<itab> TYPE TABLE.
ASSIGN ro_range->mr_rangetab->* to <itab>.
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 <rec>-<fieldname>. To get access, use ASSIGN COMPONENT <fieldname> OF STRUCTURE <rec> to <any>.
If you get stuck that way, feel free to ask.
Regards,
Clemens
Edited by: Clemens Li on May 6, 2010 12:44 PM
05-06-2010 11:45 AM
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
05-06-2010 9:13 AM
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
.
05-06-2010 12:16 PM
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.
05-06-2010 1:52 PM
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