anthyiaconsulting

ABAP Tutorial

Chapter I Overview

1 Gentle Introduction to ABAP

a Hello World, Comments, Germanness

Like your boss, the ABAP compiler does not listen to your comments. Comments are something you tell yourself to better understand the code you wrote. Assume that you do not understand yesterday’s code and comment copiously.

ABAB offers the following comments:

  • 1. asterisk comment: *

  • 2. quotation mark comment: "

1     REPORT z_abapfordummies_001.
2     * ABAP sucks my sorry soul out of my half-deceased body
3     Write 'Hello World'. "ABAP works !!! It is the greatest thing
4     * since the invention of sliced bread

Listing I.1: The two ways of commenting in ABAP

A programming language invented in Germany finishes expressions with a dot. The dot in Write 'Hello World'. is intentional, if you miss it, the German ABAP compiler will beat your code to a pulp.

Your program has to start with a REPORT, furthermore you have to name your report starting with a z, see how we named our program z_abapfordummies_001. Your ABAP file has to have the name of your report plus .ABAP. Why ? you ask me dear reader. Do not ask so much or I will kill this book project before it even has seen the light of day.

Being germanely obese, SAP needs a lot of space; in fact it needs all the space an alphabet has to offer from A to X. For the poor user, the SAP masters only permit using Y and Z. Again if you name your brain-children other than starting with a letter like Y or Z, the SAP compiler will kill your code. Since I am lazy, the following code snippets will remain un-christened.

b Variable Declaration
1 DATA: lv_text TYPE string ,
2 lv_zahl TYPE int1 VALUE 3.
3 DATA( lv_text2 ) = ' I am some text . ' .
4 DATA(lv_zahl2 ) = 3.
Listing I.2: How to declare variables

It is considered good ABAP style to name your variables as follows:

lv_name-of-local-variable
ls_name-of-local-structure
lt_name-of-local-table
gv_name-of-global-variable
gs_name-of-global-structure
gt_name-of-global-table

.

c Structures and tables

You first need to declare a structure before you can create a table. The structure is like a row in a table, telling ABAP what type of data to expect and how to call them by name.

As you can see a structure definition starts with DATA: and continues with BEGIN OF before you are allowed to name your structure.

1 DATA: BEGIN OF ls_bike ,
2   amount_tyre TYPE int1 ,
3   amount_gears TYPE int1 ,
4 END OF ls_bike .
5 ∗ Now we can   declare   a table .
6 DATA lt_bike LIKE TABLE OF ls_bike .

Here comes something cool: the chain rule. instead of starting each declaration with its own DATA statement, we can start a bunch of declarations, using DATA: and separating your declarations with a comma.

1
2 DATA: lt_bikes TYPE zob_tt_001,
3 ∗ table   type zob_tt_001 has    already    been    declared
4           ls_bikes   TYPE zob_st_001.
5 ∗ structure    type zob_st_001 has      already    been   declared
Listing I.3: Declaration of a structure, a table, and the chain rule

In lines 4 - 7 we declare a structure called ls_bike, our structure has 2 components

  • 1. amount_tyre TYPE int1,

  • 2. amount_gears TYPE int1,

Difference between TYPE and LIKE

LIKE refers to a previous variable or data-structure definition, TYPE creates a new one.

d Loops

ABAP offers 3 types of loops:

  • 1. WHILE

  • 2. DO TIMES

  • 3. LOOP AT

DO X TIMES
1 ∗Do something x times ( in our case 5 times
2 DO 5 TIMES.
3   WRITE 'Just do it ' .
4 ENDDO.
LOOP AT
1 "Loop
2 LOOP AT lt_bike INTO ls_bike .
3     " ls_bike     is a     structure      and lt_bike    is the   table
4     " over which we loop .
5     ls_bike −amount_gears = 5.
6     MODIFY lt_bike FROM ls_bike . "you use modify to modify a table .
7 ENDLOOP.
8 ∗     ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
9 LOOP AT lt_bike ASSIGNING FIELD−SYMBOL(<fs>).
10     " Zugriff     der     Spalten     der   Zeile :
11     < fs > −amount_gears = 3.
12 ENDLOOP.
13
14 ∗      ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
15 ∗ It    is     possible    to   filter      results   by using a
16 ∗ WHERE in a LOOP AT loop
17
18 "LOOP AT ... WHERE ...
WHILE

WHILE means: do something until a condition is met

1 WHILE lv_zahl = 3.
2 ∗do something
3   WRITE 'My sister        is   stupid ' .
4 ∗ according      to Linus   Torvalds   that   is the   first   program he ever   wrote
5 ∗ his   sister    denies
6
7   lv_zahl += 2.
8 ENDWHILE.

VEERY IMPORTANT in the While loop you must do something with the condition, otherwise you will create an infinite loop, i.e. a program that never stops

e Branching

The naming of if and case statements as branching probably comes from flow diagrams.

(image)

Figure I.1
IF
1    DATA( lv_color ) = ' Blue ' .
2    DATA(lv_age) = 3.
3
4    IF    lv_color = ' Red ' .
5     "Do this when lv_color = Red
6    ELSEIF lv_color = ' Blue ' AND lv_age = 5.
7     "Do this when lv_color = Blue and lv_age = 5
8    ELSEIF lv_age     < > 2.
9     "Tu dies wenn lv_age      nicht   gleich   2
10    ELSE.
11        "Tu dies wenn keins   der oberen
12    ENDIF.
CASE
1   CASE lv_color .
2    WHEN 'Red'.
3    "Do this when lv_color = Red
4    WHEN 'Yellow ' .
5    "Do this when lv_color = Yellow
6    WHEN OTHERS.
7    "Do this when    lv_color    is none of the above
8   ENDCASE.
1 "SELECT−Statement
2   SELECT
3   FROM sflight
4   FIELDS
5     " =>   alle   Spalten ,   alternativ   die
6   WHERE carrid < > ' AA' " Optionale   Bedingun
7   INTO TABLE @DATA(lt_flight_1) .
Example of SELECT statement
1
2
3    SELECT
4     carrid ,
5     connid ,
6     currency
7    FROM sflight
8    INTO TABLE @DATA(lt_flight_2) .
9    "wenn die   Tabelle   bereits   existiert   dann :
10    INTO CORRESPONDING FIELDS OF TABLE @lt_tablle
SELECT SINGLE

With SELECT␣SINGLE we will only get one row of the table.

1
2
3
4   SELECT SINGLE
5   FROM sflight
6   FIELDS
7     " =>   alle   Spalten ,   alternativ   die
8   INTO @DATA( ls_flight ) .
f Field Symbols
1    " Declaration    of a    field   symbol
2    FIELD−SYMBOLS: < fs_deklartion > TYPE int1 .
3    DATA:     lv_deklaration    TYPE int1 VALUE 5.
4
5    " declaration    and    reference    to a   variable
6    DATA: lv_name TYPE aenam VALUE 'Hans' .
7    FIELD−SYMBOLS: <fs_name> TYPE aenam. " Deklaration
8    ASSIGN lv_name TO < fs_name > . " Zuweise
9    < fs_name > = ' XX' . "ÃĆÂĺAndert von < fs_name > und lv_name
10    lv_name = ' Z ' . "ÃĆÂĺAndert von \ < fs_name\ > und lv_name
11
12
13    " Deklaration    + Verweis      auf ein    Tabellenvaraiable
14    DATA:     lt_airline   TYPE STANDARD TABLE OF scarr.
15    FIELD−SYMBOLS: < fs_line_of_airline > LIKE LINE OF                    lt_airline .
16
17    SELECT "TODO: Tabelle           befüllen
18     FROM scarr
19     FIELDS
20     INTO CORRESPONDING FIELDS OF TABLE @lt_airline
21     UP TO 10 ROWS.
22
23    LOOP AT lt_airline        ASSIGNING <      fs_line_of_airline   > .
24     " ...
25    ENDLOOP.
26
27    LOOP AT lt_airline        ASSIGNING FIELD−SYMBOL(< fs_line_of_airline_2 > ) .
28    " ...
29    ENDLOOP.
30
31    LOOP AT lt_airline        ASSIGNING < fs_line_of_airline_2        > .
32    ENDLOOP.
g READ Befehl
1
2
3
4 "READ TABLE < tabelle > INTO < struktur > WITH (TABLE) KEY < Spalte > = ' < variable > ' .
5    DATA:     ls_line_of_airline     TYPE scarr .
6    SELECT "TODO: Tabelle          befüllen
7     FROM scarr
8     FIELDS
9     INTO TABLE @DATA( lt_airline3 )
10    UP TO 10 ROWS.
11   READ TABLE lt_airline3 ASSIGNING FIELD−SYMBOL(< fs_line_of_airline3 > ) INDEX 3.
12   IF <     fs_line_of_airline3     > IS ASSIGNED. "Daten wurden gefunden
13    WRITE <      fs_line_of_airline3      > −carrname .
14   ENDIF.
15
16   READ TABLE lt_airline3 INTO               ls_line_of_airline   WITH KEY carrid = ' AA' .
17
18
19
20   IF sy − subrc = 0. "Daten wurden gefunden
21    WRITE      ls_line_of_airline −carrname .
22   ELSE.
23    WRITE 'Nothing found ' .
24   ENDIF.

h Sorting
1    ORDER BY: um im SELECT−Statement die Daten zu    sortieren
2    SORT BY: um interne   Tabelle   zu   sortieren
3    SORT < Tabelle > BY < Spalte > [ DESCENDING|ASCENDING].
4    SELECT "TODO: Tabelle   befüllen
5     FROM scarr
6     FIELDS
7     ORDER BY carrname DESCENDING,
8     url ASCENDING
9     INTO TABLE @DATA( lt_airline4 )
10    UP TO 10 ROWS.
11   SELECT
12    FROM scarr
13    INTO TABLE @DATA(lt_2)
14    ORDER BY carrname DESCENDING.
15   SORT lt_airline4   BY carrid ASCENDING.

i Filling structure and table
1 ∗ Zeilen       einer   Tabelle      einfügen / ändern
2 ∗ INSERT und APPEND
3 " INSERT: Fügt eine neue               Zeile    an einer     passenden / beliebigen          Stelle   ein
4 " APPEND: Fügt eine neue               Zeile am ende der           Tabelle    hinzu
5
6    ls_bike −amount_gears = 3.
7    ls_bike −amount_tyre = 1.
8    APPEND ls_bike TO lt_bike .
9    APPEND VALUE #( amount_gears = 1
10     amount_tyre = 2
11     ) TO lt_bike .
12   APPEND VALUE #( ( amount_gears = 1 amount_tyre = 2 )
13     ( amount_gears = 5 amount_tyre = 2 )
14     ) TO lt_bike .
15
16    ls_bikes − farbe = ' color ' .
17    ls_bikes − lenker = ' Supi ' .
18   APPEND ls_bikes TO lt_bikes .
19   APPEND VALUE #( farbe = 'Rot '
20     lenker = ' OMG'
21     ) TO lt_bikes .
22
23   DATA:       lt_airline4        TYPE STANDARD TABLE OF scarr,
24      ls_airline4      LIKE LINE OF        lt_airline4 .
25   SELECT
26    FROM scarr
27    FIELDS
28    ORDER BY carrname DESCENDING,
29     url ASCENDING
30    INTO CORRESPONDING FIELDS OF TABLE @lt_airline4
31    UP TO 10 ROWS.
32
33     ls_airline4 − carrid = ' BB' .
34     ls_airline4 −carrname = ' B ... B ... ' .
35     ls_airline4 − currcode = ' EUR'.
36
37   APPEND ls_airline4 TO               lt_airline4 .
38   APPEND VALUE #(
39     carrid     = ' XX'
40     carrname = ' X ... X ... '
41     currcode = ' USD'
42     url = ' sdf@lksdfj '
43     ) TO      lt_airline4 .
44
45   CLEAR ls_airline4 . " Struktur               leeren
46     ls_airline4 − carrid = ' DD'.
47     ls_airline4 −carrname = ' D ... D ... ' .
48     ls_airline4 − currcode = ' EUR'.
49
50   INSERT        ls_airline4      INTO TABLE lt_airline4 .
51   INSERT VALUE #(
52     carrid     = ' ZZ '
53     carrname = ' Z ...          Z ... '
54     currcode = ' USD'
55     ) INTO TABLE lt_airline4 .
56
57   INSERT VALUE #(
58     carrid     = ' ZZ '
59     carrname = ' Z ...          Z ... '
60     currcode = ' USD'
61     ) INTO       lt_airline4      INDEX 4.
62
63   "MODIFY und UPDATE
64   " MODIFY: Wenn die Zeile               existiert       ändere    sie
65   " UPDATE: Wenn die Zeile               existier       ändere    sie ,   ansonsten   leg   sie neu an
66   CLEAR ls_airline4 .
67     ls_airline4 −carrname = ' B ...              Blue ' .
68
69   MODIFy lt_airline4             FROM ls_airline4        INDEX 2.
70
71     " Index     unnötig     in    einer Loop
72   UPDATE lt_airline4             FROM ls_airline4 .
j Messages to the user
1 " Nachricht   ausgeben
2 "Typen : A = Abbruch , E = Error , I = Information , S = Status , W = Warnung, X = Exit
3 " abhängig vom Typ wird      entweder   ein Pop Up geöffnet    oder
4 " die   Nachricht   wird in der    Statusleiste    angezeigt
5
6    MESSAGE ' Hilfe ' TYPE 'I ' .
7    MESSAGE ' Hilfe ' TYPE 'I ' DISPLAY LIKE 'E' .
8
9 " Nachricht   aus   einer   Nachrichtenklasse     aufrufen
10
11 MESSAGE s000(z_ob_msg_cl_000).
12 MESSAGE e000(z_ob_msg_000). "Typ Fehler
13 MESSAGE s001(z_ob_msg_000). "Typ Erfolg
14 MESSAGE i001(z_ob_msg_000). "Typ Infromation , Pop Up
15
16 DATA( lv_test ) = ' Test ' .
17 MESSAGE s001(z_ob_msg_cl_000).
18 MESSAGE s002(z_ob_msg_cl_000) WITH lv_test ' ! ' .
k Boolean
1 " abap_bool ;       xfeld ;   boolean
2 "Abap_bool :
3 " X = abap_true = wahr
4 " = abap_false = falsch
5 " − unklar
6    DATA: lv_is_true TYPE abap_bool.
7    WRITE 'TEst' .
8    "wahr
9    lv_is_true = ' X' .
10    lv_is_true = abap_true .
11 " falsch
12   lv_is_true = " .
13    lv_is_true = abap_false .
14    " unklar
15    lv_is_true = ' −' .
16
17 " Beispiel :
18   DATA:       lv_is_smaller_six    TYPE abap_bool VALUE 'X' .
19   DATA( lv_result ) = 0.
20   WHILE lv_is_smaller_six          = abap_true .
21     IF    lv_result   > 5.
22      lv_is_smaller_six       = abap_false .
23     WRITE lv_is_smaller_six .
24     CONTINUE.
25     ENDIF.
26
27     WRITE lv_result .
28     WRITE lv_is_smaller_six .
29
30      lv_result    = lv_result     + 1.
31   ENDWHILE.
l Tabellenarten
1
2
3     DATA: lt_standard TYPE TABLE OF mara,
4      lt_standard2        TYPE STANDARD TABLE OF mara,
5      lt_sorted     TYPE SORTED TABLE OF mara WITH UNIQUE DEFAULT KEY,
6      lt_hashed TYPE HASHED TABLE OF mara WITH UNIQUE KEY matnr.
7
8 "STANDARD:
9 "     Indexzugriff
10 "        Schlüsselzugriff
11 " Non−Unique Key
12 " APPEND
13 " INSERT −> Datensatz          wird angehangen
14 "SORTED
15 "        Indexzugriff
16 "        Schlüsselzugriff
17 " Non−Unique Key & Unique Key
18 " INSERT −> Laut           Schlüsselfeld   eingefügt ,   sortiert
19 "HASHED
20 "        Schlüsselzugriff
21 " Unique Key
22 " INSERT −> Laut           Schlüsselfeld   eingefügt
23
24     Typ Ermittlung
25
26     SELECT
27      FROM MARA
28      FIELDS
29      INTO CORRESPONDING FIELDS OF TABLE @lt_sorted.
30
31
32
33     "Das Hash− Behaviour wird       erst zu   Laufzeiten    bestimmt
34
35     IF    lt_sorted [] IS NOT INITIAL
36      AND lt_sorted [ 1 ]− tabclass       = ' HASHED'.
37     ENDIF.
m Konstanten
1
2
3 Werte die zu    Laufzeit   nicht mehr   verändert   werden können
4
5 CONSTANTS: lv_test TYPE int1 VALUE 4.
6
7 DATA: lv_t TYPE int1 VALUE 2.
8
9    lv_t = lv_test .
10
11   WRITE lv_test .

n REDUCE
1    ∗ siehe           auch
2    ∗ https :// help . sap . com/doc/abapdocu_751_index_htm /7.51/ en−us/            abenconstructor_expression_reduce   . htm
3
4    ∗Example : Sum
5    DATA: lt_numbers TYPE STANDARD TABLE OF i,
6    lv_sum TYPE i.
7
8
9
10   " Tabelle           befüllen
11    lt_numbers = VALUE #( ( 1 ) ( 2 ) ( 3 ) ( 4 ) ( 5 ) ) .
12    cl_demo_output => display ( lt_numbers ) .
13
14
15
16   "Summe ermitteln
17   lv_sum = REDUCE i(
18       INIT counter = 0
19       FOR num IN lt_numbers
20       NEXT counter = counter + num ) .
21
22   WRITE lv_sum.
23
24
25
26
27
28   "        Beispiel        Fibonacci    Zahlen
29           Stringtabelle          erstellen
30   DATA( it_fib ) = REDUCE stringtab (
31           Initialwerte
32       INIT ret = VALUE stringtab ( (                |0|    ) (   |1|   ) )
33       x TYPE string
34       y TYPE string
35
36       100      Durchläufe
37       FOR n = 1 WHILE n < 101
38           letztes    und      vorletztes     Element der    Liste      ermitteln
39       NEXT x = ret [           lines ( ret ) ]
40       y = ret [        lines ( ret ) − 1 ]
41
42       addieren und an             bestehende     Liste    anfügen
43
44       ret = VALUE #( BASE ret
45
46       ( x +y )
47
48       )
49
50       ).
51
52
53
54       Ausgabe
55
56    cl_demo_output => display (                it_fib    ).
57