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: 

cl_abap_typedescr=>describe_by_data->length reports double length !

glio_ad
Active Participant
0 Kudos

Hello everybody and I wish you all a very Happy New Year !

Here is my problem:

I have created a function module with the following interface:

*"----


""Local Interface:

*" IMPORTING

*" VALUE(I_NAME) TYPE RVARI_VNAM

*" VALUE(I_TYPE) TYPE RSSCR_KIND

*" TABLES

*" T_RANGE

*" EXCEPTIONS

*" VAR_NOT_FOUND

*" NO_DATA

*"----


This FM will be used to read any variant maintained in table TVARV and will return its values in a given range (through the tables parameter t_range). For example, the program ZTEST will call this FM with a range r_ktokd (defined as: ranges: r_ktokd for kna1-ktokd) and I_NAME will have the value, say, 'ZSD_ACC_GRP'.

In order to be able to handle any type of range object defined in a program, I am trying to dynamically realize the actual length of the type range (in our example, KTOKD has length 4), so that I know exactly how to handle the data from TVARVC and move them respectively to t_range-low, t_range-high etc fields.

Therefore, I use have written the following code to do this:

DATA: wa_tvarvc TYPE tvarvc,

descr_ref TYPE REF TO cl_abap_typedescr,

wl_field_len TYPE i,

wl_high TYPE i.

CLEAR: wa_tvarvc, t_range, t_range[].

descr_ref = cl_abap_typedescr=>describe_by_data( t_range ).

  • Calculate the low-high fields' length

wl_field_len = ( descr_ref->length - 3 ) / 2 .

as t_range-sign length = 1

t_range-option length = 2

t_range-low length = 4

t_range-high length = 4

the descr_ref->length should return 11 as the total length of the t_range structure. However, it returns 22 !! So, I have changed the code as follows:

wl_field_len = ( descr_ref->length - 6 ) / 4 .

Although it works now, can someone please explain me why this happens and if there is a more safe way to do this?

Thanks in advance and HAPPY CODING in 2008 !

George

5 REPLIES 5

uwe_schieferstein
Active Contributor
0 Kudos

Hello George

You have to go for the "full monty" as shown below in the sample report ZUS_SDN_DYNAMIC_TVARVC.

&----


*& Report ZUS_SDN_DYNAMIC_TVARVC *

*& *

&----


*& *

*& *

&----


REPORT zus_sdn_dynamic_tvarvc .

TYPE-POOLS: abap.

TABLES: kna1.

DATA:

gr_ktokd TYPE RANGE OF kna1-ktokd.

DATA:

gs_component TYPE abap_compdescr,

go_typedescr TYPE REF TO cl_abap_typedescr,

go_strucdescr TYPE REF TO cl_abap_structdescr,

go_tabledescr TYPE REF TO cl_abap_tabledescr.

START-OF-SELECTION.

CALL METHOD cl_abap_typedescr=>describe_by_data

EXPORTING

p_data = gr_ktokd " range = table type

RECEIVING

p_descr_ref = go_typedescr. " table type

" Casting to table type instance

go_tabledescr ?= go_typedescr.

" Get table line type

CALL METHOD go_tabledescr->get_table_line_type

RECEIVING

p_descr_ref = go_typedescr.

" Casting to line type instance

go_strucdescr ?= go_typedescr.

" Components of range

LOOP AT go_strucdescr->components INTO gs_component.

AT FIRST.

WRITE: /1 'Length',

AT 15 'Decimals',

AT 25 'Type',

AT 35 'Name'.

WRITE: / syst-uline.

ENDAT.

WRITE: /1 gs_component-length LEFT-JUSTIFIED,

AT 15 gs_component-decimals LEFT-JUSTIFIED,

AT 25 gs_component-type_kind,

AT 35 gs_component-name.

ENDLOOP.

END-OF-SELECTION.

Regards

Uwe

0 Kudos

Hello Uwe and thanks for the reply.

I tried your code, however, gs_component-length keeps reporting double length for every component of the range structure!! I cannot figure out why this happens.... Might this be a Unicode issue??? a BASIS issue?? is it a bug or a feature? 😛

Anyway, thanks for your prompt answer.

Cheers,

George

0 Kudos

Hello George

I modified my report in order to match your requirements more closely.


*&---------------------------------------------------------------------*
*& Report  ZUS_SDN_DYNAMIC_TVARVC                                      *
*&                                                                     *
*&---------------------------------------------------------------------*
*&                                                                     *
*&                                                                     *
*&---------------------------------------------------------------------*

REPORT  zus_sdn_dynamic_tvarvc                      .

TYPE-POOLS: abap.


TABLES: kna1.


DATA:
  gr_ktokd    TYPE RANGE OF kna1-ktokd.  " itab w/o header line

**DATA:
**  gs_component    TYPE abap_compdescr,
**  go_typedescr    TYPE REF TO cl_abap_typedescr,
**  go_strucdescr   TYPE REF TO cl_abap_structdescr,
**  go_tabledescr   TYPE REF TO cl_abap_tabledescr.


SELECT-OPTIONS:
  s_ktokd         FOR kna1-ktokd.  " itab with header line

START-OF-SELECTION.



  CALL FUNCTION 'Z_US_TEST1'
       TABLES
            xt_range = gr_ktokd.
  SKIP.


  CALL FUNCTION 'Z_US_TEST1'
       TABLES
            xt_range = s_ktokd.
  SKIP.

  CALL FUNCTION 'Z_US_TEST1'
       TABLES
            xt_range = s_ktokd[].
  SKIP.

And here is the coding of the function module:


FUNCTION z_us_test1.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*"  TABLES
*"      XT_RANGE
*"----------------------------------------------------------------------

  TYPE-POOLS: abap.

  DATA:
    gs_component    TYPE abap_compdescr,
    go_typedescr    TYPE REF TO cl_abap_typedescr,
    go_strucdescr   TYPE REF TO cl_abap_structdescr,
    go_tabledescr   TYPE REF TO cl_abap_tabledescr.


  CALL METHOD cl_abap_typedescr=>describe_by_data
    EXPORTING
      p_data      = xt_range
    RECEIVING
      p_descr_ref = go_typedescr.  " structure type, not table type !!!!

" Not required anymore
**  " Casting to table type instance
**  go_tabledescr ?= go_typedescr.
**
**  " Get table line type
**  CALL METHOD go_tabledescr->get_table_line_type
**    RECEIVING
**      p_descr_ref = go_typedescr.

  " Casting to line type instance
  go_strucdescr ?= go_typedescr.

  " Components of range
  LOOP AT go_strucdescr->components INTO gs_component.
    AT FIRST.
      WRITE: /1  'Length',
               AT 15 'Decimals',
               AT 25 'Type',
               AT 35 'Name'.
      WRITE: / syst-uline.
    ENDAT.

    WRITE: /1   gs_component-length LEFT-JUSTIFIED,
             AT 15  gs_component-decimals LEFT-JUSTIFIED,
             AT 25  gs_component-type_kind,
             AT 35  gs_component-name.
  ENDLOOP.

ENDFUNCTION.

Again the results are always correct and the same (lenght of LOW / HIGH = 4). This report was developed on 4.6c.

Regards,

Uwe

0 Kudos

Hello Uwe.

Thank you for you prompt support! The last code you sent me is syntactically OK, but it keeps reporting double length!!

I tend to believe that it has to do with the fact that our system here (ECC 6.0) is Unicode...

Anyway, If anyone has some in-depth knowledge on this please advise!

Thanks again Uwe.

0 Kudos

Hello,

I'm having the same problem. Unfortunately, I cannot delete every value by 2, because not all field-lengths are doubled.

Has anyone figured out why this happens?

Kind regards,

Jorg