Global. Lokal. Egal.
Im Rahmen eines Projektes haben wir uns mit der dynamischen Erzeugung von Klassen beschäftigt und Stefan hat dabei einen netten Trick herausgefunden.
Globale Klasse
Normalerweise gibt es in einem Report nur die folgenden zwei Möglichkeiten um eine Klasse zu instantiieren:
- Ein Objekt mit Referenz zu einer global definierten Klasse (SE24)
- Ein Objekt mit Referenz zu einer im selben Programm definierten lokalen Klasse
Stefan hat nun eine Möglichkeit gefunden, wie man lokale Klassen, die in beliebigen Programmen definiert sind, erzeugen kann. Und das geht so:
Lokale Klasse
Wir brauchen ein Programm mit einer lokal definierten Klasse. In dem folgenden Programm werden zwei lokale Klassen definiert. Beide haben die Methode INFO.
REPORT zttloc01. CLASS lcl_local_01 DEFINITION. PUBLIC SECTION. METHODS info RETURNING VALUE(text) TYPE string. ENDCLASS. CLASS lcl_local_01 IMPLEMENTATION. METHOD info. text = 'Ich bin Klasse 01'. ENDMETHOD. ENDCLASS. CLASS lcl_local_02 DEFINITION. PUBLIC SECTION. METHODS info RETURNING VALUE(text) TYPE string. ENDCLASS. CLASS lcl_local_02 IMPLEMENTATION. METHOD info. text = 'Ich bin Klasse 02'. ENDMETHOD. ENDCLASS.
Dynamische Erzeugung von Klasseninstanzen
Wenn man den Namen einer Klasse erst zur Laufzeit ermitteln kann, dann kann man ein Objekt dieser Klasse dynamisch wie folgt erzeugen:
DATA classname TYPE string. DATA object TYPE REF TO object. classname = 'ZCL_CLASS_XYZ'. CREATE OBJECT object TYPE (classname).
Sinnvoller Weise verwendet man hierfür ein Interface, dass alle in Frage kommenden Klassen implementiert haben.
Ihr Auftritt Herr Kollege
Unser Trick besteht nun darin, dass wir den Klassennamen genauer spezifizieren. Wir geben dem Klassennamen die Information mit, in welchem Programm die Klasse vorhanden ist. Der Klassenname sieht dann zum Beispiel wie folgt aus:
\PROGRAM=ZTTLOC01\CLASS=LCL_LOCAL01
Wir müssen also nur noch die intern verwendete Struktur zusammenbasteln. Das folgende Programm erzeugt je nach Auswahl ein Objekt der im Programm ZTTLOC01 lokale definierten Klasse LCL_LOCAL_01 oder LCL_LOCAL_02.
REPORT zttlocaccess. PARAMETERS p_01 RADIOBUTTON GROUP cls DEFAULT 'X'. PARAMETERS p_02 RADIOBUTTON GROUP cls. PARAMETERS p_repid TYPE syrepid DEFAULT 'ZTTLOC01'. START-OF-SELECTION. DATA classname TYPE string. DATA r_object TYPE REF TO object. DATA text TYPE string. CASE 'X'. WHEN p_01. classname = 'LCL_LOCAL_01'. WHEN p_02. classname = 'LCL_LOCAL_02'. ENDCASE. CONCATENATE '\PROGRAM=' p_repid '\CLASS=' classname INTO classname. CREATE OBJECT r_object TYPE (classname). CALL METHOD r_object->('INFO') RECEIVING text = text. MESSAGE text TYPE 'I'.
Screenshot
Das rufende Programm muss natürlich genau wissen, was es tut. Je nachdem wie dynamisch der Aufruf einzelner Methoden sein soll, können ebenfalls dynamisch ermittelte Parameter über die Parameterliste übergeben werden.
Verwendet man ein Interface, dass die zu verwendenden Klassen implementieren, dann kann man verwendete Interface-Methoden direkt aufrufen.
- Interview mit Björn Schulz (Software-Heroes.com) - 3. September 2024
- Daten aus ALV ermitteln - 3. September 2024
- So lange es den SAPGUI noch gibt… - 27. Juni 2024
super, vielen Dank