The Challenge: What Happens to Your ABAP Programs During a Cloud Migration?
As part of your SAP transformation journey, you may need to move your ERP or BW system to a cloud environment such as SAP S/4HANA Public Cloud, BTP ABAP Environment, or SAP BW Bridge.
A common question arises: what happens to custom ABAP programs whose functionality remains essential but are no longer supported in the same way?
Since SAPGUI and Dynpro-based dialogs are no longer available, many legacy ABAP programs cannot be executed as before. In particular, those with selection screens for capturing and maintaining variants require a new approach to enable similar functionality in the cloud — without rebuilding everything from scratch.
While SAPUI5 or SAP Fiori could be used, they require additional development effort, new frontend skills, and Fiori Launchpad integration.
This article introduces a pragmatic approach using NextTables Cloud Edition to maintain and execute migrated ABAP logic efficiently — including integration into process chains.
The proposed solution stores program selections (variants) in one or two database tables, depending on complexity.
These tables are then maintained via NextTables, allowing users to interact with data in a familiar, intuitive way.
The approach:
The existing ABAP code is wrapped into a class, which can be executed directly from NextTables using a selected variant. This keeps the look and feel similar to the old system while maintaining the full functionality.
Users can continue using their ABAP expertise without switching to Fiori frontend development, and users can access the solution directly via URL — no Fiori Launchpad required.
The selection screen of the program to be migrated might look as follows:
There are several single fields, field pairs, a switch, a range, and a selection option.
Except for the selection option, all fields required for the selection can be stored in a single table. To store the potential combinations of a selection options, an additional table is required.
In NextTables, you can then choose the item table type to link both tables.
Maintenance of a variant in the new solution with NextTables
For the second variant, the selection options are maintained in a second table. This table is pre-filtered by its relation to variant 2. Sub variants with different selections can be created for it.
An additional button can be introduced in a menu to start processing of the selected variant.
If necessary, messages regarding the processing will be displayed at the end.
To run the processing in the background, a customer-specific process type can be used. This process type then calls a class with the specified variant.
The implementation begins with defining key domains, data types, and database tables to store the variant information.
For example, one table stores simple selection fields, while another handles more complex selection options.
Defining fixed values for specific domains (such as sign or select option) simplifies data entry and reduces the potential for user errors.
This structured approach ensures a clean and scalable foundation for managing selection variants in the cloud.
Domains, data types and tables
First, some domains and data types are needed:
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 |
Defining domain fixed values for ZSL_SIGN and ZSL_OPTION makes data entry easier and helps avoid errors.
Some important domains
Single values of the selection are stored in table.
@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;
}
The table to store the select options has the following structure:
@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;
}
In NextTables, configurations for both tables (ZSL_PAR and ZSL_PAR_SEL) are created to enable variant maintenance.
A detailed description off how to create new configurations can be found in the NextTables Knowledge Base.
Next, the configuration for the table ZSL_PAR is created. If ZSL_PAR_SEL is required, it is important to fill in the fields ‘Item Tabletype’ and ‘Item Tablename’ in the properties section. This results in the special display shown below.
Definition of an item table type
The functionality of the original ABAP report is encapsulated within a new ABAP class, where a specific method (e.g., substitute_report) acts as the execution interface.
This method retrieves the variant data, processes the logic, and returns messages for display in NextTables.
By using this structured approach, existing business logic remains fully reusable while being compatible with ABAP Cloud standards.
This minimizes redevelopment costs and ensures a smooth transition with minimal disruption to business processes.
The method first reads the selection from the transferred variant and then executes the migrated functionality. In practice, some error messages will be added.
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 .
Next, the editor BAdI of NextTables must be enhanced. If an active BAdI implementation is already in use, it can be extended, and only the filter needs to be adjusted.
For the example presented, however, a new implementation is created. Two things need to be done. At least one new button must be introduced in order to call the implemented method zslcl_migrated_report=>substitute_report. In the example, a new menu “Drop down menu” is created, which contains the button “Method with report implementation.” This is done in the method set_button_data, which is called in /nly/if_editor~set_meta_exit.
In the method /nly/if_editor~set_update_exit, the action of pressing the button is handled. The implemented class is called. The messages received are converted into the NextTables format and displayed. If multiple rows have been selected, the class is called multiple times in a loop.
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 .
The BAdI implementation must be registered for the enhancement spot. The call filter must be adjusted for the parameter table, and the extension must be activated.
You can find more information on using BAdIs to extend NextTables can be found in the respective Knowledge Base section.
Even in a cloud environment, you can continue to run ABAP processes with variants — by defining a custom process type.
This process type triggers the corresponding class and method (e.g., substitute_report) using the specified variant.
2 Create a new process type
3 Create the class that implements the process type
Definition of own process type
Note: In the method if_rspc_simple_process_type~get_user_interface, the parameters that can be passed to the process type are defined. The called method determines which parameters are required.
Here, the class, the method, and the variant number are needed.
The called method must provide the following interface:
CLASS-METHODS substitute_report
IMPORTING i_variant TYPE ZSL_VARIANT
CHANGING ct_messages TYPE rspc_t_msg .
The simplest process chain has only one process step.
Calling a method from a process chain.
The method call has the following parameters:
Parameter of the method call (including variant)
Migrating to the cloud doesn’t mean leaving your proven ABAP logic behind. By combining the flexibility of NextTables with the robustness of ABAP Cloud, you can modernize your SAP landscape efficiently — keeping development effort low and preserving business continuity.
We are happy to accompany you on your journey to the cloud – from analyzing your existing ABAP landscape to technical implementation and productive integration into S/4HANA, the SAP BTP, or BW Bridge.
Do you have questions about another topic? Simply get in touch with us – we look forward to hearing from you!