Emre Göçmen Blog

SAP ABAP New Syntax: A Comprehensive Guide

5 min. read
2511 views
0 comments

Emre Göçmen

Author

SAP ABAP New Syntax: A Comprehensive Guide

SAP ABAP New Syntax: A Comprehensive Guide

Table of Contents

  1. Introduction
  2. Core New Syntax Features
  3. Practical Application Examples
  4. Advanced Topics
  5. Performance Optimizations
  6. Conclusion
  7. Additional Resources

1. Introduction

SAP ABAP (Advanced Business Application Programming) is a powerful and flexible programming language used to develop business applications in SAP systems. With the emergence of SAP S/4HANA and modern SAP technologies, the ABAP language has significantly evolved, gaining new syntax features to support modern programming paradigms.

The new ABAP syntax (often referred to as "ABAP Modern Syntax" or "ABAP 7.4+") provides various constructs and operators that allow you to write more readable, maintainable, and efficient code. These innovations enable developers to create more powerful applications with less code, thus reducing development time and increasing code quality.

In this guide, we will explore the new syntax features of ABAP in detail, demonstrate how to use these features with practical examples, and cover modern ABAP programming techniques.

2. Core New Syntax Features

2.1 Local Variable Declarations

In classic ABAP, you would use two separate statements to declare a variable and assign a value to it. With the new syntax, you can define variables and assign values at the same time. This makes the code more concise and readable.

Old Syntax:

DATA: lv_number TYPE i,
      lv_text   TYPE string.

lv_number = 42.
lv_text   = 'Hello World'.

New Syntax:

DATA(lv_number) = 42.
DATA(lv_text)   = 'Hello World'.

The ABAP compiler automatically infers the data type based on the assigned value. This reduces the need for explicit variable declarations and makes the code shorter and more readable.

Limitations of Local Variable Declaration:

  • Local variables can only be used within the program; they cannot be used for class members or global variables.
  • A DATA(...) variable cannot be declared more than once in the same scope.
  • Initial value assignment is mandatory; an empty declaration like DATA(lv_var) is invalid.

2.2 Inline Declarations

One of the most powerful features of the new syntax is the ability to declare variables inline in SQL queries, internal table operations, and loops.

Inline Declarations in SQL Queries:

SELECT carrid, connid, fldate, price
  INTO TABLE @DATA(lt_flights)
  FROM sflight
  WHERE carrid = 'LH'.

Inline Declarations in LOOP Statements:

LOOP AT lt_flights INTO DATA(ls_flight).
  WRITE: / |Flight: { ls_flight-connid }, Date: { ls_flight-fldate }|.
ENDLOOP.

Inline Declarations in READ TABLE Statements:

READ TABLE lt_flights INTO DATA(ls_first_flight) INDEX 1.
IF sy-subrc = 0.
  WRITE: / |First flight: { ls_first_flight-connid }|.
ENDIF.

2.3 String Templates

String templates allow you to combine text and variables in an easy and readable way. This feature enables you to create text in a single line instead of using multiple CONCATENATE statements.

DATA(lv_firstname) = 'John'.
DATA(lv_lastname)  = 'Smith'.

" Classic method
CONCATENATE 'Hello ' lv_firstname ' ' lv_lastname INTO DATA(lv_greeting_old).

" Using string template
DATA(lv_greeting_new) = |Hello { lv_firstname } { lv_lastname }|.

" Formatted output
DATA(lv_price)        = 1250.55.
DATA(lv_order_date)   = '20210515'.
DATA(lv_order_output) = |Order Date: { lv_order_date DATE = USER } - Amount: { lv_price DECIMALS = 2 } USD|.

WRITE: / lv_greeting_new,
       / lv_order_output.

Template Formatting Options:

  • DATE = USER/ISO/RAW: Date formatting
  • TIME = USER/ISO/RAW: Time formatting
  • DECIMALS = n: Number of decimal places
  • WIDTH = n: Fixed width
  • ALIGN = LEFT/CENTER/RIGHT: Alignment
  • CASE = UPPER/LOWER: Upper/lower case

2.4 VALUE Operator

The VALUE operator allows you to populate structures and internal tables in a single expression. This improves code readability and enables more structured data handling.

Creating Structures:

TYPES: BEGIN OF ty_employee,
         id         TYPE i,
         first_name TYPE string,
         last_name  TYPE string,
         hire_date  TYPE d,
       END OF ty_employee.

DATA(ls_employee) = VALUE ty_employee(
  id         = 12345
  first_name = 'John'
  last_name  = 'Smith'
  hire_date  = '20210101'
).

Creating Internal Tables:

DATA(lt_employees) = VALUE tt_employee(
  ( id = 1  first_name = 'Alice'  last_name = 'Johnson' hire_date = '20200101' )
  ( id = 2  first_name = 'Bob'    last_name = 'Miller'  hire_date = '20200315' )
  ( id = 3  first_name = 'Carol'  last_name = 'Davis'   hire_date = '20200610' )
  ( id = 4  first_name = 'David'  last_name = 'Wilson'  hire_date = '20201201' )
).

Copying and Modifying Existing Structures (BASE):

DATA(ls_employee_updated) = VALUE ty_employee(
  BASE ls_employee
  first_name = 'John M.'
  hire_date  = '20210201'
).

2.5 REDUCE Operator

The REDUCE operator is used to summarize values in an internal table and calculate an aggregate value.

TYPES: BEGIN OF ty_sales,
         product_id TYPE string,
         quantity   TYPE i,
         price      TYPE p DECIMALS 2,
       END OF ty_sales.

DATA(lt_sales) = VALUE tt_sales(
  ( product_id = 'A001' quantity = 5  price = 10.50 )
  ( product_id = 'B002' quantity = 2  price = 25.75 )
  ( product_id = 'A001' quantity = 3  price = 10.50 )
  ( product_id = 'C003' quantity = 1  price = 99.99 )
).

" Calculate total sales amount
DATA(lv_total_sales) = REDUCE decfloat34(
  INIT total = 0
  FOR ls_sale IN lt_sales
  NEXT total = total + ( ls_sale-quantity * ls_sale-price )
).

WRITE: / |Total Sales Amount: { lv_total_sales DECIMALS = 2 } USD|.

2.6 FOR Expression

The FOR expression is used to process and filter data in tables. It can be used with VALUE and other constructor operators.

Creating Sequential Numbers:

DATA(lt_numbers) = VALUE tt_i(
  FOR i = 1 THEN i + 1 UNTIL i > 10
  ( i )
).

Creating Filtered Tables:

DATA(lt_lh_flights) = VALUE tt_flights(
  FOR ls_flight IN lt_flights
  WHERE ( carrid = 'LH' )
  ( ls_flight )
).

Creating Transformed Tables:

DATA(lt_prices) = VALUE tt_price(
  FOR ls_flight IN lt_flights
  ( carrier_id = ls_flight-carrid
    flight_id  = ls_flight-connid
    amount     = ls_flight-price * '1.19' "Price with VAT
    currency   = ls_flight-currency )
).

2.7 FILTER Operator

The FILTER operator is used to filter an internal table based on a specific condition. This is useful for creating table subsets based on certain criteria.

DATA(lt_lh_flights) = FILTER #( lt_flights WHERE carrid = 'LH' ).
DATA(lt_expensive_flights) = FILTER #( lt_flights WHERE price > 500 ).

EXCEPT and IN Options:

" Flights other than 'LH' and 'LX'
DATA(lt_other_flights) = FILTER #( lt_flights EXCEPT WHERE carrid = 'LH' OR carrid = 'LX' ).

" Flights with specific flight numbers
DATA(lt_selected_connids) = VALUE tt_connid( ( '0400' ) ( '0401' ) ( '0402' ) ).
DATA(lt_selected_flights) = FILTER #( lt_flights IN lt_selected_connids WHERE connid = table_line ).

2.8 Lambda Expressions

Lambda expressions are used to perform common operations. They particularly help in simplifying large code blocks, making the code more readable.

DATA(lv_total) = REDUCE i(
  INIT s = 0
  FOR i = 1 UNTIL i > 10
  NEXT s = s + i
).

" Calculate sum of squares using lambda expression
DATA(lv_sum_of_squares) = REDUCE i(
  INIT s = 0
  FOR i = 1 UNTIL i > 10
  LET square = i * i IN
  NEXT s = s + square
).

WRITE: / |Sum of numbers from 1 to 10: { lv_total }|.
WRITE: / |Sum of squares from 1 to 10: { lv_sum_of_squares }|.

3. Practical Application Examples

3.1 Customer Order Reporting

TYPES: BEGIN OF ty_customer,
         id      TYPE i,
         name    TYPE string,
         city    TYPE string,
         country TYPE string,
       END OF ty_customer.

TYPES: BEGIN OF ty_order,
         order_id    TYPE i,
         customer_id TYPE i,
         order_date  TYPE d,
         total       TYPE p DECIMALS 2,
         currency    TYPE c LENGTH 3,
         status      TYPE string,
       END OF ty_order.

" Create sample data
DATA(lt_customers) = VALUE tt_customer(
  ( id = 1 name = 'ABC Company'  city = 'New York' country = 'US' )
  ( id = 2 name = 'XYZ Ltd.' city = 'London'   country = 'UK' )
  ( id = 3 name = 'MNO GmbH'      city = 'Berlin'   country = 'DE' )
).

DATA(lt_orders) = VALUE tt_order(
  ( order_id = 1001 customer_id = 1 order_date = '20210101' total = 1250.75 currency = 'USD' status = 'Completed' )
  ( order_id = 1002 customer_id = 1 order_date = '20210115' total = 750.50  currency = 'USD' status = 'Completed' )
  ( order_id = 1003 customer_id = 2 order_date = '20210120' total = 2500.00 currency = 'GBP' status = 'Processing' )
  ( order_id = 1004 customer_id = 3 order_date = '20210125' total = 900.00  currency = 'EUR' status = 'Completed' )
  ( order_id = 1005 customer_id = 1 order_date = '20210210' total = 1800.25 currency = 'USD' status = 'Processing' )
).

" 1. Program that combines customer orders and reports them
LOOP AT lt_customers INTO DATA(ls_customer).
  WRITE: / |Customer: { ls_customer-name } ({ ls_customer-city }, { ls_customer-country })|.
  
  " Filter all orders for this customer
  DATA(lt_customer_orders) = FILTER #( lt_orders WHERE customer_id = ls_customer-id ).
  
  " Calculate total order amount
  DATA(lv_total_usd) = REDUCE decfloat34(
    INIT t = 0
    FOR ls_order IN lt_customer_orders WHERE ( currency = 'USD' )
    NEXT t = t + ls_order-total
  ).
  
  " List each order
  LOOP AT lt_customer_orders INTO DATA(ls_order).
    WRITE: /5 |Order: { ls_order-order_id } - { ls_order-order_date DATE = USER } - { ls_order-total DECIMALS = 2 } { ls_order-currency } - Status: { ls_order-status }|.
  ENDLOOP.
  
  WRITE: / |Total USD Orders: { lv_total_usd DECIMALS = 2 } USD|.
  SKIP 1.
ENDLOOP.

3.2 Data Transformation and Analysis

" Sales data
TYPES: BEGIN OF ty_sales_data,
         region    TYPE string,
         product   TYPE string,
         quantity  TYPE i,
         sales     TYPE p DECIMALS 2,
         currency  TYPE c LENGTH 3,
         sale_date TYPE d,
       END OF ty_sales_data.

DATA(lt_sales_data) = VALUE tt_sales_data(
  ( region = 'East'     product = 'Laptop'   quantity = 5  sales = 5000.00 currency = 'USD' sale_date = '20210105' )
  ( region = 'West'     product = 'Phone'    quantity = 10 sales = 3000.00 currency = 'USD' sale_date = '20210110' )
  ( region = 'East'     product = 'Phone'    quantity = 8  sales = 2400.00 currency = 'USD' sale_date = '20210115' )
  ( region = 'Central'  product = 'Tablet'   quantity = 3  sales = 1200.00 currency = 'USD' sale_date = '20210120' )
  ( region = 'East'     product = 'Tablet'   quantity = 6  sales = 2400.00 currency = 'USD' sale_date = '20210125' )
  ( region = 'West'     product = 'Laptop'   quantity = 4  sales = 4000.00 currency = 'USD' sale_date = '20210130' )
).

" 1. Product sales analysis
TYPES: BEGIN OF ty_product_sales,
         product  TYPE string,
         quantity TYPE i,
         sales    TYPE p DECIMALS 2,
       END OF ty_product_sales.

DATA(lt_product_sales) = VALUE tt_product_sales(
  FOR GROUPS product OF ls_sale IN lt_sales_data
  GROUP BY ls_sale-product
  LET total_quantity = REDUCE i( INIT q = 0
                                  FOR gs IN GROUP product
                                  NEXT q = q + gs-quantity )
      total_sales = REDUCE decfloat34( INIT s = 0
                                       FOR gs IN GROUP product
                                       NEXT s = s + gs-sales )
  IN ( product  = product
       quantity = total_quantity
       sales    = total_sales )
).

WRITE: / 'Product Sales Analysis:'.
LOOP AT lt_product_sales INTO DATA(ls_product_sales).
  WRITE: / |Product: { ls_product_sales-product } - Qty: { ls_product_sales-quantity } - Total Sales: { ls_product_sales-sales DECIMALS = 2 } USD|.
ENDLOOP.
SKIP 1.

" 2. Region sales analysis
TYPES: BEGIN OF ty_region_sales,
         region   TYPE string,
         quantity TYPE i,
         sales    TYPE p DECIMALS 2,
       END OF ty_region_sales.

DATA(lt_region_sales) = VALUE tt_region_sales(
  FOR GROUPS region OF ls_sale IN lt_sales_data
  GROUP BY ls_sale-region
  LET total_quantity = REDUCE i( INIT q = 0
                                 FOR gs IN GROUP region
                                 NEXT q = q + gs-quantity )
      total_sales = REDUCE decfloat34( INIT s = 0
                                      FOR gs IN GROUP region
                                      NEXT s = s + gs-sales )
  IN ( region   = region
       quantity = total_quantity
       sales    = total_sales )
).

WRITE: / 'Region Sales Analysis:'.
LOOP AT lt_region_sales INTO DATA(ls_region_sales).
  WRITE: / |Region: { ls_region_sales-region } - Qty: { ls_region_sales-quantity } - Total Sales: { ls_region_sales-sales DECIMALS = 2 } USD|.
ENDLOOP.

4. Advanced Topics

4.1 ABAP Object-Oriented Programming

The new syntax features make object-oriented ABAP programming more powerful and flexible.

CLASS lcl_product_manager DEFINITION.
  PUBLIC SECTION.
    TYPES: BEGIN OF ty_product,
             id          TYPE string,
             name        TYPE string,
             price       TYPE p DECIMALS 2,
             category    TYPE string,
             stock_level TYPE i,
           END OF ty_product.
    
    TYPES: tt_products TYPE TABLE OF ty_product WITH KEY id.
    
    METHODS:
      constructor,
      add_product IMPORTING is_product TYPE ty_product,
      get_products RETURNING VALUE(rt_products) TYPE tt_products,
      get_available_products RETURNING VALUE(rt_products) TYPE tt_products,
      calculate_inventory_value RETURNING VALUE(rv_value) TYPE decfloat34.
      
  PRIVATE SECTION.
    DATA: mt_products TYPE tt_products.
ENDCLASS.

CLASS lcl_product_manager IMPLEMENTATION.
  METHOD constructor.
    " Initialize with sample products
    mt_products = VALUE #(
      ( id = 'P001' name = 'Laptop Pro'  price = 1200.00 category = 'Electronics' stock_level = 10 )
      ( id = 'P002' name = 'Smart Watch' price = 249.99  category = 'Wearables'   stock_level = 15 )
      ( id = 'P003' name = 'Headphones'  price = 89.50   category = 'Accessories' stock_level = 0 )
      ( id = 'P004' name = 'Tablet Max'  price = 599.00  category = 'Electronics' stock_level = 8 )
    ).
  ENDMETHOD.
  
  METHOD add_product.
    APPEND is_product TO mt_products.
  ENDMETHOD.
  
  METHOD get_products.
    rt_products = mt_products.
  ENDMETHOD.
  
  METHOD get_available_products.
    " Filter products that are in stock
    rt_products = FILTER #( mt_products WHERE stock_level > 0 ).
  ENDMETHOD.
  
  METHOD calculate_inventory_value.
    " Calculate total inventory value
    rv_value = REDUCE decfloat34(
      INIT value = 0
      FOR ls_product IN mt_products
      NEXT value = value + ( ls_product-price * ls_product-stock_level )
    ).
  ENDMETHOD.
ENDCLASS.

" Using the class
START-OF-SELECTION.
  DATA(lo_product_manager) = NEW lcl_product_manager( ).
  
  " Add a new product
  lo_product_manager->add_product( VALUE #( 
    id = 'P005' 
    name = 'External Drive' 
    price = 129.99 
    category = 'Storage' 
    stock_level = 12 
  ) ).
  
  " List all products
  WRITE: / 'All Products:'.
  LOOP AT lo_product_manager->get_products( ) INTO DATA(ls_product).
    WRITE: / |{ ls_product-id } - { ls_product-name } - ${ ls_product-price DECIMALS = 2 } - Stock: { ls_product-stock_level }|.
  ENDLOOP.
  
  SKIP 1.
  
  " List only available products
  WRITE: / 'Products In Stock:'.
  LOOP AT lo_product_manager->get_available_products( ) INTO ls_product.
    WRITE: / |{ ls_product-id } - { ls_product-name } - ${ ls_product-price DECIMALS = 2 } - Stock: { ls_product-stock_level }|.
  ENDLOOP.
  
  SKIP 1.
  
  " Show total inventory value
  DATA(lv_inventory_value) = lo_product_manager->calculate_inventory_value( ).
  WRITE: / |Total Inventory Value: ${ lv_inventory_value DECIMALS = 2 }|.

4.2 ABAP CDS (Core Data Services)

ABAP CDS is a modern approach for data modeling and leveraging the full capabilities of the HANA database.

@AbapCatalog.sqlViewName: 'ZSALESREPORT'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Sales Report'
define view Z_SALES_REPORT
  as select from vbak as SalesHeader
    inner join vbap as SalesItem on SalesHeader.vbeln = SalesItem.vbeln
    inner join mara as Material on SalesItem.matnr = Material.matnr
    inner join kna1 as Customer on SalesHeader.kunnr = Customer.kunnr
{
    key SalesHeader.vbeln as SalesDocument,
    key SalesItem.posnr as SalesDocumentItem,
    SalesHeader.erdat as CreationDate,
    Customer.kunnr as CustomerId,
    Customer.name1 as CustomerName,
    Customer.land1 as Country,
    Material.matnr as MaterialNumber,
    Material.maktx as MaterialDescription,
    @Semantics.quantity.unitOfMeasure: 'OrderUnit'
    SalesItem.kwmeng as OrderQuantity,
    SalesItem.meins as OrderUnit,
    @Semantics.amount.currencyCode: 'DocumentCurrency'
    SalesItem.netwr as NetAmount,
    SalesHeader.waerk as DocumentCurrency,
    
    // Calculated fields
    case SalesHeader.faksk
      when 'A' then 'Order'
      when 'B' then 'Quotation'
      else 'Other'
    end as DocumentType,
    
    // Calculate gross amount with tax
    @Semantics.amount.currencyCode: 'DocumentCurrency'
    case
      when SalesItem.mwskz = 'A1' then SalesItem.netwr * 1.18
      when SalesItem.mwskz = 'A2' then SalesItem.netwr * 1.08
      else SalesItem.netwr
    end as GrossAmount
}
where SalesHeader.vbtyp = 'C'  // Select only orders

4.3 AMDP (ABAP Managed Database Procedures)

AMDP provides code pushdown at the database level using HANA SQLScript or SQL integrated with ABAP code.

CLASS zcl_sales_analysis DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC.

  PUBLIC SECTION.
    INTERFACES: if_amdp_marker_hdb.
    
    TYPES: BEGIN OF ty_sales_by_region,
             region_id   TYPE string,
             region_name TYPE string,
             total_sales TYPE p LENGTH 15 DECIMALS 2,
             currency    TYPE c LENGTH 3,
           END OF ty_sales_by_region.
    
    TYPES: tt_sales_by_region TYPE TABLE OF ty_sales_by_region.
    
    METHODS: get_sales_by_region
      IMPORTING VALUE(iv_year)        TYPE numc4
      EXPORTING VALUE(et_sales)       TYPE tt_sales_by_region
                VALUE(ev_total_sales) TYPE decfloat34.
      
ENDCLASS.

CLASS zcl_sales_analysis IMPLEMENTATION.

  METHOD get_sales_by_region BY DATABASE PROCEDURE
                             FOR HDB
                             LANGUAGE SQLSCRIPT
                             OPTIONS READ-ONLY.
                             
    -- Calculate sales by region using HANA SQLScript
    lt_sales = SELECT  reg.region_id,
                      reg.region_name,
                      SUM(si.netwr) AS total_sales,
                      sh.waerk AS currency
              FROM vbak AS sh
                INNER JOIN vbap AS si ON sh.vbeln = si.vbeln
                INNER JOIN kna1 AS cust ON sh.kunnr = cust.kunnr
                INNER JOIN zregions AS reg ON cust.regio = reg.region_id
              WHERE SUBSTRING(sh.erdat, 1, 4) = :iv_year
                AND sh.vbtyp = 'C'  -- Only orders
              GROUP BY reg.region_id, reg.region_name, sh.waerk
              ORDER BY total_sales DESC;
    
    -- Calculate total sales
    lv_total = SELECT SUM(total_sales) AS grand_total
               FROM :lt_sales;
    
    -- Return results
    et_sales = SELECT * FROM :lt_sales;
    ev_total_sales = :lv_total.grand_total;
    
  ENDMETHOD.

ENDCLASS.

4.4 RAP (RESTful ABAP Programming Model)

RAP is a modern programming model used to provide OData services via SAP Fiori applications and the SAP API Hub.

" RAP Business Object Behavior
managed implementation in class zbp_i_product unique;
define behavior for ZI_Product alias Product
persistent table zproduct
lock master
authorization master ( instance )
etag master LastChangedAt
{
  create;
  update;
  delete;

  field ( readonly ) ProductUUID;
  field ( mandatory ) ProductID, ProductName, Price;
  field ( readonly ) CreatedBy, CreatedAt, LastChangedBy, LastChangedAt;

  validation validatePrice on save { field Price; }
  validation validateProductID on save { field ProductID; }

  determination setInitialValues on modify { create; }

  mapping for zproduct
  {
    ProductUUID = product_uuid;
    ProductID = product_id;
    ProductName = product_name;
    Category = category;
    Price = price;
    Currency = currency;
    Description = description;
    StockQuantity = stock_quantity;
    UnitOfMeasure = unit_of_measure;
    CreatedBy = created_by;
    CreatedAt = created_at;
    LastChangedBy = last_changed_by;
    LastChangedAt = last_changed_at;
  }
}

5. Performance Optimizations

The new ABAP syntax not only makes your code more readable and maintainable but can also significantly improve its performance. Here are some important performance optimization techniques:

5.1 Internal Table Operation Performance Improvements

" 1. Using FILTER operator instead of LOOP...WHERE
" Poor performance:
LOOP AT lt_flights INTO DATA(ls_flight) WHERE carrid = 'LH'.
  " Processing
ENDLOOP.

" Good performance:
LOOP AT FILTER #( lt_flights WHERE carrid = 'LH' ) INTO DATA(ls_flight).
  " Processing
ENDLOOP.

" 2. Using FOR...IN instead of nested loops
" Poor performance:
LOOP AT lt_flights INTO DATA(ls_flight).
  LOOP AT lt_bookings INTO DATA(ls_booking) WHERE carrid = ls_flight-carrid 
                                              AND connid = ls_flight-connid.
    " Processing
  ENDLOOP.
ENDLOOP.

" Good performance:
DATA(lt_combined) = VALUE tt_combined(
  FOR ls_flight IN lt_flights
  FOR ls_booking IN lt_bookings
  WHERE ( carrid = ls_flight-carrid AND connid = ls_flight-connid )
  ( carrid      = ls_flight-carrid
    connid      = ls_flight-connid
    fldate      = ls_flight-fldate
    bookid      = ls_booking-bookid
    customid    = ls_booking-customid )
).

LOOP AT lt_combined INTO DATA(ls_combined).
  " Processing
ENDLOOP.

5.2 Code Pushdown (HANA Optimization)

To leverage the power of the SAP HANA database, it's important to "push down" as many operations as possible to the database layer.

" 1. Calculation in CDS views instead of ABAP
" Poor performance (calculation in ABAP layer):
SELECT carrid, connid, fldate, price, currency
  FROM sflight
  INTO TABLE @DATA(lt_flights)
  WHERE carrid = 'LH'.

DATA(lv_total) = REDUCE decfloat34(
  INIT sum = 0
  FOR ls_flight IN lt_flights
  NEXT sum = sum + ls_flight-price
).

" Good performance (calculation in database layer):
SELECT SINGLE SUM( price ) AS total
  FROM sflight
  WHERE carrid = 'LH'
  INTO @DATA(lv_total).

" 2. Grouping in database layer with GROUP BY
" Poor performance (grouping in ABAP layer):
SELECT carrid, connid, fldate, price, currency
  FROM sflight
  INTO TABLE @DATA(lt_flights).

DATA: lt_carriers TYPE TABLE OF t_carrier,
      ls_carrier  TYPE t_carrier.

LOOP AT lt_flights INTO DATA(ls_flight).
  READ TABLE lt_carriers ASSIGNING FIELD-SYMBOL()
    WITH KEY carrid = ls_flight-carrid.
  IF sy-subrc <> 0.
    ls_carrier-carrid = ls_flight-carrid.
    ls_carrier-total = ls_flight-price.
    APPEND ls_carrier TO lt_carriers.
  ELSE.
    -total = -total + ls_flight-price.
  ENDIF.
ENDLOOP.

" Good performance (grouping in database layer):
SELECT carrid, 
       SUM( price ) AS total
  FROM sflight
  GROUP BY carrid
  INTO TABLE @DATA(lt_carriers).

6. Conclusion

The new ABAP syntax represents a significant evolution in SAP development processes, making them more modern, efficient, and sustainable. The features covered in this guide help you achieve higher quality with less effort in coding.

The advantages of the new syntax include:

  • More concise and readable code
  • Fewer repetitive code blocks
  • Stronger type safety
  • Better database integration
  • Higher code performance
  • Compatibility with modern programming paradigms

By using the new syntax features in your SAP development projects, you can develop higher quality and more maintainable applications. These features are particularly important in S/4HANA and SAP Cloud Platform projects.

7. Additional Resources

Comments

0

You must be logged in to comment.

No comments yet.

Be the first to comment.

Emre Göçmen

Author & Developer

I write about my experiences as a SAP ABAP & Full Stack developer.

Category

SAP

SAP

Subscribe to Newsletter

Subscribe to my newsletter to get notified about new articles.