NextLytics Blog

Migrating ABAP-Programs into a cloud environment

Written by Stefan | 09 October 2025

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.

A Practical Solution: How Can You Preserve ABAP Logic in the Cloud?

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 selections used in the ABAP program, stored as variants, are saved in one or two database tables. For selection options, two tables are required.
  • The tables are maintained using NextTables.
  • The former ABAP coding is transferred into a class and can be executed directly from NextTables for a given variant. In doing so, minor differences between ABAP and ABAP Cloud must be taken into account.
  • Error messages are displayed as message boxes.

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:

Selection screen in the legacy system (Dynpro)

 

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.

 

Implementation in Detail: From Data Structures to Execution

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

 

Is SAP BW Bridge a smart transition or rather a detour?

Download the Whitepaper here!

 

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;
}

 

Configuring NextTables: Making Variant Maintenance Seamless

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

 

Migrating Program Logic: Keeping Your Core Code Intact

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.

 

Running in the Background: How to Use a Custom Process Type

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.

  1. Call the maintenance screen: e.g. Bridge-Cockpit --> Development BW Bridge -> Configuration ->Custom process types

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)

 

Our Conclusion: Modernize Your ABAP Landscape Without Starting from Scratch

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!