Skip to Content

How to fetch *nicely* 2 values from ITAB-Row?

I started this already via Twitter how to fetch or map two values from an internal table if you are not interested in the whole line

Input:     lt_vbpa   (just an internal table with some more columns )

target:     lv_kunn  (two fields to be filled … needed for next method or something.


Of cause there are lots of solutions, we could make a list out of it, but key is to have FAST, short an understandable code

80s style:

Read Table lt_vbpa assigning <fs>  Key …

lv_kunnr = <fs>-kunnr.

lv_land1  = <fs>-land1.

New >7.40

lv_kunnr = lt_vbpa[ parvw = “WE” ]-kunnr

lv_land1  = lt_vbpa[ parvw = “WE” ]-land1

* but worse 2 read operations in ITAB performance issue in mass processing.

Via Twitter I did receive some Ideas:

New >7.40 feat. Uwe Fetzer

Read Table ltvbpa assigning <fs>  Key …

assign lt_vbpa[ parvw = “WE” ] to <fs>.

lv_kunnr = <fs>-kunnr.

lv_land1  = <fs>-land1.

* Nicer, one read on the itab only, but still tree lines of code

Solution by Enno Wulff

* Also nicer but quite some coding overhead… and again with the performance issue of two reads.

I still do not see a great Idea to do this in a nice way in two lines of code (pls. no #Macros, or two statemts in one line ideas …)

Thanks for the two of you for your Ideas!

You must be Logged on to comment or reply to a post.
  • How about using a LET expression?

    3 lines of code, but still 1 expression. Does it give me the brownie points 😉


      BEGIN OF ty_carrier_monthly_stats,

        total_price  TYPE sflight-price,

        avg_seatsocc TYPE sflight-seatsocc,

      END OF ty_carrier_monthly_stats.

    DATA(lv_date_begin) = sy-datum - 30.


        DISTINCT carrid AS carrier,

        SUM( price ) AS total_price,

        AVG( seatsocc ) AS avg_seats_occ

      FROM sflight

      INTO TABLE @DATA(carriers)

      WHERE fldate BETWEEN @lv_date_begin AND @sy-datum

      GROUP BY carrid

      ORDER BY carrier.


        data = VALUE ty_carrier_monthly_stats(

                LET lh = VALUE #( carriers[ carrier = 'LH' ] OPTIONAL ) IN

                total_price  = lh-total_price

                avg_seatsocc = lh-avg_seats_occ

              )    " Text  oder Daten


    PS - I cannot see the solution from Enno Wullf, maybe you should post the lines of code.

    • I do not really see the advantage here, using the VALUE operator makes not really sense as I just want these two values... But for other questions it is nice code, wehre you have to get used to.

      • I just want these two values.

        TBH, my solution is similar to Enno Wulff's. Instead of using 2 separate variables, i have packed them as fields in a structure.

        Having said that my solution cannot be used anyway if you want 2 separate variable, because you cannot use VALUE operator to construct value of variables. 😐

  • I don't have any 7.4 system to try it, but cannot you use something like:

    DATA(ls_customer) = NEW ty_customer( CORRESPONDING #( lt_vbpa[ parvw = p_parvw ] MAPPING kunnr = kunnr land1 = land1 ).


  • Why do you insist of using two separate variables (lv_kunnr, lv_land1)??

    Adapt Uwes code with DATA instead of FIELD-SYMBOL and use the given structure:

    data(ls_vbpa) = lt_vbpa[ parvw = 'WE' ].

       write: / 'Customer:', ls_vbpa-kunnr,

              / 'Country: ', ls_vbpa-land1.

  • Is it really possible in another language to write it shorter? In ABAP, I really don't see how we could do it in less than 3 lines because we need to access the line of the internal table first, so that it can be used to setup the 2 fields.

  • types: BEGIN OF ty_needed_values,

                kunnr type kunnr,

                land1 type land1,

            END OF ty_needed_values.

    data: l_needed_values type ty_needed_values.

    Read Table lt_vbpa assigning <fs>  Key ...

    MOVE-CORRESPONDING <fs> TO l_:needed_values.

  • The actual 80s style:


    Not sure if it's just some kind of academic exercise, but IMHO in this odd quest to stuff as much code as possible in as few lines as possible we are starting to lose readability.

    • Jelena, I agree with you wholeheartedly.

      Certainly there is good reason to take advantage of new additions to the language when new functionality comes with it, but the headlong rush to adopt new syntax just because it is the bright shiney new thing is not merited.

      It should be remembered that OO was developed to be reusable and to allow the building of complex programs by assembling components, not writing from scratch.

      How much of THAT is happening these days outside of software houses like SAP??

      Code readability is already going extinct and we're heading back to the bad old days of trying to read assembly language code, IMHO.

      • Hello, thank you for your comments. I see coding in such a N-Angle with the - sometimes - conflicting targets: - speed of development (e.g. write only code ) - maintainability      (e.g.: comments vs. whole history of 10 projects in code ) - readability          ( find the right spot in coding ) - reusability - execution time So I think it's good from time to time to think about coding style. Yes, I agree it's some kind of an academic discussion if you need 2 or 3 lines. In a Dynpro transaction I would go for the two lines approach, cause no body will notice the performance difference there. + read + maintain In mass processing of orders performance is key so the three lines version is best.

    • Hi Jelena,

      but IMHO in this odd quest to stuff as much code as possible in as few lines as possible we are starting to lose readability.

      Unfortunately i have to disagree on this one with you.

      I don't understand why is this piece of code

      data = VALUE ty_carrier_monthly_stats(

                       LET lh = VALUE #( carriers[ carrier = 'LH' ] OPTIONAL ) IN

                       total_price  = lh-total_price

                       avg_seatsocc = lh-avg_seats_occ


      is deemed to be unreadable? 😕

      Tbh, i am often at cross-roads when to stop using functional expressions. Hence i often end up asking questions like this Cleaner syntax for filling up internal tables with VALUE?.



      PS - It's kinda addictive when you start using the functional ABAP 😳

      • It's not that it's unreadable, it is not easily translated to plain English (which is understood by humans). E.g. when I see READ TABLE... INTO... I don't even need to reach for Help. In fact, I don't even need to know ABAP.

        But take the other example: "VALUE". Hm, so what am I doing here? Am I assigning value to something? Where is a verb? Oh, there it is - LET. Uhm, let what? Let there be light? What goes where here? And then there is another VALUE, two sets of parenthesis and square brackets, dear lord...

        It might be just a matter of what one is used to (e.g. when I was in University, Java did not exist and mainframes ruled the world) as such syntax is typical for languages like C & Co. But since ABAP is rather business oriented I came to appreciate that it can read like plain English. Even a functional consultant can look at ABAP code that we call "80s style" (e.g. in a short routine) and still understand what's going on in general. I doubt they'd have the same success with VALUE... LET. Not that we need to "dumb it down" intentionally but I hope you see the point.

        • Not that we need to "dumb it down" intentionally but I hope you see the point.

          ABAP used to be verbose, no denying the fact. If one wrote the ABAP statements with good in-source comments, one could in fact read the source code like a story.

          IMHO whether to use old, verbose ABAP syntax or the new, compact, geekier 😎 syntax is a matter of one's taste. Both the syntaxes will continue to co-exist in the ABAP ecosystem and the developer has to pick what suits his/her taste.

          • If one gets to pick.  More and more I see clients requiring "geeky" code, not because they are moving headlong into Webdynrpo or Fiori or mobility apps, but because it is "the new shiny thing" and someone's performance goal (and bonus) is to implement new shiny things.

            How much money are companies willing to spend on consultants to indulge their whims?

            Again, new for the sake of a noticable gain is wonderful.  New for the sake of novelty is not a sound business decision.

            Just my free opinion and worth everything you paid for it 😆 .

          • Sorry, never seen such thing. Actually, quite the opposite: customers often don't want "the new shiny thing", even when it's proved to be way better than the old thing, because they are afraid they will not have people who knows the new thing when they need to maintain it.

            just my free opinion/experience anyway 😉

          • "and someone's performance goal (and bonus) is to implement new shiny things"

            And what about people who want to learn new things? Let's not generalize 😉

        • I think he is being sarcastic ... obviously that line of code is not readable by a human....

          This whole argument is crazy to me - surely success is judged not by how compact you can make your code, but rather by how easy it is for someone coming after you, or even yourself six months on, to be able to look at the code and know what is going on?

          To my mind the more the code reads like plain English (sorry non-English speakers) the closer you are to that goal. The more it reads like VALUE x LET y OPTIONAL z OPTIONAL z LET x = y the further you are away from that goal, even if such a statement does the same thing as twenty lines of readable code.

          Since 95% of development is changing and enhancing existing programs you have to be able to look at the code and work out what it does in a hurry. If you have to guess, something is seriously wrong.

          I thought the whole reason we used "fourth generation" languages as opposed to machine code was so that we could read the code?

          • Paul,

            if you're working with it daily, then it's readable. But that's sure that with new syntax you have to be careful not to do a mess, as then you'd probably need to put a huge comment to what you're doing inside such one very complex syntax. And in my opinion code should be self-explanatory.


          • I think he is being sarcastic ... obviously that line of code is not readable by a human....

            Hi Paul,

            No, i'm not.

            Never have i mentioned that expression-based ABAP is better than verbose ABAP.

            The trick is to strike the correct balance between the two. IMO what matters the most is that the code is clean and easy to understand.

            Let me take the liberty of adding to your statement,

            obviously that line of code is not readable by a human... who has not worked with expression-based ABAP



            PS - For the scepticals please read the response from Horst Keller here How much ABAP740 (read: functional ABAP programming) is too much?

          • I don't actually think the argument is to do with expression based ABAP vs pre 7.40 ABAP, or even about ABAP at all, but rather programming languages in general.

            As Horst says there have been obscure and/or misleading statements in ABAP for a long while.

            I think we all want the same thing. Code where it is clear what is going on to anyone who looks at it, not just the programmers but anyone else who looks at it, and much as programmers may hate it, lots of other people, like business analysts, look at your code.

            Robert Martin spends a great deal of his time talking about this subject, even more important in the version of Java he was using at the time, which has far less key words than we are used to in ABAP world.

            To me, being able to understand a line of code, and that line of code being "readable" are two separate things.

            I could see a regular expression, and I know what it means, but I could not honestly describe it as "readable" in the same way something like "REPLACE ALL OCCURENCES OF '&V1' IN message_text WITH dynamic_value" would be readable because it looks almost like a normal sentence.

            I am able to read the new "exotic" ABAP commands with no problem at all, I have to concentrate a bit harder, but not the end of the world. However I cannot help but be reminded of a book on website design called "Don't Make Me Think".

            If a block of code is 10% of the size, but it takes you longer to work out what is happening than the equivalent full size block of readable code, how have you made life for your colleagues (and you) any better?

            This whole concept is fascinating to me, as you can tell, and since it is sort of off topic for this blog I will shortly write a blog of my own about this, presenting a whole bunch f examples and arguments which people can then shoot down in the comments.

            Cheersy Cheers


          • This whole concept is fascinating to me, as you can tell, and since it is sort of off topic for this blog I will shortly write a blog of my own about this

            Now that you have mentioned it, eagerly waiting for the blog to be published 😀

        • Another way around, also "English" ABAP has its problems.

          • Statement GET spfli. Do you understand from that what id does? (no, it does not get SPFLI ...)
          • Statement SET LANGUAGE, no it does not set the language ...
          • AT SELECTION-SCREEN OUTPUT, beware!
          • ...

          Shows a general problem of verbose statements. Same for variable names. Meanings may change but but the names stay.

  • Hi Enno, Hi Uwe,

    In your solution(s) you missed the fact that the table expression can give a CX_SY_ITAB* exception if the line is not found. You have to either handle the exception or use the addition OPTIONAL/DEFAULT with the VALUE operator.



      • if we want to be pedantic today

        Lol, of course not 🙂

        My poor colleagues have to face it everyday though. I drag up ABAP help at the drop of the hat.

    • But to be honest we also have to check sy-subrc in the other way as well. Maybe I should take that into account in the statements. Cause I see an other advantage of the Uwe Fetzer solution:


      *Business Code of interest...

      assign lt_vbpa[ parvw = "WE" ] to <fs>.

      lv_kunnr = <fs>-kunnr.

      lv_land1  = <fs>-land1.

      * more Business code ..

      catch CX_SY_ITAB* ...

      * Boring dump protection ...

      end try.

      you can have more clear separation of interesting and boring code:

      Compare 80ts stuff:

      Read Table lt_vbpa assigning <fs>  Key ...  "Business Code

      if sy-subrc <> 0.                                                      "Boring

        * Error handling                                                       "Boring

      end if.                                                                      "Boring

      lv_kunnr = <fs>-kunnr.                                          "Business Code

      lv_land1  = <fs>-land1.                                         "Business Code

      you mix things up which I think, create code that is hard to read.

      • If you use ASSIGN with table expressions CX_SY_ITAB* exception won't be raised. Instead SY-SUBRC is set to 4. (refer: table_exp - Table Expressions - ABAP Keyword Documentation)

        In fact, if you use ASSIGN-construct with table expression, the code will look similar to the READ TABLE

        ASSIGN itab[...] TO FIELD-SYMBOL(<wa>)

        IF sy-subrc = 0.







        IF sy-subrc = 0.





        Cause I see an other advantage of the Uwe Fetzer solution

        I don't quite understand the rationale, sorry! 😕

  • If you just need 2 fields returned back and not the whole line, you may use TRANSPORTING addition with READ statement:

    read table customers into data(customer) transporting kunnr land1 with key kunnr = 'ABCD'.



  • If we take the idea of Enno Wulff to use structure instead of two separate fields then it could be done in one shot:

        types: begin of ty_customer,

                 kunnr type vbpa-kunnr,

                 land1 type vbpa-land1,

               end of ty_customer.

        data(lt_vbpa) = value vbpa_tab( 

                                         (  parvw = 'WE' kunnr = '111111' land1 = 'DE')

                                         (  parvw = 'AG' kunnr = '111111' land1 = 'DE')

    data(customer) = corresponding ty_customer( lt_vbpa[ parvw = 'WE' ] ).

    But with two separate fields I'd prefer assign lt_vbpa[ xx ] to field-symbol(<x>). solution.

  • I prefer the Fetzer way (well, the first line of it):

    assign lt_vbpa[ parvw = "WE" ] to FIELD-SYMBOL(<fs>).

    Jelena ( 😉 ) would write it as


    Both do exactly the same! ->Question of taste which to use (as Suhas said).

    You set a pointer to the table line.

    The field symbol is structured. No need to declare a special structure with the two components, or?

    Now you can simply use <fs>-kunnr and <fs>-land1 at any operand position.

    Normally no need for

    lv_kunnr = <fs>-kunnr.

    lv_land1  = <fs>-land1.

    (as long as you do not need to prevent overriding the values by write accesses).

    That's a bit the problem of this question "How to fetch nicely", as Sandra has pointed out already.

    • Hello Horst,

      can I propose extending the DEFAULT / OPTIONAL value specified within the construction operators VALUE or REF to the CORRESPONDING operator?

      This would enable code like:

      data(customer) = CORRESPONDING

                              ty_customer( lt_vbpa[ parvw = 'WE' ]  OPTIONAL ).

      best regards,