The ultimate ABAP Cloud Cheat Sheet with all important statements, modern expressions, and best practices for 2025. Perfect as a quick reference for daily development work.
Table of Contents
- Data Declaration
- Control Structures
- Internal Tables
- Database Access
- Modern Expressions
- String Operations
- OOP (Object Orientation)
- Exception Handling
- RAP (RESTful ABAP)
- CDS Views
Data Declaration
Elementary Data Types
" Classic (deprecated in ABAP Cloud)DATA lv_name TYPE string.DATA lv_count TYPE i.
" Modern: Inline declarationDATA(lv_name) = 'Max Mustermann'.DATA(lv_count) = 42.
" ConstantsCONSTANTS gc_max_entries TYPE i VALUE 100.
" Field Symbols & Data ReferencesFIELD-SYMBOLS <fs_data> TYPE any.DATA(lo_ref) = NEW zcl_my_class( ).Structures and Tables
" StructureTYPES: BEGIN OF ty_customer, id TYPE i, name TYPE string, email TYPE string, END OF ty_customer.
" Internal tableDATA lt_customers TYPE TABLE OF ty_customer.
" Modern: TYPE TABLE OF with indexDATA lt_indexed TYPE STANDARD TABLE OF ty_customer WITH DEFAULT KEY.DATA lt_sorted TYPE SORTED TABLE OF ty_customer WITH UNIQUE KEY id.DATA lt_hashed TYPE HASHED TABLE OF ty_customer WITH UNIQUE KEY id.Control Structures
IF Conditions
IF lv_status = 'ACTIVE'. " CodeELSEIF lv_status = 'PENDING'. " CodeELSE. " CodeENDIF.
" Modern: Inline with CONDDATA(lv_message) = COND string( WHEN lv_status = 'ACTIVE' THEN 'Active' WHEN lv_status = 'PENDING' THEN 'Pending' ELSE 'Unknown').CASE Statement
CASE lv_type. WHEN 'A'. " Code WHEN 'B' OR 'C'. " Code WHEN OTHERS. " DefaultENDCASE.
" Modern: SWITCH ExpressionDATA(lv_result) = SWITCH string( lv_type WHEN 'A' THEN 'Type A' WHEN 'B' THEN 'Type B' ELSE 'Unknown').Loops
" DO loopDO 10 TIMES. " CodeENDDO.
" WHILE loopWHILE lv_count < 100. lv_count = lv_count + 1.ENDWHILE.
" LOOP AT (internal table)LOOP AT lt_customers INTO DATA(ls_customer). " ProcessingENDLOOP.
" Modern: FOR ExpressionDATA(lt_names) = VALUE string_table( FOR ls_cust IN lt_customers ( ls_cust-name )).Internal Tables
Adding Rows
" APPENDAPPEND VALUE #( id = 1 name = 'Max' ) TO lt_customers.
" INSERTINSERT VALUE #( id = 2 name = 'Anna' ) INTO TABLE lt_customers.
" Modern: VALUE with multiple rowslt_customers = VALUE #().Reading Rows
" READ TABLE classicREAD TABLE lt_customers INTO DATA(ls_customer) WITH KEY id = 1.
" Modern: Table ExpressionDATA(ls_cust) = lt_customers[ id = 1 ].
" Optional: Default when not foundDATA(ls_opt) = VALUE #( lt_customers[ id = 999 ] OPTIONAL ).
" Set default valueDATA(ls_def) = VALUE #( lt_customers[ id = 999 ] DEFAULT VALUE #( id = 0 name = 'Unknown' ) ).Modifying Rows
" MODIFY classicMODIFY lt_customers FROM VALUE #( id = 1 name = 'Maximilian' ) TRANSPORTING name WHERE id = 1.
" Modern: Table Expressionlt_customers[ id = 1 ]-name = 'Maximilian'.Deleting Rows
" DELETE classicDELETE lt_customers WHERE id = 1.
" DELETE by indexDELETE lt_customers INDEX 1.
" CLEAR & FREECLEAR lt_customers. " Empties table (memory remains)FREE lt_customers. " Releases memoryTable Operations
" Number of rowsDATA(lv_lines) = lines( lt_customers ).
" SortSORT lt_customers BY name ASCENDING.
" FilterDATA(lt_active) = FILTER #( lt_customers WHERE status = 'ACTIVE' ).
" CORRESPONDING (Mapping)DATA(lt_target) = CORRESPONDING #( lt_source ).Database Access
SELECT
" Single RecordSELECT SINGLE id, name, email FROM ztab_customers WHERE id = @lv_id INTO @DATA(ls_customer).
" Multiple rowsSELECT id, name, email FROM ztab_customers WHERE status = 'ACTIVE' INTO TABLE @lt_customers.
" Modern: Inline with JoinsSELECT c~id, c~name, o~order_date FROM ztab_customers AS c INNER JOIN ztab_orders AS o ON c~id = o~customer_id WHERE c~status = 'ACTIVE' INTO TABLE @DATA(lt_result).
" AggregationSELECT customer_id, COUNT( * ) AS order_count FROM ztab_orders GROUP BY customer_id INTO TABLE @DATA(lt_stats).INSERT, UPDATE, DELETE
" INSERTINSERT ztab_customers FROM @ls_customer.
" UPDATEUPDATE ztab_customers SET status = 'INACTIVE' WHERE id = @lv_id.
" DELETEDELETE FROM ztab_customers WHERE id = @lv_id.
" MODIFY (INSERT or UPDATE)MODIFY ztab_customers FROM @ls_customer.COMMIT & ROLLBACK
" Save changesCOMMIT WORK.
" Undo changesROLLBACK WORK.Modern Expressions
VALUE Constructor
" StructureDATA(ls_data) = VALUE ty_customer( id = 1 name = 'Max').
" TableDATA(lt_data) = VALUE ty_customer_table( ( id = 1 name = 'Max' ) ( id = 2 name = 'Anna' )).
" BASE: Extend existing datalt_data = VALUE #( BASE lt_data ( id = 3 name = 'Peter' )).CORRESPONDING
" Simple mappingDATA(ls_target) = CORRESPONDING #( ls_source ).
" With MAPPINGDATA(ls_mapped) = CORRESPONDING #( ls_source MAPPING target_field = source_field).
" DEEP: Nested structuresDATA(ls_deep) = CORRESPONDING #( DEEP ls_source ).COND & SWITCH
" COND (IF alternative)DATA(lv_discount) = COND decfloat16( WHEN lv_amount > 1000 THEN lv_amount * '0.1' WHEN lv_amount > 500 THEN lv_amount * '0.05' ELSE 0).
" SWITCH (CASE alternative)DATA(lv_category) = SWITCH string( lv_age WHEN 0 THEN 'Baby' WHEN 1 TO 12 THEN 'Child' WHEN 13 TO 17 THEN 'Teenager' ELSE 'Adult').FILTER
" Simple filterDATA(lt_active) = FILTER #( lt_customers WHERE status = 'ACTIVE' ).
" Filter with IN conditionDATA(lt_premium) = FILTER #( lt_customers USING KEY id WHERE id IN lt_premium_ids ).REDUCE
" Calculate sumDATA(lv_total) = REDUCE i( INIT sum = 0 FOR ls_order IN lt_orders NEXT sum = sum + ls_order-amount ).
" Concatenate stringsDATA(lv_names) = REDUCE string( INIT text = || FOR ls_cust IN lt_customers NEXT text = text && ls_cust-name && ', ' ).FOR Expression
" TransformationDATA(lt_ids) = VALUE int4_table( FOR ls_customer IN lt_customers ( ls_customer-id )).
" With conditionDATA(lt_active_names) = VALUE string_table( FOR ls_cust IN lt_customers WHERE ( status = 'ACTIVE' ) ( ls_cust-name )).
" Nested FORDATA(lt_flat) = VALUE ty_table( FOR ls_group IN lt_groups FOR ls_item IN ls_group-items ( ls_item )).String Operations
String Templates
" SimpleDATA(lv_greeting) = |Hello { lv_name }!|.
" With formattingDATA(lv_price) = |Price: { lv_amount CURRENCY = lv_currency }|.DATA(lv_date) = |Date: { lv_timestamp TIMESTAMP = ISO }|.
" Alignment and paddingDATA(lv_padded) = |{ lv_text WIDTH = 20 ALIGN = LEFT PAD = '.' }|.String Methods
" LengthDATA(lv_len) = strlen( lv_text ).
" SubstringDATA(lv_sub) = substring( val = lv_text off = 0 len = 5 ).
" Search & ReplaceDATA(lv_pos) = find( val = lv_text sub = 'test' ).DATA(lv_replaced) = replace( val = lv_text sub = 'old' with = 'new' ).
" Upper/Lower CaseDATA(lv_upper) = to_upper( lv_text ).DATA(lv_lower) = to_lower( lv_text ).
" TrimDATA(lv_trimmed) = condense( lv_text ).CONCATENATE & SPLIT
" Modern: String Template instead of CONCATENATEDATA(lv_full_name) = |{ lv_first_name } { lv_last_name }|.
" SPLITSPLIT lv_text AT ',' INTO TABLE DATA(lt_parts).OOP (Object Orientation)
Class Definition
CLASS zcl_customer DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. METHODS: constructor IMPORTING iv_id TYPE i, get_name RETURNING VALUE(rv_name) TYPE string, set_status IMPORTING iv_status TYPE string.
PRIVATE SECTION. DATA: mv_id TYPE i, mv_name TYPE string, mv_status TYPE string.ENDCLASS.
CLASS zcl_customer IMPLEMENTATION. METHOD constructor. mv_id = iv_id. ENDMETHOD.
METHOD get_name. rv_name = mv_name. ENDMETHOD.
METHOD set_status. mv_status = iv_status. ENDMETHOD.ENDCLASS.Instantiation
" NEW OperatorDATA(lo_customer) = NEW zcl_customer( iv_id = 1 ).
" Method callDATA(lv_name) = lo_customer->get_name( ).lo_customer->set_status( 'ACTIVE' ).Interfaces
INTERFACE zif_processor. METHODS process IMPORTING iv_data TYPE string RETURNING VALUE(rv_result) TYPE string.ENDINTERFACE.
CLASS zcl_impl DEFINITION. PUBLIC SECTION. INTERFACES zif_processor.ENDCLASS.
CLASS zcl_impl IMPLEMENTATION. METHOD zif_processor~process. rv_result = |Processed: { iv_data }|. ENDMETHOD.ENDCLASS.Exception Handling
TRY-CATCH
TRY. DATA(lv_customer) = lt_customers[ id = lv_id ]. CATCH cx_sy_itab_line_not_found INTO DATA(lx_error). " Error handling DATA(lv_msg) = lx_error->get_text( ).ENDTRY.
" Multiple exceptionsTRY. " Code CATCH cx_sy_arithmetic_error. " Division by zero CATCH cx_sy_conversion_error. " Conversion error CATCH cx_root INTO DATA(lx_any). " All othersENDTRY.CLEANUP
TRY. " Code with resources CATCH cx_error. " Error handling CLEANUP. " Release resources (always executed) lo_resource->close( ).ENDTRY.Exception Classes
CLASS zcx_my_exception DEFINITION PUBLIC INHERITING FROM cx_static_check FINAL CREATE PUBLIC.
PUBLIC SECTION. METHODS constructor IMPORTING textid TYPE sotr_conc OPTIONAL.ENDCLASS.
" UsageIF lv_invalid. RAISE EXCEPTION TYPE zcx_my_exception.ENDIF.RAP (RESTful ABAP)
EML (Entity Manipulation Language)
" READREAD ENTITIES OF zi_travel ENTITY Travel FIELDS ( TravelId AgencyId Status ) WITH VALUE #( ( TravelId = lv_id ) ) RESULT DATA(lt_travel).
" CREATEMODIFY ENTITIES OF zi_travel ENTITY Travel CREATE FIELDS ( AgencyId CustomerId BeginDate ) WITH VALUE #( ( %cid = 'CID_1' AgencyId = '000001' CustomerId = '000010' BeginDate = cl_abap_context_info=>get_system_date( ) ) ).
" UPDATEMODIFY ENTITIES OF zi_travel ENTITY Travel UPDATE FIELDS ( Status ) WITH VALUE #( ( TravelId = lv_id Status = 'A' ) ).
" DELETEMODIFY ENTITIES OF zi_travel ENTITY Travel DELETE FROM VALUE #( ( TravelId = lv_id ) ).
" COMMITCOMMIT ENTITIES.Actions
" Execute actionMODIFY ENTITIES OF zi_travel ENTITY Travel EXECUTE acceptTravel FROM VALUE #( ( TravelId = lv_id ) ) RESULT DATA(lt_result).CDS Views
Basic View
@AbapCatalog.sqlViewName: 'ZVCUSTOMER'@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Customer View'
define view Z_Customer as select from ztab_customers{ key id as CustomerId, name as CustomerName, email as Email, @Semantics.amount.currencyCode: 'Currency' credit_limit as CreditLimit, currency as Currency}Associations & Joins
define view Z_CustomerOrders as select from ztab_customers as c association [0..*] to ztab_orders as _Orders on c.id = _Orders.customer_id{ key c.id, c.name, c.email,
_Orders // Expose association}Annotations
@Analytics.dataCategory: #CUBE@Analytics.query: true@VDM.viewType: #CONSUMPTION
define view Z_SalesAnalytics as select from ztab_sales{ @Analytics.dimension: true product_id,
@Aggregation.default: #SUM @Semantics.amount.currencyCode: 'Currency' revenue,
currency}Best Practices
DO
" Inline declarationsDATA(lv_result) = calculate_value( ).
" VALUE ConstructorDATA(lt_data) = VALUE ty_table( ( id = 1 ) ).
" String TemplatesDATA(lv_msg) = |Error: { lv_error_code }|.
" Table ExpressionsDATA(ls_customer) = lt_customers[ id = lv_id ].
" Method ChainingDATA(lv_final) = lo_object->method1( )->method2( )->get_result( ).DON’T
" Deprecated declarationDATA lv_result TYPE string.lv_result = calculate_value( ).
" CONCATENATE instead of String TemplateCONCATENATE 'Error:' lv_error_code INTO lv_msg SEPARATED BY space.
" Unnecessary helper variablesDATA ls_customer TYPE ty_customer.READ TABLE lt_customers INTO ls_customer WITH KEY id = lv_id.ABAP Cloud Restrictions
Not Allowed in ABAP Cloud
FORM/PERFORM(Subroutines)SELECT *without field list- Direct DB access to SAP tables (only Released APIs)
SUBMITfor report calls- Dynpro development (only Fiori)
CALL TRANSACTION
Use Instead
- Methods instead of FORM
- Explicit field list in SELECT
- CDS Views with Released status
- Business Events & RAP
- SAP Fiori Elements
- ABAP EML (Entity Manipulation Language)
Useful Classes & Interfaces
| Class/Interface | Usage |
|---|---|
cl_abap_context_info | System date, user, client |
cl_abap_random | Generate random numbers |
cl_abap_structdescr | Runtime Type Info (RTTI) |
cl_http_client | HTTP requests |
cl_salv_table | Create ALV lists |
if_abap_behv | RAP Behavior Constants |
cx_root | Base of all exceptions |
Summary
This cheat sheet covers the most important ABAP Cloud concepts for 2025:
- Modern syntax with inline declarations
- Constructor expressions (VALUE, CORRESPONDING, COND, etc.)
- EML for RAP development
- CDS Views for data modeling
- Best practices for clean, maintainable code
Tip: Bookmark this page or print it out for quick access during development!
See also:
- RAP Basics
- CDS Views
- ABAP Cloud Definition
- Modern ABAP Expressions