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
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.
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
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.
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