The introduction of SAP ABAP 7.40 marked a significant shift towards a modernized syntax, enabling developers to write more readable, concise, and efficient code. With these changes, SAP aimed to simplify the development process by reducing boilerplate code and making ABAP more approachable for those familiar with other modern programming languages. This post covers the major syntax improvements introduced after release 7.40.
1. Inline Declarations (DATA
and FIELD-SYMBOLS
)
ABAP 7.40 introduced inline declarations, allowing you to declare variables directly within statements. This feature eliminates the need to declare variables at the beginning of the program, enhances readability, and reduces code clutter.
Example:
DATA(result) = 5 + 10.
WRITE result.
Using inline declarations, you can avoid declaring DATA: result TYPE I
separately, simplifying your code structure.
Inline FIELD-SYMBOLS
Declarations
Similarly, you can declare FIELD-SYMBOLS
inline within an ASSIGN
statement.
Example:
ASSIGN COMPONENT 1 OF STRUCTURE ls_struct TO FIELD-SYMBOL(<field>).
2. New FOR
Expressions in Internal Table Operations
ABAP 7.40 introduced the FOR
loop as part of the new syntax for concisely constructing and filling internal tables.
Example:
DATA(lt_numbers) = VALUE #( FOR i = 1 UNTIL i > 10 ( i * i ) ).
This expression initializes lt_numbers
with the square of numbers from 1 to 10. FOR
expressions reduce the need for traditional LOOP AT
constructs, improving code readability.
3. VALUE
and CORRESPONDING
Expressions
VALUE
Expression: This allows the initialization of variables and structures directly with values in a compact way.Example:
DATA(ls_person) = VALUE #( name = 'John' age = 30 ).
CORRESPONDING
Expression: This allows easy mapping between structures, copying fields with the same names.Example:
DATA(ls_employee) = CORRESPONDING #( ls_person ).
4. FILTER
and REDUCE
Expressions
FILTER
Expression: The FILTER
expression lets you filter data in an internal table based on conditions, creating a new table with only matching entries.Example:
DATA(filtered_tab) = FILTER #( lt_table WHERE age > 25 ).
REDUCE
Expression: The REDUCE
operator is used to process internal tables and perform aggregations.Example:
DATA(sum) = REDUCE i( INIT s = 0 FOR wa IN lt_table NEXT s = s + wa-age ).
5. String Templates
ABAP 7.40 introduced string templates, a modern way to build and format strings without concatenation operators.
Example:
DATA(name) = 'John'.
DATA(age) = 30.
DATA(text) = |Name: { name }, Age: { age }|.
WRITE text.
String templates support placeholder syntax, making them intuitive and concise for formatting.
6. CONV
and CAST
Operators
CONV
Operator: The CONV
operator helps convert data between different types, allowing on-the-fly conversions.Example:
DATA(num) = CONV decfloat34( '123.45' ).
CAST
Operator: CAST
is used to cast between classes and interfaces in ABAP, helping in scenarios where down-casting is required.Example:
DATA(ref_person) = CAST cl_person( ref_object ).
7. Enhanced LOOP AT
with Inline Declaration
The new syntax allows you to declare work area variables inline within a LOOP AT
statement, removing the need to define a separate work area beforehand.
Example:
LOOP AT lt_table INTO DATA(wa).
WRITE wa-field.
ENDLOOP.
This streamlined approach reduces variable declarations and improves readability.
8. New COND
Operator
The COND
operator allows you to use conditional expressions for assignment, similar to a CASE
statement.
Example:
DATA(result) = COND #( WHEN value > 0 THEN 'Positive'
WHEN value < 0 THEN 'Negative'
ELSE 'Zero' ).
The COND
operator helps avoid IF
statements in many cases, making code cleaner.
9. SWITCH
Operator
The SWITCH
operator allows you to perform a switch-case operation within an expression, providing a compact way to handle multiple conditions.
Example:
DATA(status) = SWITCH #( val WHEN 'A' THEN 'Active'
WHEN 'I' THEN 'Inactive'
ELSE 'Unknown' ).
10. Chained Expressions
ABAP 7.40 allows chaining of functions and operations, enabling developers to write more compact and expressive code.
Example:
DATA(output) = cl_abap_conv_in_ce=>create( iv_encoding = 'UTF-8' )->convert( iv_input = input ).
Chained expressions reduce the need for intermediate variables, making the code flow more natural.
11. New TABLE_LINE
Keyword
When working with single-column internal tables, the TABLE_LINE
a keyword can be used to simplify table access by directly addressing the column value instead of specifying a structure.
Example:
LOOP AT lt_table INTO DATA(value).
WRITE value.
ENDLOOP.
12. Constructor Expressions with NEW
and VALUE
While the VALUE
operator allows inline data declarations, NEW
can be used to create instances of objects directly without the need for CREATE OBJECT
.
Example:
DATA(person) = NEW cl_person( name = 'John Doe' age = 30 ).
13. Enhanced SELECT
Syntax with Inline Declarations
SAP ABAP 7.40 also allows inline declarations within SELECT
statements, making database queries more concise.
Example:
SELECT * FROM scarr INTO TABLE @DATA(lt_carriers) WHERE carrid = 'AA'.
14. DEFAULT
Keyword for Function Parameters
ABAP now allows you to define default values for function module parameters, making calls to those functions more flexible.
Example:
CALL FUNCTION 'YOUR_FUNCTION'
EXPORTING
param1 = value1
param2 = DEFAULT.
15. LET
Expressions
The LET
expression allows for temporary variable declarations within expressions, further optimizing complex operations without creating multiple variables.
Example:
DATA(result) = LET a = 10 b = 20 IN a + b.
16. SQL Expressions in SELECT
Queries
With SAP ABAP 7.40, you can perform SQL operations directly within SELECT
statements, like CASE
, SUM
, AVG
, and UPPER
.
Example:
SELECT carrid, UPPER( carrname ) AS carrier_name FROM scarr INTO TABLE @DATA(lt_carriers).
17. Boolean Expressions in WHERE
Clauses
ABAP 7.40 allows logical expressions directly within WHERE
clauses in SELECT
statements, enabling more dynamic filtering.
Example:
SELECT * FROM scarr INTO TABLE @DATA(lt_carriers) WHERE carrid = 'AA' OR carrid = 'LH'.
18. CASE
Expression for Data Assignment
Using CASE
within expressions helps make conditional assignments compact and readable.
Example:
DATA(type) = CASE code
WHEN '1' THEN 'Type A'
WHEN '2' THEN 'Type B'
ELSE 'Unknown'.
ENDCASE.
19. Table Expressions for Accessing Entries by Key or Index
Table expressions allow direct access to internal table entries using keys or indexes, eliminating the need for explicit READ TABLE
statements.
Accessing an entry by a key
DATA(wa) = itab[ fld1 = var1 ].
Accessing an entry by index
DATA(wa) = itab[ 1 ].
Accessing a specific field directly from an entry
lv_var2 = itab[ fld1 = var1 ]-var2.
20. Line Existence and Index Checking
ABAP 7.40 introduced line_exists
and line_index
functions to simplify the process of checking for particular entries or retrieving indexes.
Check if a line exists in an internal table
IF line_exists( itab[ fld1 = var1 ] ).
Retrieve the index of a particular entry
lv_tabix = line_index( itab[ fld1 = var1 ] ).
21. Direct Table Modification Using Key Access
Directly modify an entry in a table using key access instead of the traditional READ TABLE
approach.
Modify a specific field within a table entry
itab[ fld1 = var1 ]-fld2 = 'Text'.
22. ALPHA Conversion within String Templates
New syntax for adding or removing leading zeros using ALPHA
formatting directly within string templates.
Remove leading zeros
var1 = |{ var1 ALPHA = OUT }|.
Add leading zeros
var1 = |{ var1 ALPHA = IN }|.
23. Inline Data Creation with VALUE for Tables
Initialize tables with VALUE
expressions, and add entries directly in a single step.
Creating and populating a table inline
DATA(itab) = VALUE structure(( fld1 = 1 fld2 = 'A' )
( fld1 = 2 fld2 = 'B' )).
Appending new entries to an existing internal table
itab = VALUE #( BASE itab
( fld1 = 1 fld2 = 'A' )
( fld1 = 2 fld2 = 'B' ) ).
24. Combining Tables with CORRESPONDING
Use CORRESPONDING
to combine tables and move only fields with matching names.
Combine two tables with BASE
addition
itab3 = CORRESPONDING #( BASE ( itab3 ) itab2 ).
Map fields with different names using MAPPING
itab2 = CORRESPONDING #( itab1 MAPPING t1_fld1 = t2_fld1 t1_fld2 = t2_fld2 ).
Exclude fields from mapping with EXCEPT
itab2 = CORRESPONDING #( itab1 EXCEPT t1_fld3, t1_fld4 ).
25. Inline Splitting of String Fields
ABAP allows splitting string fields within a FOR
expression, making it easier to manipulate and structure data.
Split field values inline while populating a table
DATA(lt_awkey) = VALUE gty_rseg( FOR <lfs_bkpf> IN lt_bkpf
( belnr = <lfs_bkpf>-awkey+0(10)
gjahr = <lfs_bkpf>-awkey+10(4) ) ).
26. String Template for Messages
Construct messages more efficiently by embedding variable values within string templates.
Display a message with embedded variables
MESSAGE |The User ID is { lv_name }| TYPE 'E' DISPLAY LIKE 'E'.
27. Object-Oriented Enhancements with Inline NEW
Simplify object creation and instantiation with the inline NEW
syntax.
Create an object with inline NEW
DATA(oref) = NEW class( ... ).
28. Table Expressions: Reading and Checking Entries
With ABAP 7.40, table expressions (itab[...]
) replace the READ TABLE
statements for easier access. They also raise an exception (CX_SY_ITAB_LINE_NOT_FOUND
) if the specified line does not exist, instead of using sy-subrc
.
Read Table by Index:
wa = itab[ idx ].
Read Table Using Key and Index
wa = itab[ KEY key INDEX idx ].
Read Table with Key Fields
wa = itab[ col1 = ... col2 = ... ].
Read Table with Key Components
wa = itab[ KEY key col1 = ... col2 = ... ].
Check if a Record Exists (replaces sy-subrc
check)
IF line_exists( itab[ ... ] ).
...
ENDIF.
Get Table Index (replaces sy-tabix
check)
DATA(idx) = line_index( itab[ ... ] ).
Note: If a record is missing, table expressions will dump, so SAP recommends using a field symbol and checking
sy-subrc
.
Example for Safe Assignment:
ASSIGN lt_tab[ 1 ] TO FIELD-SYMBOL(<ls_tab>).
IF sy-subrc = 0.
...
ENDIF.
29. Conversion Operator CONV
The CONV
operator in ABAP 7.40 allows you to convert data types inline, either specifying the type explicitly or allowing the compiler to infer it.
Syntax
CONV dtype|#( ... )
dtype
: The target data type for conversion (explicit).
#
: Let the compiler determine the target type (implicit).
Example:
DATA text TYPE c LENGTH 255.
DATA(xstr) = cl_abap_codepage=>convert_to( source = CONV string( text ) ).
30. Value Operator VALUE
The VALUE
operator is one of the most versatile tools introduced in ABAP 7.40, useful for initializing variables, structures, and internal tables.
Syntax for Variables
DATA var = VALUE type( ... ).
Syntax for Structures
DATA struct = VALUE type( comp1 = val1 comp2 = val2 ... ).
Syntax for Tables
DATA itab = VALUE type( ( ... ) ( ... ) ... ).
Examples
Example for Structures
TYPES: BEGIN OF ty_columns1, “Simple structure
cols1 TYPE i,
cols2 TYPE i,
END OF ty_columns1.
TYPES: BEGIN OF ty_columns2, “Nested structure
coln1 TYPE i,
coln2 TYPE ty_columns1,
END OF ty_columns2.
DATA: struc_simple TYPE ty_columns1,
struc_nest TYPE ty_columns2.
struc_nest = VALUE ty_columns2( coln1 = 1
coln2 = VALUE #( cols1 = 1
cols2 = 2 ) ).
Example for Internal Tables (Elementary Line Type)
TYPES t_itab TYPE TABLE OF i WITH EMPTY KEY.
DATA itab TYPE t_itab.
itab = VALUE #( ( ) ( 1 ) ( 2 ) ).
Example for Internal Tables (Structured Line Type, e.g., RANGES Table)
DATA itab TYPE RANGE OF i.
itab = VALUE #( sign = 'I' option = 'BT' ( low = 1 high = 10 )
( low = 21 high = 30 )
( low = 41 high = 50 )
option = 'GE' ( low = 61 ) ).
31. FOR Operator
The FOR
operator simplifies internal table processing by providing an inline loop expression, eliminating the need for explicit LOOP AT
statements.
Syntax:
FOR wa|<fs> IN itab [INDEX INTO idx] [cond]
Example 1: Populate an internal table GT_CITYS
with city names from GT_SHIPS
.
DATA(gt_citys) = VALUE ty_citys( FOR ls_ship IN gt_ships ( ls_ship-city ) ).
Example 2: Populate GT_CITYS
with cities where the route is 'R0001'
.
DATA(gt_citys) = VALUE ty_citys( FOR ls_ship IN gt_ships WHERE ( route = 'R0001' ) ( ls_ship-city ) ).
FOR with THEN and UNTIL|WHILE:
DATA(gt_itab) = VALUE ty_tab( FOR j = 11 THEN j + 10 UNTIL j > 40 ( col1 = j col2 = j + 1 col3 = j + 2 ) ).
32. Reduction Operator REDUCE
The REDUCE
operator performs aggregation operations over internal tables or ranges, reducing data in a single expression.
Syntax:
REDUCE type( INIT result = start_value FOR wa IN itab WHERE (...) NEXT result = iterated_value )
Example 1: Count entries in gt_itab
where F1
contains “XYZ”.
DATA(lv_lines) = REDUCE i( INIT x = 0 FOR wa IN gt_itab WHERE( F1 = 'XYZ' ) NEXT x = x + 1 ).
Example 2: Sum values from 1 to 10 stored in a table.
DATA(lv_sum) = REDUCE i( INIT x = 0 FOR wa IN gt_itab NEXT x = x + wa ).
33. Conditional Operators COND
and SWITCH
COND: Conditional operator for expressions, similar to IF
statements.
DATA(time) = COND string( WHEN sy-timlo < '120000' THEN |{ sy-timlo TIME = ISO } AM| WHEN sy-timlo > '120000' THEN |{ CONV t( sy-timlo - 12 * 3600 ) TIME = ISO } PM| WHEN sy-timlo = '120000' THEN |High Noon| ELSE THROW cx_cant_be( ) ).
SWITCH: Selects a value based on matching conditions.
DATA(text) = SWITCH #( sy-langu WHEN 'D' THEN `DE` WHEN 'E' THEN `EN` ELSE THROW cx_langu_not_supported( ) ).
34. Corresponding Operator CORRESPONDING
The CORRESPONDING
operator transfers data between structures or tables with similar field names. It supports additions like BASE
, MAPPING
, and EXCEPT
for flexible field mapping.
Basic Usage:
ls_line2 = CORRESPONDING #( ls_line1 ).
Using BASE
for adding unmatched fields:
ls_line2 = CORRESPONDING #( BASE ( ls_line2 ) ls_line1 ).
Creating a New Structure:
DATA(ls_line3) = CORRESPONDING line2( BASE ( ls_line2 ) ls_line1 ).
Using MAPPING
and EXCEPT
:
ls_line2 = CORRESPONDING #( ls_line1 MAPPING t1 = s1 t2 = s2 ). ls_line2 = CORRESPONDING #( ls_line1 EXCEPT t1 t2 ).
35. String Enhancements
String Templates: A string template is enclosed by | ... |
and allows embedding data objects, calculations, or functions directly.
Example: Display a carrier’s name directly using a string template.
cl_demo_output=>display( |Carrier: { lt_scarr[ carrid = 'LH' ]-carrname }| ).
Concatenation with &
: Strings can now be concatenated with &
, avoiding CONCATENATE
.
Example:
DATA(lv_out) = |Hello| & | | & |world|.
Width/Alignment/Padding:
WRITE / |{ 'Left' WIDTH = 20 ALIGN = LEFT PAD = '0' }|.
WRITE / |{ 'Centre' WIDTH = 20 ALIGN = CENTER PAD = '0' }|.
WRITE / |{ 'Right' WIDTH = 20 ALIGN = RIGHT PAD = '0' }|.
Case Transformation: Convert text to different cases.
WRITE / |{ 'Text' CASE = (cl_abap_format=>c_upper) }|.
ALPHA Conversion for Leading Zeros:
DATA(lv_vbeln) = '0000012345'.
WRITE / |{ lv_vbeln ALPHA = OUT }|.
Date Conversion:
WRITE / |{ pa_date DATE = ISO }|. "ISO format YYYY-MM-DD
36. LOOP with GROUP BY
The GROUP BY
addition allows you to loop over groups within an internal table, grouping entries by a specified key.
Syntax:
LOOP AT itab INTO DATA(ls_employee) GROUP BY ( role = ls_employee-role size = GROUP SIZE index = GROUP INDEX ) ASCENDING ASSIGNING FIELD-SYMBOL(<group>).
Example: Group by role
and calculate average age.
LOOP AT gt_employee INTO DATA(ls_employee)
GROUP BY ( role = ls_employee-role size = GROUP SIZE index = GROUP INDEX )
ASSIGNING FIELD-SYMBOL(<group>).
CLEAR: gv_tot_age.
LOOP AT GROUP <group> ASSIGNING FIELD-SYMBOL(<ls_member>).
gv_tot_age = gv_tot_age + <ls_member>-age.
ENDLOOP.
gv_avg_age = gv_tot_age / <group>-size.
WRITE: / |Average age: { gv_avg_age }|.
ENDLOOP.
37. Object-Oriented Enhancements
Referencing Fields within Returned Structures:
DATA(lv_name1) = My_Class=>get_lfa1( )-name1.
BOOLEAN Return Type:
IF My_Class=>return_boolean( ). ... ENDIF.
NEW
Operator for Object Instantiation:
DATA(lo_deliv) = new zcl_sd_delivs( )->get_deliv( lv_vbeln ).
38. Mesh Tables
Meshes allow setting up associations between related internal tables, useful for hierarchical data representation.
Example: Retrieve developers managed by “Thomas” in a mesh table.
TYPES: BEGIN OF MESH m_team,
managers TYPE tt_manager ASSOCIATION my_employee TO developers ON manager = name,
developers TYPE tt_developer ASSOCIATION my_manager TO managers ON name = manager,
END OF MESH m_team.
DATA(ls_team) TYPE m_team.
ls_team-managers = lt_manager.
ls_team-developers = lt_developer.
ASSIGN lt_manager[ name = 'Thomas' ] TO FIELD-SYMBOL(<ls_thomas>).
LOOP AT ls_team-managers\my_employee[ <ls_thomas> ] ASSIGNING FIELD-SYMBOL(<ls_emp>).
WRITE: / |Employee name: { <ls_emp>-name }|.
ENDLOOP.
39. Filter Operator
The FILTER
operator allows filtering entries in a table based on a condition or another table.
Syntax:
FILTER type( itab [IN ftab] WHERE condition )
Example: Filter SPFLI
records based on cityfrom
and cityto
values from another filter table.
DATA(lt_filter) = VALUE ty_filter_tab( ( cityfrom = 'NEW YORK' cityto = 'SAN FRANCISCO' ) ( cityfrom = 'FRANKFURT' cityto = 'NEW YORK' ) ).
DATA(lt_myrecs) = FILTER #( lt_splfi IN lt_filter WHERE cityfrom = cityfrom AND cityto = cityto )
This provides a comprehensive and organized view of the latest ABAP syntax features, from string manipulation to advanced object-oriented techniques and filtering mechanisms. Let me know if you need further clarification on any feature!
Conclusion
The inline declarations and new syntax features introduced in SAP ABAP after release 7.40 bring ABAP in line with modern programming standards. By adopting these enhancements, developers can write cleaner, more efficient, and more maintainable code, ultimately improving productivity and code quality. Leveraging these improvements can also make transitioning to ABAP easier for developers familiar with other languages.