Skip to Content
Author's profile photo Horst Keller

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).

TYPES: BEGIN OF filter,
         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.

TYPES:

  BEGIN OF line,

    id    TYPE i,

    value TYPE string,

  END OF line,

  itab TYPE SORTED TABLE OF line WITH UNIQUE KEY id.

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

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

Assigned Tags

      43 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Eitan Rosenberg
      Eitan Rosenberg

      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 .

       

       

      Regards.

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      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.

      Author's profile photo Custodio de Oliveira
      Custodio de Oliveira

      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

      Author's profile photo Nikolay Evstigneev
      Nikolay Evstigneev

      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.

      Author's profile photo Former Member
      Former Member

      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.

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      Hi Jelena,

       

      better place your demand here http://scn.sap.com/docs/DOC-58352, that's where the more important guys are involved.

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      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.

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      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.

      Author's profile photo Former Member
      Former Member

      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.

       

      @Jelena

       

      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".

       

      cheers

      Janis

      Author's profile photo Former Member
      Former Member

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

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

      Author's profile photo Peter Inotai
      Peter Inotai

      As far as I know there was also a HANA compatible version of ERP Ehp6 with 7.40 BASIS. It was SAP_APPL 616.

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      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 http://scn.sap.com/docs/DOC-58352, that might to be a much better starting point for asking these questions.

      Author's profile photo Eitan Rosenberg
      Eitan Rosenberg

      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....

       

      Regards.

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      So, it doesn't work on standard tables.

      It does work on standard tables with secondary keys and the USING KEY addtition of FILTER.

      Author's profile photo Former Member
      Former Member

      You caught me there, my bad! I realised it a couple of minutes after posting the comment, hence i deleted it.

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      Ok, I added it also to the text.

      Author's profile photo Former Member
      Former Member

      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?

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      how is it shorter then VALUE (FOR)?

       

      What is shorter?

       

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

       

      or

       

      DATA(jtab) = itab.

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

       

      And retranslated to statements, what is faster?

      jtab = itab.
      DELETE jtab WHERE NOT ...

       

      or

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

        INSERT wa INTO TABLE jtab.

      ENDLOOP.

       

      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.

      Author's profile photo Former Member
      Former Member

      What is shorter?

       

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

       

      or

       

       

      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.

      ENDLOOP.

      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)?

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      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.

      Author's profile photo Edo von Glan
      Edo von Glan

      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)?

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      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.



      Author's profile photo Edo von Glan
      Edo von Glan

      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.

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      Even then, how to decide which key field  to compare with which?

       

      By data type, by name, by position ...?

      Author's profile photo Edo von Glan
      Edo von Glan

      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, ...

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      Yes, but the expression is not restricted to those ...

      Author's profile photo Edo von Glan
      Edo von Glan

      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?

      Author's profile photo Former Member
      Former Member

      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.

      Author's profile photo Former Member
      Former Member

      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

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      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).

      Author's profile photo Former Member
      Former Member

      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.

       

       

       

       

      Author's profile photo Former Member
      Former Member

      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.

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      For that purpose you can use the FILTER operator (SP08).

       

      Horst

      Author's profile photo Former Member
      Former Member

      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:

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      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.

      Author's profile photo Custodio de Oliveira
      Custodio de Oliveira

      The low rate is because of the bad choice of subject. Nobody cares about security

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      your posts are not trending enough

      Hello, it's ABAP ...

       

       

      Author's profile photo Brian O'Neill
      Brian O'Neill

      Seriously, your posts are not trending enough

      Jurgen,

       

      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.

      Author's profile photo Christian Guenter
      Christian Guenter

      Hello Horst,

       

      considering the following code everything compiles on 7.40 SP12.

       

       

       

      CLASS test_expression DEFINITION.
        PUBLIC SECTION.
          METHODS: test IMPORTING table TYPE ANY TABLE.
      ENDCLASS.

      CLASS test_expression IMPLEMENTATION.
        METHOD test.

        ENDMETHOD.
      ENDCLASS.

      START-OF-SELECTION.
        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.

        ENDIF.

        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."

        ENDIF.

        " 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."

        ENDIF.

        " 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

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      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.

       

      Best

       

      Horst

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      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.

       

      Horst

      Author's profile photo Stefan Riedel-Seifert
      Stefan Riedel-Seifert

      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:

        DATA:
          tabledescr     TYPE REF TO cl_abap_tabledescr,
          data_reference TYPE REF TO data.
      
        FIELD-SYMBOLS:
          <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>.
          ENDLOOP.
      
          GET REFERENCE OF <data_reference> INTO data_reference.
          APPEND data_reference TO data_references.
        ENDDO.

      Any ideas for a better solution?

       

       

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      That's a case for GROUPing.

      Related example:

      https://help.sap.com/http.svc/rc/abapdocu_752_index_htm/7.52/en-US/index.htm?file=abenfor_group_by_comparison_abexa.htm