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

output length problem

lakshminarasimhan_n4
Active Contributor
0 Likes
2,262

Hi,

I have created a dynamic structure and a dynamic internal table and I have populated the dynamic internal table with values.

For the above operations, I have used RTTS(Runtime Type Services).

Please see my code below,

DATA : BEGIN OF xx,

char(100) TYPE c,

END OF xx.

DATA : wa_xx LIKE xx.

DATA : int LIKE STANDARD TABLE OF xx.

" The internal table 'int" contains all of the "data elements", upon which structure and table needs to be created

DATA:l_elem_descr TYPE REF TO cl_abap_elemdescr,

l_struct_descr TYPE REF TO cl_abap_structdescr,

l_table_descr TYPE REF TO cl_abap_tabledescr,

l_comp TYPE cl_abap_structdescr=>component,

lt_comp TYPE cl_abap_structdescr=>component_table.

FIELD-SYMBOLS : <wa> TYPE ANY, <itab> TYPE STANDARD TABLE, <comp_trg> TYPE ANY,<comp_trg> type any.

" looping through each value of internal table and creating a element of that type

LOOP AT int INTO wa_xx.

l_elem_descr ?= cl_abap_elemdescr=>describe_by_name( wa_xx-char ). u201Cwa-char contains data elements

l_comp-type = l_elem_descr.

l_comp-name = wa_xx-char.

WRITE : / l_elem_descr->output_length.

APPEND l_comp TO lt_comp.

ENDLOOP.

" Creating a structure from the list of elements available in the table lt_comp

u201C We have element name and its data type with size

u201C But we do not have its output length

IF lt_comp IS NOT INITIAL.

TRY.

l_struct_descr = cl_abap_structdescr=>create( lt_comp ).

CREATE DATA dref TYPE HANDLE l_struct_descr.

ASSIGN dref->* TO <wa>.

CATCH cx_sy_struct_creation INTO gcx_sy_struct_creation.

gv_msg_txt = gcx_sy_struct_creation->get_text( ).

MESSAGE gv_msg_txt TYPE 'E'.

ENDTRY.

ENDIF.

" ETK_ROW is a table which contains values for the dynamically created table

u201CThese values must be supplied to <wa> and later <wa> must be inserted to <itab>

LOOP AT etk_row INTO etk_wa.

ASSIGN COMPONENT count OF STRUCTURE <wa> TO <comp_trg>.

<comp_trg> = etk_wa-chavlext.

UNASSIGN <comp_trg>.

ENDLOOP.

The problem I face is the "data elements" size is obtained in <wa> but not its output length.

For example, I have supplied a data element u201CABCu201D to the internal table "int".

The data element ABC contains domain DATUM, its size is 8 and output length is 10.

The data contained in the etk_wa-chavlext is 03/03/2011.

Which is assigned to <wa>.

But what is see in my <wa> is 03/03/20 (because size is only 8, not 10).

That is, "l_comp" is of type cl_abap_structdescr=>component.

when I checked its structure ( cl_abap_structdescr=>component), it contains,

Component Technical type

NAME CString

  • * Name of the component
TYPE Reference * its type (data element) AS_INCLUDE C(1) * Boolean type SUFFIX CString * String

The above structure does not contain output length. It contains only name and data type.

I am filling only the name and type as per the structure via the lines

l_comp-type = l_elem_descr.

l_comp-name = wa_xx-char. u201Cdata element

Now this structure is appended to the lt_comp and which is of type cl_abap_structdescr=>component_table.

Now a structure is created based on the componenet table lt_comp,

l_struct_descr = cl_abap_structdescr=>create( lt_comp ).

CREATE DATA dref TYPE HANDLE l_struct_descr.

ASSIGN dref->* TO <wa>.

The field-symbol <wa> is of type any and its structure is same as that of cl_abap_structdescr=>component.

I have seen that the there is a element u201Coutput_lengthu201D in the class cl_abap_elemdescr.

When I checked it it contains the correct output length and this output length must be supplied to <wa> so that it accepts 03/03/2011.

Is there any way of doing it? I need my <wa> to accept the incoming data, as per the output length mentioned in the domain of that data element.

Please help.

6 REPLIES 6
Read only

Former Member
0 Likes
1,181

There is no length option possible for elemdescrs get_d method .

But why are you passing char fields to date fields.Here your etk_wa-chavlext should be 20110303 and not 03/03/2011.

If you want to pass 03/03/2011 then your domain should be char 10 and not DATUM

For that first you get the elemdescr and then use get

la_comp-type = cl_abap_elemdescr=>get_p(

p_length = lo_element->length

p_decimals = lo_element->decimals ).

Regards

Arshad

Read only

MarcinPciak
Active Contributor
0 Likes
1,181

As noticed above, the internal length for these fields are always shorter then its external one (output length). You can't therefore insert external value i.e. 31/01/2011 to field which accepts only its internal representation 20110131.

This is the same as below


data my_date type d.

"correct
my_date = '20110131'.

"incorrect
my_date = '31/01/2011'. 

How would you get this issue resolved? You wouldn't change my_date length to accept 31/01/2011, would you? If you persisted to have it like this, you would have to use different type (character type of length 10). So either give up using D type and use C type of correct output length or stick to D type and provide value's internal representation.

The advantage of the latter is that system takes care of any conversion for you. Therefore I would recommend to use standard FM like CONVERT_DATE_TO_INTERNAL before passing the value to your field. Then you will have it in correct internal format and during display will convert to its external form.

Regards

Marcin

Read only

lakshminarasimhan_n4
Active Contributor
0 Likes
1,181

Hi,

Actually i have taken the approach of give up using D type and use C type, now the code works very much fine.

Thanks a lot for your suggestions,

Below is my code, where i have implemented C instead of D.

LOOP AT int INTO wa_xx.

TRY.

descr_ref = cl_abap_elemdescr=>describe_by_name( wa_xx-char ). " Element description

WRITE: / 'Typename:', descr_ref->absolute_name.

WRITE: / 'Length :', descr_ref->length.

WRITE: / 'Decimals:', descr_ref->decimals.

abap_typekind_l = descr_ref->type_kind.

CATCH cx_dynamic_check INTO exc_obj.

abap_typekind_l = 'C'.

ENDTRY.

l_elem_descr ?= cl_abap_elemdescr=>describe_by_name( wa_xx-char ).

output_len = l_elem_descr->output_length. " output length

IF abap_typekind_l IS NOT INITIAL.

IF abap_typekind_l EQ 'C'.

l_elemtype = cl_abap_elemdescr=>get_c( p_length = output_len ).

ENDIF.

IF abap_typekind_l EQ 'N'.

l_elemtype = cl_abap_elemdescr=>get_n( p_length = output_len ).

ENDIF.

IF abap_typekind_l EQ 'D'.

l_elemtype = cl_abap_elemdescr=>get_c( p_length = output_len ).

ENDIF.

IF abap_typekind_l EQ 'T'.

l_elemtype = cl_abap_elemdescr=>get_c( p_length = output_len ).

ENDIF.

ENDIF.

l_comp-name = wa_xx-char.

l_comp-type ?= l_elemtype.

APPEND l_comp TO lt_comp.

ENDLOOP.

Now i face a peculiar problem. See in SAP BI a characteristic info object can be with data type (c,n,d,t,UNIT, CUKY).

Now my code works well for the data types c,n,d,t, but if the data type is either UNIT or CUKY then my code throws exception "type_not_found.". This is because the method "describe_by_name" does not create the data type. Also i cannot use try...end try, as the exception is not propagated to the code. otherwise i could catch the same and convert the type to 'C'.

Further investigation i have found the method "CREATE_ELEMDESCR_OBJECT" but i am not aware of how to use the same to attain my goal. Any help is much appreciated. Thanks.

Read only

0 Likes
1,181

Halo,

CUKY is Char data type of length 5 and UNIT contains domain MEINS which is of CHAR 3 .

So when this exception occurs you could safely create elem descr objects of the above type .

Just to make sure that this dataelements are available

you can use methods get_complete of class cl_reca_ddic_dtel and cl_reca_ddic_doma

Regards

Arshad

Read only

0 Likes
1,181

As you have said & i quote,

" The internal table 'int" contains all of the "data elements", upon which structure and table needs to be created

You don't have to worry about handling UNIT or CUKY explicitly. Let's have a look at the following example:

DATA: go_elem_descr TYPE REF TO cl_abap_elemdescr,
      gs_comp       TYPE cl_abap_structdescr=>component.

* 'MEINS' is a data element of domain 'UNIT'
go_elem_descr ?= cl_abap_elemdescr=>describe_by_name( 'MEINS' ).

CHECK go_elem_descr IS NOT BOUND.

* Check the data type kind (For MEINS data type will be 'C' & not 'UNIT')
CASE go_elem_descr->type_kind.
  WHEN cl_abap_elemdescr=>typekind_char.
    gs_comp-type ?= cl_abap_elemdescr=>get_c( go_elem_descr->output_length ).
  WHEN cl_abap_elemdescr=>typekind_num.
*   Your Custom Logic
  WHEN cl_abap_elemdescr=>typekind_date.
*   Your Custom Logic
  WHEN cl_abap_elemdescr=>typekind_time.
*   Your Custom Logic
ENDCASE.

Also you've mentioned,

Also i cannot use try...end try, as the exception is not propagated to the code. otherwise i could catch the same and convert the type to 'C'.

This is because the method DESCRIBE_BY_NAME does not propagate class-based exceptions. So if you want to capture the exception you've to restore to old exception handling techniques!

DATA: go_type_descr TYPE REF TO cl_abap_typedescr,
      go_elem_descr TYPE REF TO cl_abap_elemdescr.

cl_abap_elemdescr=>describe_by_name(
  EXPORTING
    p_name         = 'MEINS'
  RECEIVING
    p_descr_ref    = go_type_descr
  EXCEPTIONS
    type_not_found = 1
    OTHERS         = 2 ).
IF sy-subrc <> 0.
* Put your custom logic here to use 'C' instead of 'UNIT'
ELSE.
  go_elem_descr ?= go_type_descr.
ENDIF.

I'm still wondering why 'UNIT' or 'CUKY' should be bothering you

BR,

Suhas

Read only

lakshminarasimhan_n4
Active Contributor
0 Likes
1,181

Answered