You are on page 1of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

Abap/4 Coding Standards & Code Efficiency Standards

1 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

Document Control
Author File Name Path Created Last Edited Number of Pages 29 February, 2000 29 February, 2000 38 PricewaterhouseCoopers ITC ABAP Coding Standards and Code Efficiency Standards.doc

Version 0.1 0.2

Revision Date 29/02/2000

Revision Description Initial Release

Author Milan Day

Sign-off

Target Readership Project Management Team Technical Team Members

2 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

Table of Contents
1.0 General Rules..........................................................................................................................................4 1.1 Commands : .......................................................................................................................................4 2.0 Coding Style...........................................................................................................................................6 3.0 Report Standard......................................................................................................................................8 4.0 Data Definition.......................................................................................................................................9 5.0 Online Standard....................................................................................................................................10 6.0 Batch Program / Interface Standards....................................................................................................10 7.0 Message................................................................................................................................................11 8.0 Program Logic......................................................................................................................................11 9.0 Data Access..........................................................................................................................................13 10.0 Index Design.......................................................................................................................................15 11.0 Online Standards................................................................................................................................16 12.0 Internal Table ....................................................................................................................................16 13.0 String Operation..................................................................................................................................22 14.0 Hardcoding.........................................................................................................................................24 15.0 Skeleton Programs..............................................................................................................................26 15.1 Basic ABAP List Report.................................................................................................................26 15.2 Interactive ABAP List Report.......................................................................................................29 15.3 Create a Sequential Dataset...........................................................................................................32 15.4 Read Sequential Dataset and Create a BDC Session.....................................................................34 15.5 CALL TRANSACTION USING Technique.................................................................................37

3 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

This section contains a list of ABAP coding standards, as well as some efficiency standards. The purpose of these standards is to: Encourage consistent practices among programmers: Programs coded by different people should follow standard coding conventions. Provide internal documentation: Programs should be documented to the extent that another programmer could follow the logic of the code. Improve readability: Programs should follow a format that makes the code easy to read.

1.0 General Rules 1.1 Commands :


The following is a selected list of preferred and useful commands along with a short functionality description of the command. For further details, use the ABAP editor help. Youll find an ABAP command list via menu path Utilities->ABAP keyword doc. in the ABAP editor initial screen. If you use the command mode of the ABAP Editor, type help <command> at the command line.

Catch/EndCatch
You can catch ABAP runtime errors in the processing block enclosed in the CATCH ... ENDCATCH statements. Syntax: CATCH SYSTEM-EXCEPTIONS except1 = rc1 ... exceptn = rcn. Note the following: 2. rc1 ... rcn must be numeric literals. 3. CATCH ... ENDCATCH may be placed anywhere where IF ... ENDIF (for example) may occur. It is local, not cross-event. 4. It may be nested to any depth. 5. It only catches runtime errors in the current call level. This means, for example, that runtime errors resulting from PERFORM- or CALL FUNCTION statements are not trapped by CATCH ... ENDCATCH. Example: PARAMETERS FACT TYPE I. DATA: FACT_SAVE TYPE I, RES(16) TYPE P. *** ARITHMETIC_ERRORS CONTAINS COMPUTE_BCD_OVERFLOW *** CATCH SYSTEM-EXCEPTIONS ARITHMETIC_ERRORS = 5. RES = FACT_SAVE = FACT. SUBTRACT 1 FROM FACT. DO FACT TIMES. MULTIPLY RES BY FACT. "<- COMPUTE_BCD_OVERFLOW SUBTRACT 1 FROM FACT. ENDDO. ENDCATCH. IF SY-SUBRC = 5. WRITE: / 'OVERFLOW! FACTORIAL OF', FACT_SAVE, 'CAN NOT BE CALCULATED.'. ELSE. WRITE: / 'FACTORIAL OF', FACT_SAVE, 'GIVES', RES. 4 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

ENDIF.

Commit Work and Rollback Work


COMMIT WORK is used when doing database operations. It concludes a logical process and releases all database locks. SY-SUBRC is set to zero if the COMMIT WORK was successfully performed. Once a COMMIT WORK statement has been executed, it is not possible to rollback (ROLLBACK WORK) the previous database operations. Note: You cannot perform a COMMIT WORK within a SELECT loop since all open database cursors will be closed. To perform a COMMIT WORK when processing a large amount of data, a logical loop must be created where the read-loop is processed. Example:
DATA: C_COMMIT_RECS(4) TYPE

C VALUE 5000. CLEAR: MATNR, FLG_EOF.

WHILE FLG_EOF IS INITIAL. CLEAR CNT_MARA. SELECT FIELD1 FIELD2 INTO (MARA-FIELD1, MARA-FIELD 2) FROM MARA WHERE MATNR GT MATNR. IF CNT_MARA = COMMIT_RECS. EXIT. ENDIF. PERFORM UPD_MATERIAL. CNT_MARA = CNT_MARA + 1. MATNR = MARA-MATNR. ENDSELECT. IF SY-SUBRC NE 0. FLG_EOF = X. ENDIF. COMMIT WORK. ENDWHILE. When creating a program that writes new or update existing records you MUST ensure that your program handles COMMIT at a reasonable frequency. As a general rule, you should perform a commit every 1000 or 10 000 records. If your program is running for a long period of time without a commit, the data base and finally the whole system will be deadlocked and eventually shutting down the system is the only option left to terminate the execution as all resources are consumed by your program.

Describe
The DESCRIBE statement retrieves the attributes of a field, an internal table or a list. Use this command to check whether an internal table contains data. Syntax: DESCRIBE <ITAB> LINES LINES.

Free
In programs where internal tables handle extremely large amounts of data, the FREE command should be used instead of the REFRESH command to clear the table. The FREE command empties the table of all records and restores the table to the originally allocated memory size (number of occurrences times the table/structure length). The REFRESH command only clears the table.

Include
5 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

Use the INCLUDE statement to copy an existing form routine or data structure to your program. All includes must be described with a comment in your code.

ABAP programs that update master and transactional data MUST ALWAYS use SAP transaction codes (where transaction codes are available) by utilizing BDC or call transaction utilities. The only exception to this would be the use of a BAPI or "direct input" program provided by SAP. These methods ensure that logical units of work, rollback, locking operations and edits are performed. SAPsupplied tables MUST NEVER be updated directly by custom programs. ABAP programs MUST NEVER be used to update configuration tables. SAP-delivered ABAP programs, Dynpros, SAP transactions and Batch programs should never be changed without the approval of the Development Team Leader. SAP approval will also generally be required. If it becomes necessary to modify one of these objects, then, if possible, the object should be copied to a new name using SAP naming standards, and modifications should be made to the copied object. Before writing any code, make sure that no existing programs or function modules, either custom or SAP-supplied, satisfy the coding requirements. If custom coding is necessary, attempt to write the module so that it is re-usable and can be stored in a central library. Function modules are an example of this approach. When performing modifications and user exits it is good programming practice to put your new entries in an include and then call the include from the SAP object. This applies to program code as well as tables and structures. This technique reduces the disruption to others working on the system while you're performing the modification. It also makes it easier to re-implement your work after an upgrade, where the SAP object has been overwritten.

2.0 Coding Style Standard:


ABAP is an event driven programming language. However, proper program structure and modular coding are still important to maintain readability and efficiency of an ABAP program. A program should be divided into distinct sections, which are properly documented in the code. Whenever possible, use function modules already available instead of creating new ones. Use descriptive names for forms (sub routines) like: FORM INTIALISATION. FORM MAIN_PROCESSING.FORM ERR_CATCH_NO_NUMBER. FORM ERR_CATCH_NO_FILE. FORM LABEL_FETCH. Note: If a form contains very general functionality that could be used in other programs, it may be useful to create it as a function module. When events (e.g. END-OF-SELECTION, TOP-OF-PAGE, etc.) are used in the code, they should appear in the order in which they are generally executed. Skipped lines and indention should be used to promote clarity between sections of code as well as between file definitions and declarations.

6 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

For ease of reading code, concatenate repetitive commands with a colon as provided by SAP. All TYPEs, TOs, VALUEs, DEFAULTs, table names, and comments should be aligned among themselves throughout the code, For example.
LFA1_LIFNR, LFA1_NAME1, LFA1_ORTO1.

WRITE:

Use subroutines and FORM paragraphs whenever possible to improve readability and logic flow. If a block of code is executed more than once, it should be placed in a subroutine at the bottom of the code. FORM paragraphs should be placed after all non-subroutine code, after the END-OF-SELECTION event. FORM paragraphs should be positioned in the order in which they are called within the program. Every logical division within the program should have descriptive comments immediately prior to the actual code. Each program should have a comment box before the REPORT statement as shown below:

*&--------------------------------------------------------------------------------------------------------&* *& Program Name : Zxxxxxxxx &* *& Author : xxxxxx xxx , xxxxx xxxxx &* *& Module Name : Financial Accounting &* *& Sub-Module : Accounts Payable &* *& Program Type : Reports Create Date : xx/xx/xxxx &* *& SAP Release : 4.0 B Transport No : xxxxxxxxxx &* *& Description : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &* *& xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &* *&--------------------------------------------------------------------------------------------------------&* The above pattern can be got by inserting the pattern Header Pattern into your source code.

Once the program is in the production environment, every modification, no matter how insignificant, should be documented with an additional comment box added to the program. This provides an easy audit trail of the programs history, and also allows for comparison of versions in different environments at a glance rather than via remote comparisons. The modification comment box should look as follows:

*&--------------------------------------------------------------------------------------------------------&* *& REVISION LOG &* *&--------------------------------------------------------------------------------------------------------&* *& Revision No : 001 Transport No : Date : xx/xx/xx &* *& Developer : xxxxxxxxxxx xxxx Id String : MD001 &* *& Description : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &* *& xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &* *& xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &* The above pattern can be got by inserting the pattern Revision Pattern into your source code.

Comment all subroutines with their purpose. Comments should explain the business reasons for the code in a particular section and what the code in that section is accomplishing. Comments should not explain individual ABAP commands. Allow the ABAP editor to generate the comment box, by coding the "PERFORM <form>" statement and double-clicking on the <form>. Be sure to document the input and output parameters for the specific form in the comment box. Dead Code should be removed from the program, i.e., the fields which are never referenced and code which can never logically executed.

Guideline :

7 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

Keep programs to a reasonable length. Programs should be long enough so that there is not an excessive amount of data being passed between two related programs, but should be short enough so that the same program does not perform many discrete functions. Consider the use of INCLUDE programs for Data Declarations, PBO Dynpro modules, PAI Dynpro modules, Subroutines, and Individual Event Processing. Do not use complicated arithmetic expression, avoid COMPUTE, ADD, and other keyword whenever possible, e.g. using DATA = DATA + 1 instead of ADD 1 to DATA.

Tip :
The ABAP editor has a PP (Pretty Printer) command to indent specific lines of code by 2 positions and add subroutine comments. Menu path: program/pretty printer in ABAP Editor. However, since this command is CPU intensive, its use should be kept to a minimum. Use it only after making a series of changes for a new version of the program, rather than after each individual change.

3.0 Report Standard Standard :


The reports should be coded with "NO STANDARD PAGE-HEADING" specified in the "REPORT" statement. Then, in the "TOP-OF-PAGE" event, a function module should be CALLed for writing project standard header. Specify blank lines (for output) by using SKIP TO LINE <nn> or "SKIP <n>, rather than multiple WRITE / lines. For program parameters, use Selection Texts to specify literals that will appear on the screen via editing Text Elements of the program. This will enable the literal to be implemented in multiple languages. Do not use hard-coded literals. Use Text Elements to handle literal text that is printed on a report, the advantage is easier maintainability. Text elements should be defined and used in the WRITE command in addition to a corresponding string value. This technique ensures accuracy of output by using text elements, while improving readability of the program. WRITE: /20 '*'(001), /30 'COMPANY CODE TOTALS OF VENDORS'(002), /30 'COMPANY CODE OVERVIEW PER VENDOR'(003), /30 'AND A CLOSING SHEET.'(004). There should be no hard-coding of date formats in the programs, The date format of the users default information (SU3) should be used to output any date. There will be no hard-coding of currency output formats in our programs. The decimal notation of the users default information (SU3) should be used to output any currency value. The European standard paper size is A4 (210 x 297 mm) whereas the US standard is Letter size (8.5 x 11 inches). A4 is a little bit longer and a little bit narrower than Letter size paper. The reports should be designed so that they will work on either paper size, so we dont end up creating two versions of a report simply to accommodate the different dimensions. This means we should design our reports to fit on the minimum dimension of each, in Landscape orientation the report should be designed to fit Letter length (11 inches) and A4 width (210 mm). 8 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

A standard function module should be created ZZ_HEADER_ROUTINE to print a standard page heading for the report. This function module should be called in the TOP-OF-PAGE event.

4.0 Data Definition Standard :


Use CONSTANTS for variables whose values do not change (Static Data). Define CONSTANTS rather than Text Elements for these non-output hard code literals in the program. For example: CONSTANTS : C_ONE_THOUSAND TYPE I VALUE 1000, C_TRUE TYPE C VALUE TRUE, C_FALSE TYPE C VALUE FALSE. For each field, include a comment (after the field) describing the use or purpose of the field. LIKE verb is used while declaring the fields whenever feasible, e.g. when assigning internal fields that are to hold values from databases, use the LIKE option to ensure that the variables have identical characteristics. Data length and data type are not left as default. Only one table shall be listed on any one line of the program, and the table description should be added as the end of line comment. Example: TABLES: T100, TAPLT. TDCT, T001, Company codes Messages Program applications Dialog Modules

INCLUDES are created for data declarations and any data structures that will be used in more than one ABAP program.

Guideline :
Variable names should be descriptive, meaningful and understandable. Do not use "field symbols" unless there is no simpler method available. If "field symbols" are used, their use must be fully explained in program comments at the place were the symbol is defined and used. Global variables are minimized by declaring local variables or by passing parameters while creating internal subroutines. Specify the type of field-symbols and formal parameters in source code, the ABAP compiler can better optimize the code. Field-Symbol without type Typed Field-Symbol FIELD-SYMBOLS: <F>. FIELD-SYMBOLS: <I> TYPE I. 9 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

ASSIGN I1 TO <F>. I2 = <F>. I3 = <F>. I4 = <F>.

ASSIGN I1 TO <I>. I2 = <I>. I3 = <I>. I4 = <I>.

5.0 Online Standard Standard :


Always define the field with a Format = OK as OK_CODE. This field is used to validate the OK Event. Define all global data in the main program (TOP) module instead of the PBO/PAI. To handle a lock entry failure, invoke an error message (type E) to prevent any further progress but leaving the user on the current screen. The user can then take an alternative action or continue to try to lock the object. To minimize the impact on users, limit retries. When activating buttons or boxes, activate the associated text as well. This enables the user to click on either the button/box or the text. Do not use AT PFnn in programs. Instead use the function name so that any method of invoking the function will have the same effect as the use of the PF-Key.

Guideline :
Use Data Dictionary names (short, medium, long) for field text on screens where applicable.

6.0 Batch Program / Interface Standards Standard :


Document program variant(s) if a program needs to run with special parameters. An ABAP program that reads from or writes to a sequential dataset should always OPEN the dataset before the read/write operation, and after file processing it should CLOSE the file. Although these statements are not mandatory, it is good practice to include them. Also, without an OPEN DATASET statement, a file will always be opened in BINARY mode. This may not be the mode required!

Guideline :
Message statements executed in batch programs are output to the txn SM37 "Job Log". "Success" messages (type 'S') should be used generously to provide an audit trail of the program's execution. Define Logical filename as parameters See the following example: DATA: DATA: G_PDSNME LIKE FILENAME-FILEEXTERN. "Physical Dataset BEGIN OF T_TAB OCCURS ... END OF T_TAB. 10 of 38 Name.

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

PARAMETERS: P_LDSNME LIKE FILENAME-FILEINTERN "Logical Dataset Name DEFAULT 'CUSTOMER_FILE'. AT SELECTION-SCREEN. CALL FUNCTION 'FILE_GET_NAME' EXPORTING LOGICAL_FILENAME = P_LDSNME IMPORTING FILE_NAME = G_PDSNAME EXCEPTIONS FILE_NOT_FOUND = 01. IF SY-SUBRC <> 0. *-------No physical filename can be determined for & MESSAGE E016(MG)WITH P_LDSNME. ENDIF. START-OF-SELECTION. OPEN DATASET G_PDSNME FOR OUTPUT IN TEXT MODE. IF SY-SUBRC <> 0. * Insert error processing here. ENDIF. TRANSFER T_TAB TO G_PDSNME. CLOSE DATASET G_PDSNAME.

7.0 Message Standard :


Do not use SAP-supplied default message IDs, as these IDs can change from release to release. Instead, copy these messages to customer message IDs.

Guideline :
Messages are included at appropriate places to indicate illegal operation, no authorization, no data found, etc.

8.0 Program Logic Standard :


A program should test the system return code field (SY-SUBRC) after any statements that could potentially change its value unless the outcome of the statement is not important for subsequent processing. The return code should always be checked after any database table read/update statements. 11 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

Guideline :
CHECK is used instead of IF/ENDIF whenever possible When Coding IF, nest true testing conditions, so that the outer conditions are most frequently true. CASE statements are clearer for legibility and a little faster than IF-constructions. When testing fields equal to something one can use either the nested IF or the CASE statement. CASE statements are clearer and after about five nested Ifs the performance of the CASE is more efficient. WHILE is used instead of a DO+EXIT-construction, because WHILE is easier to understand and faster to execute. Do I1 = 0. DO. IF C1A NE SPACE. EXIT. ENDIF. ADD 1 TO I1. IF I1 GT 10. C1A = 'X'. ENDIF. ENDDO. Runtime Measure(in microsec): 5 While I1 = 0. WHILE C1A = SPACE. ADD 1 TO I1. IF I1 GT 10. C1A = 'X'. ENDIF. ENDWHILE. Runtime Measure(in microsec): 3

Notes: The runtimes depicted in this manual are just sample measurement, they are measured on multiprocessor environment, they are, however, not runtime measurement benchmarks. LOOP . WHERE is faster than LOOP/CHECK because LOOP . WHERE evaluates the specific condition internally. Loop/Check LOOP AT ITAB. CHECK ITAB-NAME1 = KVAL. ENDLOOP. Loop/Where LOOP AT ITAB WHERE NAME1 = KVAL. . ENDLOOP.

Tip :
CHECK, EXIT, REJECT, STOP is used to suspend processing or skip unnecessary processing. Use PERFORM i OF statement when calling a certain routine based on a given index, instead of using CASEWHEN/PERFORM, since the first statement is fast to execute. Case Perform i Of * (I1 = 5 in this test) * (I1 = 5 in this test) CASE I1. PERFORM I1 OF WHEN 1. PERFORM PV1. PV1 WHEN 2. PERFORM PV2. PV2 WHEN 3. PERFORM PV3. PV3 WHEN 4. PERFORM PV4. PV4 WHEN 5. PERFORM PV5. PV5 WHEN 6. PERFORM PV6. PV6 WHEN 7. PERFORM PV7. PV7 WHEN 8. PERFORM PV8. PV8. Runtime Measure(in microsec): 5 Runtime Measure(in microsec): 2

12 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

9.0 Data Access Standard :


Minimise database accesses. Keep the number of communication processes between the database and application servers, as well as the transferred dataset as small as possible. Do the most restrictive calls first. For example, to process all materials with a quantity-on-hand above 50, the tables containing stock quantities should be read before the material master tables. In a SELECT statement, only the fields that are needed are selected in the order that they reside on the database, thus network load is considerably less. The number of fields can be restricted in two ways using a field list in the SELECT clause of the statement or by using a view defined in ABAP Dictionary. The usage of view has the advantage of better reusability. Select * SELECT * FROM DD01L WHERE DOMNAME LIKE 'CHAR%' AND AS4LOCAL = 'A'. ENDSELECT. Runtime Measure(in microsec): 42,880 Select with select list SELECT DOMNAME FROM DD01L INTO DD01L-DOMNAME WHERE DOMNAME LIKE 'CHAR%' AND AS4LOCAL = 'A'. ENDSELECT. Runtime Measure(in microsec): 11,402

SELECT SINGLE is used instead of SELECT-ENDSELECT loop if full primary key is known. Otherwise, use Up to 1 Rows. SELECT SINGLE requires one communication with the database system. Select Endselect Select Single SELECT * FROM SCARR SELECT SINGLE * FROM SCARR WHERE CARRID = 'LH'. WHERE CARRID = 'LH'. ENDSELECT. Runtime Measure(in microsec): 861 Runtime Measure(in microsec): 741 Always specify the conditions in the WHERE-clause instead of checking them with check-statements, The database system can then use an index (if possible) and the network load is considerably less. You should not check the conditions with the CHECK statement because the contents of the whole table must be read from the database files into DBMS cache and transferred over the network. If the conditions are specified in the where clause DBMS reads exactly the needed data. Select + Check statement Select with Where condition SELECT * FROM SBOOK. SELECT * FROM SBOOK CHECK: SBOOK-CARRID = 'LH' AND WHERE CARRID = 'LH' AND SBOOK-CONNID = '0400'. CONNID = '0400'. ENDSELECT. ENDSELECT. Runtime Measure(in microsec): 2,509 Runtime Measure(in microsec): 1,479 Use a select list with aggregate functions instead of checking and computing, when try to find the maximum, minimum, sum and average value or the count of a database column, thus network load is considerably less. Select Where + Check Select using an aggregate function C4A = '000'. SELECT MAX( MSGNR ) FROM T100 INTO C4A SELECT * FROM T100 WHERE SPRSL = 'D' AND WHERE SPRSL = 'D' AND ARBGB = '00'. ARBGB = '00'. 13 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

CHECK: T100-MSGNR > C4A. C4A = T100-MSGNR. ENDSELECT. Runtime Measure(in microsec): 12,268

Runtime Measure(in microsec): 9,228

Guideline :
Always select into an internal table, except when the table will be very large (i.e., when the internal tables will be greater than 500,000 records). Use Up to N Rows when the number of records needed is known Select + Append statement Select Into Table REFRESH X006. SELECT * FROM T006 INTO TABLE X006. SELECT * FROM T006 INTO X006. APPEND X006. ENDSELECT. Runtime Measure(in microsec): 2,888 Runtime Measure(in microsec): 920 Whenever possible, use array operations instead of single-row operations to modify your database tables. The frequent communication between the application program and database system produces considerable overhead. Single-line Insert Array Insert LOOP AT TAB. INSERT CUSTOMERS FROM TABLE TAB. INSERT INTO CUSTOMERS VALUES TAB. ENDLOOP. Runtime Measure(in microsec): 12 Runtime Measure(in microsec): 12 ORDER BY statement is used in SELECT only if it can use an index else sorting is effective by reading into an internal table and use the SORT statement in the program. Order by with index Order by without index SELECT * FROM SPFLI ORDER BY SELECT * FROM SPFLI ORDER BY PRIMARY KEY. AIRPFROM AIRPTO. ENDSELECT. Runtime Measure(in microsec): 3,138 Runtime Measure(in microsec): 3,959 Do not use Nested Select. The inner select statement is executed several times which might be an overhead. Use 'Inner Join' and/or 'For all Entries' instead. 'For all Entries' is used over 'Loop at itab / Select / Endloop Inner Joins: In a 1:N relationship between two tables, the table with the 1 relationship is the preferred driving table. The 1 relationship is the smallest data set as defined by the header/item relationship and/or the smallest data set as defined by the where clause restrictions.

Tip : No complex WHERE clauses, since complex where clauses are poison for the statement optimizer in any database system.

Having Clause :
In a SELECT statement, the HAVING clause allows you to specify a logical condition for the groups in a GROUP-BY clause. Effective use of the having clause can reduce the set of data transferred from

14 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

the database to the application server. When the having clause is used, the aggregates and groups are constructed in the database instead of the application server, thereby reducing the resulting set. For all frequently used SELECT statements, try to use an index. You always use an index if you specify (a generic part of) the index fields concatenated with logical ANDs in the Select statement's WHERE clause.. Select without index support Select with primary index support SELECT * FROM T100 SELECT * FROM T002. WHERE ARBGB = '00' SELECT * FROM T100 AND MSGNR = '999'. WHERE SPRSL = T002-SPRAS ENDSELECT. AND ARBGB = '00' AND MSGNR = '999'. ENDSELECT. ENDSELECT. Runtime Measure(in microsec): 1,959,019 Runtime Measure(in microsec): 28,434

Use SAP buffering for accessing frequently used, read-only tables, network load can be considerably less. However, in case of retrieving latest data in multi-user environment, you may need to bypass the buffer. Select without buffer support Select with buffer support SELECT SINGLE * FROM T100 SELECT SINGLE * FROM T100 BYPASSING BUFFER WHERE SPRSL = 'D' WHERE SPRSL = 'D' AND ARBGB = '00' AND ARBGB = '00' AND MSGNR = '999'. AND MSGNR = '999'. Runtime Measure(in microsec): 775 Runtime Measure(in microsec): 87 Whenever possible, use column updates instead of single-row updates to update your database tables. Network load can then be considerably less. Single-line updates Column update SELECT * FROM SFLIGHT. UPDATE SFLIGHT SFLIGHT-SEATSOCC = SET SEATSOCC = SEATSOCC - 1. SFLIGHT-SEATSOCC - 1. UPDATE SFLIGHT. ENDSELECT. Runtime Measure(in microsec): 6,054 Runtime Measure(in microsec): 1,517

10.0 Index Design


The following are rules for the design of indexes. First it must be stated that table design is a more logical work while index design is rather technical. In table design it might make sense to place certain fields (client, company code, ) in the beginning. In index design, this is not advisable. Very important for an index is that it contains very selective fields in the beginning. Those are fields like object numbers. Not selective are client, company code, Indexes should be small (few fields). Some optimizers are able to combine two or more indexes to execute a query. This is not possible with wide indexes. 15 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

Indexes of one table should be disjoint (have few common fields), in order not to confuse the optimizer which index to use. Each index slows the inserts into the table down. Updates are only slowed down if indexed fields are updated. In general, heavy inserted tables should have only few indexes while heavy selected tables might have more. About three indexes on a table should not be critical.

11.0 Online Standards


If the layout for screens is the same for multiple functions (such as Add, Move, Delete), use the same screen for all functions. Use online status and security features to control which function is executed. Define all global data in the main program module instead of PBO/PAI. To handle lock entry failure, invoke an error message (type E) to prevent any further progress but leaving the user on the current screen. The user can then take an alternative action or continue to try and lock the object. When activating buttons or boxes, activate the associated text as well. This enables the user to click on either the button/box or text. Use Data Dictionary names (short, medium, long) for field text on screen where applicable. Always define the field with a format = OK as OK_CODE. This field is used to validate the OK Event. Screen and Program field names should generally be identical.

12.0 Internal Table Standard :


MOVE used instead of MOVE-CORRESPONDING for efficiency purpose.. Specify the sort fields on the sort statement, not leave the fields as default, the more restrictively you specify the sort key, the faster the program will run. Sort internal table with default sort key Sort with sort key specified explicitly * Table TAB is filled with 100 entries of 500 bytes * Table TAB is filled with 100 entries of 500 bytes each each SORT TAB. Runtime Measure(in microsec): 503 SORT TAB BY K. Runtime Measure(in microsec): 357

Guideline :
Header line of internal table is cleared before moving data into it. Internal table is defined with OCCURS 0 if the maximum size of the table is potentially >=8K. If the data to be read is estimated to be under 8K, then specifying the number of lines in the OCCURS statement (e.g. itab1 occurs 10) is effective. LOOP ... WHERE is faster than LOOP/CHECK because LOOP ... WHERE evaluates the specified condition internally. The performance can be further enhanced if LOOP ... WHERE is combined with FROM i1 and/or TO i2, if possible. Key access with LOOP/CHECK Key access with LOOP WHERE * Table TAB is filled with 100 entries of 500 bytes * Table TAB is filled with 100 entries of 500 bytes each, each, * 5 entries of which match the key condition * 5 entries of which match the key condition

16 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

LOOP AT TAB. CHECK TAB-K = KVAL. " ... ENDLOOP. Runtime Measure(in microsec): 610

LOOP AT TAB WHERE K = KVAL. " ... ENDLOOP. Runtime Measure(in microsec): 182

Tip :
Use explicit work area operations rather than header line where appropriate, since header line will have unnecessary MOVEs involved. Table operation via header line * The line width of table TAB is 500 bytes TAB = TAB_WA. APPEND TAB. Runtime Measure(in microsec): 4 Table operation via explicit work area * The line width of table TAB is 500 bytes APPEND TAB_WA TO TAB. Runtime Measure(in microsec): 3

Use one-step approach READ/INSERT. If the amount of data is small (< 20 entries), or if users need read-access to the internal table while it is being filled, however, if the data amount is larger and you need read-access only to the completely-filled table, the two-step algorithm APPEND/SORT or threestep approach APPEND/SORT/DELETE DUPLICATE(for tables without duplicates) is preferable. One-step approach: READ/INSERT * TAB_DEST is filled with 1000 entries REFRESH TAB_DEST. LOOP AT TAB_SRC. READ TABLE TAB_DEST WITH KEY K = TAB_SRC-K BINARY SEARCH. INSERT TAB_SRC INTO TAB_DEST INDEX SY-TABIX. ENDLOOP. Runtime Measure(in microsec): 41,760 One-step approach * TAB_SRC contains 1000 entries, of which 500 are different REFRESH TAB_DEST. LOOP AT TAB_SRC. READ TABLE TAB_DEST WITH KEY K = TAB_SRC-K BINARY SEARCH. IF SY-SUBRC <> 0. INSERT TAB_SRC INTO TAB_DEST INDEX SY-TABIX. ENDIF. ENDLOOP. Runtime Measure(in microsec): 22,663 Two-step approach: APPEND, then SORT * TAB_DEST is filled with 1000 entries REFRESH TAB_DEST. LOOP AT TAB_SRC. APPEND TAB_SRC TO TAB_DEST. ENDLOOP. SORT TAB_DEST BY K. Runtime Measure(in microsec): 11,557 Three-steps: copy, sort, delete duplicates * TAB_SRC contains 1000 entries, 500 are different REFRESH TAB_DEST. LOOP AT TAB_SRC. APPEND TAB_SRC TO TAB_DEST. ENDLOOP. SORT TAB_DEST BY K. DELETE ADJACENT DUPLICATES FROM TAB_DEST COMPARING K. Runtime Measure(in microsec): 14,888

COLLECT is used instead of READ BINARY/INSERT If number of entries greater than 1000. READ BINARY runs in O( log2( n ) ) time, and the internal table's index must be adjusted with each INSERT , however, COLLECT uses a hash algorithm and is therefore independent of the number of entries and

17 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

does not need to maintain a table index. If the amount of data is small, the READ/INSERT approach isn't bad, but for large amounts of data (> 1000), COLLECT is much faster. COLLECT semantics using READ BINARY Collect via COLLECT statement * Table TAB_SRC is filled with 10,000 entries, * Table TAB_SRC is filled with 10,000 entries, * 5,000 of which have different keys * 5,000 of which have different keys LOOP AT TAB_SRC. READ TABLE TAB_DEST WITH KEY K = TAB_SRC-K BINARY SEARCH. IF SY-SUBRC = 0. ADD: TAB_SRC-VAL1 TO TAB_DEST-VAL1, TAB_SRC-VAL2 TO TAB_DEST-VAL2. MODIFY TAB_DEST INDEX SY-TABIX. ELSE. INSERT TAB_SRC INTO TAB_DEST INDEX SY-TABIX. ENDIF. ENDLOOP. Runtime Measure(in microsec): 709,306 LOOP AT TAB_SRC. COLLECT TAB_SRC INTO TAB_DEST. ENDLOOP. SORT TAB_DEST BY K.

Runtime Measure(in microsec): 116,422

COLLECT is not used with the combination of APPEND, INSERT and/or MODIFY when filling in the internal table. If COLLECT is mixed with the other statements, it cannot use its hash algorithm. In this case, COLLECT resorts to a normal linear search, which is dramatically slower. Use BINARY SEARCH instead of linear search when internal table has more than 20 entries. If TAB has n entries, linear search runs in O( n ) time, whereas binary search takes only O( log2( n ) ). And also when reading a single record in an internal table, the READ TABLE WITH KEY is not a direct READ. Therefore, SORT the table and use READ TABLE WITH KEY BINARY SEARCH. Linear search of an internal table Binary search of an internal table * Table TAB is filled with 1000 entries * Table TAB is filled with 1000 entries of 100 bytes each * The READ ends with SY-SUBRC=4 * The READ ends with SY-SUBRC=4 READ TABLE TAB WITH KEY K = 'X'. Runtime Measure(in microsec): 875 READ TABLE TAB WITH KEY K = 'X' BINARY SEARCH. Runtime Measure(in microsec): 11

Specify the key fields for read access explicitly, use READ TABLE WITH KEY k = X instead of READ TABLE WITH KEY. Otherwise, the key fields have to be computed dynamically by the run time system. Access via implicit default key Access via key specified explicitly * Table TAB is filled with 30 entries of 500 bytes * Table TAB is filled with 30 entries of 500 bytes each each * The READ ends with SY-SUBRC=4 * The READ ends with SY-SUBRC=4 MOVE SPACE TO TAB. TAB-K = 'X'. READ TABLE TAB BINARY SEARCH. Runtime Measure(in microsec): 15 READ TABLE TAB WITH KEY K = 'X' BINARY SEARCH. Runtime Measure(in microsec): 7

18 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

Internal tables can be compared, copied in logical expressions just like other data objects. Two internal tables are equal if - they have the same number of lines and - each pair of corresponding lines is equal. If an internal table itab has a header line, the table itself is accessed by itab[]. Let the kernel to do the work * Tables TAB1 & TAB2 are each filled with 100 entries * of 100 Bytes each. IF TAB1[] = TAB2[]. " ... ENDIF.

Pedestrian way to compare internal tables * Tables TAB1 & TAB2 are each filled with 100 entries * of 100 Bytes each. DESCRIBE TABLE: TAB1 LINES L1, TAB2 LINES L2. IF L1 <> L2. TAB_DIFFERENT = 'X'. ELSE. TAB_DIFFERENT = SPACE. LOOP AT TAB1. READ TABLE TAB2 INDEX SY-TABIX. IF TAB1 <> TAB2. TAB_DIFFERENT = 'X'. EXIT. ENDIF. ENDLOOP. ENDIF. IF TAB_DIFFERENT = SPACE. " ... ENDIF. Runtime Measure(in microsec): 741

Runtime Measure(in microsec): 152

Use parallel cursor instead of join two tables or nested loop. If TAB1 has n1 entries and TAB2 has n2 entries, the time needed for joining TAB1 and TAB2 with the straightforward algorithm is O( n1 * log2( n2 ) ), nested loop is O( n1 * n2 ), whereas the parallel cursor approach takes only O( n1 + n2 ) time. Binary search is used when parallel cursor is not feasible and the number of entries in the internal table is greater than 20. Native join: loop tab1, read tab2 with key More sophisticated: use parallel cursor * Table TAB1 is filled with 1000 entries of 100 * Table TAB1 is filled with 1000 entries of 100 bytes each bytes each * Table TAB2 is filled with 300 entries of 100 * Table TAB2 is filled with 300 entries of 100 bytes each bytes each * Table TAB2 is assumed to be sorted by K in * Tables TAB1 & TAB2 to be sorted by K ascending ascending * order I2 = 1. LOOP AT TAB1. LOOP AT TAB1. READ TABLE TAB2 WITH KEY READ TABLE TAB2 INDEX I2. K = TAB1-K BINARY SEARCH. IF SY-SUBRC <> 0. EXIT. ENDIF. IF SY-SUBRC = 0. IF TAB2-K = TAB1-K. " ... " ... ENDIF. ADD 1 TO I2. 19 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

ENDLOOP.

ENDIF. ENDLOOP. Runtime Measure(in microsec): 16,723 Runtime Measure(in microsec): 6,228 Straight forward nested loop More sophisticated loop: parallel cursor * Table TAB1 is filled with 100 entries of 100 bytes * TAB1 is filled with 100 entries of 100 bytes each each * Table TAB2 is filled with 10 * 100 = 1000 entries * TAB2 is filled with 10 * 100 = 1000 entries of of 100 bytes each * 100 bytes each * TAB1 & TAB2 assumed to be sorted by K in ascending order LOOP AT TAB1. LOOP AT TAB2 WHERE K = TAB1-K. ENDLOOP. ENDLOOP. I2 = 1. LOOP AT TAB1. LOOP AT TAB2 FROM I2. IF TAB2-K <> TAB1-K. I2 = SY-TABIX. EXIT. ENDIF. ENDLOOP. ENDLOOP. Runtime Measure(in microsec): 8,839

Runtime Measure(in microsec): 180,472

Use the MODIFY variant MODIFY itab ... TRANSPORTING f1 f2 ... for single line, and MODIFY itab ... TRANSPORTING f1 f2 ... WHERE condition for a set of line, to accelerate the updating of internal table. The longer the table line is, the larger the speed-up is. The effect increases for tables with complex structured line types. Modifying all components of single line Modifying selected components only * Table TAB is filled with 5000 entries of 500 bytes * Table TAB is filled with 5000 entries of 500 each. bytes each. * Only the 8 bytes of the component DATE are * Only the 8 bytes of the component DATE are modified. modified. LOOP AT TAB. TAB-DATE = SY-DATUM. MODIFY TAB. WA-DATE = SY-DATUM. LOOP AT TAB. MODIFY TAB FROM WA TRANSPORTING DATE. ENDLOOP. ENDLOOP. Runtime Measure(in microsec): 56,642 Runtime Measure(in microsec): 53,849 Modifying all components of lines Modifying selected components only * Table TAB is filled with 100 entries. A line has * Table TAB is filled with 100 entries. A line has two two * components, a FLAG of typ C and an integer table * components, a FLAG of typ C and an integer table * INTTAB with 20 entries each. * INTTAB with 20 entries each. * The Flag is switched on for all 100 lines. * The Flag is switched on for all 100 lines. LOOP AT TAB. IF TAB-FLAG IS INITIAL. TAB-FLAG = 'X'. ENDIF. MODIFY TAB. 20 of 38 TAB-FLAG = 'X'. MODIFY TAB TRANSPORTING FLAG WHERE FLAG IS INITIAL.

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

ENDLOOP. Runtime Measure(in microsec): 6,190

Runtime Measure(in microsec): 235

Use APPEND LINES OF itab1 TO itab2 and INSERT LINES OF itab1 INTO itab2 INDEX idx instead of APPEND and INSERT. And thus the task of appending and insert a table to another table can be transferred to the kernel. Pedestrian way to append a table Let the kernel to do the work * Table TAB_SRC and TAB_DEST are both filled * Table TAB_SRC and TAB_DEST are both filled with 500 with 500 * entries of 100 bytes each. TAB_SRC is appended * entries of 100 bytes each. TAB_SRC is appended line by in a * line to TAB_DEST. * single step to TAB_DEST. LOOP AT TAB_SRC. APPEND TAB_SRC TO TAB_DEST. ENDLOOP. Runtime Measure(in microsec): 3,716 Pedestrian way to insert a table * Table TAB_SRC and TAB_DEST are both filled with 500 * entries of 100 bytes each. TAB_SRC is inserted line by * line to TAB_DEST at index IDX. IDX = 250. LOOP AT TAB_SRC. INSERT TAB_SRC INTO TAB_DEST INDEX IDX. ADD 1 TO IDX. ENDLOOP. Runtime Measure(in microsec): 16,121 APPEND LINES OF TAB_SRC TO TAB_DEST. Runtime Measure(in microsec): 791 Let the kernel to do the work * Table TAB_SRC and TAB_DEST are both filled with 500 * entries of 100 bytes each. TAB_SRC is inserted in a * single step to TAB_DEST at index IDX. IDX = 250. INSERT LINES OF TAB_SRC INTO TAB_DEST INDEX IDX.

Runtime Measure(in microsec): 845

Use DELETE ADJACENT DUPLICATES / DELETE itab FROM ... TO ... / DELETE itab [FROM ...] [TO ...] WHERE ... instead of DELETE, to transfer the task of deleting entries to the kernel. Pedestrian way to delete duplicates Let the kernel to do the work * Table TAB_DEST is filled with 1000 entries of * Table TAB_DEST is filled with 1000 entries of 100 bytes 100 bytes * each and contains 500 pairs of duplicates * each and contains 500 pairs of duplicates READ TABLE TAB_DEST INDEX 1 INTO PREV_LINE. LOOP AT TAB_DEST FROM 2. IF TAB_DEST = PREV_LINE. DELETE TAB_DEST. ELSE. PREV_LINE = TAB_DEST. ENDIF. ENDLOOP. Pedestrian way to delete a sequence of lines * Table TAB_DEST is filled with 1000 entries of 500 bytes 21 of 38 DELETE ADJACENT DUPLICATES FROM TAB_DEST COMPARING K.

Let the kernel to do the work * Table TAB_DEST is filled with 1000 entries of 500 bytes

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

* each, and lines 450 to 550 are to be deleted DO 101 TIMES. DELETE TAB_DEST INDEX 450. ENDDO. Pedestrian way to delete a set of lines * Table TAB_DEST is filled with 1000 entries of 500 bytes * each, 250 of which match the WHERE condition LOOP AT TAB_DEST WHERE K = KVAL. DELETE TAB_DEST. ENDLOOP. Runtime Measure(in microsec): 4,813

* each, and lines 450 to 550 are to be deleted DELETE TAB_DEST FROM 450 TO 550. Let the kernel to do the work * Table TAB_DEST is filled with 1000 entries of 500 bytes * each, 250 of which match the WHERE condition DELETE TAB_DEST WHERE K = KVAL. Runtime Measure(in microsec): 3,771

The performance gain when using DELETE itab WHERE ... instead of LOOP AT itab WHERE ... DELETE itab. ENDLOOP. increases with the number of entries the internal table contains and the number of lines to be deleted. If the data is processed only once, use a SELECT-ENDSELECT loop instead of collecting data in an internal table with SELECT .INTO TABLE because the Internal table handling takes up much more space. SELECT * FROM <TABLE> SELECT * FROM <TABLE> INTO TABLE <INT-TAB> ENDSELECT LOOP AT <INT-TAB>. .. ENDLOOP. Internal tables can be copied by move just like any other data object. If the table has a header line then the tables need to be referenced by square brackets. ITAB[] = ITAB1[]. LOOP AT ITAB INTO ITAB1. APPEND ITAB1. ENDLOOP.

Internal tables are freed when no longer needed (either by the free command or a subroutine exit), especially when the tables are large or the program is a batch program.

13.0 String Operation Guideline :


Use the special operators CO, CA, CS, instead of programming the operations yourself. If ABAP statements are executed per character on long strings, CPU consumption can rise substantially. DO-Loop with Field-Symbols Using the CA operator ASSIGN CHA(1) TO <C>. IF CHA(200) CA (). any actions DO 200 TIMES. ENDIF. IF <C> = ( OR <C> = ). any actions EXIT. ENDIF. 22 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

ASSIGN <C>+1 TO <C>. ENDDO. Runtime Measure(in microsec): 563

Runtime Measure(in microsec): 20

Use the CONCATENATE / SPLIT statement instead of programming a string concatenation of your own. Moving with offset Use of the CONCATERNATE statement MOVE Jane TO CMA. MOVE Jane TO CMA. MOVE Miller TO CMB. MOVE Miller TO CMB. MOVE New York City TO CMC. MOVE New York City TO CMC. I1 = STRLEN( CMA ). I2 = STRLEN( CMB ). MOVE Mrs. TO CHA. MOVE CMA TO CHA+5. I1 = I1 + 6. MOVE CMB TO CHA+I1. I1 = I1 + I2 + MOVE from TO CHA+I1. I1 = I1 + 5. MOVE CMC TO CHA+I1. Mrs. Jane Miller from New York City I Use of SEARCH and MOVE with Offset CMA contains (410)-45174-66354312 and shall be split into AREA_CODE, TEL_NO1, TEL_NO2. SEARCH CMA FOR -. MOVE CMA(SY-FDPOS) TO AREA_CODE. I1 = SY-FDPOS + 2. SEARCH CMA FOR - STARTING AT I1. I1 = I1 1. MOVE CMA+I1(SY-FDPOS) TO TEL_NO1. I1 = I1 + SY-FDPOS + 1. MOVE CMA+I1 TO TEL_NO2. Runtime Measure(in microsec): 27 CONCATENATE Mrs. CMA CMB from CMC INTO CHA SEPARATED BY SPACE.

Mrs. Jane Miller from New York City I Use of the SPLIT statement CMA contains (410)-45174-66354312 and shall be splitted into AREA_CODE, TEL_NO1, TEL_NO2. SPLIT CMA AT - INTO AREA_CODE TEL_NO1 TEL_NO2.

Runtime Measure(in microsec): 4

If you want to delete the leading spaces in a string, use the ABAP statement SHIFTLEFT DELETING LEADING . Other constructions (with CN and SHIFTBY SY-FDPOS PLACES, with CONDENSE if possible, with CN and ASSIGN CLA+SY-FDPOS(LEN) ) are not as fast. In any case, avoid using SHIFT inside a WHILE-loop! Shifting by SY-FDPOS places. Using SHIFT LEFT DELETING LEADING CLA contains the string CLA contains the string Editor line n. Editor line n. IF CLA CN SPACE. ENDIF. SHIFT CLA BY SY-FDPOS PLACES LEFT. SHIFT CLA LEFT DELETING LEADING SPACE. Runtime Measure(in microsec): 5 Runtime Measure(in microsec): 3

Tip :
Some function modules for string manipulation have become obsolete and should be replaced by ABAP statements or functions: 23 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

STRING_CONCATENATE -> CONCATENATE, STRING_SPLIT -> SPLIT, STRING_LENGTH -> strlen(), STRING_CENTER -> WRITETOCENTERED, STRING_MOVE_RIGHT -> WRITETORIGHT-JUSTIFIED, Use of a CONCATERNATE function module CALL FUNCTION STRING_CONCATENATE_3 EXPORTING STRING1 = T100-ARBGB STRING2 = T100-MSGNR STRING3 = T100-TEXT IMPORTING STRING = CLA EXCEPTIONS TOO_SMALL = 01. Runtime Measure(in microsec): 67 Use of the CONCATERNATE statement CONCATENATE T100-ARBGB T100-MSGNR T100-TEXT INTO CLA.

Runtime Measure(in microsec): 3

Use the strlen( ) function to restrict the DO loop to the relevant part of the field, e.g. when determining a check-sum. Get a check-sum with field length Get a check-sum with strlen() DATA: BEGIN OF STR, LINE TYPE X, END DATA: BEGIN OF STR, LINE TYPE X, END OF STR, CHECK_SUM TYPE I. OF STR, CHECK_SUM TYPE I. MOVE KALEBVPQDSCFG TO CLA. MOVE KALEBVPQDSCFG TO CLA. DO 64 TIMES VARYING STR FROM CLA NEXT CLA+1. CHECK STR NE SPACE. ADD STR-LINE TO CHECK_SUM. ENDDO. I1 = STRLEN( CLA ). DO I1 TIMES VARYING STR FROM CLA NEXT CLA+1. CHECK STR NE SPACE. ADD STR-LINE TO CHECK_SUM. ENDDO.

Use CLEAR f WITH val whenever you want to initialize a field with a value different from the fields type-specific initial value. Initializing with CLEAR/TRANSLATE Initializing with CLEAR WITH val * STRING is a 255 byte character field * STRING is a 255 byte character field CLEAR STRING. CLEAR STRING WITH *. TRANSLATE STRING USING *. Runtime Measure(in microsec): 11 Runtime Measure(in microsec): 1

14.0 Hardcoding
Programs should contain no hard coding. Hard Coding builds in maintenance problems, limits our flexibility, and makes assumptions that todays world will continue indefinitely. Examples of Hard Coding Select * from MARA where MATNR = M00123 . 24 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

If VBFA-VBTYP_N = J .. Cases where hard coding may be accepted Programs used only once, e.g. conversion programs Defining screen names and numbers for BDC processing

Reasons not to hard code include


Data values may change or be added May not be easy to change in future Requires IS personnel to make change Requires approval to make change Clients business requirement may change : New plants may get added, different codes or values used SAP may change data values in future

Possible alternate solution


Use parameters or select-option Use existing tables If none exist, consider creating a custom table. Use a function module to determine value needed.

25 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

15.0 Skeleton Programs The ABAP skeleton programs listed in this section show how various ABAP programs should be structured. As far as possible and appropriate, their structure should be followed.
15.1 Basic ABAP List Report
*REPORT ZSKELREP NO STANDARD PAGE HEADING * LINE-SIZE XX * LINE-COUNT XX * MESSAGE-ID ZZ.
*&------------------------------------------------------------------------------------------------------------*& Program Name : Zxxxxxxxx *& Author : xxxxxx xxx , xxxxx xxxxx *& Module Name : Financial Accounting *& Sub-Module : Accounts Payable *& Program Type : Reports Create Date : xx/xx/xxxx *& SAP Release : 4.0 B Transport No : xxxxxxxxxx *& Description : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx *& xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx *&------------------------------------------------------------------------------------------------------------&* &* &* &* &* &* &* &* &* &*

*&-------------------------------------------------------------------------------------------------------------&* *& REVISION LOG &* *&-------------------------------------------------------------------------------------------------------------&* *& Revision No : 001 Transport No : Date : xx/xx/xx &* *& Developer : xxxxxxxxxxx xxxx Id String : MD001 &* *& Description : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &* *& xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &* *& xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &*

* INCLUDES USED--------------------------------------------------------------------------------* * * INCLUDE XXX "DESCRIPTION * *-----------------------------------------------------------------------------------------------------* *&---------------------------------------------------------------------* *& TABLES: *&---------------------------------------------------------------------* tables: *&---------------------------------------------------------------------* *& CONSTANTS: *&---------------------------------------------------------------------* constants: *&---------------------------------------------------------------------* *& PROGRAM VARIABLES 26 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

*&---------------------------------------------------------------------* data: *&---------------------------------------------------------------------* *& STRUCTURES *&---------------------------------------------------------------------* *&---------------------------------------------------------------------* *& INTERNAL TABLES *&---------------------------------------------------------------------* *&---------------------------------------------------------------------* *& SELECT-OPTIONS *&---------------------------------------------------------------------* select-options: *&---------------------------------------------------------------------* *& PAPAMETERS *&---------------------------------------------------------------------* parameters: ************************************************************************ * INITIALIZATION ************************************************************************ * Event which occurs before the selection screen is * shown to the user. It happens only once and is * ignored in background processing. INITIALIZATION. ************************************************************************ * AT SELECTION-SCREEN ************************************************************************ * Event which occurs each time the user hits enter on * the selection screen. This event is ignored in * background processing. AT SELECTION-SCREEN. ************************************************************************ * TOP-OF-PAGE ************************************************************************ TOP-OF-PAGE. ************************************************************************ * END-OF-PAGE ************************************************************************ END-OF-PAGE. ************************************************************************ * START-OF-SELECTION ************************************************************************ START-OF-SELECTION.

27 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

************************************************************************ * END-OF-SELECTION ************************************************************************ END-OF-SELECTION. SORT ... LOOP ... AT FIRST ... ENDAT. AT NEW ... ENDAT. AT END OF ... ENDAT. AT LAST. ... ENDAT. ENDLOOP. *&---------------------------------------------------------------------* *& Form SUB_ INSERT_ENTRIES *&---------------------------------------------------------------------* * xxxxxxxxx xxxx xxxx xxx xxxxx xxxx xxxxx xxxx xx xxxxxx xxxx *----------------------------------------------------------------------* FORM SUB_INSERT_ENTRIES ... ENDFORM.

28 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

15.2 Interactive ABAP List Report


*REPORT ZSKELINT NO STANDARD PAGE HEADING * LINE-SIZE XX * LINE-COUNT XX * MESSAGE-ID ZZ.
*&------------------------------------------------------------------------------------------------------------*& Program Name : Zxxxxxxxx *& Author : xxxxxx xxx , xxxxx xxxxx *& Module Name : Financial Accounting *& Sub-Module : Accounts Payable *& Program Type : Reports Create Date : xx/xx/xxxx *& SAP Release : 4.0 B Transport No : xxxxxxxxxx *& Description : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx *& xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx *&------------------------------------------------------------------------------------------------------------&* &* &* &* &* &* &* &* &* &*

*&-------------------------------------------------------------------------------------------------------------&* *& REVISION LOG &* *&-------------------------------------------------------------------------------------------------------------&* *& Revision No : 001 Transport No : Date : xx/xx/xx &* *& Developer : xxxxxxxxxxx xxxx Id String : MD001 &* *& Description : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &* *& xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &* *& xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &*

* INCLUDES USED--------------------------------------------------------------------------------* * * INCLUDE XXX "DESCRIPTION * *-----------------------------------------------------------------------------------------------------* TABLES: ... DATA: ... SELECT-OPTIONS: ... PARAMETERS: ... * Event which occurs before the selection screen is * shown to the user. It happens only once and is * ignored in background processing. INITIALIZATION. * Event which occurs each time the user hits enter on * the selection screen. This event is ignored in * background processing. AT SELECTION-SCREEN.

29 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

TOP-OF-PAGE. * Top of page for sublists TOP-OF-PAGE DURING LINE-SELECTION. END-OF-PAGE. START-OF-SELECTION. END-OF-SELECTION. * Produce main list report SY-LSIND = 0. SORT ... LOOP... WRITE:/ ... * Hide specific fields which are of importance to the * line. HIDE: ... ENDLOOP. * Event which occurs when user hits a particular PF * key, e.g. PF6. The hide area and SY-LISEL are * automatically available. It produces a sublist SY* LSIND = 1-9. PF3 is automatic and will always * take the user back one list level, (SY-LSIND - 1). AT PF... * Event which occurs when a user types =LIST in the OK * code. The hide area and SY-LISEL are automatically * available. It produces a sublist SY-LSIND = 1-9. * PF3 is automatic and will always take the user back * one list level, (SY-LSIND - 1). AT USER-COMMAND. CASE SY-UCOMM. WHEN 'LIST'. ..... ENDCASE. * Event which occurs when the user places the cursor * to a specific line on the report and hits enter. * The hide area and SY-LISEL are automatically * available. It produces a sublist SY-LSIND = 1-9. * PF3 is automatic and will always take the user back * one list level, (SY-LSIND - 1). AT LINE-SELECTION.

30 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

Subroutines *----------------------------------------------------* SUB_INSERT_ENTRIES *----------------------------------------------------FORM SUB_INSERT_ENTRIES ... ENDFORM.

31 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

15.3 Create a Sequential Dataset


*REPORT ZSKELOUT NO STANDARD PAGE HEADING * LINE-SIZE XX * LINE-COUNT XX * MESSAGE-ID ZZ.
*&------------------------------------------------------------------------------------------------------------*& Program Name : Zxxxxxxxx *& Author : xxxxxx xxx , xxxxx xxxxx *& Module Name : Financial Accounting *& Sub-Module : Accounts Payable *& Program Type : Reports Create Date : xx/xx/xxxx *& SAP Release : 4.0 B Transport No : xxxxxxxxxx *& Description : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx *& xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx *&------------------------------------------------------------------------------------------------------------&* &* &* &* &* &* &* &* &* &*

*&-------------------------------------------------------------------------------------------------------------&* *& REVISION LOG &* *&-------------------------------------------------------------------------------------------------------------&* *& Revision No : 001 Transport No : Date : xx/xx/xx &* *& Developer : xxxxxxxxxxx xxxx Id String : MD001 &* *& Description : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &* *& xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &* *& xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &*

* INCLUDES USED--------------------------------------------------------------------------------* * * INCLUDE XXX "DESCRIPTION * *-----------------------------------------------------------------------------------------------------* TABLES: ... DATA: DATA: G_PDSNME LIKE FILENAME-FILEEXTERN. "Physical Dataset Name. BEGIN OF T_TAB OCCURS ... END OF T_TAB.

PARAMETERS: P_LDSNME LIKE FILENAME-FILEINTERN "Logical Dataset Name DEFAULT 'CUSTOMER_FILE'. AT SELECTION-SCREEN. CALL FUNCTION 'FILE_GET_NAME' EXPORTING LOGICAL_FILENAME = P_LDSNME IMPORTING FILE_NAME = G_PDSNAME EXCEPTIONS FILE_NOT_FOUND = 01.

32 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

IF SY-SUBRC <> 0. *-------No physical filename can be determined for & MESSAGE E016(MG)WITH P_LDSNME. ENDIF. START-OF-SELECTION. OPEN DATASET G_PDSNME FOR OUTPUT IN TEXT MODE. IF SY-SUBRC <> 0. . TRANSFER T_REC TO G_PDSNME. CLOSE DATASET G_PDSNAME. GET ... MOVE ... TO ... WRITE ... TO ... UNPACK ... TO ... TRANSFER ... TO ... END-OF-SELECTION.

Subroutines *----------------------------------------------------* SUB_INSERT_ENTRIES *----------------------------------------------------FORM SUB_INSERT_ENTRIES ... ENDFORM.

33 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

15.4 Read Sequential Dataset and Create a BDC Session


*REPORT ZSKELBDC NO STANDARD PAGE HEADING * LINE-SIZE XX * LINE-COUNT XX * MESSAGE-ID ZZ.
*&------------------------------------------------------------------------------------------------------------*& Program Name : Zxxxxxxxx *& Author : xxxxxx xxx , xxxxx xxxxx *& Module Name : Financial Accounting *& Sub-Module : Accounts Payable *& Program Type : Reports Create Date : xx/xx/xxxx *& SAP Release : 4.0 B Transport No : xxxxxxxxxx *& Description : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx *& xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx *&------------------------------------------------------------------------------------------------------------&* &* &* &* &* &* &* &* &* &*

*&-------------------------------------------------------------------------------------------------------------&* *& REVISION LOG &* *&-------------------------------------------------------------------------------------------------------------&* *& Revision No : 001 Transport No : Date : xx/xx/xx &* *& Developer : xxxxxxxxxxx xxxx Id String : MD001 &* *& Description : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &* *& xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &* *& xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &*

* INCLUDES USED--------------------------------------------------------------------------------* * * INCLUDE XXX "DESCRIPTION * *-----------------------------------------------------------------------------------------------------* TABLES: ... PARAMETERS: P_LDSNME LIKE FILENAME-FILEINTERN "Logical Dataset Name DEFAULT 'CUSTOMER_FILE'. DATA: DATA: DATA: DATA: G_PDSNME LIKE FILENAME-FILEEXTERN. "Physical Dataset Name. BEGIN OF T_TAB OCCURS ... END OF T_TAB. BEGIN OF T_BDCDATA OCCURS 10. INCLUDE STRUCTURE BDCDATA. END OF T_BDCDATA.

DATA: BEGIN OF T_TAB OCCURS ... END OF T_TAB. SELECT-OPTIONS: ...

34 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

PARAMETERS: ... AT SELECTION-SCREEN. CALL FUNCTION 'FILE_GET_NAME' EXPORTING LOGICAL_FILENAME = P_LDSNME IMPORTING FILE_NAME = G_PDSNAME EXCEPTIONS FILE_NOT_FOUND = 01. IF SY-SUBRC <> 0. *-------No physical filename can be determined for & MESSAGE E016(MG)WITH P_LDSNME. ENDIF. *----------------------------------------------------START-OF-SELECTION. OPEN DATASET G_PDSNME FOR INPUT IN TEXT MODE. READ DATASET G_PDSNME INTO T_TAB. IF SY-SUBRC <> 0. . ENDIF. CLOSE DATASET G_PDSNME. *-- Upload a file from a PC into an Internal table --* CALL FUNCTION 'UPLOAD' TABLES DATA_TAB = T_TAB. *--------------- Open the BDC Session ---------------* CALL FUNCTION 'BDC_OPEN_GROUP' EXPORTING CLIENT = SY-MANDT GROUP = 'SESSION_NAME' "session name USER = SY-UNAME KEEP = 'X'. "keep session "after processing LOOP AT T_TAB. *------------------- DYNPRO nnn ---------------------* PERFORM BDCDYNPRO USING 'X' 'SAPMxxxx' 'nnn' '' ''. PERFORM BDCDYNPRO USING '' '' '' 'TABL-FIELD' 'LITERAL' *------------------- DYNPRO nnn ---------------------* PERFORM BDCDYNPRO USING 'X' 'SAPMxxxx' 'nnn' '' ''. PERFORM BDCDYNPRO USING '' '' '' 'TABL-FIELD' TABVAR. *----------------------------------------------------*

35 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

PERFORM INSERT_BDC. ENDLOOP. END-OF-SELECTION. *--------------- Close the BDC Session -------------* CALL FUNCTION 'BDC_CLOSE_GROUP'. *----------------------------------------------------* * Subroutines *----------------------------------------------------* *--------- Add a line to the DYNPRO Table ----------* FORM BDCDYNPRO USING BEG PRG DYN FLD VAL. CLEAR T_BDCDATA. T_BDCDATA-DYNBEGIN = BEG. T_BDCDATA-PROGRAM = PRG. T_BDCDATA-DYNPRO = DYN. T_BDCDATA-FNAM = FLD. T_BDCDATA-FVAL = VAL. APPEND T_BDCDATA. ENDFORM. *----------------------------------------------------* * Add a transaction to the BDC session with the * * entries in BDCDATA. * *----------------------------------------------------* FORM INSERT_BDC. CALL FUNCTION 'BDC_INSERT' EXPORTING TCODE = 'TCOD' TABLES DYNPROTAB = T_BDCDATA. REFRESH T_BDCDATA. ENDFORM. *----------------------------------------------------*

36 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

15.5 CALL TRANSACTION USING Technique


*REPORT ZSKELCLT NO STANDARD PAGE HEADING * LINE-SIZE XX * LINE-COUNT XX * MESSAGE-ID ZZ.
*&------------------------------------------------------------------------------------------------------------*& Program Name : Zxxxxxxxx *& Author : xxxxxx xxx , xxxxx xxxxx *& Module Name : Financial Accounting *& Sub-Module : Accounts Payable *& Program Type : Reports Create Date : xx/xx/xxxx *& SAP Release : 4.0 B Transport No : xxxxxxxxxx *& Description : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx *& xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx *&------------------------------------------------------------------------------------------------------------&* &* &* &* &* &* &* &* &* &*

*&-------------------------------------------------------------------------------------------------------------&* *& REVISION LOG &* *&-------------------------------------------------------------------------------------------------------------&* *& Revision No : 001 Transport No : Date : xx/xx/xx &* *& Developer : xxxxxxxxxxx xxxx Id String : MD001 &* *& Description : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &* *& xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &* *& xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx &*

* INCLUDES USED--------------------------------------------------------------------------------* * * INCLUDE XXX "DESCRIPTION * *-----------------------------------------------------------------------------------------------------* TABLES: INDX, ... DATA: V_RETURN_CODE LIKE SY-SUBRC, V_MESSAGE_TEXT(120). DATA: BEGIN OF T_TRANTAB OCCURS 10. INCLUDE STRUCTURE BDCDATA. DATA: END OF T_TRANTAB. SELECT-OPTIONS: ... PARAMETERS: ... START-OF-SELECTION. *--------------------- DYNPRO nnn -------------------* PERFORM TRANS_FIELD USING '' '' '' 'TABL-FIELD' 'LITERAL'. *--------------------- DYNPRO nnn -------------------* 37 of 38

Project

<Abap/4 Coding Standards & Code Efficiency Standards>

PERFORM TRANS_FIELD USING 'X' 'SAPMxxxx' 'nnn' '' ''. PERFORM TRANS_FIELD USING '' '' '' 'TABL-FIELD' TAB-VAR. *----------------------------------------------------* CALL TRANSACTION ' ' USING T_TRANTAB MODE 'N' UPDATE 'S'.

* Message handling V_RETURN_CODE = SY-SUBRC. IF V_RETURN_CODE = 0. * At this point, various things can be done. Store key values and * confirmation document number or error message in an * internal table for future processing. MOVE 'Transaction posted' TO ... MOVE V_MESSAGE_TEXT TO ... MODIFY ... ELSE. MOVE 'Transaction failed' TO ... MOVE V_MESSAGE_TEXT TO ... MODIFY ... * In the event of erred transactions: * or create a batch input session for future * processing. REFRESH T_TRANTAB. END-OF-SELECTION. * Subroutines *----------------------------------------------------* Add an entry to the TRANTAB *----------------------------------------------------FORM TRANS_FIELD USING BEG PRG DYN FLD VAL. CLEAR T_TRANTAB. T_TRANTAB-DYNBEGIN = BEG. T_TRANTAB-PROGRAM = PRG. T_TRANTAB-DYNPRO = DYN. T_TRANTAB-FNAM = FLD. T_TRANTAB-FVAL = VAL. APPEND T_TRANTAB. ENDFORM. *----------------------------------------------------* FORM ... ... ENDFORM.

*------------------------------------------------------

38 of 38

You might also like