Customizing SAP for Dummies: ABAP Tutorial for Students with some Programming Experience – Part 3

August 20, 2008

It is time to continue the ABAP tutorial. After the basics in Part 1 and the first report in Part 2, in this part we are going to take a look at the different events in ABAP used in what is called an Interactive Report. An Interactive Report is supposed to display information about a list of items, and each time we click on one of these items, to display the details of such item in a so called subscreen.

As always let’s start with the source code of the report and the source code of the different FMs:

*&------------------------------------------------*
*& Report  Z_TEST_INT_REP
*&
*&------------------------------------------------*
*&
*&
*&------------------------------------------------*

REPORT  z_test_int_rep NO STANDARD PAGE HEADING.

DATA: vbak_input TYPE zvbak_input,
      vbak_output TYPE STANDARD TABLE OF ztabfm01,
      wa_vbak TYPE ztabfm01,

      vbap_input TYPE STANDARD TABLE OF ztabfm02,
      vbap_output TYPE STANDARD TABLE OF ztabfm02,
      wa_vbap TYPE ztabfm02,
      vbeln_n TYPE n LENGTH 10,

      vbep_output TYPE STANDARD TABLE OF ztabfm03,
      wa_vbep TYPE ztabfm03,

      box TYPE c.

PARAMETERS: vbtyp LIKE vbak_input-vbtyp
            OBLIGATORY VALUE CHECK,
            auart LIKE vbak_input-auart
            OBLIGATORY VALUE CHECK,
            vkorg LIKE vbak_input-vkorg
            OBLIGATORY VALUE CHECK,
            vtweg LIKE vbak_input-vtweg
            OBLIGATORY VALUE CHECK,
            spart LIKE vbak_input-spart
            OBLIGATORY VALUE CHECK.

INITIALIZATION.
  vbtyp = 'C'.
  auart = 'TA'.
  vkorg = '1000'.
  vtweg = '10'.
  spart = '00'.

TOP-OF-PAGE.
  WRITE:/ 'Sales Header'.
  ULINE.
  WRITE:/ 'Document', (10) 'Category',
        (12) 'Organization'.
  ULINE.

TOP-OF-PAGE DURING LINE-SELECTION.
  CASE sy-lsind.
    WHEN 1.
      WRITE:/ 'Sales Item'.
      ULINE.
      WRITE:/(15) 'Document', (10) 'Item',
      (17) 'Material Number', (12) 'Price'.
      ULINE.
    WHEN 2.
      WRITE:/ 'Sales Schedule Line'.
      ULINE.
      WRITE:/(15) 'Document', (10) 'Item',
      (18) 'Schedule Number', (15) 'Order quantity',
      (15) 'Conf. quantity'.
      ULINE.
  ENDCASE.

AT SELECTION-SCREEN.
  PERFORM vbak_in_to_out.
  IF vbak_output IS INITIAL.
    MESSAGE e888(sabapdocu) WITH 'No entries found'.
  ENDIF.

START-OF-SELECTION.
  PERFORM vbak_in_to_out.
  PERFORM display_data_vbak.

AT LINE-SELECTION.
  CASE sy-lsind.
    WHEN 1.
      CLEAR: vbap_input.
      DO.
        CLEAR: wa_vbap.
        READ LINE sy-index FIELD VALUE box
        wa_vbak-vbeln INTO vbeln_n.
        IF sy-subrc NE 0.
          EXIT.
        ELSEIF box = 'X'.
          MOVE vbeln_n TO wa_vbap-vbeln.
          APPEND wa_vbap TO vbap_input.
        ENDIF.
      ENDDO.

      IF vbap_input IS INITIAL.
        MESSAGE s888(sabapdocu) WITH
        'No line selected'.
        sy-lsind = sy-lsind - 1.
      ELSE.
        CLEAR vbap_output.
        CALL FUNCTION 'Z_TEST_FUNCT_BE_INT2'
          TABLES
            vbeln_in = vbap_input
            vbap_det = vbap_output.
        IF vbap_output IS INITIAL.
          MESSAGE s888(sabapdocu) WITH
          'No items to display'.
          sy-lsind = sy-lsind - 1.
        ELSE.
          PERFORM display_data_vbap.
        ENDIF.
      ENDIF.

    WHEN 2.
      CALL FUNCTION 'Z_TEST_FUNCT_BE_INT3'
        EXPORTING
          vbeln_in = wa_vbap-vbeln
          posnr_in = wa_vbap-posnr
        TABLES
          vbep_det = vbep_output.
      PERFORM display_data_vbep.

    WHEN 3.
      MESSAGE s888(sabapdocu)
      WITH 'No more subscreens available'.
  ENDCASE.

*&------------------------------------------------*
*&      Form  display_data_vbak
*&------------------------------------------------*
*       text
*&------------------------------------------------*
FORM display_data_vbak.
  LOOP AT vbak_output INTO wa_vbak.
    WRITE:/ box AS CHECKBOX, wa_vbak-vbeln,
    (10) wa_vbak-vbtyp, (12) wa_vbak-vkorg.
  ENDLOOP.
ENDFORM. "display_data_vbak

*&------------------------------------------------*
*&      Form  display_data_vbap
*&------------------------------------------------*
*       text
*&------------------------------------------------*
FORM display_data_vbap.
  LOOP AT vbap_output INTO wa_vbap.
    WRITE:/(15) wa_vbap-vbeln, (10) wa_vbap-posnr,
    (17) wa_vbap-matnr, (12) wa_vbap-netpr.
    HIDE wa_vbap.
  ENDLOOP.
ENDFORM. "display_data_vbap

*&------------------------------------------------*
*&      Form  display_data_vbep
*&------------------------------------------------*
*       text
*&------------------------------------------------*
FORM display_data_vbep.
  LOOP AT vbep_output INTO wa_vbep.
    WRITE:/(15) wa_vbep-vbeln, (10) wa_vbep-posnr,
    (17) wa_vbep-etenr, (15) wa_vbep-wmeng,
    (15) wa_vbep-bmeng.
  ENDLOOP.
ENDFORM. "display_data_vbep

*&------------------------------------------------*
*&      Form  vbak_in_to_out
*&------------------------------------------------*
*       text
*&------------------------------------------------*
FORM vbak_in_to_out.
  CLEAR: vbak_input, vbak_output.
  vbak_input-vbtyp = vbtyp.
  vbak_input-auart = auart.
  vbak_input-vkorg = vkorg.
  vbak_input-vtweg = vtweg.
  vbak_input-spart = spart.

  CALL FUNCTION 'Z_TEST_FUNCT_BE_INT1'
    EXPORTING
      vbak_input = vbak_input
    TABLES
      vbak_det   = vbak_output.
ENDFORM.                    "vbak_in_to_out
FUNCTION Z_TEST_FUNCT_BE_INT1.
*"------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(VBAK_INPUT) TYPE  ZVBAK_INPUT
*"  TABLES
*"      VBAK_DET STRUCTURE  ZTABFM01
*"------------------------------------------------

  SELECT vbeln erdat erzet ernam vbtyp
    auart vkorg vtweg spart FROM vbak
    INTO CORRESPONDING FIELDS OF TABLE vbak_det
*    UP TO 100 ROWS
    WHERE vbtyp = vbak_input-vbtyp AND
    auart = vbak_input-auart AND
    vkorg = vbak_input-vkorg AND
    vtweg = vbak_input-vtweg AND
    spart = vbak_input-spart.

ENDFUNCTION.
FUNCTION z_test_funct_be_int2.
*"------------------------------------------------
*"*"Local Interface:
*"  TABLES
*"      VBELN_IN STRUCTURE  ZTABFM02
*"      VBAP_DET STRUCTURE  ZTABFM02
*"------------------------------------------------

  SELECT vbeln posnr matnr kwmeng netpr werks
   INTO CORRESPONDING FIELDS OF TABLE vbap_det
   FROM vbap
   FOR ALL ENTRIES IN vbeln_in
   WHERE vbeln EQ vbeln_in-vbeln.

ENDFUNCTION.
FUNCTION z_test_funct_be_int3.
*"------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(VBELN_IN) TYPE  VBELN_VA
*"     REFERENCE(POSNR_IN) TYPE  POSNR
*"  TABLES
*"      VBEP_DET STRUCTURE  ZTABFM03
*"------------------------------------------------

  SELECT vbeln posnr etenr edatu wmeng bmeng
    FROM vbep
    INTO CORRESPONDING FIELDS OF TABLE vbep_det
    WHERE vbeln = vbeln_in AND posnr = posnr_in.

ENDFUNCTION.

The way this report works is the following:

When you run the report you are presented with a screen, called Selection Screen, where you can select the kind of Sales you want to display information about.

Selection Screen

Selection Screen

After choosing the kind and clicking continue (the green tick button on the upper left) you are presented with the sales headers, corresponding to what you have previously chosen.

First Display

First Display

After you have chosen the headers and clicked on the magnifying glass, the details of the chosen headers will be displayed, i.e. the sales items belonging to the chosen headers.

Second Display

Second Display

Finally, after double clicking any sales item, you will get information about the different schedules for the item.

Third and last display

Third and last display

As you can see, there are many new things in this example. I am just going to go through it and try to explain them all.

First of all, I am not declaring the types in the report anymore. I declare the types in the ABAP Data Dictionary. Any type declared here can be used in any report or FM in the SAP implementation, which is exactly what I do, using the same types for tables in the report and in the FM, as you can see at the declaration of the FMs. The following four types are declared:

ZTABFM01

ZTABFM01

ZTABFM02

ZTABFM02

ZTABFM03

ZTABFM03

ZVBAK_INPUT

ZVBAK_INPUT

The next important thing is Forms. Forms are nothing more than function which you can call inside your report. These are called with the keyword PERFORM and declared between FORM and ENDFORM. They help structure the code and reuse it, as I am doing with vbak_in_to_out.

You could probably identify most of the events used, now that you know how the report works. However, I will explain each one of them:

  • INITIALIZATION (line 36)
    This is how parameters are initialized for the display of the selection screen. The default values for the input, so to say.
  • AT SELECTION-SCREEN (line 67)
    This happens exactly at the moment you click continue at the selection screen. In this example I am using a message code “MESSAGE e888(sabapdocu)” which means, if it is triggered, the selection is not finished, and the user is brought back to the selection screen.
  • START-OF-SELECTION (line 73)
    Happens exactly after AT SELECTION-SCREEN. Is where you actually do the selection and prepare everything for display.
  • TOP-OF-PAGE (line 43)
    Is the display at the top of the page when displaying the first selection. You normally write the page header here.
  • AT LINE-SELECTION (line 77)
    This is the most complex of all events in this example. It is the event triggered by the double click on a line, or the click of the magnifying glass.
    sy-lsind is an important variable in this event, which tells you in which selection screen the report is. If it is equal to 1 then you are selecting items of the first selection, if it is equal to 2 then from the second, etc.
    Lines 83 to 90 is the code used to check if there is any item selected. It goes through the lines of display and checks whether it is an item line and whether the box is checked.
    Lines 93 to 110 just checks if there is any items to display. Just remember that if there is nothing to display we have to set sy-lsind back and tell the report we are still at the first display screen.
  • TOPOF-PAGE DURING LINE-SELECTION (line 50)
    Uses the same logic of AT LINE-SELECTION to display headers for the subscreens.

One last important thing is line 147. The hide statement allow us to save a variable into memory when double clicking a line, so we can use it for display in the next event (line 115 – wa_vbap).

Please feel free to create this example yourself and make small changes to it. It will surely give you a much deeper understanding of events in ABAP, and about interactive reports. Until next time.