07-04-2014 9:28 AM
Hello everyone,
writing a custom program, I try to execute the following code:
LOOP AT it_vttk REFERENCE INTO dref_vttk.
...
me->set_shipment_status( EXPORTING im_status = 2 CHANGING ch_shpmnt = dref_vttk->* ).
...
ENDLOOP.
This throws a runtime error calling me that I am not allowed to write to field "???" (tried a little and in fact I am not allowed to write to dref_vttk->*). it_vttk is defined as HASHED TABLE OF vttk WITH UNIQUE KEY tknum. it_vttk is a (private) attribute of the class containing the above coding in a (public) method.
It is clear to me that I am not allowed to change the key field tknum within loop processing, but I don't do this in method set_shipment_status.
So - what is the proper way of changing fields in a line of a hashed table using a method call? I can't specify the fields in the method call because the method decides which fields are changed.
07-04-2014 11:40 AM
07-04-2014 2:46 PM
I could, but maybe a minimal working example suffices:
REPORT zzms_test_loop.
DATA: it_vttk TYPE HASHED TABLE OF vttk WITH UNIQUE KEY tknum,
dref_vttk TYPE REF TO vttk,
wa_vttk TYPE vttk.
SELECT * FROM vttk INTO TABLE it_vttk WHERE tplst ='4017'.
LOOP AT it_vttk REFERENCE INTO dref_vttk.
dref_vttk->streg = 'X'.
wa_vttk = dref_vttk->*.
wa_vttk-streg = 'X'.
dref_vttk->* = wa_vttk.
ENDLOOP.
The first instruction in the loop works flawlessly. Then I try to achieve the same result assigning the table line to a work area (or passing it to a method as a CHANGING parameter, think this makes no difference), changing the field there and writing the result back. This leads to a dump.
If it is generally not allowed to assign anything to dref_xxx->* in a loop (which I would find weird anyway), I wonder why this gives a runtime and not a syntax error...
07-04-2014 2:58 PM
The contents of the memory location that hold wa_vttk-tknum are copied to the memory location dref-vttk->tknum which is protected, as tknum is a key field.
07-05-2014 8:50 AM
why not use wa_vttk then before equating it to dref_vttk->*.
me->set_shipment_status( EXPORTING im_status = 2 CHANGING ch_shpmnt = wa_vttk ).
dref_vttk->* = wa_vttk.
07-04-2014 3:03 PM
I know, but can't ABAP simply check whether both contents are identical and then be happy? As far as I know, there is no construction like "Write all fields except for X", so changing many fields of the structure would be quite difficult then...
07-04-2014 3:24 PM
Michael Seifert wrote:
I know, but can't ABAP simply check whether both contents are identical and then be happy? .
I'm sure it could. But it doesn't so we'll have to live with it.
You could use:
LOOP AT it_vttk ASSIGNING <vttk>.
...
me->set_shipment_status( EXPORTING im_status = 2 CHANGING ch_shpmnt = <vttk> ).
...
ENDLOOP.
Then within your set_shipment_status, use
ASSIGN COMPONENT fieldname OF STRUCTURE ch_shpmnt TO <status>.
<status> = im_status.
07-04-2014 3:25 PM
Michael Seifert wrote:
I know, but can't ABAP simply check whether both contents are identical and then be happy? As far as I know, there is no construction like "Write all fields except for X", so changing many fields of the structure would be quite difficult then...
I not sure if other programming languages are capable of doing this, but afaik the ABAP kernel is not too smart enough to do this. I checked recent ABAP documentation on MOVE-CORRESPONDING but still no luck.
Until SAP builds this functionality into the ABAP Kernel you have to live using this workaround involving field symbols.
BR,
Suhas
07-05-2014 4:44 AM
Suhas,
The post not mine, but i have a question... When you make reference into dref_flight, this does not need to be declared (eg. DATA dref_flight TYPE REF TO data)? Or this is declared when you pass DATA(dref_flight) (creating the same data type how i show above) ?
07-05-2014 8:32 AM
Those are inline declarations for ABAP 740 - ABAP Keyword Documentation.
There are quite a few blogs by Horst Keller about the new features of ABAP 740. You can find those in the ABAP forums, should read those!
BR,
Suhas
07-05-2014 2:40 PM
07-15-2014 12:27 PM
I don't get your idea right, I think... If I have to use a workarea anyway, why not use LOOP ... INTO instead of REFERENCE INTO? And if I want to change just a single component of dref_flight->*, I could change the component directly. Maybe I should give you indeed an example using methods, so you understand what I am trying to do 🙂
This one works, but only because main and test are methods of the same class which has dref_vttk as an attribute:
REPORT zzms_test_loop.
CLASS test DEFINITION.
PUBLIC SECTION.
CLASS-DATA:
it_vttk TYPE HASHED TABLE OF vttk WITH UNIQUE KEY tknum,
dref_vttk TYPE REF TO vttk.
CLASS-METHODS:
test IMPORTING flag TYPE c,
main.
ENDCLASS. "test DEFINITION
CLASS test IMPLEMENTATION.
METHOD test.
IF flag = 'X'.
dref_vttk->streg = 'X'.
ENDIF.
ENDMETHOD. "test
METHOD main.
SELECT * FROM vttk INTO TABLE it_vttk WHERE tplst ='4017'.
LOOP AT it_vttk REFERENCE INTO dref_vttk.
test=>test( EXPORTING flag = '').
ENDLOOP.
ENDMETHOD.
ENDCLASS.
This one does not work (runtime error), because I am not allowed to pass dref_vttk->* as CHANGING parameter:
REPORT zzms_test_loop.
CLASS test DEFINITION.
PUBLIC SECTION.
CLASS-DATA:
it_vttk TYPE HASHED TABLE OF vttk WITH UNIQUE KEY tknum.
CLASS-METHODS:
test IMPORTING flag TYPE c CHANGING shpmnt TYPE vttk,
main.
ENDCLASS. "test DEFINITION
START-OF-SELECTION.
test=>main( ).
CLASS test IMPLEMENTATION.
METHOD test.
IF flag = 'X'.
shpmnt-streg = 'X'.
ENDIF.
ENDMETHOD. "test
METHOD main.
DATA dref_vttk TYPE REF TO vttk.
SELECT * FROM vttk INTO TABLE it_vttk WHERE tplst ='4017'.
LOOP AT it_vttk REFERENCE INTO dref_vttk.
test=>test( EXPORTING flag = 'X' CHANGING shpmnt = dref_vttk->* ).
ENDLOOP.
ENDMETHOD. "main
ENDCLASS.
But this is (as far as I can see) the only way to do it if main and test are not methods of the same class. I simply don't understand a) why the pure assignment of dref_vttk->* as a CHANGING parameter leads to an error (because at that time it is unclear what will happen to this parameter) and b) why this is a runtime and not a syntax error.
07-04-2014 3:24 PM
Hi,
Maybe I am missing something but why not use field symbols .
Regards.
Code:
REPORT y_r_eitan_test_30_07.
START-OF-SELECTION .
PERFORM at_start_of_selection .
*----------------------------------------------------------------------*
FORM at_start_of_selection .
PERFORM test05 .
ENDFORM . "at_start_of_selection
*----------------------------------------------------------------------*
FORM test05 .
DATA: it_sbook TYPE HASHED TABLE OF sbook WITH UNIQUE KEY bookid .
SELECT * INTO TABLE it_sbook FROM sbook UP TO 10 ROWS .
FIELD-SYMBOLS: <st_sbook> LIKE LINE OF it_sbook .
LOOP AT it_sbook ASSIGNING <st_sbook> .
PERFORM recalc CHANGING <st_sbook> .
ENDLOOP.
ENDFORM. " TEST05
*----------------------------------------------------------------------*
FORM recalc
CHANGING st_sbook TYPE sbook .
st_sbook-forcuram = 1 .
ENDFORM. " RECALC