[ABAP] Transienter Code / Dynamisch ABAP-Code generieren und ausführen

DATA: progname TYPE program.
DATA: msg TYPE string.
DATA: lin TYPE i.
DATA: wrd TYPE string.
DATA: off TYPE i.
DATA: mid TYPE trmsg_key.
DATA: sid TYPE string.

DATA(it_code) = VALUE stringtab( ( |PROGRAM SUBPOOL.| )
                                 ( |CLASS main DEFINITION.| )
                                 ( |  PUBLIC SECTION.| )
                                 ( |    CLASS-METHODS show| )
                                 ( |      IMPORTING| )
                                 ( |        i_txt TYPE string| )
                                 ( |      RETURNING VALUE(ret_val) TYPE string.| )
                                 ( |ENDCLASS.| )
                                 ( |CLASS main IMPLEMENTATION.| )
                                 ( |  METHOD show.| )
                                 ( |    WRITE: / i_txt.| )
                                 ( |    ret_val = \|\{ i_txt \} - Return value.\|.| )
                                 ( |  ENDMETHOD.| )
                                 ( |ENDCLASS.| ) ).

* Subroutinen-Pool im ABAP-Speicher des akt. Programms erzeugen
* it_code wird übergeben, Programmname wird temporär vom System vergeben
GENERATE SUBROUTINE POOL it_code NAME progname MESSAGE msg LINE lin WORD wrd OFFSET off MESSAGE-ID mid SHORTDUMP-ID sid.

CASE sy-subrc.
  WHEN 0. " ok
    TRY.
* dynamischen Klassennamen ermitteln
        DATA(lv_class) = |\\PROGRAM={ progname }\\CLASS=MAIN|.
        DATA: ret TYPE string.

        WRITE: / 'Programm:', progname.
        WRITE: / 'Class:', lv_class.
        SKIP.

* statischer Methodenaufruf
        CALL METHOD (lv_class)=>show
          EXPORTING
            i_txt   = 'Static call'
          RECEIVING
            ret_val = ret.

        WRITE: / ret.

* dynamischer Methodenaufruf
        DATA o_ref TYPE REF TO object.
        CREATE OBJECT o_ref TYPE (lv_class).
        CALL METHOD o_ref->('SHOW')
          EXPORTING
            i_txt   = 'Dynamic call'
          RECEIVING
            ret_val = ret.

        WRITE: / ret.

      CATCH cx_root INTO DATA(e_text).
        MESSAGE e_text->get_text( ) TYPE 'I'.
    ENDTRY.

  WHEN 4. " Syntaxfehler
    WRITE: / msg.
  WHEN 8. " Laufzeitfehler
    WRITE: / sid.
  WHEN OTHERS.
    MESSAGE 'Unbekannter Fehler.' TYPE 'I'.
ENDCASE.

Weiterführende Infos: Link

[ABAP] Elemente des Textpools (Selektionsbildtexte) lesen / schreiben

DATA: it_text TYPE STANDARD TABLE OF textpool.

PARAMETERS: p_report LIKE sy-repid DEFAULT sy-repid.
PARAMETERS: p_lang LIKE sy-langu DEFAULT sy-langu.

START-OF-SELECTION.

* Textpool lesen
  READ TEXTPOOL p_report INTO it_text LANGUAGE p_lang.

  LOOP AT it_text ASSIGNING FIELD-SYMBOL(<fs_line>).
    WRITE: / |{ <fs_line>-id } { <fs_line>-key } { <fs_line>-entry } { <fs_line>-length }|.
  ENDLOOP.

  IF lines( it_text ) > 0.
* Eintrag ändern
    it_text[ 1 ]-entry = 'Programm DEMO1'.

* Textpool schreiben
    INSERT TEXTPOOL p_report FROM it_text LANGUAGE p_lang.
  ENDIF.

[ABAP] Funkionsbausteine zum Untersuchen von ABAP-Quellcode

GET_TABLES          " Liefert alle im Prog. verw. Tabellen (TABLES, SEGMENTS, INCLUDE STRUCTURE)
GET_GLOBAL_SYMBOLS  " Liste der globalen Daten eines Programms
GET_COMPONENT_LIST  " ABAP: Komponentenliste zu einem globalen Datenobjekt
RS_GET_ALL_INCLUDES " Bestimmt alle Includes zu einem Modulpool/Report
RS_GET_MAINPROGRAMS " Alle Rahmenprogramme ermitteln, in denen eine Include vorkommt

[ABAP] Alter / obsoleter Code

Weiterführende Infos: Link

alt / obsolet                                       neu

DATA: f1(8) TYPE d. (Längenangaben bei Datentypen)  DATA: f1 TYPE d.
FORM, PERFORM (obsolete Modularisierung)            CLASS DEFINITION, CLASS IMPLEMENTATION + Methoden (Kapselung)
CALL FUNCTION func EXCEPTIONS ...                   CLASS DEFINITION, CLASS IMPLEMENTATION + Methoden (Kapselung)
LIKE, STRUCTURE                                     TYPE, außer bei LIKE LINE OF
LOCAL                                               Verzichten auf Zugriff auf globalen Daten des Rahmenprogramms
FIELD-SYMBOLS: ...                                  LOOP AT ... ASSIGNING FIELD-SYMBOL(<...>)
READ TABLE ... INDEX 1                              itab[ 1 ]
READ TABLE ... ASSIGNING ...                        itab[ ... ]
READ TABLE ... WITH KEY type = '1'                  itab[ type = '1' ]
READ TABLE ... INTO ...                             DATA(var) = itab[ ... ].
READ TABLE ... REFERENCE INTO ...                   DATA(oref) = REF type( itab[ ... ] ).
READ TABLE ... TRANSPORTING NO FIELDS               IF line_exists( itab[ ... ] ). ... ENDIF.
REFRESH                                             CLEAR, FREE
DATA name TYPE ...                                  DATA(name) = VALUE type( ... ).
CLASS class DEFINITION LOAD.                        CLASS class DEFINITION.
INTERFACE intf LOAD.                                INTERFACE intf.
CREATE OBJECT oref EXPORTING ...                    DATA(oref) = NEW class( ... ).
OCCURS                                              Tabellen mit Kopfzeilen sind obsolet, im OO nicht mehr unterstützt
WITH HEADER LINE                                    Tabellen mit Kopfzeilen sind obsolet, im OO nicht mehr unterstützt
RANGES                                              DATA rg_name = TYPE|LIKE RANGE OF type.
MOVE                                                =
COMPUTE                                             weglassen, komplett überflüssig
PACK src TO dest                                    dest = src
TABLES                                              weglassen, komplett überflüssig, außer TABLES sscrfields.
TYPE-POOLS                                          weglassen, komplett überflüssig
DATA - COMMON PART                                  weglassen, komplett überflüssig
TABLES *                                            weglassen, komplett überflüssig
TYPE TABLE                                          TYPE ... TABLE WITH ... KEY (explizite Typisierung)
CHECK SELECT-OPTIONS.                               wird im OO nicht mehr unterstützt

READ, LOOP, INSERT, COLLECT,
APPEND, MODIFY, DELETE                              ohne INTO im OO nicht mehr unterstützt
SELECT * FROM tab.                                  ohne INTO im OO nicht mehr unterstützt, neu: SELECT ... INTO wa
LOOP AT itab.                                       ohne INTO im OO nicht mehr unterstützt, neu: LOOP AT ... INTO wa, ASSIGNING ... oder TRANSPORTING NO FIELDS
LOOP AT screen.                                     nur noch LOOP AT SCREEN INTO DATA(screen_wa).
MODIFY screen.                                      nur noch MODIFY SCREEN FROM screen_wa.
FIELDS obj.                                         ##NEEDED
"#EC ... (Pseudokommentare)                         ## ... (Pragmas)
CALL TRANSACTION ...                                CALL TRANSACTION ... WITH|WITHOUT AUTHORITY-CHECK.
CALL METHOD ...                                     weglassen, nur noch direkter Methodenaufruf
CALL DIALOG ...                                     globale Klassen oder FuBa
CALL CUSTOMER-FUNCTION ...                          CALL BADI ...
LEAVE                                               LEAVE PROGRAM, LEAVE TO TRANSACTION, LEAVE [TO] SCREEN, LEAVE LIST-PROCESSING.
><, =>, =<                                          <>, >=, <=, NE, GE, LE
IS REQUESTED                                        IS SUPPLIED
CATCH SYSTEM-EXCEPTIONS ...                         TRY ... CATCH
SEARCH itab                                         FIND IN TABLE

SELECT a b FROM tbl                                 SELECT a, b FROM tbl
  INTO CORRESPONDING FIELDS OF TABLE itab             INTO CORRESPONDING FIELDS OF TABLE @itab
  WHERE c = v1                                        WHERE c = @v1
  ORDER BY a, b.                                      ORDER BY a, b.

GUID_CREATE                                         cl_system_uuid
GUID_CONVERT                                        cl_system_uuid
SYSTEM_UUID_CREATE                                  cl_system_uuid
SYSTEM_UUID_C_CREATE                                cl_system_uuid
SYSTEM_UUID_C22_CREATE                              cl_system_uuid