ABAP News for Release 7.40 – Table Expressions
Table expressions with the syntax
… itab[ … ] …
are a new way for accessing table lines in operand positions. You can view a table expression simply as a short form of a READ TABLE statement. The result of a table expression is a single table line. All you have to know is the syntax that does the same as a given READ TABLE statement.
If a table line is not found, the exception CX_SY_ITAB_LINE_NOT_FOUND is raised. No sy-subrc from expressions, of course.
The operand positions where table expressions can be used are read positions but also some write positions where you can modify the resulting table line. Table expressions are LHS-expressions!
Specifiying the line
Index access using the primary index
The assignment of the table expression
wa = itab[ idx ].
does the same as
READ TABLE itab INDEX idx INTO wa.
Index access using a secondary index
The assignment of the table expression
wa = itab[ KEY key INDEX idx ].
does the same as
READ TABLE itab INDEX idx USING KEY key INTO wa.
Access using a free key
The assignment of the table expression
wa = itab[ col1 = … col2 = … ].
does the same as
READ TABLE itab WITH KEY col1 = … col2 = … INTO wa.
Key access using a table key
The assignment of the table expressions
wa = itab[ KEY key col1 = … col2 = … ].
wa = itab[ KEY key COMPONENTS col1 = … col2 = … ].
do the same as
READ TABLE itab WITH TABLE KEY key COMPONENTS col1 = … col2 = … INTO wa.
Influencing the result
With READ TABLE you can read into a work are, assign a field symbol or set a reference. The result of table expressions can be influenced accordingly.
- … itab[ … ] …
as a rule works like READ TABLE … ASSIGNING … . The temporary result of the expression is a field symbol.
- … VALUE type( itab[ … ] ) …
forces the expression to work like READ TABLE … INTO … . The temporary result of the expression is a data object.
- … REF type( itab[ … ] ) …
forces the expression to work like READ TABLE … REFERENCE INTO … . The temporary result of the expression is a reference variable.
While the third case is important, if you want to work with references to table lines, the results of the other two cases are normally transparent to the user. You don’t have to care how the intermediate result is represented internally. But there are some performance considerations. The same rules when to use what hold for table expressions as for READ TABLE. Therfeore, the syntax checker might kindly remind you from time to time to place the VALUE operator in front of a table expression (or to leave it away …).
Chainings
The following chainings with table expressions are possible:
- … itab[ …]-comp
- … struct-comp[ … ] …
- … itab[ … ][ … ] …
and combinations of those
Fun example
TYPES:
BEGIN OF struc1,
col1 TYPE i,
col2 TYPE i,
END OF struc1,
itab1 TYPE TABLE OF struc1 WITH EMPTY KEY,
itab2 TYPE TABLE OF itab1 WITH EMPTY KEY,
BEGIN OF struc2,
col1 TYPE i,
col2 TYPE itab2,
END OF struc2,
itab3 TYPE TABLE OF struc2 WITH EMPTY KEY.
DATA(itab) = VALUE itab3(
( col1 = 1 col2 = VALUE itab2(
( VALUE itab1(
( col1 = 2 col2 = 3 )
( col1 = 4 col2 = 5 ) ) )
( VALUE itab1(
( col1 = 6 col2 = 7 )
( col1 = 8 col2 = 9 ) ) ) ) )
( col1 = 10 col2 = VALUE itab2(
( VALUE itab1(
( col1 = 11 col2 = 12 )
( col1 = 13 col2 = 14 ) ) )
( VALUE itab1(
( col1 = 15 col2 = 16 )
( col1 = 17 col2 = 18 ) ) ) ) ) ).
* Reading the column with value 13 with READ TABLE statements
READ TABLE itab INTO DATA(wa1) INDEX 2.
READ TABLE wa1-col2 INTO DATA(wa2) INDEX 1.
READ TABLE wa2 INTO DATA(wa3) INDEX 2.
DATA(num1) = wa3-col1.
* Reading the column with value 13 with chained table expressions
DATA(num2) = itab[ 2 ]-col2[ 1 ][ 2 ]-col1.
Unbelievable, is this still ABAP?
Hello Horst,
thank you for your blog-series about the great changes in the ABAP-Language. ( Shortly: WOW! ). Cannot wait until get my fingers dirty on it...
Extremly: The new way of constructing tables which are pre-filled directly after definition. No more macros, appends or other methods...
What about SY-SUBRC handling: Is this still the same? Or do we have to check it like in other languages?
Kind regards,
Hendrik
Ooooopsi!
Forgot to mention it, I added a line to the blog as follows:
If a table line is not found, the exception CX_SY_ITAB_LINE_NOT_FOUND is raised. No sy-subrc from expressions, of course.
Thanx for notifying.
No problem 😉 There are a lot of changes, so this is just a small piece lost...
I will be looking forward to get a 740 instance and try out the new features!
Keep on remodel ABAP!
Hendrik
Is this true for reading by index and reading by key? If yes, this means a lot of try-endtry's in my 7.4 code. Why the choice for raising an exception when reading by key?
Sure, also for key access. What else can one do? Returning a Null value instead? Expressions that can be used in statements shouldn't influence the sy-subrc (bad enough that a functional method call sets sy-subrc for historical reasons).
There is one exception:
ASSIGN itab[ ... ] TO <fs>.
sets sy-subrc.
Maybe the new predicate function (I will come back to this later)
line_exists( itab[ ... ] )
that you can use behind IF is what you need (kind of short form for READ TABLE TRANSPORTING NO FIELDS with subsequent check of sy-subrc). Another new table function
line_index( itab[ ... ] )
returns 0 if the line is not found.
Otherwise, there's still the READ-statement you can use. Note, that table expressions are mainly made for usage at operand positions and not for standalone usage. Therefore, there's hardly another way then exceptions.
In case of
and itab has no line with field1 = <wa>-field1 (which means: <wa>-field2 has not been changed), no subrc is set and exception CX_SY_ITAB_LINE_NOT_FOUND occurs.
Am I right?
Or have I to a
if line_exists( itab[ field1 = <wa>-field1 ] ).
before?
And:
Does
<wa>-field2 = itab[ field1 = <wa>-field1 ]-field2.
choose an applicable secondary key of sorted table itab if it is defined? in READ table, I can say "WITH TABLE KEY name COMPONENTS comp1 comp2 comp3"....
Yes, an expression must not set sy-subrc because you simply cannot handle it at every expression position. From 7.40, SP08 on, you can also catch the exception by defining a default value: VALUE #( itab[ ... ] OPTIONAL|DEFAULT def ).
No, a table expression does not choose a secondary key itself. As for READ TABLE and for the same reasons you have to do so yourself:
itab[ KEY keyname COMPONENTS ...].
You find this also in the documentation ...
Hi Horst,
If I use ASSIGN itab[...] TO FIELD-SYMBOL(<FS>) then it is not giving runtime error but if I use MOVE-CORRESPONDING itab[...] TO WA then I am getting runtime error if line does not exist in itab.
Why we need runtime error here as we need to write some lines of code for exception handling!!! Idea is to make ABAP leaner but here it is making fattier.
Regards,
Sid
Hi,
A table expression - as any expression - cannot set sy-subrc, because it is used at operand positions of statements.
You do not get a runtime error for table expressions in ASSIGN, since a dynamic ASSIGN handles the exception itself by setting sy-subrc - as it always did. MOVE-CORRESPONDING did never set sy-subrc - and it doesn´t do it now.
But meanwhile there is a workaround: Simply use the possibility to set deault values for table expressions, introduced with 7.40, SP08 - ABAP News for 7.40, SP08 - More for Internal Tables.
Best
Horst
Thanks Horst. I understood now.
Hi Horst,
I know it is an old thread, but still useful!.
Is there any way to do something like this ?
data(lv_error) = line_exists( it_messages[ msgty = 'E' ] ).
where lv_error would be a boolean variable with vaules abap_true if line found or abap_false otherwise
Looks like i have to re-learn ABAP to get myself accustomed to 740
Is there any expression for READ TABLE ... TRANSPORTING?
BR,
Suhas
Not yet and good point.
It is not recommended to write a lot of
itab[ ... ]-col1, itab[ ... ]-col2, ...
with the same itab and same line specification inside a program, You would read the same line again and again.
-> There are small traps you have to take care of.
I know how you feel Suhas, i have to re-learn too... So many things to read...
were is "group by" for internal tables?
ABAP News for 7.40, SP08 - GROUP BY for Internal Tables
Is it possible to use the addition "BINARY SEARCH"?
Regards, Stefan
Documentation:
Can table expressions be used in operand positions where functional method call is present?
What I mean is: say "meth" is a functional method that has a RETURNING parameter as a table. Can I get the table row by doing the following:
table_row = meth( ..)[ 5 ].
Thanks for the great blog.
Hi,
1: yes, but there are more positions, see documentation for a list of positions.
2: no, itab must be given directly (see the same documentation)
Best
Horst
There is an expression, I don't understand:
... itab[ ... ] ...
as a rule works like READ TABLE ... ASSIGNING ... . The temporary result of the expression is a field symbol.
This means:
<itabline> = itab[ col1 = .... ].
works, if <itabline> is declared with data.
Can I use it with inline declaration?
field-symbol(<itabline>) = itab[ col1 = .... ].
does not work...
Hello Ralf,
In fact you want to write something like
FIELD-SYMBOL(<fs2>) = <fs1>.
which is not possible. The LHS of an assignment is a declaration position for DATA(...) but not for FIELD-SYMBOL(...).
Declaration positions for FIELD-SYMBOL(...) are only behind ASSIGN and ASSIGNING.
So you have to write
ASSIGN itab[ ... ] TO FIELD-SYMBOL(<line>).
In fact, even specifying expressions behind ASSIGN is something special, because the position after ASSIGN is a result position that is reserved for writable expressions.
Best
Horst
Ahhhhh! *licht aufgeh
Thanks!
Hello,
I see this blog-series as really cool. I like the new synax in 7.40 too.
Is there a new syntax which simplify the loop over a table. For example you have list of flights and you want to loop over only of subset of them (e.g. carrier Lufthansa) instead of all?
Best regards,
Mladen
Hi Mladen,
With SP08 there will be a GROUP BY addition for LOOP AT (and also for FOR expressions) that will allow you to use freely defined grouping criteria for internal tables. Inside a LOOP with GROUP BY you can then use a new LOOP AT GROUP statement (or FOR IN GROUP expression) to process the subsets. I guess, that's what you are looking for.
Best
Horst
Hi Horst,
i can't see the difference to ordinary where clauses.
Can you please elaborate on this a bit further?
Thanks.
Christian
Btw.: When will SP08 be released?
Well, GROUP BY is a kind of convenience tool that replaces the old AT NEW ... constructs. You could also program the same funtionality by hand (WHEREs and IFs) but much more lengthy. One main benefit of GROUP by will be that you can define the grouping criteria by expressions or method calls with the table lines as arguments.
SP08 will be released very soon (next week or so ...).
Horst
Thanks for clarification.
I'm really looking forward to the ABAP News for Release 7.40 SP08 blog series
Christian
Hi Horst,
Thanks for the update. I am impressed.
It is really nice to see changes that happen so offen. Is there a place where we can see which improvement comes in which SP?
Best regards,
Mladen
In the news section of the ABAP Kexword Documentation ...
Will be updated as soon as SP08 is available.
Nice Blog
Thanks for sharing the valuable Information.
Hi
How do we achieve a BINARY SEARCH using this syntax:
wa = itab[ col1 = ... col2 = ... ].
thank you
see ABAP Keyword Documentation
What's about
wa = itab[ key KEYNAME col1 = ... col2 = ... ].
This would work, I think, if KEYNAME is a secondary key of itab.
Yes, that is alternative 3 - the table key variant - of the above link to the ABAP Keyword Documentation.
The statement cited above is for alternative 2 - the free key variant.
Note that a table expression has the same 3 variants as the READ TABLE statement: index access, free key accesss and table key access. But the free key variant can be supported by a secondary table key only for the READ TABLE statement not for the respective table expressions.
Hi
Thanks for the post.
This is really useful.
Any idea how I can make accessing an internal table using a free key ignore case?
Example:
Internal table contents:
From To
Aaa bbb
AAA BBB
aaa Bbb
Read the internal table with key From = 'aaa'.
Should return all 3 rows.
Thanks
Hi Faaiez,
Maybe you can use the statement - FIND ...IN TABLE....[{RESPECTING|IGNORING} CASE]
The exact statement should be constructed like:
FIND ALL OCCURRENCES OF 'aaa' IN TABLE itab IN CHARACTER MODE IGNORING CASE RESULTS DATA(result_tab).
Sincerely,
Muthukumar
TYPES t_tab TYPE TABLE OF string WITH EMPTY KEY.
DATA(itab) = VALUE t_tab( ( `Aaa` ) ( `AAA` ) ( `aaa` ) ( `xxx` ) ).
DATA(jtab) = VALUE t_tab( FOR wa IN itab WHERE ( table_line CS 'aaa' ) ( wa ) ).
cl_demo_output=>display( jtab ).
So .. raise an exception (CX_SY_ITAB_LINE_NOT_FOUND) isn't less performative?
And in the end, just writing more...
(...)
TRY .
DATA(st_charg) = it_charg[ 1 ].
(...)
CATCH cx_sy_itab_line_not_found.
*........do nothing
ENDTRY.
(...)
DATA(def) = VALUE line( id = 0 value = `not found` ).
...
DATA(result) = VALUE #( itab[ id = ... ] DEFAULT def ).
http://scn.sap.com/community/abap/blog/2014/10/06/abap-news-for-740-sp08--more-for-internal-tables
Hello Horst ,
it's a pleaser for me to read this .
I wonder what about performance issues with this new method of reading data from internal tables .
when I write my code i usually keep all the option on the table which means that I can read and write at the same time , like that :
field-symbols: <fs_tb_line> type mara.
READ TABLE lt_mara[] ASSINGING <fs_tb_line> with key k1 = 'some value'.
<fs_tb_line>-col1 = some_value "write in
lv_some_var = <fs_tb_line>-col1 .
then the coming up question is whether the new method can support this form of table access ?
thank's for you quick answer
Very Sincerely ,
Harel Gilor.
Hi Harel,
Table expressions can be used at LHS positions. And the section "Influencing the result" in the blog says that ASSIGNING is the standard variant for the intermediate result.
Therefore
lt_mara[ k1 = 'some value' ]-col1 = some_value.
is the same as
field-symbols: <fs_tb_line> type mara.
READ TABLE lt_mara[] ASSINGING <fs_tb_line> with key k1 = 'some value'.
<fs_tb_line>-col1 = some_value.
Best
Horst
Hi Horst
Is there a way of changing more than one line of an internal table using table expressions. I tried the above example that you gave and it only changes one line
Kind regards
Hi,
There is no way of changing more than one line of an internal table using table expressions. A table expression itab[ ... ] is a shortcut for READ TABLE that addresses one line only.
Best
Horst
I don't like standard tables, in most cases I used sorted tables with keys. But if I call a function module, which expects a table in TABLES expression (in most cases this FMs are from SAP), I have to send a standard table.
Is there a way to transfer a sorted table as standard table? Something like "conv #( sorted_table )....?
In fact, it is:
But not applicable to TABLES parameters of function modules, since no expressions can be passed to them. You need a helper variable for those.
Hmpf - and this will not be changed in the future? I have this problem quite often....
How? TABLES parameters are CHANGING parameters. You can't pass expressions to CHANGING parameters.
What are the implications for performance and/or memory usage? Does lazy copying occur?
The conversion operator constructs an intermediate result that is passed to the method. It is a syntactical shortcut for creating a helper table, copying the original table, passing the helper table, deleting the helper table.
In cases, where a constructor operator works directly on an existing table, it is noted in the documentation, e.g. an itab as LHS of a VALUE-expression .
Perhaps someone can help me with that example coding:
data: materials type sorted table of mara with unique key matnr.
data: salv type ref to cl_salv_table.
select * into materials from mara up to 30 rows.
if salv is not bound.
cl_salv_table=>factory
importing r_salv_table = salv
changing t_table = materials. " <=== ERROR
endif.
Is there any way to find an ABAP statement, that converts the sorted table into a standard table? Something like
changing conv standard( materials ). ?
Maybe second example under CONV?
I added into my coding:
types: materials_type type standard table of mara.
and changed the following line to
syntax check says, that I the value of a generic table can not be constructed.
Next question: In user command method after sorting the table (with the standard SAP button), do I have a problem? Because the table materials is type sorted and can not be sorted.
You can't construct data objects at changing position of method calls. So you have to use an auxiliary variable like this. And you have to fully specify the table key for constructor expressions.
The parameter t_table of the factory method is typed as "table" which means in fact standard table. So you can't pass anything else than a standard table.
Works as suspected. Thanks for this information.
I found some restriction regarding the chaining of table expressions.
Maybe somebody can tell me what I'm doing wrong (or maybe it's not yet supported in ABAP - I'm on a System with SAP_BASIS 740 SP12). Maybe there is a special reason why this doesn't work, just would be interesting to know.
It seems that it is not possible to access attributes of a data-reference through a table expression chain.
TYPES:
BEGIN OF s_struct,
field TYPE string,
r_material TYPE REF TO mara,
END OF s_struct.
TYPES:
ts_table TYPE SORTED TABLE OF s_struct WITH UNIQUE KEY field.
DATA table TYPE ts_table.
DATA: matl_type TYPE mtart.
matl_type = table[ field = `FIRST` ]-r_material->mtart.
Also dereferencing a generic data reference doesn't work in a table expression chain:
TYPES:
BEGIN OF s_data_struct,
field TYPE string,
r_data TYPE REF TO data,
END OF s_data_struct.
TYPES:
ts_data_table TYPE SORTED TABLE OF s_data_struct WITH UNIQUE KEY field.
DATA data_table TYPE ts_data_table.
FIELD-SYMBOLS: <table> TYPE ANY TABLE.
ASSIGN data_table[ field = 'FIRST' ]-r_data->* TO <table>.
It seems that the operator is not recognized and therefore the component, the operator and the attribute/star are interpreted as the component name of the structure of the table.
Hi Amadeus,
Yes, that's a restriction in release 7.40 and it was not documented that it should work.
The restriction is suspended in Release 7.50, see point 4.
The respective 7.50 documentation is enhanced compared to the 7.40 version.
Horst
Hi Horst,
thank you for clarifying!
Although it wasn't stated that it would work, I hoped so - because it makes the code much shorter for such cases.
Good to know that in the next release it is possible.
BR, Amadeus
Hi Horst,
for some reason the second example from Amadeus doesn't work for me even though I am on SAP_BASIS 7.50 and it's documented on the F1-Help.
I get this error if I try to activate my method:
A generic reference cannot be dereferenced (->) in the current statement.
..when trying to...
FIELD-SYMBOLS: <l_any> TYPE any.
ASSIGN table[ key = value ]-r_data->* TO <l_any>.
Do you know what could cause this error to occur or do you know what I am doing wrong?
Kind regards,
Kai
Hi Horst,
Any plans to make similar improvements for assignment of structures components to field symbols?
Hypothetically so that something like this...
ASSIGN COMPONENT <fs_acct_assgn_dimension>-dimension
OF STRUCTURE <fs_aco_address>
TO <fs_dimension_value>.
... could be something like this...
ASSIGN <fs_aco_address>[<fs_acct_assgn_dimension>-dimension] TO <fs_dimension_value>.
Or even better allow off-by one correction of INCREMENT when using SY-INDEX/SY-TABIX without creating a temporary variable. So this...
DATA: lv_inc TYPE int2.
DO 2 TIMES.
lv_inc = sy-index - 1.
ASSIGN <fs_override_dimension>-msgv3 INCREMENT lv_inc TO <fs_acct_assgn_dimension>.
...
ENDDO.
....could be rephrased as something like this...
ASSIGN <fs_override_dimension>-msgv3[sy-index - 1] TO <fs_acct_assgn_dimension>.
Believe it or not, but I made the same proposal to development some time ago.
But for some reasons, it was turned down
Would like to know that are those new expressions efficient to use where we use read statement with Binary search?
Hi Anusha,
The documentation says the following:
"Unlike the statement READ TABLE with a free key specified, no binary searches can be forced for a table expression and it is not possible to specify explicit table key for optimizing searches using secondary keys."
BINARY SEARCH ist so 80s and needs to sort the table (which needs time). Developers should use sorted tables with secondary keys for different access strategies.
In conclusion, you asked the wrong question.
thanks !
Hi Former Member Hi Horst Keller ,
As Binary search is not possible with new syntax and you suggested to create sorted tables but we are not created Internal tables manually anymore right?
With the select query the table is generated automatically, is that table is sorted kind of...
If not what else we can do to improve reading internal table.
Thanks,
Anmol Bhat
See discussion above ...
Would be cool if there was an expression to identify multiple result lines to a read:
Hi Horst!
I would like to have something like
field-symbol(<result>) = itab[ ... ].
However, this does not work, though ABAP should know the type of a line of itab.
Instead, I have to manually define the field-symbol including its type.
Can you comment on that?
Thanks and best regards
David
Thanks for the answer!
The 'problem' with this statement is, that the newly created structure is on the right of the expression. I find it a lot cleaner if all created structures are on the left.
Well yes, but
means value semantics where the itab line is assigned to the data object <fs> is pointing to.
We'd need to invent a new assignment operator to replace the ASSIGN statement. And inventing a new short meaningful operator in ABAP isn't that simple. I already tried to convince my dev buddies to have something like += to replace ADD, but ...
Yes I see.
Keep convincing your dev buddies to implement += and have an assign operator
Hello from 2020. The += operator is implemented :^)
Hi Horst.
And why your dev buddies refuse to implement +=?
This is very conveniently for development.
Hi Horst,
When i use Table expressions instead of Read Table with Binary search, I am facing ATC issue
saying 'Low performance on internal table' .
And also wanted to know what kind of searching technique table expressions use to fetch record
as i guess linear search and how to implement searching techniques while using them to increase
performance.
Regards,
Naga
BINARY SEARCH is not supported for table expressions. As an educative measure, ABAP wants you to use sorted keys instead.
As we can rewrite
as
I thought we could replace
with
But unfortunatelly this is not (yet?) possible. On my wishlist.
For that, you use the REF operator, see alternative 3
(Mist), should have known this ...
Thank you.
but they are not equivalent, right? the assign statement is not dumping whereas the ref statement will dump
I would not actually mind, but the SAPs own style-guides on github are currently recommending to use fields symbolds only in case of dynamic access and in general prefer references. It seems that this is another exception to this rule
Hi Horst,
ASSIGN itab1[ KEY key col1 = ‘ABC’ ] TO <fs_wa1>.
Above statement is replacement of one single READ. If entry not found it is returning sy-subrc, No Dump. I am good here.
ASSIGN itab1[ KEY key col1 = ‘ABC’ col2 = itab2[ col1 = 123]-col2 ] TO <fs_wa1>.
Above statement is replacement of two READ statements. If itab2 don’t have entry with col1 = 123 I am getting DUMP, it is not returning sy-subrc. Do I need to use line_exists statement?. If entry found in itab2 but entry not found in itab1, I am not getting dump, it returns sy-subrc.
I am not interested to use line_exists statements as it sequentially search for the record two times if record found. Please correct me if I am wrong.
I am no more using READ statement in my program. Can completely forgot about READ statement?.
Recently I came across a situation I need to READ a data from internal table based on different cases(5 READ’s on diff columns). Do we need to declare one internal 5 diff secondary keys if we use table expressions?.
Thanks,
Vinod
As much as I love the new 7.4/7.5 notations, I still have to question this again:...
The READ TABLE statement seems quicker and safer to me that both the TRY/CATCH and the field-symbol assign methods
assign lt_table[ seq = 3 ] to field-symbol(<ls_fs>).
if sy-subrc = 0.
ls_rec = <ls_fs>.
endif.
vs.
read table lt_table into ls_rec with key seq = 3.
check sy-subrc = 0.
And we didn't have so many issues now with developers forgetting to put table access in TRY/CATCH when everyone was using READ TABLE. Is this another example of SAP making things more complicated inadvertently?
Why couldn't
lt_table[ seq = 3 ]
simply return blank if not found?
It can
https://help.sap.com/http.svc/rc/abapdocu_752_index_htm/7.52/en-US/index.htm?file=abentable_exp_optional_default.htm
That is exactly my point. The programmer should not have to do VALUE + DEFAULT ' ', or TRY+CATCH, or ASSIGN+FIELD_SYMBOL every time they want to access a table entry. It should be the default behaviour...
Instead of
data(ls_rec1) = value #( lt_table[ seq = 3 ] DEFAULT '' ).
I should be able to just do
data(ls_rec1) = lt_table[ seq = 3 ]
It is obvious that ls_rec1 will be null if seq = 3 does not exist. It's just natural, it's the way it works in other languages.
Am I wrong?
Compare with strings. Internal tables as well as strings are dynamic data objects.
What happens if you access a position in a string that's not there? Sic.
Yes, the way Abap handles strings is also out-dated. Accessing a non-existence position in a string should just return blank, or "undefined", or "null"... It should definitely not dump.
My point is, if we're now moving Abap towards more modern notations, we have to also modernize the behaviour.
Arrays in Javascript for example:
var cars = ["Saab", "Volvo", "BMW"]
Then cars[6] simply returns "undefined"
Same for strings:
var myCar = "BMW"
then myCar[6] is "undefined"
In Abap this causes a runtime error, and clients screaming at developers 😉
It's just not natural, we've modernized the notation but the behaviour remains out-dated. A lot of developers continue to have issues with this. I've seen it in multiple clients.
Just sharing my experience and opinion.
I appreciate your experience and opinion.
Well, yes then there's not much left to say. In fact, "we’ve modernized the notation but the behaviour remains out-dated". And I'm afraid, that's that. No booleans, no Null values (maybe Open SQL will do something about that), and so on.
Problem is, besides a few guys like you there are not too many stakeholders for a real face-lifted ABAP, especially not inside SAP and not in leading positions. I tried to address this for years but to no avail (hey, I'm only a documentation writer). Let's be happy that at least we have the expression enabled syntax, despite the flaws.
Agreed. Thanks for the insight.
You simply miss the important fact that table expressions are, well, expressions that can be used in operand positions and can prevent unnecessary helper variables.
Hi Horst,
Currently I am at GUI 7.5 and i tried using
wa = itab[ 1 ].
instead of READ
READ TABLE itab INDEX 1 INTO wa.
but is is giving me syntax error. Do you have any idea why?
You really want to say GUI 7.5 ???
Hi,
Unfortunately the following is not working
SET PARAMETER ID 'MAT' FIELD lt_table component = '0010' ]-matnr.
I have to use a variable in between, which is not a concise as i hopped.
Best Regards
Robert
The operand position behind SET PARAMETER ID is not documented as an expression position.
As a rule, in the documentation you find for each operand position which kind of operands are allowed and there are even overview pages:
https://help.sap.com/http.svc/rc/abapdocu_752_index_htm/7.52/en-US/index.htm?file=abenexpression_positions_read.htm
Hi Horst,
I read through all the comments and hopefully didn't miss an answer for this, but am I correct that this notation won't work for a field-symbol that points to an internal table. For example...
Cheers,
Amy
If the field symbol is typed as an internal table, it should work.
But in your example, the field symbol points to a line of table itab which most probably isn’t tabular but structured (as seen in the ASSIGN statement).
Hi Horst,
Thanks. In my scenario, the field-symbol points to a table of parameter object references held by a Web Dynpro event (type ref to CL_WD_CUSTOM_EVENT). I can't find a way of making the <itab>[ index ]-field syntax work in this scenario but was able to achieve what I need with slightly less concise code...
I'm trying to make the transition to the new 740 syntax and it's a lot to absorb. Your blogs have been very helpful.
Cheers.
Amy,
“I’m trying to make the transition to the new 740 syntax “, Like!
Therefore, I’m going back to your first example.
If everything is typed and coded properly, the syntax works, as the following example shows:
Remember, that also in the old world, field symbols (or formal parameters) must be typed properly in order to carry out table operations.
Best
Horst
Thanks Horst. 🙂
Hi! Great post!
What if I want to do something like this:
itab1[] = itab2[ col1 = 'A' ]
I'm aware that "The result of a table expression is a single table line. " but what are my options?
The good old 'loop where'?
Thanks!
It is not clear what you want to achieve.
The syntax shows the assignment of a stuctured table line to a table body. This is of course not possible.
Maybe it is an operator like REDUCE or VALUE, you are looking for?
Hi Horst Keller,
Thanks for an informative article!
I have a requirement where the READ statement is
READ itab WHERE KEY = 123 TRANSPORTING NO FIELDS.
Now, how can we rewrite this above read statement using new syntax?
Regards,
Srikar Poshetti
You should better post the question in the forum.
Hello Mr. Horst,
I have a condition/situation where in i would want to clear the contents of a few columns in the table, from a particular row to the last row of the table,however, with the new syntax, i am able to achieve it only from the said line. Also, the rows prior to the said line disappear.
For example, i would want to clear column3, 4 and 5 from the 6th row to the last row(lets say for example 48th row), in this case, the behavior of the new syntax is as below,
Table contains only 42 entries (the first 6 entries are discarded in the newly constructed table).
The traditional ABAP code is as below:
LOOP AT lt_poc ASSIGNING FIELDSYMBOL(<fs1>) FROM lv_tabindex TO lv_maxperiod -1. CLEAR : <fs1>-revenue_recognition,
<fs1>-poc_percent.
ENDLOOP.
ABAP.4 code is as below:
DATA(lt_temppoc) = VALUE tt_poc( FOR lspoc IN lt_poc FROM lv_tabindex TO lv_maxperiod - 1
INDEX INTO index
LET base = VALUE ty_poc( revenue_recognition = ' '
poc_percent = ' ' )
IN ( CORRESPONDING #( BASE ( base ) lspoc EXCEPT
revenue_recognition
poc_percent
) ) ).
Request you to please let me know what am i missing/addition(syntax) that needs to be added for retaining my entries prior to the change.
Hi,
not sure if it is a good idea to post this as a comment, but let's see if anybody reacts, otherwise I need to find another place 😀
Is it planned to have a syntax warning for missing catch of CX_SY_ITAB_LINE_NOT_FOUND after a table expression?
I think it is exactly the same as a missing Catch of exceptions when calling a method that has raising clauses.
It would help developers a lot, IMHO.
Gruß,
Sebastian
Hello
What is the table expression variant of below code ?
Regards
I have a small question. I know if the table is of type SORTED or HASHED, the expression itab[ field = 'X' ] will carry out the search optimally based on the table type. How does this expression perform when being used on a Standard table with no defined key ? Is the read carried out sequentially ?