[ABAP] Grundaufbau ABAP-Programm / Ereignisse

* globaler Deklarationsteil
TYPES ... " Definitionen
DATA ...  " Datenobjekte
CLASS ... " Klassen

* Implementierungsteil mit Ereignisblöcken
* Ereignis beim Laden eines Programms in die interne Sitzung
LOAD-OF-PROGRAM.
  " häufig für Autorisierungsabfrage genutzt

* Ereignis vor Prozessierung des Selektionsbildes
INITIALIZATION.
  " hier können z.B. dynamische Vorbelegungen vorgenommen werden

* Ereignis vor Anzeige des Selektionsbildschirms
AT SELECTION-SCREEN OUTPUT.
  " Parameter auf reine Anzeige setzen

* Ereignis bei Eingabeprüfung für Einzelfelder
AT SELECTION-SCREEN ON Feldname.

* Ereignis für F1-Hilfe bei einem Feld
AT SELECTION-SCREEN ON HELP-REQUEST FOR Feldname.
 " z.B. bei Druck auf Taste F1 in Eingabefeld

* Ereignis für F4-Hilfe bei einem Feld
AT SELECTION-SCREEN ON VALUE-REQUEST FOR Feldname.
  " z.B. bei Aufruf von File-Open-Dialogen o.ä.		

* Ereignis, wenn Benutzer die Funktionen "Zurück", "Beenden", Abbrechen" wählt
AT SELECTION-SCREEN ON EXIT-COMMAND.
 
* während der Abarbeitung des Selektionsbildschirms
AT SELECTION-SCREEN.
  " hier werden keine WRITE-Ausgaben prozessiert
  " hier zum Beispiel:
  "   AUTHORITY-CHECK ...
  "   MESSAGE ...

* Ereignis während Prozessierung des Selektionsbildes
START-OF-SELECTION.
  " WRITE wird erst am Ende der kompletten Abarbeitung des Ereignisses prozessiert

* Ereignis bei dem der Benutzer einen im Programm definierten Funktionscode auslöst
AT USER-COMMAND.
  " häufig für CASE ...
  " oder LOOP AT SCREEN INTO ...

* Ereignis zu dem der Benutzer den vordefinierten Funktionscode PICK (Mausklick) auslöst
AT LINE-SELECTION.
  " auf KLicks reagieren
  "   WRITE: / 'Verzweigungsliste Nr.: ', sy-lsind.
  "   WRITE: / 'Absolute Nummer der Zeile: ', sy-lilli.
  "   WRITE: / 'Inhalt der Zeile: ', sy-lisel.
  "   WRITE: / 'Row: ', sy-curow.
  "   WRITE: / 'Col: ', sy-cucol.

* Ereignisse während der Listenverarbeitung, wenn eine neue Seite begonnen wird
TOP-OF-PAGE.
  " und
TOP-OF-PAGE DURING LINE-SELECTION.
  " z.B. zur formatierten Ausgabe von Listenüberschriften
  "   WRITE: 'Nr.', 15 'NAME1', 25 'NAME2'.

[ABAP] Parameter mit Auswahlbereich (SELECT-OPTIONS)

Variante 1 (DATA)

DATA: lv_matnr TYPE matnr.

* Parameterfeld von ... bis mit Dictionary-Type
SELECT-OPTIONS: so_matnr FOR lv_matnr DEFAULT '0000000001' TO '1000000000'.

START-OF-SELECTION.

* so_matnr ist eine itab mit Kopfzeile
  IF lines( so_matnr ) > 0.
* erstes Element der itab ausgeben
    WRITE: / so_matnr[ 1 ]-sign, so_matnr[ 1 ]-option, so_matnr[ 1 ]-low, so_matnr[ 1 ]-high.
  ENDIF.

Variante 2 (sy-datum)

* von 01.01.1999 bis Systemdatum
SELECT-OPTIONS: so_date FOR sy-datum DEFAULT '19990101' TO sy-datum.

START-OF-SELECTION.

* so_date ist eine itab mit Kopfzeile
  IF lines( so_date ) > 0.
* erstes Element der itab ausgeben
    WRITE: / so_date[ 1 ]-sign, so_date[ 1 ]-option, so_date[ 1 ]-low, so_date[ 1 ]-high.
  ENDIF.

Variante 3 (INITIALIZATION)

SELECT-OPTIONS: so_date FOR sy-datum.

INITIALIZATION.
* Initialwerte für so_date setzen
  so_date[] = VALUE #( ( sign   = 'I'
                         option = 'BT'
                         low    = sy-datum - 5
                         high   = sy-datum
                       )
                     ).

START-OF-SELECTION.
* so_date ist eine itab mit Kopfzeile
  IF lines( so_date ) > 0.
* erstes Element der itab ausgeben
    WRITE: / so_date[ 1 ]-sign, so_date[ 1 ]-option, so_date[ 1 ]-low, so_date[ 1 ]-high.
  ENDIF.

Variante 4 (TABLES)

* Zugriff Tabellenobjekt aus dem Dictionary deklarieren,
* automatische Verknüpfung der Suchilfe auch zu and. Objekten des Selektionsbildschirms
* obsolet (sollte nicht mehr verwendet werden)
TABLES: mara.

* Parameterfeld von ... bis mit Dictionary-Type
SELECT-OPTIONS: so_matnr FOR mara-matnr DEFAULT '0000000001' TO '1000000000'.

START-OF-SELECTION.

* so_matnr ist eine itab mit Kopfzeile
  IF lines( so_matnr ) > 0.
* erstes Element der itab ausgeben
    WRITE: / so_matnr[ 1 ]-sign, so_matnr[ 1 ]-option, so_matnr[ 1 ]-low, so_matnr[ 1 ]-high.
  ENDIF.

[ABAP] Einfacher Parameter (Labeled Edit)

PARAMETERS: p_mypar1 TYPE c LENGTH 2 DEFAULT 'AB'.        " einfacher Parameter mit Vorgabewert
PARAMETERS: p_mypar2 TYPE dicttype-var DEFAULT 'XY'.      " einfacher Parameter mit Dictionary-Type mit Suchhilfe, Langtext usw.
PARAMETERS: p_mypar3 TYPE string OBLIGATORY DEFAULT 'DE'. " einfacher Parameter mit Defaultwert und als Pflichteingabefeld
PARAMETERS: p_mypar4 TYPE i OBLIGATORY DEFAULT '1000'.

oder

PARAMETERS: p_mypar TYPE transparentetabelle-spalte DEFAULT 'XY'. " Spalte aus transparenter Tabelle (Dictionary Objekt) nutzen mit Suchhilfe, Langtext usw.

[ABAP] OpenSQL verwenden

Beispiel 1

DATA: it_tab TYPE itabtype,        " itab definieren
      ls_line LIKE LINE OF it_tab, " Zeile der itab definieren
      name TYPE string.

INITIALIZATION.
  name = 'test'.

* zwei Spalten aus Tabelle 'mytable' holen und in Datenelement 'ls_line' speichern
  SELECT spalte1, spalte2 FROM mytable INTO @ls_line WHERE spalte3 = @name.
    WRITE: / ls_line-element1.
    APPEND ls_line TO it_tab. " Zeile an itab anfügen
  ENDSELECT.

* Fehlerabfrage
  IF sy-subrc <> 0.
    RAISE EXCEPTION TYPE cx_list_error. " hier mal eine Systemexception werfen
  ELSE.
    ...
  ENDIF.

Beispiel 2

DATA: it_tab TYPE itabtype,        " itab definieren
      ls_line LIKE LINE OF it_tab, " Zeile der itab definieren
      name TYPE string.

INITIALIZATION.
  name = 'test'.

* zwei Spalten aus Tabelle 'mytable' holen und in itab 'it_tab' speichern
  SELECT spalte1, spalte2 FROM mytable INTO TABLE @it_tab WHERE spalte3 = @name.

* Fehlerabfrage
  IF sy-subrc <> 0.
    RAISE EXCEPTION TYPE cx_list_error. " hier mal eine Systemexception werfen
  ELSE.
* durch die Elemente der itab loopen
    LOOP AT it_tab INTO ls_line.
      WRITE: / ls_line-element1.
    ENDLOOP.
  ENDIF.

Weiterführende Infos: Link

[ABAP] Verwendung von Feldsymbolen (Zeiger)

* Zeilentyp
TYPES: BEGIN OF ty_data,
         name TYPE string,
         ort TYPE string,
       END   OF ty_data.

* Tabellentyp
TYPES: ty_it_itab TYPE STANDARD TABLE OF ty_data WITH DEFAULT KEY.

* Tabelle
DATA: it_itab TYPE ty_it_itab.

* Feldsymbol definieren
FIELD-SYMBOLS: <fs_line> TYPE ty_data.

* Beispielausgabe 1 mit Feldsymbol
LOOP AT itab ASSIGNING <fs_line>.
  WRITE: / <fs_line>-name, <fs_line>-ort.
ENDLOOP.

* Beispielausgabe 2 mit Inline-Feldsymbol
LOOP AT itab ASSIGNING FIELD-SYMBOL(<fs_inline>).
  WRITE: / <fs_inline>-name, <fs_inline>-ort.
ENDLOOP.

[ABAP] Strings ersetzen

* Variante 1 (REPLACE, alle Vorkommen von '!' mit '.')
DATA: s TYPE string VALUE 'Test!'.
REPLACE ALL OCCURRENCES OF '!' IN s WITH '.'.
WRITE: / s.

* Variante 2 (replace, 1 Zeichen an der Stelle 4)
DATA(res) = replace( val = 'Test!' off = 4 len = 1 with = '.' ).
WRITE: / res.

* Variante 3 (replace, das erste Vorkommen von '-')
DATA(rep) = replace( val = '1-2' sub = '-' with = '+' ).
WRITE: / rep.

* Variante 4 (replace, alle Vorkommen von '*')
DATA(rep) = replace( val = '*test*' sub = '*' with = '%' occ = 0 ).
WRITE: / rep.

[ABAP] Nachrichtenklassen pflegen

Nachrichtenklasse anlegen

  • SE91 (Nachrichtenpflege)

oder

  • SE80 (Object Navigator)->Paket->Rechtsklick->Anlegen->Weitere (1)->Nachrichtenklasse

oder

  • im Code auf den neu eingegebenen Klassennamen hinter ‘MESSAGE …’ doppelklicken

danach

  • in der Tabelle die Kurztexte (000…) zur Nachrichtenklasse editieren
  • Es können max. 4 Platzhalter ‘&’ oder explizit ‘&1’, ‘&2’, ‘&3’, ‘&4’ eingefügt werden, die später beim Aufruf des Textes mit Variablenwerten gefüllt werden können.
  • evtl. Haken bei ‘Selbserklärend’ setzen
  • evtl. Langtext über Button ‘Langtext’ pflegen
  • Button “Sichern” (Diskette) und “Aktivieren” (Streichholz) nicht vergessen

[ABAP] Messages ausgeben

Messagetypen

Typ  Bezeichnung  Bedeutung

A    Abbruch      Anzeige der Nachricht in einem Dialogfenster. Die gesamte Transaktion wird nach der Bestätigung durch ENTER abgebrochen.
E    Error        Anzeige der Nachricht in der Statuszeile. Nach der Bestätigung durch ENTER wird der aktuelle Ereignisblock abgebrochen und die Anzeige der vorhergehenden Listenstufe bleibt bestehen. Während der Erstellung der Grundliste wird das gesamte Programm abgebrochen.
I    Information  Anzeige der Nachricht in einem Dialogfenster. Nach der Bestätigung durch ENTER wird die Verarbeitung hinter der MESSAGE-Anweisung wieder aufgenommen.
S    Status       Anzeige der Nachricht in der Statuszeile der momentan erstellten Liste.
W    Warnung      siehe E
X    Exit         Dieser Nachrichtentyp löst einen Laufzeitfehler aus und erzeugt einen Kurzdump.

Codebeispiele

* Beispiele
* Popup-Message des Typs 'E' (Fehler)
MESSAGE 'Nachricht.' TYPE 'I' DISPLAY LIKE 'E'.
* Popup-Message vom Typ 'I' (Information)
MESSAGE 'Text.' TYPE 'I'.

* Message in der Statuszeile vom Typ 'E' (rot)
MESSAGE 'Nachricht.' TYPE 'S' DISPLAY LIKE 'E'.
* Message in der Statuszeile vom Typ 'W' (gelb)
MESSAGE 'Nachricht.' TYPE 'S' DISPLAY LIKE 'W'.
* Message in der Statuszeile (grün)
MESSAGE 'Nachricht.' TYPE 'S'.

* Nachrichtentext Nr. 004 der Nachrichtenklasse 'mymessageclass', Typ 'I' (Information) mit Parameter v1
MESSAGE i004(mymessageclass) TYPE 'I' WITH v1.
* Nachrichtentext Nr. 004 der Nachrichtenklasse 'MYMESSAGECLASS' (Großschreibung!), Typ 'I' (Information)
MESSAGE ID 'MYMESSAGECLASS' TYPE 'I' NUMBER '004'.
* Fehlermessage komplett in der Statusleiste anzeigen
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 DISPLAY LIKE 'E'.
* Fehlermessage in String konvertieren
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO DATA(lv_message_str).
WRITE: / lv_message_str.

sy-msg in String

* Variante 1
DATA(lv_msg) = |{ sy-msgv1 } { sy-msgv2 } { sy-msgv3 } { sy-msgv4 }|.
WRITE: / lv_msg.

* Variante 2
DATA(lv_msg) = ||.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO lv_msg.
WRITE: / lv_msg.

Weiterführender Link: Link

[ABAB] Struct (Datentyp) definieren

Einfaches Beispiel

* Definition
TYPES: BEGIN OF s_adresse,
         knr(8)  TYPE n,
         name    TYPE string,
         vorname TYPE string,
         plz(5)  TYPE n,
         ort     TYPE string,
       END OF s_adresse.

* Variable vom Typ
DATA: adresse TYPE s_adresse.

* Zugriff
adresse-knr = '1234'.
adresse-name = 'Hoffmann'.
adresse-vorname = 'Horst'.
adresse-plz = '01069'.
adresse-ort = 'Dresden'.

* Ausgabe
WRITE:  / adresse-knr,
        / adresse-name,
        / adresse-vorname,
        / adresse-plz,
        / adresse-ort.

Verschachtelung von Structen

TYPES: BEGIN OF s_type1,
         num TYPE i,
         name TYPE string,
       END OF s_type1.

TYPES: BEGIN OF s_type2,
         col TYPE i,
         text TYPE string,
       END OF s_type2.

TYPES: BEGIN OF s_mystruct,
         a TYPE s_type1,
         b TYPE s_type2,
       END OF s_mystruct.