‎2010 Sep 21 8:59 PM
Hello experts!
I would be very grateful for assistance with a complicated requirement I have gotten.
I am working within a user exit in BI-IP and one of the parameter in the method is a table (whose structure is dynamic):
C_TH_DATA Changing Type HASHED TABLE Transaction Data
Due to the requirements I have I need to create a table based on the C_TH_DATA table BUT with a few additional fields.
I have posted my first attempt below (it is syntactically correct).
Does my approach make sense???
Grateful for any suggestions.
Greetings,
Martin
method IF_RSPLFA_SRVTYPE_IMP_EXEC_REF~EXECUTE.
field-symbols:
<f_ref_data> type any,
<f_interim_data> type any,
<f_new_data> type any,
<f_itab> type any table,
<f_infoprov> type RSINFOPROV,
<f_infoprov_ref> type RSINFOPROV,
<f_ref_data_BCCMP07> type any,
<f_ref_data_BCCMC02> type any,
<f_spc> type /bic/oiBHSPC0,
<f_spc_ref> type /bic/oiBHSPC0,
<f_blcopem1> type /bic/oiblcopem1,
<f_blcopem1_ref> type /bic/oiblcopem1,
<f_blcalpo0> type /bic/oiblcalpo0,
<f_blcalpo0_ref> type /bic/oiblcalpo0.
data:
l_r_data1 type ref to data,
l_r_data2 type ref to data,
l_d_sumcostpo type f,
l_d_deltacostpo type f,
l_d_sumdeltacostpo type f.
Generate new (empty record)
create data l_r_data1 like line of c_th_data.
assign l_r_data1->* to <f_new_data>.
TYPES:
BEGIN OF l_modif_c_th_data,
l_r_itab type ref to data,
thiscostpo type /bic/oiblcopem1,
thiscostto type /bic/oiblcopem2,
thiscostcm type /bic/oiblcopem3,
thismanpo type /bic/oiblmansec1,
thismanto type /bic/oiblmansec2,
thismancm type /bic/oiblmansec3,
END OF l_modif_c_th_data.
data:
l_r_itab type ref to data.
create data l_r_itab type table of l_modif_c_th_data.
assign l_r_itab->* to <f_itab>.
Generate new (empty record)
create data l_r_data2 type l_modif_c_th_data.
assign l_r_data2->* to <f_interim_data>.
‎2010 Sep 21 9:26 PM
Hi Martin,
What you want is to include all the components from table C_TH_DATA + some additional ones. What you do here
TYPES:
BEGIN OF l_modif_c_th_data,
l_r_itab type ref to data,
thiscostpo type /bic/oiblcopem1,
thiscostto type /bic/oiblcopem2,
thiscostcm type /bic/oiblcopem3,
thismanpo type /bic/oiblmansec1,
thismanto type /bic/oiblmansec2,
thismancm type /bic/oiblmansec3,
END OF l_modif_c_th_data.
is creating a type (for a table) where one component is a "pointer" to other table + new components. As long as you address l_r_itab table independently of other components you can leave with that. However this rather creates a deep table (with reference to other table as a component) then a flat one (where all components are of elementary data types).
I would suggest to search a little bit around CL_ALV_TABLE_CREATE=>CREATE_DYNAMIC_TABLE where you can provide any component listing as ALV fieldcatalog generating this way new table.
OR
Use dynamic data generation by means of RTTS . Please refer my blog [Do you really know everything about typing? - part 2|http://www.sdn.sap.com/irj/scn/weblogs?blog=/pub/wlg/20887] [original link is broken] [original link is broken] [original link is broken];.
Regards
Marcin
‎2010 Sep 22 5:54 PM
Hi marcin,
thanks for your answer.
Im trying your examples ( /people/marcin.pciak/blog/2010/09/09/do-you-really-know-everything-about-typing--part-2 ) but your example dumps.
DATA gr_elemdescr_p TYPE REF TO cl_abap_elemdescr.
DATA gr_elemdescr_i TYPE REF TO cl_abap_elemdescr.
DATA: gt_components TYPE cl_abap_structdescr=>component_table,
wa_component LIKE LINE OF gt_components.
DATA: gr_structdescr TYPE REF TO cl_abap_structdescr.
wa_component-name = 'HEADCOUNT'.
wa_component-type = gr_elemdescr_i.
APPEND wa_component TO gt_components.
wa_component-name = 'CAPACITY'.
wa_component-type = gr_elemdescr_p.
APPEND wa_component TO gt_components.
gr_structdescr = cl_abap_structdescr=>create( gt_components ). <= causes error CX_SY_STRUCT_COMP_TYPE
DATA gr_data TYPE REF TO data.
CREATE DATA gr_data TYPE HANDLE gr_structdescr.
I suspect Im doin something wrong.
‎2010 Sep 22 7:07 PM
You are missing component creation. At the end of the blog there is a full code which you can use, but what you need is
*-- elementary type reference variables
DATA: gr_elemdescr_i TYPE REF TO cl_abap_elemdescr,
gr_elemdescr_p TYPE REF TO cl_abap_elemdescr,
gr_elemdescr_n TYPE REF TO cl_abap_elemdescr.
*-- generate fields
gr_elemdescr_p = cl_abap_elemdescr=>get_p( p_length = 6 p_decimals = 2 ). "
gr_elemdescr_i = cl_abap_elemdescr=>get_i( ).
Now gr_elemdescr_i and gr_elemdescr_p can be passed to wa_component-type , otherwise there are empty.
Regards
Marcin
PS: what you can also do is:
- use describe_by_data method of cl_abap_typedescr for C_TH_DATA
- call get_table_line (or similar method - don't know it by heart) to get the line type
- get all the components of the structure
- add new components as shown in the blog appending new rows to component table
- generate brand new structure based on this component table
Edited by: Marcin Pciak on Sep 22, 2010 8:08 PM
‎2010 Sep 21 10:49 PM
Hello Martin
You may have a look at the Wiki
[Creating Flat and Complex Internal Tables Dynamically using RTTI |http://wiki.sdn.sap.com/wiki/display/Snippets/CreatingFlatandComplexInternalTablesDynamicallyusingRTTI]
I have not yet tried to generate a HASHED table but I think even this should be possible.
Regards
Uwe
‎2010 Sep 22 7:32 PM
Hello Uwe,
thanx for your answer. The example provided in the link ( http://wiki.sdn.sap.com/wiki/display/Snippets/CreatingFlatandComplexInternalTablesDynamicallyusingRTTI ) is very interesting BUT it deals with a DBtable.
I am using an at runtime generated internal table.
I am unable to get the statement:
go_sdescr ?= cl_abap_structdescr=>describe_by_name( p_tabnam ).
to work with this internal table.
I have tried:
go_tdescr ?= cl_abap_typedescr=>describe_by_data( I_T_DATA_CHARSEL ).
but it doesnt contain the fields ... what am I doing wrong?
‎2010 Sep 22 7:59 PM
Ok, this should go like
data: go_tdescr type ref to cl_abap_tabledescr,
go_sdescr type ref to cl_abap_structdescr,
go_edescr type ref to cl_abap_elemdescr.
data gt_components type cl_abap_structdescr=>component_table.
"get table description based on table data
go_tdescr ?= cl_abap_typedescr=>describe_by_data( C_TH_DATA ).
"get its line type
go_sdescr = go_tdescr->GET_TABLE_LINE_TYPE( ).
"and components
gt_components = go_sdescr->get_components( ).
"now add new components
"here you must provide DDIC type
go_edescr ?= cl_abap_typedescr=>describe_by_name( '/BIC/POBLCOPEM1' ).
wa_component-name = 'THISCOSTPO'.
wa_component-type = go_edescr.
APPEND wa_component TO gt_components.
"do the same for rest of the components
...
"now generate new structure type
gr_sdescr = cl_abap_structdescr=>create( gt_components ).
That's it.
Regards
Marcin
‎2015 Jun 26 3:59 PM
Hello,
in my case the structure creation still throws the exception "CX_SY_STRUCT_COMP_TYPE". I use a a table type from the type pool (SPTA_T_INDXTAB). Using an none table type from the type pool the error doesn't occure. Someone has an idea? Here is the code:
DATA lt_component_tab TYPE abap_component_tab.
DATA ls_component TYPE abap_componentdescr.
ls_component-name = 'tab'.
ls_component-type ?= cl_abap_typedescr=>describe_by_name( 'SPTA_T_INDXTAB' ).
APPEND ls_component TO lt_component_tab.
lr_structdescr = cl_abap_structdescr=>create( lt_component_tab ).