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

How to export a reference to a table line from a method?

Former Member
0 Likes
2,751

Hello,

I have a class which has a hashed table as an attribute. I want to retrieve a line from the table using the key and return a reference to the table line. I want changes to the return value of the method to be directly reflected in the table, as if using a local field symbol. I have tried to approaches, neither of which works.

First, I returned a reference to the local field symbol. This dumps, because after returning from the method call, the target of this reference no longer resides on the stack.

Second, I have tried using an export parameter marked as "pass by reference", i. e. without VALUE(). Strangely, this still seems to give me only a copy of the data.

What is the correct way to proceed?

Illustrative pseudo-code follows.

Thanks, Sebastian


*==============================================================
*Possibility 1: (using references)

DATA mt_key_map TYPE zt_entity. " member variable (hash table of zs_entity)
  
METHODS get
    IMPORTING
      !is_key TYPE zs_key
    EXPORTING
      !er_vt TYPE REF TO zs_entity.

METHOD get.
  FIELD-SYMBOLS: <fs_vt> TYPE zs_entity.  

  READ TABLE mt_key_value WITH KEY key = is_key ASSIGNING <fs_vt>.
  GET REFERENCE OF <fs_vt> INTO er_vt.
ENDMETHOD.      
      
      
" Client Code:

  FIELD-SYMBOLS: <fs_vt> TYPE zs_entity.  
  
  CALL METHOD get
    EXPORTING
      is_key        = is_key
    IMPORTING
      er_vt         = lr_vt.
      
  ASSIGN lr_vt->* TO <fs_vt>.  " will dump, because the local field symbol
                               " to which lr_vt points is no longer on the stack
  <fs_vt>-value = 'newdata'.        
  
*==============================================================
*Possibility 2:  (using a structure passed by reference)

DATA mt_key_map TYPE zt_entity. " member variable (hash table of zs_entity)
      
METHODS get
    IMPORTING
      !is_key TYPE zs_key
    EXPORTING
      !es_vt TYPE zs_entity.   
      
METHOD get.
  FIELD-SYMBOLS: <fs_vt> TYPE zs_entity.  

  READ TABLE mt_key_map WITH KEY key = is_key ASSIGNING <fs_vt>.
  es_vt = <fs_vt>.
ENDMETHOD.    


" Client Code:

  DATA: ls_vt TYPE zs_entity.

  
  CALL METHOD get
    EXPORTING
      is_key        = is_key
    IMPORTING
      es_vt         = ls_vt.
      
  ls_vt-value = 'newdata'.   " will not change the contents of the
                             " table mt_key_value        

Hello,

I have a class which has a hashed table as an attribute. I want to retrieve a line from the table using the key and return a reference to the table line. I want changes to the return value of the method to be directly reflected in the table, as if using a local field symbol. I have tried to approaches, neither of which works.

First, I returned a reference to the local field symbol. This dumps, because after returning from the method call, the target of this reference no longer resides on the stack.

Second, I have tried using an export parameter marked as "pass by reference", i. e. without VALUE(). Strangely, this still seems to give me only a copy of the data.

What is the correct way to proceed?

Illustrative pseudo-code follows.

Thanks, Sebastian


*==============================================================
*Possibility 1: (using references)

DATA mt_key_map TYPE zt_entity. " member variable (hash table of zs_entity)
  
METHODS get
    IMPORTING
      !is_key TYPE zs_key
    EXPORTING
      !er_vt TYPE REF TO zs_entity.

METHOD get.
  FIELD-SYMBOLS: <fs_vt> TYPE zs_entity.  

  READ TABLE mt_key_value WITH KEY key = is_key ASSIGNING <fs_vt>.
  GET REFERENCE OF <fs_vt> INTO er_vt.
ENDMETHOD.      
      
      
" Client Code:

  FIELD-SYMBOLS: <fs_vt> TYPE zs_entity.  
  
  CALL METHOD get
    EXPORTING
      is_key        = is_key
    IMPORTING
      er_vt         = lr_vt.
      
  ASSIGN lr_vt->* TO <fs_vt>.  " will dump, because the local field symbol
                               " to which lr_vt points is no longer on the stack
  <fs_vt>-value = 'newdata'.        
  
*==============================================================
*Possibility 2:  (using a structure passed by reference)

DATA mt_key_map TYPE zt_entity. " member variable (hash table of zs_entity)
      
METHODS get
    IMPORTING
      !is_key TYPE zs_key
    EXPORTING
      !es_vt TYPE zs_entity.   
      
METHOD get.
  FIELD-SYMBOLS: <fs_vt> TYPE zs_entity.  

  READ TABLE mt_key_map WITH KEY key = is_key ASSIGNING <fs_vt>.
  es_vt = <fs_vt>.
ENDMETHOD.    


" Client Code:

  DATA: ls_vt TYPE zs_entity.

  
  CALL METHOD get
    EXPORTING
      is_key        = is_key
    IMPORTING
      es_vt         = ls_vt.
      
  ls_vt-value = 'newdata'.   " will not change the contents of the
                             " table mt_key_value        

6 REPLIES 6
Read only

naimesh_patel
Active Contributor
0 Likes
1,354

In the first approch, try to change the exporting parameter type REF TO DATA.

Try like:


*----------------------------------------------------------------------*
CLASS lcl_test DEFINITION.

  PUBLIC SECTION.

    DATA: t_mara TYPE HASHED TABLE OF mara WITH UNIQUE KEY matnr.

    METHODS:
      constructor,

      get
        IMPORTING
          if_matnr TYPE matnr
        EXPORTING
          ea_mara  TYPE REF TO data.

ENDCLASS.                    "lcl_test DEFINITION

START-OF-SELECTION.
  DATA: lo_test TYPE REF TO lcl_test,
        lr_data TYPE REF TO data.

  FIELD-SYMBOLS: <fa_mara> TYPE ANY,
                 <f_field> TYPE ANY.


  CREATE OBJECT lo_test.

  lo_test->get(
    EXPORTING
      if_matnr = '000000000077000000'   " << Replace Your Material
    IMPORTING
      ea_mara  = lr_data ).

  ASSIGN lr_data->* TO <fa_mara>.
  ASSIGN COMPONENT 'ERSDA' OF STRUCTURE <fa_mara> TO <f_field>.
  <f_field> = space.


  WRITE: 'Done'.

*----------------------------------------------------------------------*
CLASS lcl_test IMPLEMENTATION.

  METHOD constructor.

    SELECT * INTO TABLE t_mara
           FROM mara
           UP TO 10 ROWS.

  ENDMETHOD.                    "constructor

  METHOD get.

    FIELD-SYMBOLS: <lfs_mara> LIKE LINE OF me->t_mara.

    READ TABLE me->t_mara ASSIGNING <lfs_mara> WITH KEY matnr = if_matnr.

    GET REFERENCE OF <lfs_mara> INTO ea_mara.

  ENDMETHOD.                    "get

ENDCLASS.                    "lcl_test IMPLEMENTATION

Regards,

Naimesh Patel

Read only

GrahamRobbo
SAP Mentor
SAP Mentor
0 Likes
1,354

Hi Seb,

I imagine you will get lots of responses on how to do this.

I just wanted to point out that what you are trying to do breaks one of the underlying principles of OO design - namely "encapsulation".

You should not allow the modification of a class attribute directly, rather you should only allow attribute changes by calling the appropriate method of the class.

Cheers

Graham Robbo

Read only

Former Member
0 Likes
1,354

Dear Sebastian ,

My suggesstion is as follows:

Since the table is an hashed table , try to export the hash algorithm instead of a field symbol to a record.

If we can export the hash algorithm , then we can get access to any table line(record) of the hashed table.

I hope , this idea works.

Thanks and Regards ,

Debojyoti chanda.

Read only

Former Member
0 Likes
1,354

Thanks Naimesh. Your code is structurally identically to what I posted (taking away the type information from the reference is not significant) You made me see that I actually made another mistake which I did not include in my example code - I apologize for that. My mistake occurred when I inserted a new line in the table. I simply returned a reference to the inserted structure instead of re-reading the table to obtain a reference to the new line. Thank you for your help.

@Graham: Encapsulation is not a concern. I did not state in my post that the get-method is private. The reference never leaves the enclosing class.

Read only

0 Likes
1,354

Don't agree with you - but anyway...

    READ TABLE me->t_mara REFERENCE INTO ea_mara WITH KEY matnr = if_matnr.

Cheers

Graham Robbo

Read only

matt
Active Contributor
0 Likes
1,354

I'd say only use setters and getters for public access to attributes. Maybe protected. But private - I don't see the need!

matt