Baics and Classical Reports
Baics and Classical Reports
Internal table is a data object in ABAP that exists only at run time of the program. It means when the
program execution is complete then the internal table will be lost. We use internal table to store
database table after fetching it by a select query. The ABAP runtime system dynamically manages the
internal table’s memory. It means we developer do not need to work on memory management of
internal table.
Internal table has three parts – rows, columns and work area.
1. Rows are the line type of internal table. It is a structure which contains several fields. Those
fields are of data elements. We need to declare the structure locally or globally to declare the
internal tables.
2. Columns are the fields of internal table. Those fields are of different data element declared by
locally or globally.
3. The most important part of the internal table is its work area. Work area is basically the line type
of internal table. It means it has the same structure of the rows of the internal table. Work area
contains the same field of same type of the rows. It is of two types Implicit and Expicit work
area.
A. When we declare an internal table with header line then a work area will automatically be
created with the same name of the table. This work area is called the implicit work area which is
actually the header line. There is no need to declare the work area separately. This work area /
header line contains the same table as of the internal table.
Example:
Here we have declared a local structure ty_mat. This is the line type / row of the internal table. It means
the table will contain rows which has three fields (matnr, werks & lgort). We declare the internal table
it_mat with this local structure. We also can declare with global structure.
Here slis_qinfo_alv is a structure which has been declared globally in data dictionary. We can declare the
internal table directly with the table type also.
It also contains the same name IT_MAT but it is mentioned IT_MAT[ ] in the program.
B. If we declare an internal table without header line then we need to declare its work area seperately.
Since we are declaring the work area explicitly it is called explicit work area. This work area contains the
different name from the internal table.
Example –
TYPES: BEGIN OF ty_mat,
matnr TYPE mara-matnr,
werks TYPE marc-werks,
lgort TYPE mard-lgort,
END OF ty_mat.
Similarly we can declare internal table with globally declared structure or table type also.
DATA: it_qinfo TYPE TABLE OF slis_qinfo_alv WITH NON-UNIQUE KEY type.
DATA: it_qinfo TYPE slis_t_qinfo_alv.
To declare an internal table there is three basic specifications. They are 1. Row type, 2. Key & 3. Types
of internal table. Internal table is of three types – standard table, sorted table & hashed table.
Standard & sorted tables are called index table because we can access its records by its index. Index is
nothing but a row number of the internal table.
1. Standard table is an index table which has non-unique key. It can be accessed by index or key also. If
we want to access by key then the key must be defined otherwise default key would be considered. The
declaration is as follows:
DATA: it_mat TYPE STANDARD TABLE OF ty_mat WITH NON-UNIQUE KEY matnr.
OR
DATA: it_mat TYPE TABLE OF ty_mat WITH NON-UNIQUE KEY matnr.
If we don’t mention “Standard table of” clause then by default the system takes it as a standard internal
table. We can enter data into a standard internal table by using the APPEND statement. Append always
enters data at the last row of the table.
2. Sorted table is another kind of index table which has unique / non unique key. It also can be accessed
via index or key. For sorted table the key must be specified. The declaration is as follows:
DATA: it_mat TYPE SORTED TABLE OF ty_mat WITH UNIQUE KEY matnr,
it_mat TYPE SORTED TABLE OF ty_mat WITH NON-UNIQUE KEY matnr.
Unique key means the MATNR (material no) will must be unique. If same material number is inserted
then a run time error will happen. However we can declare the sorted table with non unique key also. In
this case same material number can be entered but it will be sorted after entering the number. Here the
sorted table behaves similar to sorted standard table. We use INSERT statement to enter any records to
the sorted table.
3. Hashed table is not an index table. It follows the hash algorithm. Here the declaration of key is must and
also the key must be unique. Hence no duplicate entry will be in the hashed table. We can access
records only by the key.
DATA: it_mat TYPE HASHED TABLE OF ty_mat WITH UNIQUE KEY matnr.
Similar to sorted tables data can be inserted here by INSERT statement. Hashed tables are used when
the internal table contains huge volume of data.
Standard table is an index table which has non-unique key. It can be accessed by index or key also. If
we want to access by key then the key must be defined otherwise default key would be considered. The
declaration is as follows:
DATA: it_mat TYPE STANDARD TABLE OF ty_mat WITH NON-UNIQUE KEY matnr.
OR
DATA: it_mat TYPE TABLE OF ty_mat WITH NON-UNIQUE KEY matnr.
OR
DATA: it_mat TYPE TABLE OF ty_mat.
If we don’t mention “STANDARD TABLE OF” clause then by default the system takes it as a standard
internal table. We can enter data into a standard internal table by using the APPEND statement. APPEND
always enters data at the last row of the table.
APPEND wa_mat TO it_mat.
REPORT zabap_gui.
WRITE: /3 'Item',
17 'Quantity',
32 'Price'.
WRITE / '=========================================='.
SKIP. " Skipping one single line
WRITE: /3 wtab-item,
12 wtab-quantity,
25 wtab-price.
ENDLOOP.
SKIP.
WRITE '=========================================='.
Sorted Internal Table
Sorted table is another kind of index table which has unique / non unique key. It also can be accessed
via index or key. For sorted table the key must be specified. The declaration is as follows:
DATA: it_mat TYPE SORTED TABLE OF ty_mat WITH UNIQUE KEY matnr,
it_mat TYPE SORTED TABLE OF ty_mat WITH NON-UNIQUE KEY matnr.
Unique key means the MATNR (material no) will must be unique. If same material number is inserted
then a run time error will happen. However we can declare the sorted table with non unique key also. In
this case same material number can be entered but it will be sorted after entering the number. Here the
sorted table behaves similar to sorted standard table. We use INSERT statement to enter any records to
the sorted table.
WRITE: /3 wtab-item,
12 wtab-quantity,
25 wtab-price.
ENDLOOP.
SKIP.
WRITE '=========================================='.
Since the key is unique the similar entries are ignored by the system.
REPORT zabap_gui.
WRITE: /3 'Item',
13 'Quantity(KG)',
28 'Price(Rs)'.
WRITE / '=========================================='.
SKIP. " Skipping one single line
WRITE: /3 wtab-item,
12 wtab-quantity,
25 wtab-price.
ENDLOOP.
SKIP.
WRITE '=========================================='.
REPORT zabap_gui.
WRITE: /3 'Item',
13 'Quantity(KG)',
28 'Price(Rs)'.
WRITE / '=========================================='.
SKIP. " Skipping one single line
WRITE: /3 wtab-item,
12 wtab-quantity,
25 wtab-price.
ENDLOOP.
SKIP.
WRITE '=========================================='.
Continue Statement
The CONTINUE statement is used inside a loop only. When the program controller finds the CONTINUE
statement it quits the current loop pass. Hence all other statements after the CONTINUE will not be
executed inside that loop. The program controller then goes to the next loop iteration.
REPORT zabap_gui.
WRITE: /3 'Item',
13 'Quantity(KG)',
28 'Price(Rs)'.
WRITE / '=========================================='.
SKIP. " Skipping one single line
WRITE: /3 wtab-item,
12 wtab-quantity,
25 wtab-price.
CLEAR wtab.
ENDLOOP.
SKIP.
WRITE '=========================================='.
Whenever the program controller finds Rice item it just ignores it and goes to next loop iteration. That is
why Rice item is not coming to the output.
Check Statement
The CHECK statement checks a condition first inside a loop. If the condition is true then rest of the
statements inside that loop will be executed. If the condition is false then the program controller
terminates the current loop pass and it will go to the next loop iteration. Hence the condition is the
prerequisite of CHECK statement. No condition will lead the syntax error of the program. Outside of the
loop CHECK will leave the current processing block of the program.
REPORT zabap_gui.
WRITE: /3 'Item',
13 'Quantity(KG)',
28 'Price(Rs)'.
WRITE / '=========================================='.
SKIP. " Skipping one single line
WRITE: /3 wtab-item,
12 wtab-quantity,
25 wtab-price.
CLEAR wtab.
ENDLOOP.
SKIP.
WRITE '=========================================='.
Whenever the check condition finds Rice item it goes to the rest of the statements of current loop. If the
condition finds false (other than Rice) it leaves the current loop iteration and goes to the next loop pass.
Exit Statement
The EXIT statement quits the processing of the current loop. If we use EXIT outside of the loop then it
leaves the current processing block. Hence no other statement of that processing block will be executed.
It is recommended that EXIT needs to be used inside a loop. We can use it outside of loop as per
requirement as well.
If there are nested loops and we use EXIT statement in the inner loop then the system will leave the inner
loop after executing the EXIT statement. The program control will continue with the outer loop execution.
REPORT zabap_gui.
WRITE: /3 'Item',
13 'Quantity(KG)',
28 'Price(Rs)'.
WRITE / '=========================================='.
SKIP. " Skipping one single line
WRITE / '=========================================='.
SKIP. " Skipping one single line
WRITE: /3 wtab-item,
12 wtab-quantity,
25 wtab-price.
CLEAR wtab.
ENDLOOP.
SKIP.
WRITE '=========================================='.
Here the first set of output has come without the exit statement. Second set has come by exit statement.
Whenever the program controller finds the item Rice then it executes exit. The system leaves the loop
totally. That is why only one output has come yet.
There are different kinds of fetching the records of internal table. One of these is READ TABLE
statement. By using READ TABLE we can fetch only the first record from the table. Hence it can fetch a
single record always. Read table statement can be used to any type of table to fetch the record. Now if
the table is sorted then we can use BINARY SEARCH to fetch record. Now fetching records may take
time but if we use BINARY SEARCH then the system performance will improve. Obviously if the table is
sorted then the fetching operation will be faster.
We can describe an internal table as well. If the table stores 300 records then the system will inform us by
the system field SY-TFILL. Here note that SY-TFILL will not work alone. We need to describe the table
first then we can get data from SY-TFILL field.
REPORT zabap_gui.
WRITE: /3 'Item',
13 'Quantity(KG)',
28 'Price(Rs)'.
WRITE / '=========================================='.
SKIP. " Skipping one single line
SKIP.
WRITE '=========================================='.
Though the output is showing only one record the table still contains six
records.
Internal table can be edited as per requirement. We can modify one particular record when it is required.
Two kinds of statements can be used to modify one single line.
Note that by these statements one single line can be modified. We can add more fields as per
requirement. We can modify any type of internal table by these statements. After modification the old
record is lost completely from the table. If we store it to any outer structure before modification then the
old record can be reused.
REPORT zabap_gui.
WRITE: /3 'Item',
13 'Quantity(KG)',
28 'Price(Rs)'.
WRITE / '=========================================='.
SKIP. " Skipping one single line
SKIP.
WRITE '=========================================='.
SKIP.
wtab-item = 'Complan'.
wtab-price = 220.
MODIFY TABLE itab FROM wtab.
ENDIF.
WRITE: /3 wtab-item,
12 wtab-quantity,
25 wtab-price.
ENDLOOP.
Here the item Horlicks has been modified to Complan.
Internal table can be edited as per requirement. We can delete a particular line of it based on the
condition. The statement is “DELETE TABLEitab FROM wtab.” Here itab is internal table and wtab is
its work area. This statement can be used in any type of internal table whenever there is a requirement.
REPORT zabap_gui.
WRITE: /3 'Item',
13 'Quantity(KG)',
28 'Price(Rs)'.
WRITE / '=========================================='.
SKIP. " Skipping one single line
LOOP AT itab INTO wtab.
IF wtab-item = 'Rice'.
DELETE TABLE itab FROM wtab.
ELSEIF wtab-item = 'Suger'.
DELETE TABLE itab FROM wtab.
ENDIF.
ENDLOOP.
SKIP.
WRITE '=========================================='.
SKIP.
Whenever the program controller finds Rice & Suger it deletes from the internal table.
DELETE ADJACENT DUPLICATE statement works logically on sorted standard table and sorted
table with non-unique key. It compares the adjacent rows. If similar records are found based on the
comparing fields then it deletes from the second records onward. The system keeps only the first record.
Let us suppose we are having the following table with records.
We know that in standard table APPEND statement is used to enter data records. Now APPEND
appends data to the last position of the standard table. It is not possible to enter in any other position.
Now if we run the Delete adjacent duplicate command on the previous table then the data records will
remain same. Nothing will be changed. Because the command will check every single adjacent line and
found nothing to similar. Hence in this case we need to sort the table (standard table).
The command will remove always the second record onward. It will keep only the first record. Here if we
use Sorted table with non-unique key then after inserting the records we can find the sorted structure of
the data records. That is why DELETE ADJACENT DUPLICATE command always run sorted standard
table or sorted table with non-unique key properly.
In this statement we are comparing EBELN (PO No.). If we don't mention this then all fields will come into
the comparison. Then any change in any field will be compared and it will fall into the unique category. So
comparing field or fields is very important for this to avoid logical error.
REPORT zabap_gui.
WRITE: /3 'Item',
13 'Quantity(KG)',
28 'Price(Rs)'.
WRITE / '=========================================='.
SKIP. " Skipping one single line
SKIP.
WRITE '=========================================='.
Collect Statement
COLLECT statement can be used in the internal table whose non key fields are all numeric. It means the
statement finds the key (non numeric fields) and if the records are same then the statement will add all
other numeric field values. The prerequisite of this statement is that the internal table must have numeric
data type fields which are non key fields. COLLECT statement can be applied on any type of internal
tables.
If we run the collect statement upon this table then the output will be as following
WRITE: /3 'Item',
13 'Quantity(KG)',
28 'Price(Rs)'.
WRITE / '=========================================='.
SKIP. " Skipping one single line
WRITE: /3 wtab-item,
12 wtab-quantity,
25 wtab-price.
ENDLOOP.
SKIP.
WRITE '=========================================='.
Control Break - AT NEW statement
AT NEW is one of a control break statements. It works inside the LOOP – ENDLOOP. Let’s take an
example. We have prepared an internal table where we are storing 50 rows of material, plant & storage
location data. Now we run the operation of AT NEW for plant record. Whenever the system finds a new
plant with respect to previous then it will trigger the AT NEW statement. Here the internal table must be
sorted. Otherwise similar plant may come afterwards and system will trigger AT NEW wrongly.
IF sy-subrc = 0.
SORT itab.
WRITE: / 'Material', 20 'Plant', 27 'Storage Location'.
ULINE.
AT NEW werks.
WRITE: '***** AT NEW plant triggers at ', sy-tabix.
ENDAT.
ENDLOOP.
ENDIF.
Now we shall see at debugging mode how AT NEW works. At the first loop iteration AT NEW will
definitely trigger because the plant is read as new. Here SY-TABIX = 1.
After entering into AT NEW, we can see the other fields which are right side of the mentioned field contain
***. Only the mentioned field contains the proper data.
After that whenever system finds a new plant data it will trigger AT NEW similarly. Here at SY-TABIX = 3.
AT END OF statement always triggers when there is any change of fields’ data. This statement triggers at
the last occurrence of that value. Let’s take an example. We have a table MARD which contains material,
plant & storage location. Now we want to trigger AT END OF at the last occurrence of plant data as
follows.
As we can see that the statement triggers at the last occurrence of plant data.
START-OF-SELECTION.
AT END OF werks.
WRITE: '=== At End Of plant - triggers at line ', sy-tabix.
ENDAT.
ENDLOOP.
Here we have shifted the plant (WERKS) at field 1 in structure level. Otherwise system will consider
material & plant both as a key. Because the AT END OF will trigger if there is any change from left most
field to the particular field.
Now we want to see at the debugging level of AT END OF statement. On second line it has triggered
because that is the last occurrence of plant 1200. SY-TABIX = 2. For the rest of the rows system will skip
the AT END OF statement.
There is only one entry for plant 7500. So it triggers at the next loop iteration. SY-TABIX = 16.
At the last of the table record AT END OF triggers. Here the plant occurrence & table data both are of last
entry.
AT FIRST triggers at the first loop iteration whereas AT LAST triggers at the last loop iteration. We can’t
mention any particular field here as we can do in AT NEW or AT END OF. The main purpose of this
control break is to write some header or footer information. We can write some header info by using AT
FIRST statement and similarly some footer info by using AT LAST statement.
START-OF-SELECTION.
IF sy-subrc = 0.
SORT itab BY werks.
WRITE: / 'Material', 20 'Plant', 27 'Storage Location'.
ULINE.
AT FIRST.
WRITE: '===AT FIRST will trigger here'.
ENDAT.
AT LAST.
WRITE: '===AT LAST will trigger here'.
ENDAT.
ENDLOOP.
ENDIF.
Now at the debugger level we see the following results. AT FIRST triggers at 1st loop iteration when SY-
TABIX = 1. Here all fields of work area are ***.
After that the system triggers AT LAST statement at the last loop iteration when SY-TABIX = 25.
Previously the values of work area are also ***.
ON CHANGE OF triggers when there is any change of the first occurrence of mentioned fields’ value. It
means it actually works like AT NEW statement. If there is any change of the value of the mentioned field
then ON CHANGE OF will trigger. At the time of triggering all of other fields contain their respective data.
Hence it doesn’t go for *** value at the time of triggering. ON CHANGE OF can be used outside the loop
also.
REPORT zctrlbrk_on_change NO STANDARD PAGE HEADING.
START-OF-SELECTION.
IF sy-subrc = 0.
SORT itab BY werks.
WRITE: / 'Material', 20 'Plant', 27 'Storage Location'.
ULINE.
ON CHANGE OF wtab-werks.
WRITE: '=== On Change Of triggers at plant - ', wtab-werks.
ENDON.
ENDLOOP.
ENDIF.
Now at debugging level we can see as follows. At first loop iteration system will definitely triggers the ON
CHANGE OF statement because the plant data is new. All other fields contain their respective data at the
time of triggering.
Control Break with SUM statement
SUM statement can only be used in LOOP – ENDLOOP statement. It is considered in AT – END AT
control break structure. Inside the control break SUM calculates the sum of all the fields which are like I or
P or F type. SUM holds the summation at it is reflected to the respective work areas. This summation
must be the total of current control break. SUM doesn’t work when the row type of the internal table
contains table type components.
Here we have prepared an example in which purchase order item table EKPO has been selected. Now
we use SUM statement which calculates the summation of quantity & net price inside the AT END OF
control statement. Hence at the last occurrence of PO the system calculates the total quantity & price for
different item level.
*-----Event Initialization---------------------------------------------*
INITIALIZATION.
SELECT-OPTIONS: s_ebeln FOR ekpo-ebeln.
IF sy-subrc = 0.
IF v_flag = 'X'.
WRITE: / wa_ekpo-ebeln,
20 wa_ekpo-ebelp,
27 wa_ekpo-menge,
45 wa_ekpo-meins,
50 wa_ekpo-netpr.
ELSE.
WRITE: /20 wa_ekpo-ebelp,
27 wa_ekpo-menge,
45 wa_ekpo-meins,
50 wa_ekpo-netpr.
ENDIF.
In below example we are fetching records of PO no, item no, material, plant & storage location from table
EKPO where the PO no is 3000000232. The database contains only 3 items for this PO.
REPORT zabap_gui.
TABLES: ekpo.
* Creating a custom structure of Item Table
TYPES:
BEGIN OF ty_ekpo,
ebeln TYPE ekpo-ebeln,
ebelp TYPE ekpo-ebelp,
matnr TYPE ekpo-matnr,
werks TYPE ekpo-werks,
lgort TYPE ekpo-lgort,
END OF ty_ekpo.
WRITE:/ wa_ekpo-ebeln,
15 wa_ekpo-ebelp,
28 wa_ekpo-matnr,
48 wa_ekpo-werks,
55 wa_ekpo-lgort.
Output of this:
The database contains 3 records here. But select single statement fetches only single record from
database. Here the first record is always fetched by this statement.
Select up to statement is used to mention the rows need to be selected from the database table. If the
database contains that number of rows then it will display accordingly. Here we are declaring an internal
table to store the multiple row records and print the output as well.
REPORT zabap_gui.
TABLES: ekpo.
Select Distinct
Select distinct only selects the unique entries of the fields in the select statement. It will not allow any
duplicate entry into the internal table. In the below example we are having a selection screen where we
are defining a selection range of PO number by select option. At first we are fetching the records with
normal select statement and we find six records from the database.
REPORT zabap_gui.
TABLES: ekpo.
Now with the similar selection range we use select distinct statement and we are getting only three
records. This is because we have selected only the PO number in select statement with distinct clause.
Now distinct will not allow any duplicate entry of PO number.
REPORT zabap_gui.
TABLES: ekpo.
Here we know that one PO can have multiple items. Hence in database table EKPO the PO entries are
having duplicate entries for different items. But selecting the PO number with distinct clause will fetch only
the unique PO number from the database. If we select here the item also with the distinct clause the SAP
system will treat both of those fields as unique. In that case the system will recognize PO number and
corresponding item number is the unique. In this way if we increase the fields in selection the system will
give uniqueness according to the combination of all those selected fields.
To know the total numbers of rows we have used describe table statement so that we can see the total
number records.
REPORT zabap_gui.
TABLES: ekpo.
* Not using Where condition will fetch all rows from the fields
SELECT ebeln ebelp
FROM ekpo INTO TABLE it_ekpo.
Where is optional. By using APPENDING clause we can re-select and fetch another sort of records into
the same internal table. Here the system appends the records to the last position of the internal table.
After appending these records when we write the data then it will come one by one (not in the same row).
In below example at first we have selected PO number. So the system will append the PO numbers only.
After that in the second select the system will select the materials and append those to the last position of
the internal table and so on.
REPORT zabap_gui.
TABLES: ekpo.
REFRESH it_ekpo.
SELECT ebeln
FROM ekpo APPENDING TABLE it_ekpo
WHERE ebeln = '3000000232'.
SELECT matnr
FROM ekpo APPENDING TABLE it_ekpo
WHERE ebeln = '3000000232'.
SELECT werks
FROM ekpo APPENDING TABLE it_ekpo
WHERE ebeln = '3000000232'.
SELECT lgort
FROM ekpo APPENDING TABLE it_ekpo
WHERE ebeln = '3000000232'.
In this case the output will come with the corresponding fields. The system will put the respective data on
the respective fields of the output screen. But the records will come one by one (different rows) rather the
same row.
REPORT zabap_gui.
TABLES: ekpo.
REFRESH it_ekpo.
SELECT ebeln
FROM ekpo APPENDING CORRESPONDING FIELDS OF TABLE it_ekpo
WHERE ebeln = '3000000232'.
SELECT matnr
FROM ekpo APPENDING CORRESPONDING FIELDS OF TABLE it_ekpo
WHERE ebeln = '3000000232'.
SELECT werks
FROM ekpo APPENDING CORRESPONDING FIELDS OF TABLE it_ekpo
WHERE ebeln = '3000000232'.
SELECT lgort
FROM ekpo APPENDING CORRESPONDING FIELDS OF TABLE it_ekpo
WHERE ebeln = '3000000232'.
REPORT zabap_gui.
DATA:
average TYPE p DECIMALS 2,
sum TYPE p DECIMALS 2,
maximum TYPE p DECIMALS 2,
minimum TYPE p DECIMALS 2.
Here we have created a custom structure of the internal table named it_mara. This structure
ty_mara contains Material No, Creation Date, Name, Material Type and Group. Hence output
will have only these fields. We have declared an work area wa_mara for internal table. Here
the internal table is of standard table type.
Now under INITIALIZATION event we have initialized the Program name, date and user name
which are to be displayed at the Top of page. TOP OF PAGE is another event where we are
declaring the select option s_matnr in a selection screen for input of material no.
Next we are declaring the START-OF-SELECTION event under which we mention a subroutine
get_mara. Subroutine is declared by the key word perform. Under this perform we select
required fields from MARA into internal table it_mara based on the where condition. So after
getting proper data from the MARA table we shall prepare the output in the subroutine of
get_output.
Now on the next event END-OF-SELECTION we are declaring a subroutine get_output and
inside there we are looping the internal table it_mara into wa_mara. Hence we fetch the data
from internal table to the work area and then display it with simple write statement. Since
this is a loop, so one by one record will be fetched into work area and then it will be displayed.
Now we want to display the name of the fields heading at the beginning. To do this we call
control break statement at first & endat inside the loop. At first statement will be triggered at
the first time of the loop. Similarly when the listing will be completed then At Last - endat
statement will be triggered to display ending of report message.
Next we raise the event TOP-OF-PAGE which is used to display the top message. On the top
we can write program name, user name, date etc.
REPORT zabap_gui.
*------Declaring the local types for Internal table & Work area--------*
TYPES: BEGIN OF ty_mara,
matnr TYPE mara-matnr, "Material No.
ersda TYPE mara-ersda, "Creation Data
ernam TYPE mara-ernam, "Created By
mtart TYPE mara-mtart, "Material Type
matkl TYPE mara-matkl, "Material Group
END OF ty_mara.
*-------------Event initialization-------------------------------------*
INITIALIZATION.
v_repid = sy-repid.
v_date = sy-datum.
v_user = sy-uname.
IF sy-subrc <> 0.
MESSAGE 'Material Doesn''t Exist.' TYPE 'I'.
LEAVE LIST-PROCESSING.
ENDIF.
WRITE: / wa_mara-matnr,
25 wa_mara-ernam,
40 wa_mara-matkl,
55 wa_mara-mtart,
70 wa_mara-ersda.
ENDLOOP.
ENDIF.
We have created a report which contains multiple tables like MARA, MARC and MARD. The
materials contain different Plant and Storage Location in MARC and MARD tables respectively.
All those different plant and storage location will be displayed with material number in output
here.
Here the plant is a big item and the storage location is small item. One single plant contains
different storage locations. Materials are stored inside one of these storage locations. Now
different materials can be stored in the same storage location.
In the program we have prepared internal table it_mara from MARA table based on the Select
Option material number range. If material number is entered then only the program will give
an output.
After preparing valid information of it_mara the program selects data from MARC (plant) table
into it_marc for all entries in it_mara. Here we have to check the it_mara table if it is not
initial. If we don't give this checking then all records will be selected from MARC table and
that would be wrong. Hence we can say that this table checking is one of a prerequisites of
For All Entries.
Similarly after preparing the it_marc table we shall prepare the it_mard table from MARD
(storage location) for all entries in it_marc. Similarly the table checking of it_marc must be
there.
Now we have material (it_mara), plant (it_marc) & storage location (it_mard) information.
We have to collate all these information to display the required output. To do this we have
prepared an internal table it_out with an work area wa_out. This internal table & work area
contains the structure ty_out as per the report output requirement.
Now we are looping it_mara to fetch material & type into the output work area. Here MARA
is a master table hence we have to loop this table. Now one material can be maintained for
different storage locations under one plant or different plant. Hence to populate output table
we have to loop into it_marc and it_mard table. Here we are looping it_marc and it_mard
with WHERE clause because we are going to fetch all records of plant and storage location at
one time. So where clause will help us to point out the particular material and also will increase
the performance.
Finally at the output population we have used control break statement like AT FIRST, AT END
OF, AT LAST. With the help of that we have synchronized the output in different lines.
REPORT zabap_gui.
BEGIN OF ty_marc,
matnr TYPE marc-matnr,
werks TYPE marc-werks,
xchar TYPE marc-xchar,
END OF ty_marc,
BEGIN OF ty_mard,
matnr TYPE mard-matnr,
werks TYPE mard-werks,
lgort TYPE mard-lgort,
pstat TYPE mard-pstat,
END OF ty_mard,
BEGIN OF ty_out,
matnr TYPE marc-matnr, "Material
werks TYPE marc-werks, "Plant
lgort TYPE mard-lgort, "Storage Location
mtart TYPE mara-mtart, "Material Type
xchar TYPE marc-xchar, "Batch number
pstat TYPE mard-pstat, "Maintenance Status
END OF ty_out.
*------Event initialization--------------------------------------------*
INITIALIZATION.
v_prog = sy-repid.
v_date = sy-datum.
v_time = sy-uzeit.
*-----------Declaring selection screen with select option for input----*
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.
SELECT-OPTIONS: s_matnr FOR mara-matnr.
SELECTION-SCREEN END OF BLOCK b1.
*&---------------------------------------------------------------------*
*& Form GET_MARA
*&---------------------------------------------------------------------*
* Select data from MARA table
*----------------------------------------------------------------------*
FORM get_mara .
IF sy-subrc = 0.
SORT it_mara BY matnr.
ELSE.
MESSAGE 'Material doesn''t exist' TYPE 'I'.
ENDIF.
ENDIF.
IF sy-subrc = 0.
SORT it_marc BY matnr.
ELSE.
MESSAGE 'Plant doesn''t exist' TYPE 'I'.
ENDIF.
ENDIF.
IF sy-subrc = 0.
SORT it_mard BY matnr.
ELSE.
MESSAGE 'Storage Location doesn''t exist' TYPE 'I'.
ENDIF.
ENDIF.
WRITE: / wa_out-matnr,
21 wa_out-werks,
27 wa_out-lgort,
37 wa_out-mtart,
45 wa_out-xchar,
54 wa_out-pstat.
IF wa_out-matnr IS INITIAL.
AT END OF matnr. "Control break statement
SKIP.
ENDAT.
ENDIF.
WRITE: / v_prog,
/ v_date DD/MM/YYYY,
/ v_time.
ULINE.
Output:
1. Selection Screen -
2. Classical Display -
Classical Interactive Report
Interactive program generally interacts with user on the output screen. Let us suppose we
have an output for a particular program/report. Now if we want details description by double
clicking on a particular field or clicking on a button then it will be called interaction with
output. By doing this we can go to the detailed report or secondary output. When we are on
the secondary output then we can back to our first out by clicking on Back button. We can
generate 20 secondary list of output. Hence a total of 21 output screen (1 Primary
+ 20 Secondary) can be generated by Interactive program.
We have mentioned the tables EKKO, EKPO and T161T. Now we have declared the structure
types of internal tables of it_ekko, it_text, it_out1 and it_ekpo. Here it_out1 contains the
combination of two internal tables it_ekko and it_text and it_ekpo is for the secondary output.
For internal operation we have declared work area of every internal tables.
Next we have mentioned the event INITIALIZATION. Under this we are calling program name,
user name and system date of the program. We have declared here selection screen begin
with block b1 and under this we are mentioning obligatory select option.
Now under START-OF-SELECTION we are declaring all the operations for primary listing. We
have made 4 subroutines. In get_ekko we select fields from EKKO into internal table it_ekko.
Then in get_t161t we select fields from t161t into internal table it_text for all entries in
it_ekko. After that we are preparing the primary output in the basic_output subroutine. Now
we have made another subroutine for displaying the primary output and that is disp_basic.
Hence the primary list is prepared now and now we have to create the secondary list. To
make the secondary list we are calling event AT LINE-SELECTION which raises functionality
when user double clicks in any field. Now we are mentioning GET CURSOR for that field and
for that value of the field. When these two are matches with Purchase Order (EBELN) field
then we are calling two subroutines for secondary list.
Subroutine get_ekpo Selects fields from EKPO into table it_ekpo for all entries in it_ekko.
Then it prepares the secondary output display in the subroutine of ekpo_output.
We also have raised events TOP-OF-PAGE which shows the header list of primary output and
TOP-OF-PAGE DURING LINE-SELECTION which shows the top list of secondary output. Here
TOP-OF-PAGE DURING LINE-SELECTION is used only for interactive reports. That means when
user double clicks on the field the TOP-OF-PAGE DURING LINE-SELECTION event triggers to
make the secondary output header.
REPORT zabap_gui.
BEGIN OF ty_text,
spras TYPE t161t-spras,
bsart TYPE t161t-bsart,
bstyp TYPE t161t-bstyp,
batxt TYPE t161t-batxt, "PO Info
END OF ty_text,
BEGIN OF ty_ekpo,
ebeln TYPE ekpo-ebeln, "Purchase Order
ebelp TYPE ekpo-ebelp, "PO Item
matnr TYPE ekpo-matnr, "Material
werks TYPE ekpo-werks, "Plant
lgort TYPE ekpo-lgort, "Storage Location
matkl TYPE ekpo-matkl, "Material Group
menge TYPE ekpo-menge, "Quantity
meins TYPE ekpo-meins, "Unit
END OF ty_ekpo,
BEGIN OF ty_out1,
ebeln TYPE ekko-ebeln,
bukrs TYPE ekko-bukrs,
bstyp TYPE ekko-bstyp,
bsart TYPE ekko-bsart,
lifnr TYPE ekko-lifnr,
batxt TYPE t161t-batxt,
END OF ty_out1.
* Event Initialization
INITIALIZATION.
v_repid = sy-repid. "Program Name
v_user = sy-uname. "User name
v_date = sy-datum. "Current Date
CASE v_field1.
* When we double click on PO number on Basic output list
WHEN 'WA_OUT1-EBELN'.
PERFORM get_ekpo. "Get data from Item table
PERFORM ekpo_output. "Displaying output of second list
ENDCASE.
CASE v_field2.
* When we double click on Material on Second list
WHEN 'WA_EKPO-MATNR'.
PERFORM get_mara. "Get Information by calling MM03 Transaction
ENDCASE.
*&---------------------------------------------------------------------*
*& Form get_ekko
*&---------------------------------------------------------------------*
* Get data from header table
*----------------------------------------------------------------------*
FORM get_ekko .
IF sy-subrc = 0.
SORT it_ekko BY ebeln.
ELSE.
MESSAGE 'Purchase Order doesn''t exist.' TYPE 'I'.
LEAVE LIST-PROCESSING.
ENDIF.
IF sy-subrc = 0.
SORT it_text BY bsart bstyp.
ENDIF.
ENDIF.
WRITE: / wa_out1-ebeln,
20 wa_out1-bukrs,
33 wa_out1-bstyp,
40 wa_out1-bsart,
50 wa_out1-lifnr,
65 wa_out1-batxt.
IF sy-subrc <> 0.
MESSAGE 'PO Item doesn''t Exist.' TYPE 'I'.
LEAVE LIST-PROCESSING.
ENDIF.
ENDIF.
ENDIF.
AT FIRST.
WRITE: / 'Purchase Order',
20 'PO Item',
30 'Material',
48 'Plant',
55 'Storage',
65 'Material Group',
83 'PO Quantity',
100 'Unit'.
ULINE.
SKIP.
ENDAT.
WRITE: / wa_ekpo-ebeln,
20 wa_ekpo-ebelp,
30 wa_ekpo-matnr,
48 wa_ekpo-werks,
55 wa_ekpo-lgort,
70 wa_ekpo-matkl,
75 wa_ekpo-menge,
100 wa_ekpo-meins.
AT LAST.
SKIP.
ULINE.
WRITE: /12 '~~End of PO Item~~'.
ENDAT.
ENDLOOP.
ENDIF.
Primary Listing:
If we double click on the PO in this list then following will be generated:
Classical Interactive with Push Button
Interactive reports increase the visibility of user when the user interacts with the basic list to get detail
secondary lists. The basic list contains the brief information whereas the detail list contains the detail
information. As per the requirement the user interacts with the detailed list whenever it is needed. That is
the reason why it increases the visibility. Instead of an extensive and detailed list the user can actively
control data retrieval and display during the session through this interactive report. The user can interact
with the report with having the cursor position and entering the command.
To interact by using a push button the R/3 system has an option which is menu painter. We can do this by
using the PF-STATUS. With the help of that we can create our customized menu where we can set push
button. After that we have to write functionality under the event at user command. The push button must
have a function code and by using that we can write our custom function. The system field SY-UCOMM is
used to set the different functions in different push buttons.
Here we have an example where we select Vendor account details based on the selection criteria by
select options. The report will have a basic list which will display the vendor details from LFA1 table. Then
by selecting a vendor account number if we click the push button Purchase Order then we shall go to the
first secondary list. This list is coming from the EKKO table. After that if we select any purchase order and
then click the PO item button then second secondary list will be coming. This list is coming from EKPO
table.
In this point of view we have used HIDE statement. HIDE actually hides the field value into the system to
reuse that at any time. With the help of this statement the system loads the field name, field content and
line number in which the line exists. The line number is stored in SY-LINNO field. Field symbols cannot be
specified in HIDE. This statement works independently. If we select the cursor to any blank field then also
the HIDE will store that value.
REPORT zabap_gui.
BEGIN OF ty_ekko,
ebeln TYPE ekko-ebeln,
bukrs TYPE ekko-bukrs,
aedat TYPE ekko-aedat,
ernam TYPE ekko-ernam,
lifnr TYPE ekko-lifnr,
END OF ty_ekko,
BEGIN OF ty_ekpo,
ebeln TYPE ekpo-ebeln,
ebelp TYPE ekpo-ebelp,
matnr TYPE ekpo-matnr,
werks TYPE ekpo-werks,
lgort TYPE ekpo-lgort,
END OF ty_ekpo.
DATA:
*-----Declaring Work Areas---------------------------------------------*
wa_lfa1 TYPE ty_lfa1,
wa_ekko TYPE ty_ekko,
wa_ekpo TYPE ty_ekpo,
*---Event Initialization-----------------------------------------------*
INITIALIZATION.
SELECT-OPTIONS: s_lifnr FOR lfa1-lifnr.
REFRESH it_lfa1.
IF sy-subrc = 0.
LOOP AT it_lfa1 INTO wa_lfa1.
WRITE: / wa_lfa1-lifnr,
20 wa_lfa1-land1,
25 wa_lfa1-name1,
65 wa_lfa1-regio.
ELSE.
MESSAGE 'Vendor doesn''t exist' TYPE 'I'.
ENDIF.
ELSE.
MESSAGE 'Please enter a valid Vendor Account Number' TYPE 'I'.
LEAVE LIST-PROCESSING.
ENDIF.
REFRESH it_ekko.
IF sy-subrc = 0.
LOOP AT it_ekko INTO wa_ekko.
WRITE: / wa_ekko-ebeln,
15 wa_ekko-bukrs,
22 wa_ekko-aedat,
34 wa_ekko-ernam,
50 wa_ekko-lifnr.
REFRESH it_ekpo.
IF sy-subrc = 0.
LOOP AT it_ekpo INTO wa_ekpo.
WRITE: / wa_ekpo-ebeln,
15 wa_ekpo-ebelp,
22 wa_ekpo-matnr,
42 wa_ekpo-werks,
50 wa_ekpo-lgort.
AT LAST.
SKIP 2.
WRITE: /25 'End of Material List'.
ENDAT.
ENDLOOP.
ENDIF.
ELSE.
MESSAGE 'Select a Purchase Order' TYPE 'I'.
ENDIF.