SAP ABAP New Syntax after Release 7.40

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.

Leave a Comment