top of page
Search

Differences : Classic ABAP , Modern ABAP and CLOUD ABAP tutorial list

  • Writer: Sergio Cannelli
    Sergio Cannelli
  • Oct 11, 2024
  • 13 min read

Updated: Oct 14, 2024


Cheat Sheet Modern ABAP


The ABAP language has evolved tremendously since NetWeaver ABAP 7.40. Many new language constructs have been added. Especially, of course, many new expressions. With them you can write clean code and save many auxiliary variables and declarations. The new language elements should be used to make the code more robust and readable. However, faster execution is not to be expected.

This poster shows the most important and useful new features. Omitted are the new ABAP SQL syntax and ABAP Built-In Functions.


Tip #1 - Reduce Expression


There are many occasion in which COLLECT comes as the first option when you want to sum up some fields. Just writing COLLECT wa IN itab will do the trick. But, there is always a "but". What I don't like about it is how quick you can screw up the logic. You either have to be extra careful to define the keys of the internal table or to be sure that the structure will not sum up fields you don't want to (in a standard table without keys it sums up all numeric data type field). This made me ask myself: is there a way to write this better? And to make it even better, use the new ABAP syntax ?.


Let's see the following example I wrote below:


REPORT ZREDUCE.
TYPES:
  BEGIN OF TY_SALES_ORDER_ITEM,
    MATERIAL      TYPE MATNR,
    ITEM_PRICE    TYPE NETWR_AP,
    ITEM_QUANTITY TYPE KWMENG,
  END OF TY_SALES_ORDER_ITEM,
  TYT_SALES_ORDER_ITEM TYPE STANDARD TABLE OF TY_SALES_ORDER_ITEM WITH DEFAULT KEY.

SELECT MATNR  AS MATERIAL,
        NTGEW  AS ITEM_PRICE,
        KWMENG AS ITEM_QUANTITY
        FROM VBAP
        UP TO 10 ROWS
        INTO TABLE @DATA(LT_DATA).

DATA(LT_SALES_ORDER_ITEM) = VALUE TYT_SALES_ORDER_ITEM(
                                      FOR GROUPS <GROUP_KEY> OF <GROUP> IN LT_DATA GROUP BY ( MATERIAL = <GROUP>-MATERIAL )
              LET SL_COLL_LINE = REDUCE #( INIT SL_LINE TYPE TY_SALES_ORDER_ITEM             
                                             FOR <MEMBER> IN GROUP <GROUP_KEY>
               NEXT SL_LINE-MATERIAL      = <MEMBER>-MATERIAL
                   SL_LINE-ITEM_PRICE    = ( SL_LINE-ITEM_PRICE + <MEMBER>-
                                                      ITEM_PRICE ) / 2
                   SL_LINE-ITEM_QUANTITY = SL_LINE-ITEM_QUANTITY + <MEMBER>-
                                              ITEM_QUANTITY )
                                      IN ( SL_COLL_LINE ) ) .

CL_DEMO_OUTPUT=>WRITE( LT_SALES_ORDER_ITEM ).

CL_DEMO_OUTPUT=>DISPLAY( ).

This block has 3 ( or 4 ) main points:

  1. FOR GROUP -> this is the same as LOOP AT GROUP

  2. LET coll_line = REDUCE -> the hole group will be reduced into one line

  3. FOR <m> IN GROUP <group_key> NEXT -> here we make the necessary calculation

  4. IN ( coll_line ) -> last line. We append the result line to the new table.

This piece of code is easy to be enhanced both with new values or new keys. You have complete control over it. As it can be seen, I can applay any logic needed.Though, if you are concerned about readability or complexity then a similar option is using LOOP AT GROUP. You will achieve the same result, and it will be easier to read.


Summing Values

BEGIN OF mard_sum1,
         matnr TYPE mard-matnr,
         werks TYPE mard-werks,
         labst TYPE mard-labst,
       END OF mard_sum1,
 
       mard_sum1s TYPE HASHED TABLE OF mard_sum1
                  WITH UNIQUE KEY primary_key COMPONENTS matnr werks.
 
TYPES: BEGIN OF mard_sum2,
         matnr TYPE mard-matnr,
         labst TYPE mard-labst,
       END OF mard_sum2,
 
       mard_sum2s TYPE HASHED TABLE OF mard_sum2
                  WITH UNIQUE KEY primary_key COMPONENTS matnr.
 
SELECT matnr, werks, lgort, labst FROM mard INTO TABLE @DATA(mard_entries).
 
DATA(sum1) = REDUCE mard_sum1s(
    INIT _sum = VALUE mard_sum1s( )
    FOR GROUPS _grp OF _mard_entry IN mard_entries
    GROUP BY ( matnr = _mard_entry-matnr
               werks = _mard_entry-werks )
    NEXT _sum = VALUE mard_sum1s(
         BASE _sum
         ( matnr = _grp-matnr
           werks = _grp-werks
           labst = REDUCE #(
                INIT _labst_sum TYPE mard-labst
                FOR _grp_entry IN GROUP _grp
                NEXT _labst_sum = _labst_sum + _grp_entry-labst ) ) ) ).

Tip #2 - Inline Declarations


With inline declarations, a variable can be defined where it is used for the first time, that is, where a value is assigned to it for the first time. In many places in ABAP code, the data type of a variable results from the context.

With DATA(<variable name>) a variable can be defined where it is needed.

Modern ABAP

LOOP AT <TABLE> INTO DATA(Result). 
    ...
ENDLOOP. 
 
  
Classic ABAP
DATA Result_Line LIKE LINE OF TABLE_RESULT 

LOOP AT TABLE_RESULT  INTO Result_Line. 
    ...
ENDLOOP. 

The main advantage of the inline declaration is, besides the more compact code, more flexibility. If the field list changes in the example, the data type of RESULT is automatically adjusted. Especially with JOIN operations you often don`t have a suitable structure definition either.

Modern ABAP
SELECT * 
  FROM VBAK
 INTO TABLE @DATA(Result). 
 
 
Classic ABAP
DATA Result TYPE TABLE OF VBAK.

SELECT * 
  FROM VBAK
 INTO TABLE Result. 

Field symbols can also be assigned to an existing memory area with inline declarations. Either with an ASSIGN or with the appropriate statements for accessing internal tables, such as

LOOP AT ... ASSIGNING FIELD-SYMOBL(<fs-name>). or

READ TABLE ... ASSIGNING FIELD-SYMBOL(<fs-name>) ... 


Tip #3 - Concatenation Operator &&


Two strings can be concatenated using the && operator. This is much more elegant than using CONCATENATE and also works at operand positions without an auxiliary variable.

Modern ABAP
out->write( `year ` 
                && sy-datum(4) ). 
  

Classic ABAP
DATA tmp TYPE c LENGTH 100.
CONCATENATE `year ` 
            sy-date(4) INTO tmp.
out->write( tmp ).             
Calculation assignment with &&=

When composing strings, it is often necessary to use 'append'. For example, when generating HTML.

Modern ABAP
html &&= `<b>Hello</b>`

Classic ABAP
CONCATENATE html `<b>Hello</b>`
       INTO html. 

Tip #4 - String Templates


String Templates are expressions that generate a string of characters. They consist of liters that can contain embedded expressions, formatting, and control characters. A string template starts and ends with a vertical bar |. Everything in between is constant text (=literal), unless it is an embedded expression surrounded by curly braces { ... }.

The characters {, }, | and \ must be escaped in the literal by a backslash \.

Modern ABAP
out->write( |Today: { 
    sy-date DATE = USER }| ).
Classic ABAP
DATA tmp TYPE string.
DATA theDate TYPE c LENGTH 10.

WRITE sy-date TO theDate.
CONCATENATE `Today: ` theDate INTO tmp.

out->write( tmp ). 
Expressions in String Templates

In curly braces { ... }, expressions can be embedded directly into the string template. This can be used to call a functional method or perform a calculation, for example. Nice examples of this can be found in the box about the constructor expressions COND and SWITCH.

Formatting

The appearance of the expressions can be customized using the formatting options. The most important ones are

  • WIDTH = <length> - width in characters

  • ALIGN = <alignment> - Either LEFT, RIGHT or CENTER

  • DATE = USER - format the date according to the user master record, see above

  • TIME = USER - The same for the time

  • ALPHA = IN/OUT - Alpha conversion

Control characters in String Templates

The control characters
  • \n - Line Feed

  • \r - Carriage Return and

  • \t - Tabulator

can be used directly in String Templates. So you can easily create multiline texts without using CL_ABAP_CHAR_UTILS=>CR_LF:

out->write( |Hello\r\nWorld| ).

Tip #5 - Enumerations


With enumerations, we have type-safe enumeration types. This means that with the enumeration, a datatype is also defined. And it is checked at design time if the data type is correct for assignments and method calls. So only the values that have been defined can be used.

Definition of an Enumeration
TYPES: BEGIN OF ENUM eColour,
          Red,
          ...
          Orange,
          Violet,
        END OF ENUM eColour.
Enumeration usage
DATA MyColour TYPE eColor.

" MyColour = 0. "Gives an error.
MyColour = Red .
Grouping in a structure

Since sometimes many constant values need to be defined, it is possible to group the individual components of an enumeration in a structure. This makes it easier to find the correct values. The access is the same as for a constant structure: MyColour = Colour-Red

definition with structure
TYPES: 
    BEGIN OF ENUM eColour STRUCTURE Colour,
      Red,
      ...
      Orange,
      Violet,
    END OF ENUM eColour STRUCTURE Color.
Fixed values and other data types.

Normally the data type I is used internally and values are assigned from 0 to N. However, this can also be changed manually. The data type can be up to 8 characters long. It is also important that for a constant always the value IS INITIAL is used.

TYPES ColourDef TYPE c LENGTH 7.
TYPES: BEGIN OF ENUM eColour
            STRUCTURE Colour
              BASE TYPE ColourDef,

         Black VALUE IS INITIAL,
         Red VALUE '#ff0000',
         Green VALUE '#00ff00',
         Blue VALUE '#0000ff',

       END OF ENUM eColour
            STRUCTURE Color.
Value and enum type

Since a direct value assignment is not possible or leads to the wrong result in one direction, a conversion with the constructor operator CONV is always required for storing the values in the database (or for all interfaces):

DATA MyColour TYPE eColour.
DATA ColourHex TYPE ColourDef.

"Wrong content 'GREEN':
ColourHex = Colour-green.

" Correct content '#00ff00' :
ColourHex = conv #( Colour-Green ).

" Syntax error:
" MyColour = '#00ff00'.

" Correct assignment:
MyColour = conv #( '#00ff00' ). 

Tip #6 - Constructor Expressions


Constructor expressions create a new (data) object of a specific (data) type. So-called constructor operators are used for this purpose. These cover a variety of very different use cases. However, they always have the following syntax in common:

<ConstructorOperator> <DataType>( <Parameter> ).

A simple example: use the VALUE operator to create an internal table with fixed contents.

DATA tt_tadir TYPE STANDARD TABLE OF tadir.
DATA ObjectCatalog TYPE tt_tadir.

ObjectCatalog = VALUE tt_tadir( ( obj_name = 'ZCL_CLASS' object = 'CLAS' )
                                ( obj_name = 'MARA' object = 'TABL' ) ).
The data type and the hash character #

Depending on the situation, the appropriate data type is specified, e.g. a data element, a table type, a structure type or a class name.

If the data type can be derived from the context, then it does not need to be specified. Instead, the # character is used. This is the case, for example, with an assignment.

Readability of constructor expressions

Some operators can perform very complex logic. For this purpose, constructor expressions can also be nested within each other. The code quickly becomes confusing. It is therefore recommended to calculate only simple logic in constructor expressions. For complex logic, classic ABAP is often more readable. There is no way to debug constructor expressions in ADTs.


 Tip #7 - Create data and objects with VALUE and NEW


The two operators create data. With VALUE you get the data directly, with NEW you get the reference to it. If no parameters are passed, both operators create empty data objects.

Create structures

If structures are created, the individual components can be passed as parameters. Unassigned components are assigned their initial value.

DATA(line) = VALUE tadir( obj_name = 'ZCL_CLASS' object = 'CLAS' ). 
Create internal tables

The individual lines of an internal table are again enclosed in round brackets.

DATA DateRange TYPE RANGE OF dats.

DateRange = VALUE #( ( sign = 'I' option = 'EQ' low = '20241031' )
                     ( sign = 'I' option = 'EQ' low = '20240406' ) ).

Common components of the individual lines can also be defined before the round brackets:

DateRange = VALUE #( sign = 'I' option = 'EQ' ( low = '20241031' )
                                               ( low = '20220406' ) ).
BASE specifies an initial value

For structures, a compatible structure can be specified before the first component with BASE, which fills the unassigned components with values.

For internal tables an internal table can be specified with BASE, which is then supplemented by the following lines. So this corresponds to an APPEND.

NewDateRange = VALUE #( BASE DateRange
                      ( sign = 'I' option = 'EQ' low = '20240101' ) ).

In the VALUE operator FOR loops are also possible. These are described in the REDUCE operator.

Create objects with NEW

Instances of classes can also be created with NEW:

NEW <class name>( <constructor parameter> )

Tip #8 - Data type change with CONV


This operator is used to easily convert data types. This is a common problem with method parameters, for example: the content of a variable matches, but the data type does not.

Modern ABAP
my_method( TEXT = CONV #( sy-datum ) ).
Classic ABAP
DATA DateText TYPE char8. 
DateText = sy-date. 
my_method( Text = DateText )

Tip #9 - Down- and upcast of reference variables with CAST


In classic ABAP, the upcast is done by simple assignment with =, the downcast with the cast operator ?=. This always requires an auxiliary variable of the appropriate type. With the CAST operator, this can be omitted in many cases:

Modern ABAP
DATA Task TYPE zbc_tasks.     

DATA(Components) = cast cl_abap_structdescr( 
                          cl_abap_typedescr=>describe_by_data( 
                              Task ) )->get_components( ).
Classic ABAP
DATA Task TYPE zbc_tasks.
DATA StructDescr TYPE REF TO cl_abap_structdescr.
DATA(TypeDescr) = cl_abap_typedescr=>describe_by_data( Task ).

StructDescr ?= TypeDescr.
DATA(Components) = StructDescr->get_components( ).

Tip #10 - Case distinctions with COND and SWITCH


These constructor expressions correspond to the CASE expression in SQL. Simple case distinctions depending on a single field are implemented with SWITCH:

Modern ABAP
out->write( 
  |Hello { SWITCH #( User-Gender
                    WHEN 'F' THEN 'Mrs.'
                    WHEN 'M' THEN 'Mr.'
                    ELSE '' )
              } { User-Lastname } | ).
              
Classic ABAP
DATA salutation TYPE string.

CASE user-gender.
  WHEN 'F'.    Salutation = 'Mrs.'.
  WHEN 'M'.    Salutation = 'Mr'.
  WHEN OTHERS. Salutation = ''.
ENDCASE.

out->write( |Hello { Salutation  
                  } { user load name }| ).

More complex distinctions with arbitrary conditions are made with COND:

out->write( |The status is { COND #( WHEN Priority > 3 
                                       AND DueDate <= SY-DATUM THEN 'Critical'.
                                      WHEN Priority > 2        THEN 'Medium
                                                               ELSE 'Low' ) }|.

Tip #11 - Create Internal Tables with the FILTER operator


The FILTER operator can be used to create internal tables based on another internal table by filtering. Either via a simple WHERE clause or based on another table. Basically, the table type and key must be optimized for filtering, otherwise there will be syntax errors.

FILTER with WHERE clause
DATA lt_data TYPE sorted TABLE OF I_CountryText WITH UNIQUE KEY LANGUAGE COUNTRY.
SELECT * FROM i_countrytext INTO TABLE @lt_data.

out->WRITE( FILTER #( lt_data WHERE LANGUAGE = 'D' ) ).
FILTER with IN ... WHERE

Here we filter for another internal table. This corresponds to an INNER JOIN in SQL.

DATA lt_data TYPE sorted TABLE OF I_CountryText WITH UNIQUE KEY COUNTRY.    
DATA(lt_filter) = VALUE tt_demo( ( COUNTRY = 'ES' )
                                  ( COUNTRY = 'US' ) ).
SELECT * FROM i_countrytext WHERE LANGUAGE = 'S' INTO TABLE @lt_data.

out->WRITE( FILTER #( lt_data IN lt_filter WHERE COUNTRY = COUNTRY ) ).

Tip #12 - The CORRESPONDING Operator


This operator is reminiscent of the MOVE-CORRESPONDING statement. It can be used for structures as well as for internal tables. The CORRESPONDING operator can be used to create another data object from a structured data object, i.e. an internal table or a structure, and to take over the values of identical fields. This is similar to the MOVE-CORRESPONDING statement.

Basic form of CORRESPONDING

The data is copied to fields with the same names. Fields that do not exist in the source remain empty in the destination.

TasksSmall = corresponding #( TasksOriginal ).
Explicit MAPPING and EXCEPT

If the components do not have exactly the same name but should still be copied to each other, or if individual components should not be copied, this can be specified explicitly with the MAPPING and EXCEPT additions:

TaskSmall = corresponding #( TaskOriginal
                                MAPPING id    = task_id
                                        title = summary
                                EXCEPT assignee ).

With BASE initial values are given, see VALUE operator. This is used to prefill the values for structures or set additional lines at the beginning for internal tables.


CORRESPONDING with lookup table

This variant performs a lookup to another internal table. This corresponds to a LEFT OUTER JOIN with a :1 cardinality. As with the FILTER operator, this only works if the table type and key definition match the join condition in the USING clause.

DATA Lookup TYPE HASHED TABLE OF I_CountryText WITH UNIQUE KEY Country.
DATA(Original) = VALUE tt_demo( ( Country = 'ES' )
                                ( Country = 'US' ) ).
SELECT * FROM I_CountryText WHERE LANGUAGE = 'S' INTO TABLE @Lookup.

DATA(Result) = CORRESPONDING tt_demo( Original FROM Lookup
                                      USING country = Country
                                      MAPPING country_text = CountryName ).

Tip #13 - Predicative Method Calls

Behind the unwieldy term Predicative Method Call  lies a simple concept that is standard in (almost) all other programming languages: a method call as a predicate, e.g. it is used directly in an IF statement. Since in ABAP the values TRUE and FALSE are not clearly defined, the following definition applies: If the return value of a functional method (i.e. with RETURNING ) is initial, the predicate is logically FALSE, otherwise TRUE. Thus, it corresponds to IF method( ) IS NOT INITIAL.

Modern ABAP
IF isRelevant( ).
  ...
ENDIF.
Classic ABAP
IF isRelevant( ) EQ abap_true.
  ...
ENDIF.

Tip #14 - Table Expressions


Even if the name suggests otherwise, table expressions provide us a row of a table. In SQL, therefore, they would be called row expressions.

They are not copies of the row, but the row in the table. Therefore, write operations on table expressions also modify the table. So they can replace READ ... INTO and READ ... ASSIGNING statements.

Construction of table expressions: <table>[ <RowSpecification> ]

The table can be any internal table. The row specification is enclosed in square brackets and can be done in several ways: By specifying the row number for standard tables, a free key or the table key.

Modern ABAP
* Copy of the first row 
DATA(row) = users[ 1 ]. 
 
* Change the first name of the 1st row
users[ 1 ]-firstname = 'Sergio'.   


* Change Maria last name
users[ firstname = 'Maria'
          ]-lastname = 'Pan'. 

Classic ABAP
DATA row LIKE LINE OF users.
READ TABLE users INTO row INDEX 1.

FIELD SYMBOLS <row> LIKE LINE OF users. 
READ TABLE users ASSIGNING <row> INDEX 1. 
<row>-firstname = 'Edgar'. 

FIELD SYMBOLS <row> LIKE LINE OF users. 
READ TABLE users ASSIGNING <row>. 
           WITH firstname = 'PEdro'. 
<row>-lastname = 'Pan'. 

Accessing non-existent lines will generate an exception CX_SY_ITAB_LINE_NOT_FOUND.

Modern ABAP
* Changing sergio's last name
TRY.
  users[ firstname = 'Sergio' 
               ]-lastname = 'Pan'. 
CATCH CX_SY_ITAB_LINE_NOT_FOUND. 

ENDTRY. 
Classic ABAP
* Changing Sergio last name
FIELD SYMBOLS <row> LIKE LINE OF users. 
READ TABLE users ASSIGNING <row>. 
           WITH firstname = 'Sergio'. 
IF sy-subrc = 0. 
  <row>-lastname = 'Pan'.
ENDIF.  

Alternatively, for read access, use the VALUE operator to create a default value or mark the access as OPTIONAL.

...VALUE #( <table>[<RowSpecification>] 
             DEFAULT <AlternativeValue> | OPTIONAL )

Tip #15 - New Group Level Processing


The classic group level processing with AT NEW/END depends on the sorting of the data and the order of the columns. Both must fit exactly. Thus it is error-prone and sometimes hardly usable. The new group level processing solves this problem by nested LOOPs.

Modern ABAP
LOOP AT tl_materials
     INTO DATA(Grouping)
     GROUP BY ( material = Grouping-material )
     INTO DATA(Grp).                     
" A            
  LOOP AT GROUP Grp
          INTO DATA(sl_Material). 
" B   
  ENDLOOP.         
" C
ENDLOOP. 
Classic ABAP
LOOP AT PlantMats 
     INTO DATA(sl_material).
  AT NEW material.
" A
  ENDAT.
" B
  AT END OF material.
" C
  ENDAT.

ENDLOOP.


Other example : Description

Grouping of an internal table flights with the assignment of a group key. The group key of the group loop is constructed as a structure. In it, the values of the columns carridor cityfromeach row of the internal table are assigned to the components carrierand cityfr. In this way, groups of rows are created that have the same value in these columns. In addition, the components sizeand indexare created for the special language elements GROUP SIZEor GROUP INDEXto determine the size and index of each group.

The group key, associated with a reference variable group_ref, and additional components are generated in the group loop. In a member loop, the rows of each group are placed in an internal table membersusing the value operator with the sum BASE. These rows are also displayed.

memberscan also be completed by evaluating a table by understanding sing FOR ... IN GROUP, rather than in a loop of members LOOP AT GROUP:

members = VALUE #( FOR <flight> IN GROUP group_ref ( <flight> ) ).

The executable example for grouping withFOR demonstrates how the entire group loop can be implemented using expressions.

DATA(out) = cl_demo_output=>new( ).

    out->begin_section( `Flights` ).
    out->write( flights ).
    out->begin_section( `Grouping` ).
    DATA members LIKE flights.
    LOOP AT flights INTO DATA(flight)
         GROUP BY ( carrier = flight-carrid cityfr = flight-cityfrom
                    size = GROUP SIZE index = GROUP INDEX )
                  ASCENDING
                  REFERENCE INTO DATA(group_ref).
      out->begin_section(
        |Group Key: { group_ref->carrier }, { group_ref->cityfr }| ).
      out->write(
        |Group Size: {  group_ref->size  }, | &&
        |Group Index: { group_ref->index }| ).
      CLEAR members.
      LOOP AT GROUP group_ref ASSIGNING FIELD-SYMBOL(<flight>).
        members = VALUE #( BASE members ( <flight> ) ).
      ENDLOOP.
      out->write( members )->end_section( ).
    ENDLOOP.

    out->display( ).

Tip #16 - ABAP CLOUD


Tutorials for ABAP Cloud


The ABAP Cloud best practices are documented in the form of step-by-step tutorials for learning how to develop and deploy full-stack transactional and analytical applications using the ABAP RESTful Application Programming Model (RAP) and embedded analytics.

The exercises are based on the Travel sample application of the Flight Reference Scenario that is the best practice example for developing, deploying, and operating a full-stack application using ABAP RESTful Application Programming Model (RAP) and SAP Fiori.

You can also go through the Develop a Full-Stack RAP Application Following the SAP BTP Developer’s Guide that is based on the Travel sample application. This mission has three main parts. The first part contains the RAP100 basics, for building an SAP Fiori application with RAP. The second part is for creating, developing, and integrating an SAP Fiori application. The third part builds on top of RAP100 basics and contains the intermediate tutorials, with additions such as dynamic feature control and ABAP unit tests.

Analytical Scenario

The analytical scenario shows the end-to-end development of an analytical application. It consists of a business service exposing an analytical query and a report built with SAP Analytics Cloud. The analytical report can be used to analyze complex situations and freely interact with large amounts of data in real time.

The analytical scenario is provided in the form of tutorials with beginner and intermediate experience levels.

Transactional Scenario

The transactional scenario shows the end-to-end development of a transactional SAP Fiori elements list report application. It consists of an OData-based business service built with RAP and an SAP Fiori elements-based UI. It also shows the deployment of the SAP Fiori application in the ABAP environment and its integration in the local SAP Fiori launchpad for SAP BTP, ABAP environment.

You will develop a simple, transactional list report application, the Travel Processing application, that is used by a department responsible for processing worldwide travel for multiple agencies.

The transactional scenario built with RAP is provided as a tutorial mission, which is divided into three tutorial groups with beginner and intermediate experience levels.

The following beginner tutorial groups are available for the transactional scenario:

The advanced exercises of the transactional scenario are provided as a tutorial group. They are built on top of the exercises of the beginner tutorial groups.

Build an SAP Fiori App Using the ABAP RESTful Application Programming Model (RAP) – Intermediate [RAP100]:

The Develop and Consume Queries on SAP Analytics Cloud beginner tutorial is available for the analytical scenario.

The Develop Queries Based on Booking Supplement and Consume on SAP Analytics Cloud tutorial covers the advanced exercises of the analytical scenario.

 
 
 

Comments


bottom of page