ALV – Dynpro controlled by a global class

SAPIn this article I’ll present an approach how to handle a screen with a global ABAP class. The idea is simple – we will create a class which will listen to PAI and PBO events raised by the screen. All data processing and screen element manipulation is done in the class code. Let’s check out how exactly it is done

In SE80 create a function group with one function module and one screen. The function module will be the entry point from the class. The screen will be used to draw elements on the screen. The screen elements will be manipulated from the ABAP class code.

Function group and FM creation

For demonstration purposes we will have only a screen with one grid and we will capture just the OKCODE. So we will have one global variable defined in TOP include:

FUNCTION-POOL ZCA_ALV.                      

DATA:
  g_okcode TYPE okcode.

The code of our new function module will also be simple:

FUNCTION ZCA_ALV_GRID1.
* call the editor screen
  call screen 100.
ENDFUNCTION.

Now we create the screen 0100.
Please note the size of the screen – this is because we would like the ALV grid to be stretched across the whole page and we don’t want double scroll bars (issue when grid is too large) – this will require also modification in the screen layout (explained later).

Screen creation

In the following picture you can see how the global variable G_OKCODE is connected to the screen (is passed in/from the screen)

Screen elements

The flow logic of our new screen is trivial:

PROCESS BEFORE OUTPUT.
  MODULE pbo.
*
PROCESS AFTER INPUT.
  MODULE pai.

In new include for modules PBO and PAI we put the following simple code

*&---------------------------------------------------------------*
*&      Module  PBO  OUTPUT
*&---------------------------------------------------------------*
*       text
*----------------------------------------------------------------*
MODULE pbo OUTPUT.
  DATA:
    lt_ucomm TYPE TABLE OF sy-ucomm.

  FIELD-SYMBOLS:
    <fs_ucomm> type sy-ucomm.

* This will ensure some commands/buttons will by hidden/disabled
  CLEAR lt_ucomm[].
  APPEND INITIAL LINE TO lt_ucomm ASSIGNING <fs_ucomm>.
  <fs_ucomm> = 'EXECUTE'.

  SET PF-STATUS 'MY_PF_STATUS' excluding lt_ucomm.
  SET TITLEBAR 'MY_TITLEBAR'.
  zcl_ca_grid_handling=>raise_pbo( i_dynnr = sy-dynnr ).
ENDMODULE.                 " PBO  OUTPUT
*&---------------------------------------------------------------*
*&      Module  PAI  INPUT
*&---------------------------------------------------------------*
*       text
*----------------------------------------------------------------*
MODULE pai INPUT.
  IF g_okcode = 'CANC'.
    SET SCREEN 0.
  ENDIF.

  zcl_ca_grid_handling=>raise_pai(
    i_dynnr    = sy-dynnr
    i_okcode   = g_okcode
  ).
ENDMODULE.                 " PAI  INPUT

Now in the layout editor for screen 0100 I’ll create the ALV grid container. Again please note – the grid size is the same as screen size (-1 so it fits in) and what is also important – note the Resize section – this will ensure the grid will not have it’s own scrollbar (no double scroll bars)

Screen layout

Now let’s step forward to the class (Usual ABAP class) creation. In screen 0100 we are calling two static methods – RAISE_PAI and RAISE_PBO. We have to define the corresponding interface

Raise PAI interface

Raise PBO interface

Their code is simple:

METHOD raise_pai.
  RAISE EVENT pai
    EXPORTING
      i_dynnr       = i_dynnr
      i_okcode      = i_okcode.
ENDMETHOD.

METHOD raise_pbo.
  RAISE EVENT pbo
    EXPORTING i_dynnr = i_dynnr.
ENDMETHOD.

You can see we’re raising some non-standard events – so we have to define them with the corresponding interface:

Class events attributes

PBO event interface

PAI event interface

If we want to react on an event, we have to register a listener for it and have a method to handle it. The listener registration can be put directly in the class instance constructor:

METHOD constructor.
* register for the events
  SET HANDLER handle_pai.
  SET HANDLER handle_pbo.
ENDMETHOD.

We have registered listener methods (HANDLE_PAI, HANDLE_PBO) but we actually don’t have them implemented yet so let’s create them now:

PAI Handler method interface

PBO Handler method interface

Now we would like to implement our handlers. At first we have to define their interface – this is easy as class designer offers a button to fill the parameters automatically according to the event:

Event handler interface

Event handler interface auto-filled

Finally we can fill our event handlers with some code:

METHOD handle_pbo.
  CASE i_dynnr.
    WHEN '0100'.
      show_editor( ).
*  	WHEN OTHERS.
  ENDCASE.
ENDMETHOD.

METHOD HANDLE_PAI.
  CASE i_dynnr.
    WHEN '0100'.
      "screen 0100: configuration
      CASE i_okcode.
        WHEN 'CANCEL' OR 'LEAVE' OR 'BACK'. 
          SET SCREEN 0.
*      	WHEN OTHERS.
      ENDCASE.
  ENDCASE.
ENDMETHOD.

Method SHOW_EDITOR in HANDLE_PBO is a method for creation of the container object, ALV grid object and displaying it.
It uses standard ALV components CL_GUI_CUSTOM_CONTAINER and CL_GUI_ALV_GRID and displays data of SFLIGHT – we will keep the data and references to container and grid in class attributes:

Class attributes

The simplest form of the SHOW_EDITOR method might look like this:

METHOD show_editor.
  DATA:
    lt_fieldcat TYPE lvc_t_fcat,
    ls_layout   TYPE lvc_s_layo,
    ls_variant  TYPE disvariant.

  IF me->mr_container IS INITIAL.

    CREATE OBJECT me->mr_container
      EXPORTING
        container_name = 'GO_GRID_CONTAINER'.

    CREATE OBJECT me->mr_grid
      EXPORTING
        i_parent = me->mr_container.

    ls_layout-sel_mode = 'A'.
    ls_layout-no_rowmark = abap_true.
    ls_layout-cwidth_opt = abap_true.

    ls_variant-report   = sy-repid.
    ls_variant-username = sy-uname.

    CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
      EXPORTING
        i_structure_name = 'SFLIGHT'
      CHANGING
        ct_fieldcat      = lt_fieldcat.

    SELECT * INTO TABLE mt_data FROM sflight.

    me->mr_grid->set_table_for_first_display(
      EXPORTING
        is_layout             = ls_layout
        is_variant            = ls_variant
        i_save                = 'A'
        i_default             = 'X'
      CHANGING
        it_fieldcatalog       = lt_fieldcat
        it_outtab             = mt_data ).
  ENDIF.
ENDMETHOD.

Now we have everything prepared…so we just add one more public class method to run the whole magic 🙂

Method RUN

The code is simple:

METHOD run.
  CALL FUNCTION 'ZCA_ALV_GRID1'.
ENDMETHOD.

Here’s the output after ZCL_CA_GRID_HANDLING is instantiated and method RUN is called:

ALV Grid output

Let’s put a breakpoint on first line of method HANDLE_PAI to make sure the method is called when user performs an action in the screen (I pressed ESC…OK_CODE=’BACK’):

Debugger started in class

Voila ! We have fully functional ALV handled by an ABAP global class.

3 thoughts on “ALV – Dynpro controlled by a global class

  1. Hi,
    Good article, thanks. Say if you wanted to process all the fields on the screen – for example, save all the field values into a database table. Would you need to pass all the values via the raise_PAI event?

  2. Hi JFG,
    I didn’t think of this much yet (having a dynpro with fields already defined using Layout designed) and didn’t try yet – but now I will 🙂
    Code in this article was used just to manage one ALV grid by a global class.
    But I believe there’s a was how to access screen components dynamically so it should also be possible to access them from the global class without a need to pass their values back and forth from/to the dynpro. I’ll check it out and let you know if it’s possible (in another article) or I’ll leave a comment here if this is not possible/not practical.

Leave a Reply