06-08-2011 9:51 AM
Hello Xperts,
from the following code we are calling a method READ_SELECTIVELY:
TYPES:
t_struct TYPE TABLE OF /BIC/VBPPP01j
DATA:
t_all_data TYPE t_struct,
w_dref type ref to data.
GET REFERENCE OF t_all_data into w_dref.
CALL METHOD ZCL_B_TECHNICAL_UTILITY=>READ_SELECTIVELY
IMPORTING
P_SEL_READ_DATA = w_dref.
Pls note: it is coded like this because method READ_SELECTIVELY is supposed to work generically with t_struct being a table of any type.
Declarations of method READ_SELECTIVELY:
method READ_SELECTIVELY.
public section.
type-pools RSDRC .
class-methods READ_CUBE_SELECTIVELY
exporting
!P_CUBE_SEL_READ_DATA type ref to DATA .
Coding of method READ_SELECTIVELY:
method READ_SELECTIVELY.
DATA:
go_sdescr TYPE REF TO cl_abap_structdescr,
go_sdescr_new TYPE REF TO cl_abap_structdescr,
go_tdescr TYPE REF TO cl_abap_tabledescr,
gdo_handle TYPE REF TO data,
gs_element TYPE REF TO cl_abap_elemdescr,
gt_components type cl_abap_structdescr=>component_table,
gs_component like line of gt_components,
gs_comp like line of gt_components.
field-symbols:
<g_t_data> TYPE STANDARD TABLE.
go_tdescr ?= cl_abap_tabledescr=>describe_by_data( P_CUBE_SEL_READ_DATA ).
go_sdescr ?= go_tdescr->get_table_line_type( ).
* Begin create dynamic standard table copy of P_CUBE_SEL_READ_DATA
" Create instances of dynamic structure and dynamic internal table
go_sdescr_new = cl_abap_structdescr=>create( P_COMPONENTS = gt_components p_strict = abap_false ).
go_tdescr = cl_abap_tabledescr=>create( go_sdescr_new ).
" Create data refence followed by table creation
CREATE DATA gdo_handle TYPE HANDLE go_tdescr.
ASSIGN gdo_handle->* TO <g_t_data>.
* End create dynamic standard table copy of P_CUBE_SEL_READ_DATA
...
The idea is to create a copy of the table passed thru parameter P_CUBE_SEL_READ_DATA. After that the copy will be filled and in a loop appended to P_CUBE_SEL_READ_DATA which will be returned to the calling coding (i.e. the first code snippet above). Makes sense?
Unfortunately it fails at the statement:
go_tdescr ?= cl_abap_tabledescr=>describe_by_data( P_CUBE_SEL_READ_DATA ).
Any suggestions are very appreciated.
06-08-2011 10:40 AM
If you want to pass the table and modify it within method's body, you need to use changing parameter. I guess describe_by_data fails as P_CUBE_SEL_READ_DATA has initial value at that point (you marked it only as EXPORTING parameter so it receives this initial value and method entry). Changing the parameter signature should do the job, as at point of describe_by_data call this data reference won't be empty anymore.
Another issue is that you should be using method DESCRIBE_BY_DATA_REF not DESCRIBE_BY_DATA as the expected parameter type is data reference in first case, and simple data in the latter one.
So the correct snippet would be
"signature
class-methods READ_CUBE_SELECTIVELY
changing
!P_CUBE_SEL_READ_DATA type ref to DATA .
"method
if P_CUBE_SEL_READ_DATA is bound.
go_tdescr ?= cl_abap_tabledescr=>DESCRIBE_BY_DATA_REF( P_CUBE_SEL_READ_DATA ).
....
else.
"raise some exception saying that data reference is initial
endif.
Regards
Marcin
06-08-2011 10:40 AM
If you want to pass the table and modify it within method's body, you need to use changing parameter. I guess describe_by_data fails as P_CUBE_SEL_READ_DATA has initial value at that point (you marked it only as EXPORTING parameter so it receives this initial value and method entry). Changing the parameter signature should do the job, as at point of describe_by_data call this data reference won't be empty anymore.
Another issue is that you should be using method DESCRIBE_BY_DATA_REF not DESCRIBE_BY_DATA as the expected parameter type is data reference in first case, and simple data in the latter one.
So the correct snippet would be
"signature
class-methods READ_CUBE_SELECTIVELY
changing
!P_CUBE_SEL_READ_DATA type ref to DATA .
"method
if P_CUBE_SEL_READ_DATA is bound.
go_tdescr ?= cl_abap_tabledescr=>DESCRIBE_BY_DATA_REF( P_CUBE_SEL_READ_DATA ).
....
else.
"raise some exception saying that data reference is initial
endif.
Regards
Marcin
06-08-2011 12:04 PM
Dear Marcin,
thanks for your answer. U r great! I would never have been able to figure that out
So thanx to u we got a step further, but now the failure occurs at
go_sdescr_new = cl_abap_structdescr=>create( P_COMPONENTS = gt_components p_strict = abap_false ).
More specifically after exiting out of:
method CONSTRUCTOR.
CALL METHOD SUPER->CONSTRUCTOR
EXPORTING
TEXTID = TEXTID
PREVIOUS = PREVIOUS
COMPONENT_NAME = COMPONENT_NAME
COMPONENT_NUMBER = COMPONENT_NUMBER
.
IF textid IS INITIAL.
me->textid = CX_SY_STRUCT_ATTRIBUTES .
ENDIF.
endmethod.
Aprreciate ur help. thankx again.
Greetings,
Martin
06-08-2011 12:18 PM
field-symbols:
<g_t_data> TYPE STANDARD TABLE.
go_tdescr ?= cl_abap_tabledescr=>describe_by_data( P_CUBE_SEL_READ_DATA ).
go_sdescr ?= go_tdescr->get_table_line_type( ).
* Begin create dynamic standard table copy of P_CUBE_SEL_READ_DATA
" Create instances of dynamic structure and dynamic internal table
go_sdescr_new = cl_abap_structdescr=>create( P_COMPONENTS = gt_components p_strict = abap_false ).
go_tdescr = cl_abap_tabledescr=>create( go_sdescr_new ).
" Create data refence followed by table creation
CREATE DATA gdo_handle TYPE HANDLE go_tdescr.
ASSIGN gdo_handle->* TO <g_t_data>.
* End create dynamic standard table copy of P_CUBE_SEL_READ_DATA
Hello Martin,
If i understand correctly, you want to create the dynamic table from the data ref. P_CUBE_SEL_READ_DATA.
Instead of using the RTTC technique( CREATE* methods), you can directly dereference P_CUBE_SEL_READ_DATA. Something like this:
field-symbols: <g_t_data> TYPE STANDARD TABLE.
ASSIGN P_CUBE_SEL_READ_DATA->* TO <g_t_data>.
Later on if you want to analyse the structure of this table you can use the DESCRIBE_BY_DATA( ) on <g_t_data> or DESCRIBE_BY_DATA_REF( ) on P_CUBE_SEL_READ_DATA !
@Marcin: I don't think OP needs the RTTI at all. He can just de-reference the variable to some "compatible" field-symbol. Watsay?
BR,
Suhas
06-08-2011 12:28 PM
@Marcin: I don't think OP needs the RTTI at all. He can just de-reference the variable to some "compatible" field-symbol. Watsay?
Misleading here might be this statement
Begin create dynamic standard table copy of P_CUBE_SEL_READ_DATA
I so thought he needs local copy of the table. But of coure is he only needs to change original one, no reason to use RTTS, but working directly with table behind P_CUBE_SEL_READ_DATA suffice.
Regards
Marcin
06-08-2011 12:56 PM
Dear Marcin & Suhas,
yes indeed I need to create a copy of the table and it works now.
Thanks to both of you for your input.
Greetings,
Martin
06-08-2011 12:16 PM
Well, unless you need components of the table for some purpose (i.e. to add new components dynamically), there is no need to break down table into structure then into components. By using only describe_by_data_ref method you already get description of this table type under go_tdescr . So you simply use this object reference to create your local copy of table which P_CUBE_SEL_READ_DATA "points" to.
So in fact you need only
go_tdescr ?= cl_abap_tabledescr=>describe_by_data_ref( P_CUBE_SEL_READ_DATA ).
CREATE DATA gdo_handle TYPE HANDLE go_tdescr.
That's it.
Regards
Marcin