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_SALV_TABLE with dynamin table: typing issue

Former Member
0 Kudos

Hi, everyone.

I need help in solving the following issue. Consider the code:

DATA: lr_table TYPE REF TO STANDARD TABLE,

      lo_salv TYPE REF TO cl_salv_table.

FIELD-SYMBOLS: <lt_table> TYPE TABLE.

GET REFERENCE OF some_table INTO lr_table.

ASSIGN lr_table->* TO <lt_table>.

cl_salv_table=>factory(

  IMPORTING r_salv_table = lo_salv

  CHANGING t_table = <lt_table> ).

This code throws an exception on FACTORY method: the T_TABLE parameter is said to have invalid type. Meanwhile, under debugger I can see that this field-symbol points to a valid standard table.

Now I try to use a specific internal table instead of generic reference:

DATA: lt_table TYPE STANDARD TABLE OF some_thing,

      lo_salv TYPE REF TO cl_salv_table.


FIELD-SYMBOLS: <lt_table> TYPE TABLE.

ASSIGN lt_table TO <lt_table>.


cl_salv_table=>factory(

  IMPORTING r_salv_table = lo_salv

  CHANGING t_table = <lt_table> ).


  And now it works like a charm, while the field-symbol type remains the same. BTW, the lt_table in this example is the same table, that is referenced by lr_table in the first code snippet.

So, the question is: what am I doing wrong in the first code sample? Why is field-symbol considered invalid?

Thank you in advance.

1 ACCEPTED SOLUTION

Former Member
0 Kudos

Hi Alex,

Firstly, In the First Code Snippet, I suppose you cannot declare generic data type after 'TYPE REF TO'.

Secondly, After getting reference of a table in object and assigning it to a field-symbol, should work.

I just made a small change and program is running smooth.

Here it is,

Data: lr_table TYPE REF TO data,
      lo_salv
TYPE REF TO cl_salv_table,
      lt_vbap
TYPE STANDARD TABLE OF vbap. "Some table

FIELD-SYMBOLS: <lt_table> TYPE TABLE.

GET REFERENCE OF lt_vbap INTO lr_table.

ASSIGN lr_table->* TO <lt_table>.

cl_salv_table
=>factory(

 
IMPORTING r_salv_table = lo_salv

 
CHANGING t_table = <lt_table> ).

Should you be able to provide reference of a table in ALV Factory method, problem should not occur as invalid type.

11 REPLIES 11

Former Member
0 Kudos

Hi Alex,

Firstly, In the First Code Snippet, I suppose you cannot declare generic data type after 'TYPE REF TO'.

Secondly, After getting reference of a table in object and assigning it to a field-symbol, should work.

I just made a small change and program is running smooth.

Here it is,

Data: lr_table TYPE REF TO data,
      lo_salv
TYPE REF TO cl_salv_table,
      lt_vbap
TYPE STANDARD TABLE OF vbap. "Some table

FIELD-SYMBOLS: <lt_table> TYPE TABLE.

GET REFERENCE OF lt_vbap INTO lr_table.

ASSIGN lr_table->* TO <lt_table>.

cl_salv_table
=>factory(

 
IMPORTING r_salv_table = lo_salv

 
CHANGING t_table = <lt_table> ).

Should you be able to provide reference of a table in ALV Factory method, problem should not occur as invalid type.

0 Kudos

Indeed, it does work this way. However, my case is a bit more complicated. The code is located in class methods. The reference to the itable is actually a class field initialized in constructor:

CLASS lcl_my_class DEFINITION.

  PUBLIC SECTION.

    METHODS: constructor IMPORTING im_data TYPE STANDARD TABLE,

             show_grid.

  PRIVATE SECTION.

    DATA: mr_data TYPE REF TO data.

ENDCLASS.

CLASS lcl_my_class IMPLEMENTATION.

  METHOD constructor.

        GET REFERENCE OF im_data INTO me->mr_data.

  ENDMETHOD.


  METHOD show_grid.

    DATA: lo_grid TYPE REF TO cl_salv_table.

    FIELD-SYMBOLS: <lt_data> TYPE TABLE.


    ASSIGN me->mr_data->* TO <lt_data>.


    cl_salv_table=>factory(

      IMPORTING r_salv_table = lo_grid

      CHANGING t_table = <lt_data> ).


    lo_grid->display( ).

  ENDMETHOD.

ENDCLASS.

The class is used like this:

DATA: lo_cls TYPE REF TO lcl_my_class,

       lt_table TYPE STANDARD TABLE OF ... .

CREATE OBJECT lo_cls EXPORTING im_data = lt_table.

lo_cls->show_grid( ).

Everything seems to be almost the same as in your working snippet, but this way a CX_SY_DYN_CALL_ILLEGAL_TYPE exception is thrown. That just does not make any sense.

UPDATE

I've just realized that I can pass data table to my show_grid method as a parameter and use it for constructing the grid (so no references or field-symbols are needed). It does work this way, however I still want to find out what is wrong with my current code.

0 Kudos

Hello Alex.

The problem is, that the CONSTRUCTOR has an IMPORTING parameter. You can not change an importing parameter and so you also cannot change a reference of it. The factory-method uses the parameter as CHANGING and that causes the dump. A working solution is this. Use a method with a changing parameter instead of the constructor and it will work:

CLASS lcl_my_class DEFINITION.

  PUBLIC SECTION.

    METHODS: set_data   CHANGING im_data TYPE STANDARD TABLE, "<-----

             show_grid.

  PRIVATE SECTION.

    DATA: mr_data TYPE REF TO data.

ENDCLASS.                    "lcl_my_class DEFINITION

CLASS lcl_my_class IMPLEMENTATION.

  METHOD set_data.

    GET REFERENCE OF im_data INTO me->mr_data.

  ENDMETHOD.   

               

  METHOD show_grid.

    DATA: lo_grid TYPE REF TO cl_salv_table.

    FIELD-SYMBOLS: <lt_data> TYPE table.

    ASSIGN me->mr_data->* TO <lt_data>.

    cl_salv_table=>factory( IMPORTING r_salv_table = lo_grid

                            CHANGING  t_table      = <lt_data> ).

    lo_grid->display( ).

  ENDMETHOD.                    "show_grid

ENDCLASS.                    "lcl_my_class IMPLEMENTATION

START-OF-SELECTION.

  DATA: lo_cls   TYPE REF TO            lcl_my_class,

            lt_table TYPE STANDARD TABLE OF vbak.

  CREATE OBJECT lo_cls.

  lo_cls->set_data( CHANGING im_data = lt_table ).  "<-----

  lo_cls->show_grid( ).

regards,

Peer.

tolga_polat
Active Participant
0 Kudos

Hi Alex,

As said, in constructor method you assign a importing parameter to mr_data. So you can not make any changes on this data. You can use set_data method as Peer suggest or you can create mr_data by handle syntax :

METHOD constructor.

    DATA : lo_table_type TYPE REF TO cl_abap_tabledescr.

    lo_table_type ?= cl_abap_tabledescr=>describe_by_data( im_data ).

    CREATE DATA me->mr_data TYPE HANDLE lo_table_type.

ENDMETHOD.

This is working just fine.

Regards

Tolga

0 Kudos


Hi

As you have suggested creating me->mr_data of TYPE im_data but this again raises a question of data passing as both me->mr_data and im_data are of generic data type and data between them can only be referenced as per my knowledge. Even if you address data of im_data to a field symbol and then again get reference of it to mr_data, it should not work as indirectly you are referencing im_data only.

If you have any other approach to pass data, do enlighten us.

0 Kudos

METHOD constructor.

     CREATE DATA me->mt_data LIKE im_data.

     ASSIGN me->mt_data->* TO FIELD-SYMBOL(<fs>).

     <fs> = im_data.

ENDMETHOD.

0 Kudos

Perfect!

0 Kudos

Hi.

It depends, what you want. The solution with the additional method works with a reference to the data (Data is only hold 1 time in memory). The solution with the create data copies the data, so the table is twice in memory. If you have many lines, or the table is changed during the transaction, this may me an issue.

0 Kudos

I agree ) Sometimes ref is enough, sometimes its better to copy data.

0 Kudos

Hi

To pass data I will add this code after create data :

field-symbols : <table> type table.

assign me->mr_data->* to <table>.

check sy-subrc eq 0.

<table> = im_data.

Or did. Logic is create new data for importing parameters.

I prefer cl_abap*descr classes for this kind of aproach, I dont like to use LIKE.

Former Member
0 Kudos

Thanks everyone, the problem is solved. The exception class confused me - I thought that something was wrong with identifying field-symbol as a table. And I never realized that ABAP runtime is that thorough in guarding the IMPORTING parameters.