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

In the first part of this tutorial I explained the basics of programs and types in ABAP. Today I will introduce you to the a first ABAP program, which in a way is a Hello World program for ABAP, using the possible features of ABAP in a single simple report. As I said last time a report is nothing more than an executable file.

So here it is:

*&--------------------------------------------*
*& Report  ZSER1301
*&
*&--------------------------------------------*
*&
*&
*&--------------------------------------------*
REPORT  zser1301.

* Declarative Section
TYPES: BEGIN OF zsf_type,
  carrid LIKE sflight-carrid,
  carrname LIKE scarr-carrname,
  currcode LIKE scarr-currcode,
  minpay LIKE sflight-paymentsum,
  maxpay LIKE sflight-paymentsum,
  avgpay LIKE sflight-paymentsum,
  totpay LIKE sflight-paymentsum,
END OF zsf_type.

DATA: i_tab_fl TYPE STANDARD TABLE OF zsf_type,
      wa_tab_fl TYPE zsf_type,
      time_beg TYPE i,
      time_end TYPE i,
      time_tot TYPE i.

* Program Statements
GET RUN TIME FIELD time_beg.

SELECT sflight~carrid scarr~carrname
  MIN( paymentsum ) AS minpay
  MAX( paymentsum ) AS maxpay
  AVG( paymentsum ) AS avgpay
  SUM( paymentsum ) AS totpay
  FROM sflight JOIN scarr
  ON sflight~carrid = scarr~carrid
  INTO CORRESPONDING FIELDS OF TABLE tab_fl
  GROUP BY sflight~carrid scarr~carrname
  ORDER BY sflight~carrid.

GET RUN TIME FIELD time_end.

time_tot = ( time_end - time_beg ).

WRITE:/ 'Carriers Data'.
ULINE.
WRITE:/(8) 'CARRIER', (20) 'NAME',(23) 'MIN PAY',
(23) 'MAX PAY', (23) 'AVG PAY', (23) 'SUM PAY'.
ULINE.

LOOP AT i_tab_fl INTO wa_tab_fl.
  WRITE:/(8) wa_tab_fl-carrid,
  (20) wa_tab_fl-carrname,
  (17) wa_tab_fl-minpay, wa_tab_fl-currcode,
  (17) wa_tab_fl-maxpay, wa_tab_fl-currcode,
  (17) wa_tab_fl-avgpay, wa_tab_fl-currcode,
  (17) wa_tab_fl-totpay, wa_tab_fl-currcode.
ENDLOOP.

WRITE: /, / 'Runtime = ', time_tot.

Now let’s go through it and I will try to explain how all this code works.

Lines 11-19:

Here we declare the structure type we will use in the program. sflight and scarr are two tables declared in the ABAP dictionary. All tables declared in this dictionary are global and may be used in any program. In scarr information about different airlines in store, and in sflight that about flights of these airlines.

Lines 21-25:

We declare an internal table, which is of type of this structure. This means we have one or more entries, and in each entry such an structure. After this we declare a work area, of the same type as the table entry. And declare three integer variables, which we use to calculate the runtime of the report.

Lines 28, 41, 43:

We get the user time before the logic, after it, and then calculate the total.

Lines 30-39:

SQL query. I asume you have some idea of SQL, so I am just going to explain all the ABAP related stuff. We select diferent fields and use some aggregate functions on the paymentsum field of sflight. In order to do this we use group by, and use order by just to have a better output. We are selecting from a join of two different tables.
Pay attention to line 37. In this line we tell the database to store the result of the SQL query into the internal table tab_fl, and to only store the fields of the select, which exist in the internal table.

Lines 45-49:

We display the title and fields of the table.

Lines 51-58:

We display the data store in our internal table. To do this we use a loop at the internal table into the work area. This means that in each iteration of the loop we will get another entry of the internal table in the work area. We use the syntax workarea-fieldname to access the field values.

We let the program run, and get the following screen:

Screen of Report ZSER1301

Screen of Report ZSER1301

That was not so difficult, was it? I know you are probably thinking this is not the kind of program you program in every language, but it is the most typical report in ABAP. Actually, a report is call this way, because you get information and report it back.

So now that we have written a program that works, let’s try to write the same thing and use the right tools for it.

In the next example we will do exactly the same. For it we will declare the structure type in the ABAP dictionary and create a function module (FM), which works like a subroutine, to get the information from the database. This way we make use of the principle of modularity, reusability and continuity.

So the first thing we do, is create the structure type, using the object explorer:

ZSF_TYPE Structure

ZSF_TYPE Structure

We rewrite the report:

*&--------------------------------------------*
*& Report  ZSER1300
*&
*&--------------------------------------------*
*&
*&
*&--------------------------------------------*
REPORT  zser1300.

* Declarative Section

*TABLES: scarr, sflight.

DATA: i_tab_fl TYPE STANDARD TABLE OF zsf_type,
      wa_tab_fl TYPE zsf_type,
      time_tot TYPE i.

* Program Statements

CALL FUNCTION 'ZSER1300_FM'
  IMPORTING
    time_tot = time_tot
  TABLES
    tab_fl   = i_tab_fl.

WRITE:/ 'Carriers Data'.
ULINE.
WRITE:/(8) 'CARRIER', (20) 'NAME',(23) 'MIN PAY',
(23) 'MAX PAY', (23) 'AVG PAY', (23) 'SUM PAY'.
ULINE.

LOOP AT i_tab_fl INTO wa_tab_fl.
  WRITE:/(8) wa_tab_fl-carrid,
  (20) wa_tab_fl-carrname,
  (17) wa_tab_fl-minpay, wa_tab_fl-currcode,
  (17) wa_tab_fl-maxpay, wa_tab_fl-currcode,
  (17) wa_tab_fl-avgpay, wa_tab_fl-currcode,
  (17) wa_tab_fl-totpay, wa_tab_fl-currcode.
ENDLOOP.

WRITE: /, / 'Runtime = ', time_tot.

and in line 20 we call the function module ZSER1300_FM and pass the variables which are going to be return.

If you take a look at the interface of ZSER1300_FM, you will see the declaration of the variables used in the FM. All not optional will have to be assigned at the time of the FM call.

FUNCTION ZSER1300_FM.
*&--------------------------------------------*
*"Local Interface:
*"  EXPORTING
*"     REFERENCE(TIME_TOT) TYPE  I
*"  TABLES
*"      TAB_FL STRUCTURE  ZSF_TYPE
*"  CHANGING
*"     REFERENCE(TIME_BEG) TYPE  I OPTIONAL
*"     REFERENCE(TIME_END) TYPE  I OPTIONAL
*&--------------------------------------------*

GET RUN TIME FIELD time_beg.
SELECT sflight~carrid scarr~carrname
  MIN( paymentsum ) AS minpay
  MAX( paymentsum ) AS maxpay
  AVG( paymentsum ) AS avgpay
  SUM( paymentsum ) AS totpay
  FROM sflight JOIN scarr
  ON sflight~carrid = scarr~carrid
  INTO CORRESPONDING FIELDS OF TABLE tab_fl
  GROUP BY sflight~carrid scarr~carrname
  ORDER BY sflight~carrid.
GET RUN TIME FIELD time_end.

time_tot = ( time_end - time_beg ).

ENDFUNCTION.

I hope after reading through all the code you will feel more comfortable with ABAP. To all of you who follow the tutorial, I want to thank you and encourage you to write comments about what you would like to see more of, or what you do not like about the tutorial. Thanks! See you next time.

Just as a small disclaimer: All the code written in this blog has been writen by me, during my free time and is not used in any way at my work. All the information has been either obtained from the SAP help site or from talks with other people.

One Response to Customizing SAP for Dummies: ABAP Tutorial for Students with some Programming Experience – Part 2

  1. […] 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 […]

Leave a comment