Skip to Content

ABAP News for 7.40, SP08 – More for Internal Tables

Besides the already mentioned REDUCE operator, the conditional FOR and  LINES OF inside VALUE & Co. and the grouping of internal tables, there are some other ABAP enhancements for internal tables in 7.40, SP08:

FILTER expressions

The new FILTER operator enables two kinds of filtering an internal table.

FILTER with single values

In this variant, you simply extrract the lines from an internal table into a tabular result, that fulfill a simple value condition.

DATA(extract) =

  FILTER #( spfli_tab USING KEY carr_city

              WHERE carrid   = CONV #( to_upper( carrid ) ) AND

                    cityfrom = CONV #( to_upper( cityfrom ) ) ).

As a prerequisite, the filtered table must have a sorted or a hash key (primary or secondary), that is evaluated behind WHERE. You can also extract the lines that do not fulfill the WHERE condition by using an EXCEPT addition.  Of course, you can achieve the same result by using a FOR inside a VALUE ror a REDUCE expression but FILTER allows you to write it shorter and it should be faster.

FILTER with filter table

In this variant, you compare the lines of one table with the contents of another table, the filter table, and you extract those lines, where at least one match is found (say hello to FOR ALL ENTRIES).

         cityfrom TYPE spfli-cityfrom,
         cityto   TYPE spfli-cityto,
       END OF filter,
       filter_tab TYPE HASHED TABLE OF filter
                  WITH UNIQUE KEY cityfrom cityto.

DATA(filter_tab) = …        

DATA(extract) =
  FILTER #( spfli_tab IN filter_tab
              WHERE cityfrom = cityfrom  AND cityto = cityto ).

Here, the filter table – that can be specified also as a functional method call – must have a sorted or a hashed key (primary or secondary) that is evaluated.

Standard Value for Table Expressions

Table expressions itab[ …] cannot support sy-subrc. Up to now, an exception was raised anytime if a table line specified in the square brackets could not be found. Not everybody liked this behavior.

As a workaround, you can place a table expression inside a VALUE or REF expression, that contains a OPTIONAL or DEFAULT addition. If a line is not found, the OPTIONAL addition returns an initiial line while the DEFAULT addition returns a given value, that can be specified as an expression, especially another table expression.


  BEGIN OF line,

    id    TYPE i,

    value TYPE string,

  END OF line,


DATA(def) = VALUE line( id = 0 value = `not found` ).

DATA(result) = VALUE #( itab[ id = … ] DEFAULT def ).

You must be Logged on to comment or reply to a post.
  • Hi,



    I am reading about all this wonderful enhancements to ABAP and I do like them.



    But I wander what needs to be done to get those new shining tools ?



    For example when a new Java release is out I just install a new JDK and I have all the new features , I do not need to do any thing else.



    Is it possible to upgrade just the ABAP part of a system ?



    Can our basis team do it ?



    I appreciate any response .




    • Great question. By googling 'ABAP 7.4' I found this document, from which I understand that this would be part of Netweaver 7.4. Consequently, by googling 'Netweaver 7.4' I found this SCN post that mentions 'Currently only Business Suite EHP7 is supported.' So, applying simple logic I'm guessing one must be running Netweaver 7.4 together with ECC EHP 7 to get to the ABAP 7.4 stuff. (One could probably run Netweaver all by itself on some basement server or in the cloud or whatever, but I'm guessing it's not the most relevant information for the majority of ABAPers.)


      If someone could post some simple cross-reference of "what comes with what" or "how to get from here to there", it would be very helpful. We need this information in simple layman's terms that any SAP specialist could easily find and understand.

      • I believe you are right. I have been playing in ABAP 7.40 in my customer's BW (7.4) on HANA installation (on premise). Too bad we are in SP7 so I can't try these new things yet

      • Hi, Elena!

        We also decided it would be easier to upgrade from EhP6 to EhP7 to get new ABAP

        Couldn't but quote your words about

        "what comes with what" or "how to get from here to there".

        Unfortunately, it's really not evident at all.

      • According to our Basis, for "technical use ECC systems", we need to upgrade to EHP7 for SAP ERP 6.00 in order to get to Netweaver 7.40.

        • Horst, I believe you are way too modest about your importance.


          The thing is - there needs to be information available in simple lanuage that ABAPers and even some functional folks could easily understand and digest. All the information I've seen so far appears to be written by Basis for Basis, so to say. Most ABAPers don't need a 6 page document about the release strategy (it's TMTR, quite frankly) but some simple chart with dependencies. What Julie Plummer did in her blog about NWBC is an excellent example of how such information could be presented.

          • No really, I am writing the ABAP language documentation (day in, day out) and I can only blog about things I happen to know. I also tried to explain what is ABAP 7.40, but I can't tell you how to get your hands on it.  What I intend to do is to give you a simple sneak preview of new features in ABAP to come. It is far, far out of my reach to influence someone to make it more easily available. But it is absolutely perfect that you liked the blog of Julie Plummer. She works in Karl Kessler's team and its really those guys who can tell you more about release policy.

          • Thank you very much, and sorry for hijacking the comments with "deployment options" talk (largely impenetrable to me atleast) - this is the last from me.




            This comment, I believe, confirms your "simple logic" and what our Basis said:

            [I]t is not possible to replace the NetWeaver foundation of an existing ERP to higher release such as NetWeaver 7.4.

            However, the next version of the Business Suite (containing EHP7 of ERP) will be based on NetWeaver 7.4.


            My "simple logic" was telling me that one should somehow be able to upgrade "basis" and "application basis" without disrupting too much or rendering "application" inoperable, and that it should have been less of an effort than doing full fledged ERP EHP... But then I probably still know too little about "application basis" and "application".




          • But then I probably still know too little about "application basis" and "application".

            Hence the terms - "technical upgrade", "functional upgrade".

    • I just install a new JDK and I have all the new features


      ABAP is not like Java. ABAP is the programming language of the ABAP Application Server (AS ABAP) of SAP Netweaver. You need an AS ABAP and an underlying database to work in ABAP. In former times this was the so called SAP Basis as part of an R/3 System and you normally had to have access to such a system in order to work with ABAP. Standalone SAP Basis systems (R/3 without application programs so to say) were more or less rare.


      Nowadays the namings and environments have become more and more complex and I (as the ABAP language documentation writer) am far from having a synoptic view of this. Here people with more knowledge come into play. See e.g. Karl Kessler's contributions to this subject, e.g. Understanding Kernel Releases for the SAP NetWeaver AS ABAP or Demystifying SAP’s Support Strategy for SAP NetWeaver 7.4.


      But all in all it hasn't changed too much, that you need to have access to an AS ABAP of Release 7.40, SP08 in order to work with the features of ABAP Language 7.40, SP08. And on this AS ABAP, everything has to match. You must have the respective Kernel Release (742 for ABAP 7.40, SP08), the respective ABAP Support Package (tools, texts, and other repository objects must match the kernel requirements) and meanwhile you even need a matching database version (e.g. some new built-in ABAP CDS functions are delivered with required database versions only)!


      How to get there is another question. Possiblities can include upgrading your ERP, BW, or whatsoever, installing a standalone Newtweaver or AS ABAP, or getting access to a trial version in the cloud once it is available (see Christopher Kästner's contributions). To my knowledge, the free AS ABAP Trial Versions for local installation are not available any more.


      But this discussion is far out of scope of my blogging about some ABAP Language news. For this there are places like SAP NetWeaver Application Server or  SAP NetWeaver Technology Platform. There you find another more general document, that might to be a much better starting point for asking these questions.

      • Hi,


        Thanks for prompt response .


        Yes I understand that "ABAP is not like Java" .


        I am not saying that it should. But it seems to me that for the benefit of programmers productivity and code quality a quick upgrade is something to wish for .


        Organization simply do not upgrade because of the overhead involve.


        I am not happy....



  • Regarding "FILTER with single values",

    1. I know it might sound petty, bu how is it shorter then VALUE (FOR)?

    2. Why is there a prerequisite for sorted/hashed key? Doesn't VALUE (FOR) uses table key when possible?

    • how is it shorter then VALUE (FOR)?


      What is shorter?


      DATA(jtab) = FILTER #( itab WHERE ... ).




      DATA(jtab) = itab.

      jtab = VALUE #( FOR wa IN itab WHERE ( ...  ) ( wa ) ).


      And retranslated to statements, what is faster?

      jtab = itab.
      DELETE jtab WHERE NOT ...



      LOOP AT itab INTO DATA(wa) WHERE ...

        INSERT wa INTO TABLE jtab.



      Doesn't VALUE (FOR) uses table key when possible?


      No, same as for LOOP. You must specify USING KEY in order to keep programs stable in case a (dictionary) type is enhanced with secondary keys lateron.

      • What is shorter?


        DATA(jtab) = FILTER #( itab WHERE ... ).





        DATA(jtab) = VALUE #( FOR wa IN itab WHERE ( ...  ) ( wa ) ).

        Well, you got there. FILTER is (little) shorter.


        jtab = itab.
        DELETE jtab WHERE NOT ...


        LOOP AT itab INTO DATA(wa) WHERE ...

          INSERT wa INTO TABLE jtab.


        Now I'm a little confused.

        What FILTER is translated to? DELETE or LOOP ... INSERT?

        No, same as for LOOP. You must specify USING KEY in order to keep programs stable in case a (dictionary) type is enhanced with secondary keys lateron.

        Yes, I'm aware of the fact you should specify USING key when using secondary keys (but not when using primary key).

        My question is why sorted/hashed key is mandatory in FILTER statment? Couldn't it be optional (with the risk bad performance)?

        • FILTER is translated to DELETE and VALUE FOR  to LOOP. DELETE is faster (in fact the "full text search" in the ABAP Keyword Documentation is nothing but a DELETE on the text index table).


          Couldn't it be optional (with the risk bad performance)?


          Yes, but it was a design decision to enforce performance optimization here.

          • I am not sure whether I understood the "it" in "couldn't it be optional" correctly. It would be nice if you could clarify this.

            Does "it" mean this:

            Why is it not possible in the example from your blog above to write


            DATA(extract) =

              FILTER #( spfli_tab IN filter_tab

                          WHERE cityfrom = cityfrom  AND cityto = cityto ).


            omitting the WHERE statement for the key fields (which are known to the compiler anyway)?

          • Why not

            omitting the WHERE statement for the key fields

            • Because you can compare arbitrary columns from spfli_tab as LHS with key fields from filter_tab as RHS.

            • Because for sorted keys it is possible to cover only a part of the key.

          • ok, but I think the case "complete key fields" is the 90% case. So it would be nice to have this as the default, and an optional WHERE part for the two cases that you mention.

          • I was thinking of tables which have exactly the same type. That is a programming task that occurs quite frequently for me: Here is a list of objects (not in an OO sense) from source A (or time t1), here is another one from source B (or time t2). Now we need to know which objects are only in the A list, or which ones are in both lists, ...

          • Sorry, I was thinking of an OPTIONAL shorter variant for a common/default case of this expression. I forgot to write this.

            By the way: I am quite new to posting in SCN. Is there something like a private message, to avoid long public discussions?

          • Well, this might be another topic (which Horst has already responded to), but, for the matter of fact, I was talking about the primary/secondary key definition and not about omitting the WHERE criteria.

  • Hi Horst,

    to be honest i am really missing the subrc (for ALL the newly added expressions).

    Any chance to add them in one of the next sp?
    I believe this really is an gap - on the one hand we try to keep the code small and clean and on the other hand well need to to code around missing subrc and even have to handle exceptions. 


    Cheers, Thomas

    • Table expressions itab[ ...] cannot support sy-subrc.


      And it really means cannot.


      How will you handle something like

      result = itab1[ ...]-col + itab2[ ...]-col + any_other_expression ... .


      or deeply nested expressions using sy-subrc? From sy-subrc <> 0 you would only derive that the result is partly correct, and then?


      An expression works or it doesn't  An expression must be side-effect free and must not influence system fields. Functional methods should be  programmed side-effect free too (unfortunately, for historical reasons sy-subrc is set to 0 when calling them, but never to another value).

      • Well partly correct always implies an error happened - since the assumptions made during coding were not met -> exit

        It is just that that the coding will get bloated again after. Youll get the point, but since you said an expression must be side-effect free - ill guess ill have to stick / adapt to this behaviour.

        (but basically expressions are nothing more than a nicely wrapped set of reads, loops, deletes reads, etc etc which itself do set a subrc). Thxs for the quick reply.





  • Hi

    it is possible to do something like:


    DATA(itab2) = itab1[ WHERE col = "XXX"]


    i mean, a way to move a part of itab1 to itab2 and get a table as a result and not only an structure.


    thanks and regards.

  • Do any of your blog posts receive less than a 5-star rating?


    Seriously, your posts are not trending enough, because I recall having had that exact requirements (filtering a table by a converted value and using itab[ ... ] expression w/o the error being thrown) couple of weeks ago, thinking "Darn, I cannot use expressions here!" and coded the old way.


    Today I see this blog, going "Darn, couldn't he have posted that earlier?!".


    But then I see the post is from 2014, so this is me now:

    • Jürgen Lukasczyk wrote:


      Do any of your blog posts receive less than a 5-star rating?


      Yes, some jerks gave this one only 4 stars. I'd expect more trending somewhere in 2025 when most ABAPers finally get access to 7.4.

    • Seriously, your posts are not trending enough



      You need to get a Horst Keller tracker! Click his name to view his profile and click receive email notifications.


      You get an email every time Horst posts to SCN. That is an email for every post and comment, so it can be a lot emails, but it is totally worth it and makes it easy to stay on top of the latest news when you are not able to regularly login in to SCN.

  • Hello Horst,


    considering the following code everything compiles on 7.40 SP12.




    CLASS test_expression DEFINITION.

    CLASS test_expression IMPLEMENTATION.
      METHOD test.


      TYPES: BEGIN OF ty_data,
               i TYPE i,
               s TYPE string,
             END OF ty_data,
             tty_data TYPE HASHED TABLE OF ty_data
                      WITH UNIQUE KEY i.

      DATA(items) = VALUE tty_data( ( i = 1 s = 'Test' )
                                    ( i = 2 s = 'Hello World' )
                                    ( i = 3 s = 'xyz') ).

      DATA(filtered_data) = FILTER #( items EXCEPT WHERE i = 1 ).

      IF lines( filtered_data ) > 0.


      DATA(sum) = REDUCE i( INIT result = 0
                            FOR item IN filtered_data
                            NEXT result = result && item-i ).

      NEW test_expression( )->test( filtered_data ).


    If i inline the filter expression replacing the filtered_data variable like this, i get 2 syntax errors.

      " Syntax error here: Unexpected operator "FILTER"
      IF lines( FILTER #( items EXCEPT WHERE i = 1 ) ) > 0."


      " Syntax error here: "FILTER ANY( )" is not an internal table
      DATA(sum) = REDUCE i( INIT result = 0
                            FOR item IN FILTER #( items EXCEPT

                                                        WHERE i = 1 )
                            NEXT result = result && item-i ).

      " No syntax error here
      NEW test_expression( )->test( FILTER #( items EXCEPT

                                                    WHERE i = 1 ) ).


    It seems that the compiler can't recognize the result type of a filter expression as table. And so i can't use filter expressions where (any) table is expexted, right?


    So that would explain the first two errors. But i wonder why is then the method call possible? It seems in this case the compiler is able to recognize the result of the filter expression as a table.


    Interestingly enough, if i replace the # with tty_data it works for the reduce expression, but not for the lines operator


      " Still a syntax error here: Unexpected operator "FILTER"
      IF lines( FILTER tty_data( items EXCEPT WHERE i = 1 ) ) > 0."


      " No syntax error anymore !
      DATA(sum) = REDUCE i( INIT result = 0
                            FOR item IN FILTER tty_data(

                                        items EXCEPT WHERE i = 1 )
                            NEXT result = result && item-i ).


    I can't find anything about that in the documentation. Maybe i'm missing the obvious. Can you explain that?


    Regards Christian

    • No syntax errors in my 7.50 system (duh!).


      Apparently a bug that is meanwhile fixed.


      I'll try to find the kernel patch number.





    • These bugs were corrected with Kernel 7.44 but not patched to lower Kernel versions (<= 7.43).


      This means no patch for NW 7.40, SPxx. The highest Kernel for NW 7.40 is 7.42 for NW 7.40, from SP08 on.


      The earliest NW with Kernel 7.44 is NW 7.61 that is available for SAP's development of S/4 HANA only.


      The earliest publicly available NW having the bugfix will be NW 7.50 with Kernel 745.



  • I often have the task to process an internal table blockwise, i.e. Lines 1-20, lines 21-40, ...
    I tried to construct something smart with the filter statement, but came not up with a useful solution
    and ended up with:

        tabledescr     TYPE REF TO cl_abap_tabledescr,
        data_reference TYPE REF TO data.
        <structure>      TYPE any,
        <data_reference> TYPE STANDARD TABLE,
        <work_area>      TYPE any.
      tabledescr ?= cl_abap_typedescr=>describe_by_data( internal_table ).
      DO COND #( LET  mod  = lines( internal_table ) MOD size IN
                 WHEN mod > 0 THEN lines( internal_table ) DIV size + 1
                 ELSE lines( internal_table ) DIV size ) TIMES.
        CREATE DATA data_reference TYPE HANDLE tabledescr.
        ASSIGN data_reference->* TO <data_reference>.
        LOOP AT internal_table ASSIGNING <work_area> FROM ( ( sy-index - 1 ) * size + 1 ) TO ( sy-index * size ).
          APPEND INITIAL LINE TO <data_reference> ASSIGNING <structure>.
          <structure> = <work_area>.
        GET REFERENCE OF <data_reference> INTO data_reference.
        APPEND data_reference TO data_references.

    Any ideas for a better solution?



    • That's a case for GROUPing.

      Related example: