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

Class method returning any table

Former Member
0 Likes
10,256

Hi all,

Is there a way in ABAP to solve below problem?

I have a class CL with method METH which inside of itself CREATES an internal table.

Table structure and its data depends of various factors and its structure is always unexpected.

Class definition:

* ...

methods:
     METH
         importing
           iv_filepath type string
           changing et_table type ref to data.


Class implementation:

method METH.

* ... internal table itab already has a structure and data based on user choose

     field-symbols: <fsym> type any.
         assign itab to <fsym>.
        
et_table = <fsym>.

endmethod.

I need to call METH and get this table, eg.:

program ZPROG.

data fname type string.
field-symbols: <fs_tab> type any table.

CL=>METH( importing et_table = <fs_tab> )

or

<fs_tab> = CL=>METH(  ).

or so on.

But <fs_tab> is not assigned (and I get error) but I cannot assign <fs> not knowing table structure first (like I wrote above, structure is not known at design-time).

I'm very new in ABAP. Usually I'm coding in C#, which easly allows to return, assign to variable and iterate on rows and columns of any table in memory.

1 ACCEPTED SOLUTION
Read only

Former Member
0 Likes
6,008

Hello,

Your method returns a data object, so inside you should have a statement like:

     get reference of itab into et_table, instead of ASSIGN...

Outside you should dereference your data object:


      data: lo_tab type ref to data.

      lo_tab = cl=>meth( ).   "with a RETURNING parameter instead of CHANGING

      assign lo_tab->* to <fs_tab>.

br,

Manu.

15 REPLIES 15
Read only

Former Member
0 Likes
6,009

Hello,

Your method returns a data object, so inside you should have a statement like:

     get reference of itab into et_table, instead of ASSIGN...

Outside you should dereference your data object:


      data: lo_tab type ref to data.

      lo_tab = cl=>meth( ).   "with a RETURNING parameter instead of CHANGING

      assign lo_tab->* to <fs_tab>.

br,

Manu.

Read only

0 Likes
6,008

Very thanks. It works.

Unfortunatelly I cannot assign:

field-symbols:

                 <fs> type standard table,

                 <wa> type any,

                 <fld> type any.

data: lo_tab type ref to data. 

      lo_tab = cl=>meth( ).   "with a RETURNING parameter instead of CHANGING 

      assign lo_tab->* to <fs_tab>.

>>>>>>>>>>>> loop at <fs_tab> assigning <wa>.

    assign component 'COLNAME' of structure <wa> to <fld>.

    write:/ <fld>.

endloop.

Error is in line with '>>>>>' where I try to assign <wa>.

Short text:     Field symbol has not yet been assigned.

PS Please be patient for a beginner.

Read only

matt
Active Contributor
0 Likes
6,008

Try this:

lo_tab = cl=>meth( ). 

   assign lo_tab->* to <fs_tab>.

IF sy-subrc IS NOT INITIAL:

write: / 'Something when wrong in CL=>METH() - no reference returned".

exit.

ENDIF.


This is not the complete answer, but rather to guide you to where the error lies. HINT: read the ABAP Help on GET REFERENCE

Read only

0 Likes
6,008

Yes, I know that assigning is dead. I'm worrying about GET REFERENCE Help text:

"You must specify the data type of the object using the TYPE or LIKE addition."

Problem is (like I wrote in my first post in thread) the structure (type) reveals itself inside method and it is not known before method call.

Read only

matt
Active Contributor
0 Likes
6,008

For a start your field symbol should not be type ANY, but ANY TABLE.

It would be helpful if you would post your latest code attempt.

Read only

0 Likes
6,008

I changed:

    <fs> type standard table

to

    <fs> type any table

Nothing changed.

To be sure I removed temporarily unused <wa> and <fld> (for the eventuality of some unplanned interaction) - of course nothing.

Result always is the same - dead assigning.

Maybe this will matter: in method declaration i have return like below:

     returning value(et_table) type ref to data.

and at the and of implementation:

     get reference of itab into et_table.

Read only

Former Member
0 Likes
6,008

I discovered (using debugger) that reference which is returned to method call is 'FREED STACK".

In the method the reference is Ok.

In my mind it marks that ABAP destroys memory before program get it back!

Read only

Former Member
0 Likes
6,008

Ok, I found it.

Class method that returns a reference needs to declare referenced variable (table in this case) in class-data (or data) of public section. I returned other simple table. Problem is that I need to return reference to other, more complex table, which I build in method body (implementation). Unfortunatelly ABAP significantly complicates programmers life. It would seem that they are a simple things but you need to do horrible stunts to reach them.

Thanks all for hints! (buttons for praise stopped showing /???/)

Read only

matt
Active Contributor
0 Likes
6,008

The object that you create must persist. If you create a local object then return a reference to it, then as soon as the local object is out of scope, the reference is initialised.

I should have spotted that!

Read only

0 Likes
6,007

You will surely lose your reference once you work with the local variable.

For this purpose you do not need to work with class-data defined object (variable, reference...). You can work with the returning parameter of the method itself for the whole time (et_table from your first post, but with "returning" parameter type). E.g. create data et_table...

There is one thing to remember here - returning variables are always returned by value (not referenced). So if in your case the returning parameter is a reference to an instance variable of the object, your method will always return a reference to a copy of the attribute, not the reference to the attribute itself. But other approach would ruin whole concept of OO, so you should never be trying to do that.

Read only

0 Likes
6,007

This means that for each method returns whatever I need to have a separate variable in the "public section" and I have to watch to do not accidentally use this for another method?

Eg:

Public Section.

gt_xxxxx_for_method_returnTable1_only

gt_yyyyy_for_method_returnTable2_only

....

gt_zzzzz_for_method_returnTableN_only

This promotes a mess!

What if the method returns the variable will run recursively? Do I have to declare 100 variables and reduce the number of recursive calls to 100?

I'll try to use one variable and use local identical variables and assign them just before returning method.

However it is significal discomfort (for me accustomed to real OO) because every language I was used not cause any problems at this point (returned local value or reference, and I did not have to care if it still exists or is no longer).


Regards.

Read only

0 Likes
6,007

Hi,

My sympathy...

For people coming from different programing environment it could be a quite an experience.....

You are not alone....

Regards.

Read only

0 Likes
6,007

good to know that I'm not alone

Read only

tom_demuyt
Explorer
0 Likes
6,007

I am curious, can you tell us more about your use case, what are you trying to accomplish?

Perhaps there is an alternative approach that does not require dynamic tables?

T.

Read only

0 Likes
6,007

Thank you for your willingness to help but isuue of tables is already resolved (above).