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: 

Assign Field-Symbol with new Cond # Syntax

julian_horn
Explorer
0 Kudos

Hey first question here, and I hope I'm doing it right and it is not redundant

I want to read a specific line of an internal table, and modify the table line afterwards.

This can be accomplished by this codeblock:
IF is_estrh_tar IS NOT INITIAL.
READ TABLE ms_spc_db-estrh WITH KEY matched = abap_false subid = is_estrh_tar-subid
ASSIGNING FIELD-SYMBOL(<fs_estrh>).
IF <fs_estrh> IS ASSIGNED.
es_estrh_db = <fs_estrh>.
<fs_estrh>-matched = abap_true.
UNASSIGN <fs_estrh>.
ENDIF. "<fs_estrh>
ENDIF. "ls_estrh_tar

Since I became an avid fan of the constructor expressions Value, Cond, etc I tried building this with the new syntax. es_estrh_db = COND #( WHEN is_estrh_tar IS NOT INITIAL THEN
VALUE #( ms_spc_db-estrh[ matched = abap_false subid = is_estrh_tar-subid ] OPTIONAL ) ).
ms_spc_db-estrh[ recn = es_estrh_db-recn ]-matched = COND #( WHEN es_estrh_db IS NOT INITIAL THEN abap_true ).

The only problem I have is that the new syntax requires two read operations on the table.

I tried using LET <fs_estrh> = ms_spc_db-estrh[ matched = abap_false subid = is_estrh_tar-subid ] in the COND #-Statment, but although that might work in the Condition there is no way to modify this field-symbol in the same expression, since the COND-Expression is specifically designed to only change es_estrh_db.

Is there any way to assign a field-symbol to the output, like:
"ASSIGN <fs_estrh> TO VALUE # / COND # ( .... )" ?

Then I could just Assign the fieldsymbol via constructor operator and modify it in the next statement.

Hope this explaines my question and thanks for any considerations to my question!

Best regards
Julian Horn

1 ACCEPTED SOLUTION

UweFetzer_se38
Active Contributor

See comments under frdric.girod 's answer:

TRY.
    DATA(my_var) = REF #( ms_spc_db-estrh[ matched = ABAP_FALSE subid = is_estrh_tar-subid ] ).
    my_var->matched = ABAP_TRUE.
  CATCH cx_sy_itab_line_not_found ##no_handler.
ENDTRY.
18 REPLIES 18

FredericGirod
Active Contributor

For my point of view, field-symbol should be used for dynamic purpose & really important optimisation need.

And it is not recommended for Clean-Code

(I have not tested the code)

TRY.
     ms_spc_db-estrh[ matched = ABAP_FALSE subid = is_estrh_tar-subid ]-matched = ABAP_TRUE.
  CATCH cx_sy_itab_line_not_found.
ENDTRY.

0 Kudos

Hey,
thanks for your answer.
Sure, when working with dynamical structures there is no way around field-symbols, but i also use them strongly as pointers (eg in LOOP or READ TABLE as opposed to filling a new local structure with the linecontent and writing it back for changes).
Your code should surely modify the selected lines' 'matched'-field, but it doesn't copy that line into my es_estrh_db-Variable. Which could of course be achieved with "es_estrh_db = ms_spc_db-estrh[ matched = abap_false subid = is_estrh_tar-subid ]" before your statement but would effectivly result in 2 read processes on ms_spc_db-estrh.
Therefore the question if this could be combined in one statement (copying the content of a table line into my variable and modifying it) or using a fieldsymbol as reference so the modification doesnt need a new read on the table.

I know the READ TABLE itab WITH key ASSIGNING <fs> does the trick, but I'm interested in the limitations of the constructor expressions VALUE # / COND #. Is this task to complex to achieve it just with them (and I should stick with READ TABLE here) or am I just missing a clever keyword use on the right place? 😄

0 Kudos

"really important"? I personally use field symbols as much as possible (LOOP AT ... ASSIGNING, ASSIGN itab[ ... ] TO, etc., everywhere as rule of thumb), and if the syntax checker sends a warning that it's better to use a data object for performance (example: LOOP AT refs INTO DATA(ref) is to prefer over ASSIGNING FIELD-SYMBOL(<ref>), because a reference is only 8 bytes so INTO is faster than ASSIGNING).

0 Kudos

julian_horn the problem doing two things at the same times is not clean-code (yes! I am addict to clean-code 😉 )

sandra.rossi I am sorry, I don't understand, you use it or not ?

Frederic Girod Sorry, I was unclear. I use field symbols as much as possible, not only when it's "really important". I have edited my comment to make it more clear (I hope)

0 Kudos

julian_horn It's technically impossible to change two data objects in one statement (if one excludes statements like SPLIT INTO f1 f2, FIND REGEX SUBMATCHES f1 f2, etc.)

0 Kudos

sandra.rossi bad bad bad, maybe you will not go to Clean-code-Heaven due to that ...

😉

If you really need the variable you can use the reference:

TRY.
    DATA(my_var) = REF #( ms_spc_db-estrh[ matched = ABAP_FALSE subid = is_estrh_tar-subid ] ).
    my_var->matched = ABAP_TRUE.
  CATCH cx_sy_itab_line_not_found ##no_handler.
ENDTRY.

Frederic Girod Maybe I was still not clear, I was referring to field symbols in general compared to the use of data objects, in reference of your general sentence "For my point of view, field-symbol should be used for dynamic purpose & really important optimisation need."

Concerning your code, I prefer it, FROM FAR:

ms_spc_db-estrh[ matched = ABAP_FALSE subid = is_estrh_tar-subid ]-matched = ABAP_TRUE.

Compared to:

ASSIGN ms_spc_db-estrh[ matched = ABAP_FALSE subid = is_estrh_tar-subid ]-matched TO FIELD-SYMBOL(<matched>).
<matched> = ABAP_TRUE.

But what the OP wants is more something like that:

ASSIGN ms_spc_db-estrh[ matched = ABAP_FALSE subid = is_estrh_tar-subid ] TO FIELD-SYMBOL(<fs_estrh>).
IF sy-subrc = 0.
  es_estrh_db = <fs_estrh>.
  <fs_estrh>-matched = abap_true.
ENDIF.

Can you explain what is not "clean code".

Sorry julian_horn to use your question for other purpose

sandra.rossi it is better explain here https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#prefer-ref-to-to-field-symbol

but I have to admit it is little bit dogma arround field-symbol. I do not like them because I have saw so many time people doing bad things with them ...

Frederic Girod Thank you, I understand now. Let's go for Uwe Fetzer answer!

se38 I think you should create an answer with your proposal, it is (for my point of view) the best one

se38 Yeah that was kinda was i was looking for, overlooked the Ref-Syntax.

So, is there any way for me to accept this answer while it is a comment or does it really have to be resubmitted? (Shall I just submit his answer as proxy?)

Thanks in general for the discussion (also about field-symbols in general 😄 )

0 Kudos

I've re-posted my comment as answer

Sandra_Rossi
Active Contributor

Please use the CODE button to format your code so that it's shown in a more user-friendly format (colorized).

julian_horn
Explorer

First Codeblock - "traditional" Read table:

IF is_estrh_tar IS NOT INITIAL.
  READ TABLE ms_spc_db-estrh WITH KEY matched = abap_false subid = is_estrh_tar-subid ASSIGNING FIELD-SYMBOL(<fs_estrh>).
  IF <fs_estrh> IS ASSIGNED.
    es_estrh_db = <fs_estrh>.
    <fs_estrh>-matched = abap_true.
    UNASSIGN <fs_estrh>.
  ENDIF. "<fs_estrh>
ENDIF. "ls_estrh_ta

Second Codeblock - via constructor operator:

es_estrh_db = COND #( WHEN is_estrh_tar IS NOT INITIAL THEN
                      VALUE #( ms_spc_db-estrh[ matched = abap_false subid = is_estrh_tar-subid ] OPTIONAL ) ).
ms_spc_db-estrh[ recn = es_estrh_db-recn ]-matched = COND #( WHEN es_estrh_db IS NOT INITIAL THEN abap_true ).

Thx for the hint, hope that formatting works out when i click submit now 😉

Best regards
Julian Horn

DoanManhQuynh
Active Contributor
0 Kudos

I think you don't need to check the condition of is_estrh_tar like that. but for dynamic way you may try function method inside [ ]:

ASSIGN ms_spc_db-estrh[ matched = abap_false subid = func=>in( is_estrh_tar-subid ) ] TO <fs_estrh>.

UweFetzer_se38
Active Contributor

See comments under frdric.girod 's answer:

TRY.
    DATA(my_var) = REF #( ms_spc_db-estrh[ matched = ABAP_FALSE subid = is_estrh_tar-subid ] ).
    my_var->matched = ABAP_TRUE.
  CATCH cx_sy_itab_line_not_found ##no_handler.
ENDTRY.