Since I develop ABAP in SAP I must deal with the old, dusty dynpros. Unfortunately, many customers are still not willing to more forward any use Web Dynpro, UI5 or any of the other modern technologies out there. In our current project, we were lucky enough and could start from scratch so I introduced the BUS Screen Framework. The first time I came in touch with this little framework was read the book Anwendungsentwicklung mit ABAP Objects from Thorsten Franz and Tobias Trapp.

The BUS Screen Framework is a way to develop dynpros using an object orientated approach. But don’t crow too soon: we still must use the dynpro painter and a handful modules and form routines. But it helps you to create an object orientated report and to handle the dynpro logic and events.
Let’s dive a little bit deeper into the framework. It provides you the abstract basic classes for main screens and sub screens. These classes provide some functions like the object orientated access to tab strips, to set the title and status, raising messages or to handle events triggered from the GUI.













The Dynpro Class

Since the BUS screen classes are defined as abstract you must create your own (local) class and inherit from the proper super class. In my example, I have one Dnypro 9000 which acts as my only main screen. This example should give you a first impression of the framework.
Due to the inheritance, we must redefine the abstract methods CALL_SCREEN and CALL_SCREEN_STARTING_AT.

CLASS lcl_scr9000 DEFINITION INHERITING FROM cl_bus_abstract_main_screen.
   METHODS call_screen_starting_at REDEFINITION.

The implementation of the class very light. All we must do is to call the Dynpro.

 METHOD call_screen.
   CALL SCREEN iv_dynpro_number.

 METHOD call_screen_starting_at.
   CALL SCREEN iv_dynpro_number STARTING AT iv_xstart iv_ystart
     ENDING AT iv_xend iv_yend.

Now we have our Dynpro class. It does not contain any logic but it is enough to create and show our Dynpro. But wait – we have a Dynpro class but no Dynpro yet.
The Dynpro is created like any other Dynpro you have created in your life before. I have created a normal screen that contains a label only.


The Dynpro does not yet communicate with the framework (and therefore with our screen class). First, we must program some code in the Dynpro flow logic. Due to the coding restrictions, we must create two modules (one for PBO and one for PAI).

 MODULE dynpro_pbo.

 MODULE dynpro_pbo.

The only thing these modules do is to handover the PBO and PAI handling for the actual Dynpro to the framework. The methods DYNPRO_PBO and DYNPRO_PAI retrieve an instance from your screen class from the internal buffer and invokes the corresponding methods on this screen object instance.

MODULE dynpro_pbo OUTPUT.
      iv_program_name = sy-repid
      iv_dynpro_number = sy-dynnr

MODULE dynpro_pai INPUT.
      iv_program_name = sy-repid
      iv_dynpro_number = sy-dynnr
Both methods, DYNPRO_PBO and DYNPRO_PAI, are internally divided into two methods: PBO_BEGIN/PBO_END and PAI_BEGIN/PAI_END. In a later tutorial, you will see what is the reason for that.

Let’s review the current implementation status:

  • We have created a screen class for our main screen 9000. It inherits from the class CL_BUS_ABSTRACT_MAIN_SCREEN.
  • We have created the normal Dynpro 9000 and added some flow logic to handover the PBO/PAI handling to the framework.

The Handler Class

As we have learned the flow logic hands over the event handling to our screen class. Well to be accurate the method PAI_END in super class CL_BUS_ABSTRACT_MAIN_SCREEN raises the event PROCESS_AFTER_INPUT with the function code as parameter. For the ones who wonder where we have defined the function codes: this example does not have a custom status. If we don’t set a status the BUS framework uses the default status BUS_MAIN_SCREEN in function group BUS_LOCATOR. A later example will show how to use a customer own status.
Let’s return to the handler class. The screen class raises an event and we must have a handler that listens to it. There is nothing wrong with adding the handler method into the screen class but I prefer a dedicated class. The local class LCL_HANDLER implements a method that listens to the mentioned event. The only action we perform is to leave the screen.

    METHODS handle_pai
process_after_input OF cl_bus_abstract_main_screen

  METHOD handle_pai.
    CASE iv_function_code.
*      when using the default status we can use the constants to
*      check the PAI events
      WHEN cl_bus_abstract_main_screen=>gc_function_code_back OR
*         static variable contains a reference to the actual main screen
          cl_bus_abstract_main_screen=>gv_current_main_screen->leave( ).

When we invoke the method LEAVE on the actual main screen, the screen instance will be removed from the internal stack. If there was another main screen before the program would return to the previous screen, otherwise the program ends.

Let’s view the current implementation status:

  • We have created a screen class and Dynpro for our main screen 9000.
  • We have created the handler class LCL_HANDLER that listens to the event PROCESS_AFTER_INPUT which is raised by the framework.
  • Since we don’t set a custom status the BUS screen framework uses its default status.

Call the Screen and register the Handler

Next we must program some logic to call our screen, register the handler and display the screen. Personally, I like to put my Dynpros into function groups. Therefore, I have created a simple function module that calls our screen.

FUNCTION z_ft_start_example_1.
*"*"Local Interface:
* object reference to main screen
  DATA lo_scr9000       TYPE REF TO lcl_scr9000.
  DATA lo_handler       TYPE REF TO lcl_handler.

* create instance of screen 9000
      iv_program_name  = cl_abap_syst=>get_current_program( )
      iv_dynpro_number = |9000|
      ev_screen        = lo_scr9000

* create and register handler
  lo_handler = NEW #( ).
  SET HANDLER lo_handler->handle_pai FOR lo_scr9000.

* display dynpro
   lo_scr9000->show( ).

The method GET_SCREEN from class CL_BUS_ABSTRACT_MAIN_SCREEN creates an instance of our screen class LCL_SCR9000 and adds it to the internal call stack. But how does the framework know that it should create an instance of class LCL_SCR9000 for our Dynpro 9000? For this purpose, we need the only form routine. Method GET_SCREEN performs the form routine BUS_SCREEN_CREATE in the actual program. We must implement this form routine and return an instance of the screen class.

FORM bus_screen_create
    iv_program_name  TYPE bus_screen-program_name
    iv_dynpro_number TYPE bus_screen-dynpro_number
    ev_screen        TYPE any.
  CASE iv_dynpro_number.
    WHEN '9000'.
      ev_screen = NEW lcl_scr9000(
        iv_program_name  = iv_program_name
        iv_dynpro_number = iv_dynpro_number


Let’s review the current implementation status:

  • We have created a screen class and Dynpro for our main screen 9000.
  • We have created the handler class that listens to the PAI event.
  • We have implemented the form routine BUS_SCREEN_CREATE which creates an instance of our local class.
  • We have programmed the logic to call the screen and register the handler.

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply