Skip to Content
Author's profile photo Horst Keller

ABAP News for Release 7.40 – Expression Warm Up

Where do we come frome?

We come from Release 7.0. ABAP was statement oriented then.

Say, we have the task to output a string concatenated from a column value of an internal table with some literal contents using a given method. In 7.0 that would look as follows:

DATA itab TYPE TABLE OF scarr.
SELECT * FROM scarr INTO TABLE itab.

DATA wa LIKE LINE OF itab.
READ TABLE itab WITH KEY carrid = ‘LH’ INTO wa.

DATA output TYPE string.
CONCATENATE ‘Carrier:’ wacarrname INTO output SEPARATED BY space.

cl_demo_output=>display( output ).


Where do we stay?

Hopefully most of you stay already on Release 7.02 or 7.03/7.31. With Release 7.02 ABAP took the first large step into the direction of expression enabling. Lots of new built-in functions, string expressions with concatenation operator && combined with string templates, and the capability of writing expressions at many operand positions opened a new realm of ABAP programming. In Release 7.02 the above task can already be writtten as follows:

DATA itab TYPE TABLE OF scarr.
SELECT * FROM scarr INTO TABLE itab.

DATA wa LIKE LINE OF itab.
READ TABLE itab WITH KEY carrid = ‘LH’ INTO wa.

cl_demo_output=>display( |Carrier: { wacarrname }| ).

One helper variable and a statement less thanks to curly brackets in ABAP 😉 .

Where do we go?

With Release 7.40 we go into the direction of real expression orientation: More expressions and more expression positions.

Example, inline declarations in declaration positions. Let’s rewrite the above code in 7.40:

DATA itab TYPE TABLE OF scarr.
SELECT * FROM scarr INTO TABLE itab.

READ TABLE itab WITH KEY carrid = ‘LH’ INTO DATA(wa).

cl_demo_output=>display( |Carrier: { wacarrname }| ).

The compiler knows the data type needed for wa. Therefore, we can declare the structure inline at an operand position. You can imagine that there are lots of such positions.

Again one line less. But wa-carrname is still a helper variable. Let’s go one step further using a table expression:

DATA itab TYPE TABLE OF scarr.
SELECT * FROM scarr INTO TABLE itab.

cl_demo_output=>display( |Carrier: { itab[ carrid = ‘LH’ ]carrname }| ).

Gee! Square brackets within curly brackets and no READ-statement any more 😎 .

More details later ….

 

Assigned Tags

      29 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Custodio de Oliveira
      Custodio de Oliveira

      Hi Horst,

      I'm loving your latest blogs. Can't wait to have my hands dirty on 7.40 (currently in 7.31/7.03, which is not bad).

      I never understood why we could do :

      itab2[] = itab[].

      But not:

      wa = itab[1] .

      Now it's sorted 😉

      Anyway, I'm pretty sure as soon as I started using things like

      cl_demo_output=>display( |Carrier: { itab[ carrid = 'LH' ]-carrname }| ).

      the clarity police will find me guilty and tell me to go back to the 90's for good readability's sake. Luck I don't hear them.

      Cheers,

      Custodio

      Author's profile photo Former Member
      Former Member

      the clarity police will find me guilty and tell me to go back to the 90's for good readability's sake.

      They can R.I.P man .. 😉

      Author's profile photo Paul Hardy
      Paul Hardy

      That looks very good, I do have one observation to make.

      In the above example the data object ITAB refers to an internal table, and when CL_DEMO_OUTPUT is called you have a data object starting with ITAB[ which refers to a line of that internal table. Two data objects with the same name referring to different things? You know what that reminds me of? I'll sing it to you.

      Guess who just got back today, those wild eyed header lines that went away,

      Haven't changed, haven't much to say,

      But man, I still think them cats are crazy

      The Header Lines Are Back In Town

      The Header Lines Are Back in Town

      da da da da, da, da da da da da, etc

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

      So I'll sing back to you:

      Whatever you do,

      Do it good

      Whatever you do do do lord lord lord do it good (yeah)

      Express yourself

      Express yourself (oh do it)

      itab[ ... ] is not a data object but an expression that has a result! Compare it to something like strlen( ... ) or meth( ...). Would you say that strlen or meth are data objects?.

      Author's profile photo Paul Hardy
      Paul Hardy

      Just to re-iterate I do think this is an improvement. However because this expression does not have a name like STRLEN, it is just indicated by a pair of brackets, the name ITAB gains prominence, and so despite being an expression, Frankie Valli and the Four Seasons would probably describe it thus:-

      "It looks like a header line,

      It talks like a header line,

      It walks like a header line my soooooooooooon....."

      I'll sing no more on the subject, any further arguments would put me on the "Road to Nowhere" as the famous American pop group "Talking Header Lines" would say.

      In regard to the Clarity Police (another pop group) the less lines you have the better, as then you can see more of the code at once so as long as the variables have meaningful names that benefit may outweighth the implicit nature of the expressions.

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

      Well, well, following your line of argument, all programming languages that allow annotations like array(n) or matrix(n,m)  support headerlines 😯 .

      We're on a road to nowhere

      Come on inside

      Takin' that ride to nowhere

      We'll take that ride ...

      Author's profile photo Former Member
      Former Member

      Hello Horst,

      I'm on 731 & i love the crazy string operations you can do with the { } brackets 😘

      But 740 seems to open a whole new plethora of tricks, can't wait to get my hands on it! 😉

      BR,

      Suhas

      PS - Is it mere coincidence that ABAP 740 & Xbox One reveals are so close to each other? 😛

      Author's profile photo B. Meijs
      B. Meijs

      I'm loving the 740 blogs. Thanks for that. (no singing from my part, though 😛 )

      Is it possible in 740 to use conversion exits in embedded expressions of string templates?

      It's not in one of the formatting options in 702 and also not automatically executed. Or have I missed something?

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

      I love these questions hitting the mark.

      No, you didn't miss it, conversion routines are simply not supported in string tenplates. If there is a large demand for an important general routine, it might be covered by a special format option. E.g. with Release 7.40 is a new option ALPHA was introduced, that does the same as CONVERSION_EXIT_ALPHA_INPUT or CONVERSION_EXIT_ALPHA_OUTPUT.

      Yes, yes, I know. In building all this new stuff we tend to forget established old features that are widely used in customer programs. Last week I was asked something similar: "It's easy to say don't use classical selection screens any more but what about all the variants that are stored in customer systems?" - Pooh!

      Author's profile photo Paul Hardy
      Paul Hardy

      Just as a matter of interest, if I am writing a report to run in the SAP GUI, and I am not supposed to use a SELECTION-SCREEN, what am I supposed to be doing to get the user input?

      What do SAP do now when they create a new report that runs in the GUI? SAP has been touting OO development, and saying they do it internally themselves for new developments, ever since 4.6, that came out around the year 2000 I think.

      So if SAP themselves don't use SELECTION-SCREENS for new developments there must  be a standard report somewhere in my ECC 6.0 EHP5 system you can point me at which uses a superior technique?

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

      "Don't know" says Button Bright.

      As a matter of fact I'm in that situation too. I'm writing the ABAP Keyword Documentation and for my examples I need a simple and robust way to allow some user input and to output some results. On the one side I don't want to use the somewhat old fashioned selection screens and classical lists any more, on the other side the new technologies like WDA or UI5 (where you have to code JS on top of ABAP) are too sophisticated for my simple purposes.

      My handmade solution for my own problem was to boldly create a dedicated input/output framework for myself: CL_DEMO_INPUT and CL_DEMO_OUTPUT that are used in the ABAP examples in 7.40 and even enable executable examples in Eclipse. The output is based on an XML-output stream that is based on a kind of a stripped down ODATA format. It is good enough to replace WRITE in my examples and even more comfortable, since it allows to output structures or internal tables in one go.

      I created these as prototypes to show what can be achieved if one really wants to go for something like this,  but of course, they are not intented for public usage (other than my class CL_ABAP_BROWSER, which I created for similar reasons but which is robust enough that it can be used by everybody). A full replacement of selection screens and lists with a modern framework for public usage is far beyond my scope (I'm only documentation writer and shouldn't mess around with such things at all ...).

      But why not dreaming of selection screens and list outputs in modern UIs that can be handled easily from ABAP ("ABAP Managed UI")? Maybe these questions (that are valid from my unimportant point of view) must be asked at the right places ...

      Author's profile photo Former Member
      Former Member

      Horst Keller wrote:

      No, you didn't miss it, conversion routines are simply not supported in string tenplates. If there is a large demand for an important general routine, it might be covered by a special format option.

      Good to know, then I can stop searching and pulling my hairs over this.

      Are there plans for getting this done? It's already 7.40SP08 here. 😐

      Do I have your blessing to use WRITE TO until this is available? 😏

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

      Are there plans for getting this done?

      Nothing I know of.

      use WRITE TO

      Guess, why WRITE TO isn't declared as obsolete 😉

      Author's profile photo Former Member
      Former Member

      Good article....looking forward to hear more on this...

      Thanks,

      Anmol.

      Author's profile photo Former Member
      Former Member

      Great Horst.......!!!!!!!!!!!!

      Why can't we expect some thing like,,

      SELECT * FROM scarr INTO TABLE Data ( itab ).

      and let the compiler decide the type of ITAB...!!!!!!

      (Just for Default Standard Table Type)

      Its Yummy .........!!!!!!!!!!!!

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

      Why can't we expect some thing like,,

      SELECT * FROM scarr INTO TABLE Data ( itab ).

      You can expect it, but it takes some time (it will be an inline declaration with an anonymous type derived from the SELECT list).

      Author's profile photo Former Member
      Former Member

      And how do we define the type of internal table, i mean STANDARD, SORTED or HASHED? 😕

      - Suhas

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

      Only standard tables ....

      Author's profile photo Bruce Hartley
      Bruce Hartley

      Horst;

      Based on your previous comment - I am concerned about your above comment ( "Only standard tables ..." ) from a performance point of view.

      I do our code reviews here, and almost once a week I have to make sure that someone didn't use a standard table and do a READ TABLE ..... WITH KEY .... and not declare an index on it ( or a LOOP AT with a WHERE clause and not have a SORTED index ).

      I love the fact in that in 7.02 secondary indexes were added - that was a GODSEND because that allowed us to add indexes for performance where none were previously allowed.  As many programmers are aware, some function modules only take older style standard tables, and if you wanted to do a READ TABLE WITH KEY on it or a LOOP AT with a WHERE clause, you were stuck in linear search mode and since a secondary index doesn't change the table type, the older function module can work with it and populate it and our new code that gets the data back from the function module can slice it and dice it far faster than before.

      We have been requiring secondary indexes to be added to new code where applicable and it has been a huge performance boost to us.  People don't often understand this until they have to do a nested LOOP AT with two tables with a 1000 entries and if you don't have indexes you are talking 1,000,000 iterations to process it all.  We even older programs to be rewritten to take advantage of the appropriate internal table index if they are being ported to our ECC 6 EHP5 system for this reason as a lot of them come from ECC 5 ( we also require them to change to the new ALV grid as well unless it can be shown it isn't worth the rewrite - my boss and I make that decision on a case-by-case basis ).

      My conclusion is this - the new expressions are great - but you have to be careful to not introduce performance issues along with it.  I can easily see programmers doing the above and then just to find that one entry in a 1000 row table requires a linear search when a hash index would have been far more appropriate ( or worst case - a sorted index ).

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

      Bruce,

      First of all, you make us very happy with your fervent plea for using secondary indexes with internal tables. Yes, that's what they are made for and we wished that many developers would use them in a way you are telling your devlopers to do.

      But now for the  inline declarations. In all operand positions, where inline declarations are possible up to now, the full type information is available statically. E.g., if you assign a returning parameter of type table with secondary keys to an inline declaration, of course the resulting table has the same type including the secondary keys. In the INTO clause of the statement, we don't have this information. The only information we have are the components of the SELECT clause that make up the structure of the line type.  So the only thing we can do with the simple inline declaration DATA(...) is to declare a standard table type without secondary keys. What can we do else? Should we blow up the inline declaration inside an INTO clause with additionaly parameters like declaring table type and secondary keys? I don't think so. Such an inline declaration would become more like a fully fledged inline TYPES statement (and that inside SELECT?).

      So you are right, expressions can be very helpful, but they also must be used with care. They should neither obfuscate  programs nor have negative impacts on performance (another trap are expressions within loops that are evaluated over and over again). In such cases the guideline is to use variables that are explicitly declared. And this is also true for your case,  If SELECT should read into other internal tables than mere standard tables without sceondary keys, you must declare these tables always explicitly before the SELECT statement. This will stay true, even if the inline declaration will be available in some future release.

      If you don't want to construct the line type yourself, you might then use a workaround as follows  (involving an additional assignment):

      SELECT carrid connid cityfrom cityto
             INTO TABLE DATA(result)
             FROM spfli
             WHERE ...

      TYPES result_line LIKE LINE OF result.
      DATA  itab TYPE SORTED TABLE OF result_line
            WITH NON-UNIQUE KEY cityfrom cityto
            WITH UNIQUE HASHED KEY mkey COMPONENTS carrid connid.

      itab = result.

      Author's profile photo Former Member
      Former Member

      Hi Horst,

      we recently upgraded to EHP6 with ABAP Stack 7.31

      When I try to run any of our sample coding in our system,

      I get a syntax error stating that method display has no parameters.

      Can U help me?

      Regards Frank

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

      Hi Frank,

      CL_DEMO_OUTPUT was under continous development last year. In some SP for Release 7.31 it should already work, but a final version will be avaiable in 7.40 only (or as an addon to an upcoming ABAP Language book,  For the time being, please regard the above code simply as an example for any method that can output data ....

      See also  http://scn.sap.com/community/abap/blog/2013/07/04/abap-news-for-release-740--abap-and-hana#comment-371657.

      Author's profile photo Saumitra Tiwari
      Saumitra Tiwari

      Thanks for the wonderful blog.. it is a great guide to the new 7.40..

      Author's profile photo Former Member
      Former Member

      Horst,

      I am really astonished by the new expression features as they help to clean code and reshuffle the cards between declarative and executable coding - the coding gets a more "dynamic" touch.

      There' s one thing that gets lost on the way - and that the possibility to stepwise debug programming flow and inspect the result of statements on runtime values.

      The complex statements with tons of expressions start to get more and more black boxes - either they work or they dump (ooops - I forgot the try - catch block).

      Regards,

      Thomas

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

      The new ABAP Debugger offers stepwise debugging for expressions.

      But in fact your'e rigth. It makes sence not to put everything into one statement with expressions but to stray in one or the other helper variable for testing.

      Author's profile photo Dominik Krämer
      Dominik Krämer

      Hi Horst,

      is there any document available on how to stepwise debug the expressions? As I am not able to get this to work in the new ABAP Debugger.

      Regards,

      Dominik

      Author's profile photo Former Member
      Former Member

      Hello Dominik,

      probably you already know this by now but I leave my opinion nevertheless.

      This could be one good reason for you to jump to ADT aka ABAP on Eclipse.

      In Eclipse, if you forget a try..catch block you will have a warning reminding you of that, even before the compile step.

      You could also run ABAP Test cockpit (ATC) for your development and you will be informed that you are missing a try..catch block.

      For the setpwise in debugger, you should see the tab Auto in the debugger.

      KR

      Sérgio

       

       

      Author's profile photo ANISH KOSHY OOMMEN
      ANISH KOSHY OOMMEN

      Hi Horst,

      Great Document. And looking forward to get my hands on the same. This should definitely clean up the coding.

      Regards,

      Anish Oommen

      Author's profile photo Pappu Kumar
      Pappu Kumar

      Dear Horst Keller,

       

      Really nice and valuable blog.

       

      Thanks.

      Pappu.