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: 

How to fix a bug in Rich Heilman's weblog code?

Former Member
0 Kudos

Dear all,

I'm trying to create a report on a code given in the weblog by Rich Heilman:

/people/rich.heilman2/blog/2005/07/27/dynamic-internal-tables-and-structures--abap

Unfortunately, there is a bug in the code and a short dump occurs:

A RAISE statement in the program "CL_ABAP_TYPEDESCR=============CP" raised the

exception condition "TYPE_NOT_FOUND".

I copied here the whole code:

REPORT  Z_DYNAMIC.
type-pools : abap.

field-symbols: <dyn_table> type standard table,
               <dyn_wa>,
               <dyn_field>.

data: dy_table type ref to data,
      dy_line  type ref to data,
      xfc type lvc_s_fcat,
      ifc type lvc_t_fcat.

selection-screen begin of block b1 with frame.
parameters: p_table(30) type c default 'T001'.
selection-screen end of block b1.

start-of-selection.

  perform get_structure.
  perform create_dynamic_itab.
  perform get_data.
  perform write_out.


form get_structure.

data : idetails type abap_compdescr_tab,
       xdetails type abap_compdescr.

data : ref_table_des type ref to cl_abap_structdescr.

* Get the structure of the table.
  ref_table_des ?=
      cl_abap_typedescr=>describe_by_name( p_table ).
  idetails[] = ref_table_des->components[].

  loop at idetails into xdetails.
    clear xfc.
    xfc-fieldname = xdetails-name .
    xfc-datatype = xdetails-type_kind.
    xfc-intlen = xdetails-length.
    xfc-decimals = xdetails-decimals.
    append xfc to ifc.
  endloop.

endform.

form create_dynamic_itab.

* Create dynamic internal table and assign to FS
  call method cl_alv_table_create=>create_dynamic_table
               exporting
                  it_fieldcatalog = ifc
               importing
                  ep_table        = dy_table.

  assign dy_table->* to <dyn_table>.

* Create dynamic work area and assign to FS
  create data dy_line like line of <dyn_table>.
  assign dy_line->* to <dyn_wa>.

endform.


form get_data.

* Select Data from table.
  select * into table <dyn_table>
             from (p_table).

endform.

form write_out.
* Write out data from table.

  loop at <dyn_table> into <dyn_wa>.
    do.
      assign component  sy-index
         of structure <dyn_wa> to <dyn_field>.
      if sy-subrc <> 0.
        exit.
      endif.
      if sy-index = 1.
        write:/ <dyn_field>.
      else.
        write: <dyn_field>.
      endif.
    enddo.
  endloop.
endform.

Could someone fix a bug, please?

Best regards,

Eugene

1 ACCEPTED SOLUTION

Former Member
0 Kudos

Hi,

Trying to figure out what's wrong with my system or the code.

CORRESPONDING FIELDS OF doesn't work for MARA in my system (now I use R/3).

I noticed that the code doesn't work for tables containing the following types:

INT2, INT4, QUAN (and probably CURR).

For example, it works for: T001,T002,T003,T004,T008,T009,MAKT

and doesn't work for:

T005,T006,T014,MARA,COSP,COEP,MAST.

Executing the code for these tables gives a short dump.

The general meaning of the error is too small internal table to place a result.

My system is not Unicode.

Best regards,

Eugene

15 REPLIES 15

christian_wohlfahrt
Active Contributor
0 Kudos

Hi Eugene!

I tried this method in SE24 with two different inputs:

T001 - working alright

T001jk - type_not_found -> no table, no result

Looks like the description is not available in the same way in BW as in R/3.

Have to go for an alternative way to build up a list of fields:

- hardcode

- tricky select to DD03L (or equivalent)

- have a look at ABAP-statement 'DESCRIBE FIELD INTO'

Regards,

Christian

0 Kudos

Thank you Christian!

I also tried T001 in SE24 with the same error.

After that I went for your option 2 and found that I couldn't get description also.

Looking into T001 table I found that it is empty in BW!

With T005 everything worked out.

So, it was not really a bug, but a lack of protection from a fool.

Thank you for your help!

Best regards,

Eugene

0 Kudos

Hi,

Maybe you can notify Rich too in order that he can put this additional info in his blog.

Eddy

0 Kudos

You know this code is a little funny. It works good on most tables, but some tables, it really handles very badly. For example, MARA, when building the dynamic internal table, it adds an extra space to the beginning of the structure. This will then cause a problem during the select. I've spent many hours trying to figure it out, but nothing yet.

Regards,

Rich Heilman

0 Kudos

Hi Rich,

I'm trying to get the table name dynamically, during a report run, and using your code create an internal table.

I got the name, created an internal table. But during the table load I've got a short dump in the statement

select * into table <dyn_table>

from (p_table).

of the get_data form.

The message says:

"In a Unicode system, the type of the operand "dbtab" must be convertible to

the type of the operand "itab", in the statement

"SELECT * FROM dbtab INTO TABLE itab".

Independent of the length of a Unicode character, both operands must

have the same structure layout.

In this case, this condition has been violated."

What could be a reason?

The internal table is created according to your code, p_table is simply CHAR(30).

Best regards,

Eugene

0 Kudos

Hi Rich

For me it looks like, that the dynamic internal table is built correctly.

If I define

lt_mara type table of mara

lt_mara has size of 846 bytes but should have 844 bytes on the system I am working on (I counted the bytes ). The dynamically built itab has "correct" size of 844. Eg. one extra byte is right after MATNR.

Btw. for a dynamic table with correct data types one could add the following lines:

xfc-ref_table = p_table.

xfc-ref_field = xdetails-name.

Those fields are used in LSKBHF06, Line 330

Maybe this helps solving your Problem also, Eugene.

Regards

Rene

Message was edited by: Rene Guenther

Former Member
0 Kudos

Thank you Rene.

I also have counted bytes. My db-table has 906 bytes, internal dyn table - 894.

My table has a couple of INT4 fields and in the dictionary their length is declared as 10 bytes (as it should be).

During filling of tables with table fields description they are coming as TYPE I and length = 4 bytes!

The difference (10-4)*2 = 12 bytes is exactly the one that exists between db-table & itab lengths.

And as a result I have a short dump.

So, it looks like improper work of

cl_abap_typedescr=>describe_by_name( p_table )

if I'm not missing something.

Best regards,

Eugene

0 Kudos

Hello Eugene,

10 doesnt equal 10 bytes it equals 10 digits.

Check the domain description for INT4. It says 4 bytes. With 4 bytes you have 32 bits with 32 bits maximal possible number is 2^32. This should result in a number with 12 digits, enough to represent a positive or negative 10 digits number

Maybe you can solve your problem by switching off unicode checks, but I am not sure.

Regards

Rene

0 Kudos

Hi!

So solution is to use DD01D-LENG of the corresponding domains? But then I could use a join (or view) and base the internal table with field descriptions on DD0x tables.

Christian

0 Kudos

Hi,

I guess the method cl_abap_typedescr=>describe_by_name( p_table ) just reads the DD0x tables. Further more I guess the different lengths results from

DATA: lw_mara type mara.

is <b>different</b> to

Data: BEGIN OF lw_mara,

mandt type mara-mandt,

matnr type mara-matnr,

...

...

...

at least for some tables

Btw.

SELECT * INTO <b>CORRESPONDING FIELDS OF</b> TABLE <dyn_table>

FROM (p_table).

works at my place for p_table = MARA

Regards

Rene

Former Member
0 Kudos

Hi,

Trying to figure out what's wrong with my system or the code.

CORRESPONDING FIELDS OF doesn't work for MARA in my system (now I use R/3).

I noticed that the code doesn't work for tables containing the following types:

INT2, INT4, QUAN (and probably CURR).

For example, it works for: T001,T002,T003,T004,T008,T009,MAKT

and doesn't work for:

T005,T006,T014,MARA,COSP,COEP,MAST.

Executing the code for these tables gives a short dump.

The general meaning of the error is too small internal table to place a result.

My system is not Unicode.

Best regards,

Eugene

0 Kudos

Try adding those lines:

xfc-ref_table = p_table.

xfc-ref_field = xdetails-name.

in form get_structure in loop

LOOP AT idetails INTO xdetails.

and use INTO CORRESPONDING FIELDS OF

Regards

Rene

0 Kudos

It's super, Rene!

Now it works fine.

Thank you so much!

I think Rich should update his code in the weblog.

Best regards,

Eugene

Former Member
0 Kudos

Hi Eugene,

I made a small change to the code and it works even for MARA. See the code below..


REPORT zsritest58 .

TYPE-POOLS : abap.

FIELD-SYMBOLS: <dyn_table> TYPE STANDARD TABLE,
               <dyn_wa>,
               <dyn_field>.

DATA: dy_table TYPE REF TO data,
      dy_line  TYPE REF TO data,
      xfc TYPE lvc_s_fcat,
      ifc TYPE lvc_t_fcat.

SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME.
PARAMETERS: p_table(30) TYPE c DEFAULT 'T001'.
SELECTION-SCREEN END OF BLOCK b1.

START-OF-SELECTION.

  PERFORM get_structure.
  PERFORM create_dynamic_itab.
  PERFORM get_data.
  PERFORM write_out.


*---------------------------------------------------------------------*
*       FORM get_structure                                            *
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
FORM get_structure.

<b>*data : idetails type abap_compdescr_tab,
*       xdetails type abap_compdescr.
*
*data : ref_table_des type ref to cl_abap_structdescr.
*
** Get the structure of the table.
*  ref_table_des ?=
*      cl_abap_typedescr=>describe_by_name( p_table ).
*  idetails[] = ref_table_des->components[].
*
*  loop at idetails into xdetails.
*    clear xfc.
*    xfc-fieldname = xdetails-name .
*    xfc-datatype = xdetails-type_kind.
*    xfc-intlen = xdetails-length.
*    xfc-decimals = xdetails-decimals.
*    append xfc to ifc.
*  endloop.

  SELECT SINGLE tabname INTO p_table FROM dd02l
  WHERE tabname EQ p_table
    AND as4local EQ 'A'
    AND as4vers EQ '0000'.
  IF sy-subrc NE 0.
    STOP.
  ENDIF.

  CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
   EXPORTING
*   I_BUFFER_ACTIVE              =
     i_structure_name             = p_table
*   I_CLIENT_NEVER_DISPLAY       = 'X'
*   I_BYPASSING_BUFFER           =
    CHANGING
      ct_fieldcat                  = ifc[]
   EXCEPTIONS
     inconsistent_interface       = 1
     program_error                = 2
     OTHERS                       = 3.
  IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.</b>
ENDFORM.

*---------------------------------------------------------------------*
*       FORM create_dynamic_itab                                      *
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
FORM create_dynamic_itab.

* Create dynamic internal table and assign to FS
  CALL METHOD cl_alv_table_create=>create_dynamic_table
               EXPORTING
                  it_fieldcatalog = ifc
               IMPORTING
                  ep_table        = dy_table.

  ASSIGN dy_table->* TO <dyn_table>.

* Create dynamic work area and assign to FS
  CREATE DATA dy_line LIKE LINE OF <dyn_table>.
  ASSIGN dy_line->* TO <dyn_wa>.

ENDFORM.


*---------------------------------------------------------------------*
*       FORM get_data                                                 *
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
FORM get_data.

* Select Data from table.
  SELECT * INTO CORRESPONDING FIELDS OF TABLE <dyn_table>
             FROM (p_table).

ENDFORM.

*---------------------------------------------------------------------*
*       FORM write_out                                                *
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
FORM write_out.
* Write out data from table.

  LOOP AT <dyn_table> INTO <dyn_wa>.
    DO.
      ASSIGN COMPONENT  sy-index
         OF STRUCTURE <dyn_wa> TO <dyn_field>.
      IF sy-subrc <> 0.
        EXIT.
      ENDIF.
      IF sy-index = 1.
        WRITE:/ <dyn_field>.
      ELSE.
        WRITE: <dyn_field>.
      ENDIF.
    ENDDO.
  ENDLOOP.
ENDFORM.

Hope this helps..

Sri

0 Kudos

Thank you Sri,

It'a little bit workaround.

Fortunately, the amendmends proposed by Rene have worked out.

Best regards,

Eugene