Die Herausforderung: Was passiert mit bestehenden ABAP-Programmen in der Cloud?
Im Rahmen einer Migration wollen oder müssen Sie Ihre SAP-Lösung (ERP oder BW) in eine Cloud-Umgebung bringen (S/4HANA Public Cloud, BTP ABAP Environment, SAP BW-Bridge) und stellen sich die Frage, was mit ABAP-Programmen passieren soll, deren Funktionen weiterhin benötigt werden.
Ein SAPGUI mit auf Dynpros basierenden Dialogen gibt es nicht mehr und damit auch keine Selektionsbildschirme für ABAP-Programme.
Insbesondere müssen Lösungen für ABAP-Programme mit Selektionsbildschirmen gefunden werden, die in der neuen Umgebung einen ähnlichen Umgang (Eingabe, Speicherung, Änderung und Aufruf) ermöglichen – und das ohne auf SAPUI5 oder SAP Fiori umsteigen zu müssen.
Eine Entwicklung mit SAPUI5 und SAP Fiori ist grundsätzlich möglich, bedeutet aber einen erhöhten Aufwand bei der Implementierung, die Einarbeitung in eine neue Entwicklungsumgebung und die Einbindung in das Fiori-Launchpad.
In diesem Artikel wird eine Möglichkeit vorgestellt, um mit Hilfe der Cloud-Version von NextTables Selektionsvarianten zu pflegen und dann für ausgewählte Varianten die bewährte Funktionalität direkt aus NextTables heraus aufzurufen.
Auch für den Aufruf innerhalb einer Prozesskette wird eine Lösung vorgestellt.
Welcher Lösungsansatz ermöglicht die Weiterverwendung bestehender ABAP-Programme?
Der folgende Ansatz zeigt, wie ABAP-Kode weitgehend beibehalten werden kann.
- Die im ABAP-Programm verwendeten Selektionen, abgelegt als Varianten, werden in 1 oder 2 Datenbank-Tabellen gespeichert. Für Selektions-Optionen werden 2 Tabellen benötigt.
- Die Tabellen werden mit NextTables gepflegt.
- Das ehemalige ABAP-Coding wird in eine Klasse übernommen und lässt sich direkt aus NextTables heraus für eine Variante aufrufen. Dabei müssen kleinere Unterschiede zwischen ABAP und ABAP Cloud beachtet werden.
- Fehlermeldungen werden als Meldungsboxen angezeigt.
Soll der Prozess im Hintergrund laufen, kann die Klasse unter Umständen auch aus einer Prozesskette heraus aufgerufen werden und greift auf die Tabellen mit den Varianten zu.
Das ‘Look and Feel’ der vorgestellten Lösung ähnelt dem der alten Lösung mit ABAP-Programmen und bietet dieselbe Funktionalität.
Anwender müssen nicht das Fiori-Launchpad benutzen, NextTables ist direkt über eine URL erreichbar.
Die Entwickler können weiter ihre ABAP-Kenntnisse nutzen und müssen nicht auf die Frontend-Entwicklung mit Fiori umsteigen.
Der Selektionsbildschirm des zu migrierenden Programms mag wie folgt aussehen:
Selektionsbildschirm im alten System (Dynpro)
Es gibt mehrere Einzelfelder, Feldpaare, einen Schalter, einen Bereich und eine Selektionsoption.
Bis auf die Selektionsoption kann man alle zur Selektion benötigten Felder in eine Tabelle aufnehmen. Um die Möglichkeit einer Selektionsoption abzuspeichern, benötigt man eine weitere Tabelle.
In NextTables kann man dann den Item-Tabellentyp wählen, um beide Tabellen zu verbinden.
Erfassen einer Variante in der neuen Lösung in NextTables.
Für die zweite Variante werden die Selektionsoptionen in einer zweiten Tabelle gepflegt. Diese ist durch die Beziehung auf die Variante 2 vorgefiltert. Zu dieser lassen sich Untervarianten mit unterschiedlichen Selektionen anlegen.
Über eine zusätzlich eingefügte Schaltfläche lässt sich die Verarbeitung der selektierten Variante starten.
Gegebenenfalls werden am Ende Meldungen zur Verarbeitung angezeigt.
Um die Verarbeitung im Hintergrund laufen zu lassen, kann ein kundeneigener Prozesstyp genutzt werden. Dieser ruft eine Klasse mit der angegebenen Variante auf.
Schritt für Schritt zur Cloud: so läuft die Implementierung ab
Domänen, Datentypen und Tabellen.
Zuerst werden einige Domänen und Datentypen angelegt.
Data element |
Domain |
Type |
Length |
Description |
ZSL_VARIANT |
ZSL_VARIANT |
NUMC |
4 |
Selection variant |
ZSL_SUBVAR |
ZSL_SUBVAR |
NUMC |
3 |
Sub-variant for selection |
ZSL_SIGN |
ZSL_SIGN |
CHAR |
1 |
Sign |
ZSL_OPTION |
ZSL_OPTION |
CHAR |
2 |
Possible select option |
ZSL_OBJNM |
ZSL_OBJNM |
CHAR |
20 |
Object name |
RSSOURSYSID |
RSSOURSYSID |
CHAR |
2 |
Source system ID |
/BI0/OIMANDT |
/BI0/OIMANDT |
NUMC |
3 |
Client |
ZSL_ATTR |
ZSL_ATTR |
INT4 |
10 |
Attribute value |
ZSL_BOOL |
ZSL_BOOL |
CHAR |
1 |
Flag |
ZSL_DATEFROM |
ZSL_DATEFROM |
DATS |
8 |
Date from |
ZSL_DATETO |
ZSL_DATETO |
DATS |
8 |
Date to |
Das Definieren von Domänenfestwerten für ZSL_SIGN und ZSL_OPTION erleichtert die Eingabe und vermeidet Fehler.
Einige wichtige Domänen.
Die Einzelwerte der Selektion werden in der Tabelle ZSL_PAR gespeichert.
@EndUserText.label : 'Parametzer selection header'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
Define table zsl_par {
Key variant : zsl_variant not null;
Qsys : rssoursysid;
Client : mandt;
Object1 : zsl_objnm;
Object2 : zsl_objnm;
Attr1 : zsl_attr;
Attr2 : zsl_attr;
Deltaflag : zsl_bool;
Vfrom : zsl_datefrom;
Vto : zsl_dateto;
}
Die Tabelle zur Aufnahme der Selektionsoptionen hat folgende Struktur:
@EndUserText.label:'Select options'
@AbapCatalog.enhancement.category:#NOT_EXTENSIBLE
@AbapCatalog.tableCategory:#TRANSPARENT
@AbapCatalog.deliveryClass:#A
@AbapCatalog.dataMaintenance:#RESTRICTED
Define table zsl_par_sel {
Key variant : zsl_variant not null;
Key subvar : zsl_subvar not null;
sign : zsl_sign;
Seloption : zsl_selopt;
unam_low : zsl_objnm;
unam_high : zsl_objnm;
}
NextTables in Aktion – so gelingt die Konfiguration
Nach dem Aufruf von NextTables wird zuerst eine neue Konfiguration für die Tabelle ZSL_PAR_SEL angelegt (nur, wenn Selektionsoptionen benötigt werden). Wie Sie neue Konfigurationen anlegen erfahren Sie unter der NextTables Knowledge Base.
Danach wird die Konfiguration für die Tabelle ZSL_PAR angelegt. Benötigt man ZSL_PAR_SEL, ist es dabei wichtig, im Bereich Eigenschaften die Felder ‘Item Tabellentyp’ und ‘Item_Tabellenname’ zu füllen. Das führt zu der unten gezeigten speziellen Darstellung.
Definition eines Item-Tebellentyps
Programmfunktionalität migrieren – ohne den Code neu zu schreiben
Die Programmfunktionalität wird in eine Klasse übertragen. In dieser Klasse bildet eine Methode die aufzurufende Schnittstelle, im Beispiel ist das die Methode substitute_report. Diese muss 2 Parameter haben. Über i_variant wird die Variante an die Methode übergeben, an ct_messages können Meldungen angehängt werden. Die Meldungen werden später konvertiert und in NextTables angezeigt.
Die Methode liest zuerst die Selektion aus der übergebenen Variante und führt dann die migrierte Funktionalität aus. In der Praxis wird man einige Fehlermeldungen hinzufügen.
CLASS zslcl_migrated_report DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION .
TYPES:
" types to process the tables ZSA_PAR and ZSL_PAR_SEL
ty_zsl_par TYPE zsl_par , "
tt_zsl_par TYPE STANDARD TABLE OF zsl_par , "
ty_zsl_par_sel TYPE zsl_par_sel , "
tt_zsl_par_sel TYPE STANDARD TABLE OF ty_zsl_par_sel . "
CLASS-METHODS substitute_report
IMPORTING i_variant TYPE ZSL_VARIANT
CHANGING ct_messages TYPE rspc_t_msg .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zslcl_migrated_report IMPLEMENTATION .
METHOD substitute_report .
DATA:
ls_msg TYPE rspc_s_msg , "
ls_zsl_par TYPE ty_zsl_par , "
lt_zsl_par_sel TYPE tt_zsl_par_sel , "
lt_rs_msg TYPE rspc_t_msg , " Messages received
l_variant TYPE string . "
FIELD-SYMBOLS:
TYPE ANY TABLE , " Receive the selected rec's
TYPE zsl_par . " One record
" Read variant data.
SELECT SINGLE * FROM zsl_par
WHERE variant EQ @i_variant
INTO @ls_zsl_par .
IF sy-subrc EQ 0 .
" Read item table.
CLEAR lt_zsl_par_sel .
SELECT * FROM zsl_par_sel
WHERE variant EQ @ls_zsl_par-variant
INTO TABLE @lt_zsl_par_sel .
ELSE .
" Can occur, if method was called from a process chain.
" Error message
ls_msg-msgid = '/NLY/TABLE_REST' . " Use your message class.
ls_msg-msgno = '000' . " generic message
ls_msg-msgty = 'E' . " Information
ls_msg-msgv1 = |Variant { i_variant } is unknown. Check table ZSL_PAR.| .
APPEND ls_msg TO ct_messages .
RETURN .
ENDIF .
" Transform the selection into select-options or other structures
" The coding of the former report goes here.
" ...
" In case of errors, fill up ct_messages.
" Sample message that will be displayed in NextTablers.
ls_msg-msgid = '/NLY/TABLE_REST' . " Use your message class.
ls_msg-msgno = '000' . " generic message
ls_msg-msgty = 'I' . " Information
ls_msg-msgv1 = 'ZSLCL_MIGRATED_REPORT=>SUBSTITUTE_REPORT' .
ls_msg-msgv2 = | was called for variant { i_variant }.| .
APPEND ls_msg TO ct_messages .
ENDMETHOD .
ENDCLASS .
Ist die SAP BW Bridge ein cleverer Übergang - oder doch nur ein Umweg?
Laden Sie hier das Whitepaper herunter!
Nun muss noch das Editor-BAdI von NextTables erweitert werden. Wird schon eine aktive BAdI-Implementierung genutzt, kann diese erweitert werden. Dann muss nur der Filter angepasst werden. Für das vorgestellte Beispiel wird eine neue Implementierung angelegt.
Zwei Dinge sind zu tun. Es muss mindestens eine neue Schaltfläche eingeführt werden, um die implementierte Methode zslcl_migrated_report=>substitute_report aufzurufen. Im Beispiel wird ein neues Menü ‘Drop down menue’ angelegt, in dem es die Schaltfläche ‘Method with report implementation’ gibt. Das wird in der Methode set_button_data gemacht, welche in /nly/if_editor~set_meta_exit aufgerufen wird.
In der Methode /nly/if_editor~set_update_exit wird die Betätigung der Schaltfläche behandelt. Die implementierte Klasse wird aufgerufen. Die erhaltenen Meldungen werden in das NextTables-Format konvertiert und ausgegeben. Wurden mehrere Zeilen selektiert, dann wird die Klasse in einer Schleife mehrfach aufgerufen.
CLASS zslcl_nt_editor_badi_sample DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES if_badi_interface
ALL METHODS ABSTRACT .
INTERFACES /nly/if_badi_editor . " For NextTables
INTERFACES /nly/if_editor . " For NextTables
" To convert standard messages to NextTable messages to be displayed.
CLASS-METHODS msg_to_nt_msg
IMPORTING it_msg TYPE rspc_t_msg
EXPORTING et_message TYPE /nly/tt_message .
PROTECTED SECTION.
PRIVATE SECTION.
CLASS-METHODS set_button_data
IMPORTING
!i_tabname TYPE /nly/de_tabname
CHANGING
!ct_table_info TYPE /nly/ts_table_info .
ENDCLASS .
CLASS zslcl_nt_editor_badi_sample IMPLEMENTATION.
METHOD /nly/if_editor~set_data_exit .
" We do not need to do anything in this method for our sample.
ENDMETHOD .
METHOD /nly/if_editor~set_meta_exit .
* ******************************************************************************
* ** In this method we set the button data for our sample.
* ******************************************************************************
set_button_data( EXPORTING i_tabname = i_tabname
CHANGING ct_table_info = ch_s_table_info
) .
ENDMETHOD .
METHOD /nly/if_editor~set_update_exit .
DATA:
ls_zsl_par TYPE zslcl_migrated_report=>ty_zsl_par , " param. record
l_variant TYPE zsl_variant , "
lt_rs_msg TYPE rspc_t_msg , " Messages received
ls_nt_msg TYPE /nly/ts_message , " Message in NextTables format
lt_nt_msg TYPE /nly/tt_message , " Messages in NextTables format
l_count TYPE i .
FIELD-SYMBOLS:
TYPE ANY TABLE , " To receive the selected rec's
TYPE zsl_par . " One record
CASE i_tabname .
WHEN 'ZSL_PAR' .
CASE i_button .
WHEN 'METHOD_1' .
CHECK i_step = 1 .
CLEAR: lt_rs_msg , ct_messages, l_count .
" Read selected records
ASSIGN co_table->* TO .
LOOP AT ASSIGNING .
l_variant = -variant .
" Call the processing class for every record.
" Your class here.
zslcl_migrated_report=>substitute_report(
EXPORTING
i_variant = l_variant
CHANGING
ct_messages = lt_rs_msg
) .
l_count = l_count + 1 .
ENDLOOP .
" Check received messages.
IF lt_rs_msg IS NOT INITIAL .
" Convert messages into NextTables style.
CLEAR lt_nt_msg .
msg_to_nt_msg(
EXPORTING it_msg = lt_rs_msg
IMPORTING et_message = lt_nt_msg
) .
APPEND LINES OF lt_nt_msg TO ct_messages .
CLEAR lt_rs_msg .
ENDIF .
" Add confirmation message.
ls_nt_msg-type = /nly/cl_table_rest_v3=>co_msg_type_success .
ls_nt_msg-visu_type = /nly/cl_table_rest_v3=>co_visu_type_modal .
ls_nt_msg-hdr = 'Method call.' .
ls_nt_msg-msg = |Method ZSLCL_MIGRATED_REPORT=>| &
|SUBSTITUTE_REPORT was called | &
|{ l_count } time(s).| .
APPEND ls_nt_msg TO ct_messages .
e_skip = 'X'.
WHEN OTHERS .
ENDCASE . " button
WHEN OTHERS .
ENDCASE . " table name
ENDMETHOD .
METHOD set_button_data .
" Add button in the top of the layout.
" Buttons are table specific.
CASE i_tabname .
WHEN 'ZSA_PAR' .
ct_table_info-buttons = VALUE #( BASE ct_table_info-buttons
( name = 'NO_ACTION_T'
descr = 'Drop down menue'
icon = 'copy'
action = /nly/cl_table_rest_v3=>co_action_no_action
location = /nly/cl_table_rest_v3=>co_location_top
tooltip = 'Call any kind of method.'
)
( name = 'METHOD_1'
descr = 'Method with report implementation'
icon = 'copy' " could be a different icon
action = /nly/cl_table_rest_v3=>co_action_send_sel
location = /nly/cl_table_rest_v3=>co_location_top
sort_order = '0'
parent = 'NO_ACTION_T'
tooltip = 'Call method 1 with parameters'
)
( name = 'METHOD_2'
descr = 'Another method (yet empty)'
icon = 'paper-plain' " could be a different icon
action = /nly/cl_table_rest_v3=>co_action_send_sel
location = /nly/cl_table_rest_v3=>co_location_top
sort_order = '1'
parent = 'NO_ACTION_T'
tooltip = 'Call method 2 with parameters'
)
) .
WHEN OTHERS .
ENDCASE .
ENDMETHOD .
METHOD msg_to_nt_msg .
DATA:
ls_msg TYPE rspc_s_msg , " Standard message
ls_message TYPE /nly/ts_message . " Message in NextLytics format
LOOP AT it_msg INTO ls_msg .
MESSAGE ID ls_msg-msgid TYPE ls_msg-msgty NUMBER ls_msg-msgno
WITH ls_msg-msgv1 ls_msg-msgv2 ls_msg-msgv3 ls_msg-msgv4
INTO DATA(l_e_msg) .
CASE ls_msg-msgty .
WHEN 'E' .
CLEAR ls_message .
ls_message-type = /nly/cl_table_rest_v3=>co_msg_type_error .
ls_message-visu_type = /nly/cl_table_rest_v3=>co_visu_type_modal .
ls_message-hdr = 'Fehler' .
WHEN 'W' .
CLEAR ls_message .
ls_message-type = /nly/cl_table_rest_v3=>co_msg_type_warning .
ls_message-visu_type = /nly/cl_table_rest_v3=>co_visu_type_modal .
ls_message-hdr = 'Warnung' .
WHEN 'I' .
CLEAR ls_message .
ls_message-type = /nly/cl_table_rest_v3=>co_msg_type_info .
ls_message-visu_type = /nly/cl_table_rest_v3=>co_visu_type_modal .
ls_message-hdr = 'Information' .
ENDCASE .
ls_message-msg = l_e_msg .
APPEND ls_message TO et_message .
ENDLOOP .
ENDMETHOD .
ENDCLASS .
Die BAdI-Implementierung muss zum Enhancement-Spot registriert werden. Der Aufruf-Filter muss für die Parametertabelle angepasst werden und die Erweiterung muss aktiviert werden.
Mehr zur Verwendung von BAdis, um NextTables zu erweitern,gibt es auf der NextTables Knowledge Base.
Flexibel bleiben: Aufruf über kundenspezifische Prozesstypen
In der ‘alten’ Umgebung kann man ABAP-Programme mit einer Variante aufrufen. Mit einem eigenen Prozesstyp geht das auch in einer Cloud-Umgebungen, sofern es möglich ist, eigene Prozesstypen zu definieren.
- Aufruf des Pflegedialogs: Bridge-Cockpit --> Entwicklung BW Bridge -> Configuration ->Custom Prozesstypen
2 Anlegen eines neuen Prozesstyps.
3 Anlegen der Klasse, die den Prozesstyp implementiert.
Definition eines eigenen Prozesstyps
Hinweis: In der Methode if_rspc_simple_process_type~get_user_interface werden die Parameter festgelegt, die dem Prozesstyp mitgegeben werden können. Die aufgerufene Methode bestimmt, welche Parameter benötigt werden.
Hier werden die Klasse, die Methode und die Nummer der Variante benötigt.
Die aufgerufene Methode muss folgende Schnittstelle beinhalten:
CLASS-METHODS substitute_report
IMPORTING i_variant TYPE ZSL_VARIANT
CHANGING ct_messages TYPE rspc_t_msg .
Die einfachste Prozesskette hat nur einen Prozessschritt:
Aufruf einer Methode in einer Prozesskette
Der Methodenaufruf ist folgendermaßen parametriert:
Parameter des Methodenaufrufs (mit Variante).
Migration bestehender ABAP-Programme in SAP-Cloud-Umgebungen: Unser Fazit
Mit diesem Ansatz gelingt es, bewährte ABAP-Funktionalitäten zukunftssicher in Cloud-Umgebungen zu überführen, ohne sie komplett neu entwickeln zu müssen.
Das spart Entwicklungszeit, Kosten und minimiert Projektrisiken – bei gleichzeitig hoher Anwenderakzeptanz.
Wir begleiten Sie gern auf dem Weg in die Cloud – von der Analyse Ihrer bestehenden ABAP-Landschaft über die technische Umsetzung bis zur produktiven Integration in S/4HANA, die SAP BTP oder BW Bridge.
Haben Sie Fragen zu einem anderen Thema? Nehmen Sie einfach Kontakt zu uns auf - wir freuen uns auf den Austausch mit Ihnen!
FAQ
Im wesentlichen, ja. In der BTP wird zwar ABAP Cloud verwendet aber der größte Teil des ABAP-Kodes läuft dort ebenfalls. SQL-Befehle müssen manchmal umgestellt werden und einige Funktionen wie Konvertierungsexits, Zeitfunktionen oder der Zugriff auf Systemvariablen müssen angepasst werden. Der Zugriff auf systemeigene Tabellen ist eingeschränkt.
Das hängt von der Lizenz ab. Bei entsprechender Lizenz ist die Anzahl nicht begrenzt.
NextTables wird über eine URL aufgerufen. Die kann wo immer möglich eingebaut werden oder im Browser direkt eingegeben oder als Lesezeichen gespeichert werden.
Wie bei jedem anderen Prozesstyp auch. Die aufgerufene Methode kann Meldungen im Standardformat erzeugen. Diese werden an den Prozessketten-Monitor übergeben.
Ja, in NextTables kann man ein entsprechendes Menü mit mehreren Schaltflächen definieren. Jede Schaltfläche kann eine andere Methode für die selektierte Variante aufrufen.
Ja, das ist im Koding schon vorgesehen.
SAP Data Warehouse, SAP BW Bridge
