Mit Abap Best Practices
Mit Abap Best Practices
If you have questions about topics in this guide, would like to suggest
changes, or provide new topics to be included, please submit the
topics and details about the updates to David Rosenberg
([email protected]).
Revision History
Revision Date Description of Changes
START-OF-SELECTION.
GET table.
IF f1 = f2.
f1 = 0.
ELSE.
f1 = 1.
ENDIF.
LOOP AT tab.
AT NEW f1.
CASE F1.
WHEN ... WRITE:/ ...
WHEN ... WRITE:/ ...
ENDCASE.
ENDAT.
WRITE:/ f1, f2, ...
ENDLOOP.
3. Variable naming
ABAP/4 variable names can be up to 30 characters for DATA fields and
subroutines and up to 8 characters for SELECT-OPTIONS and PARAMETERS,
therefore, as a standard make the names descriptive. Since SAP
segment/table-field names are hyphenated with a '-' (dash), use an '_'
(underline) to separate the words for program-specific variables. Whenever
possible, the LIKE parameter should be used to define work fields.
DATA: MAT_DT LIKE SY-DATUM,
DAYS TYPE I,
HOLD_ACCTNO LIKE sg-field1,
GROSSAMT(10) TYPE P DECIMALS 2,
GROSS_PERCENT(3) TYPE P DECIMALS 2,
NET%(3) TYPE P DECIMALS 2.
PARAMETERS: P_DEST(4).
Subroutine examples:
FORM CALCULATE_MATURITY_DATE.
MAT_DT = SY-DATUM + DAYS.
ENDFORM.
FORM F100_CALCULATE_MATURITY_DATE.
4. Reusable code
If a block of code is executed more than once, it should be placed in a
subroutine at the bottom of the code. This makes the code more readable,
requires less indentation, and is easier to debug since the debugger can
jump through an entire subroutine via a PF key. Also, when possible
parameters should be passed to and from subroutines to make the purpose
easier to understand and reduce the need for global variables. Always
document the purpose of each parameter.
5. Parameter passing in subroutines
Whenever possible use a TYPE or LIKE statement when specifying the formal
parameters of a subroutine. This is a good programming style, plus it allows
the ABAP compiler to generate more efficient code (which can increase
performance up to a factor of 2x). For example:
form <subroutine> tables p_tab1 like <tab1>[]
using p_param1 like <data>
p_param2 like <dd-field>
p_param3 like <dd-structure>
p_param4 type <standard data type>
p_param5 type <user defined data type>
....
endform.
6. Text handling
Literal text which is printed on the report can be handled two ways.
One way is to hard code the literal in the code and give the option of
maintaining Text Elements for multi-lingual clients.
WRITE:/ TEXT-001.
The advantages to the first way are readability and the Text Element only
needs to be maintained for multi-lingual clients. The advantage to the
second way is easier maintainability if TEXT-001 is coded several times in
the program and it needs to be changed. The editor command REPLACE
does not change contents inside single quotes.
7. Program Analysis Utility
To determine the usage of variables and subroutines within a program, you
can use the ABAP utility called ‘Program Analysis’ included in transaction
SE38. To do so, execute transaction SE38, enter your program name, then
use the path Utilities -> Program Analysis
8. Usage of UserIDs in programs
In no case should a production program or function contain a UserID as
either literal or constant data. In the development system it may be
necessary to code temporary breakpoints for specific UserIDs, however,
these debugging techniques must be removed before the program will be
transported.
Authorization Groups
If a program DOES NOT have the 'ZOPN2ALL' authorization group configured for it,
we assume that only certain users should be able to execute it and that other
methods of authorization, such as authorization objects are being used to prevent
improper use.
All external file layouts used for interfaces to and from the R/3
system should be discussed with and approved by the Bridges Team
before the layout is finalized. This is to insure consistency in field
conventions and file processing standards. The requirements for the
following data elements are:
Dates
As indicated in the section "Writing dates in reports," dates should use a 4-
digit year with certain exceptions.
Cost Objects
Cost objects should be left-aligned in a 12-character field with trailing
blanks. (Optionally, a 7-character field followed by 5 characters of blank
filler is acceptable)
Cost Elements
Cost elements should be left-aligned in a 10-character field with trailing
blanks. (Optionally, a 6-character field followed by 4 characters of blank
filler is acceptable)
Interface : Dropbox mechanism for file interfaces
Many programs are inputs or extracts from the R/3 system that
require detailed tracking of data file names and error statuses beyond
the capability of the standard R/3 job scheduler or if the program is
run in the foreground to capture the status its last run. To provide a
common repository for job status, the ZJOBRUN table was created.
All programs that need to track job status should read / write records
to / from this table. Using text files outside of the R/3 system or
other custom tables for this purpose is not recommended.
Additionally, if there are other programs that are using methods other
than the ZJOBRUN table to track status, they should be modified to
use ZJOBRUN instead.
ZJOBRUN Table
BATCH Sequential 85
number of the
job run
In SAP master data tables, names can be stored in either upper case
or mixed case depending on how they are entered into the system.
Any program or function which searches master data tables for a
person's name should search in a non-case sensitive fashion to
account for this situation.
Also, existing extract programs may need to be modified for the new
document type, hence it is necessary to pro-actively notify The
Financial Architecture Group of the creation of a new document type
(Larry Connelly, [email protected]). After the new document type is
approved, the Financial Architecture Group will communicate the
changes to all other necessary parties so that other programs can be
modified.
case <variable>.
when 'Y'. "explain what 'Y' actually means
...
when 'H'. "explain what 'H' actually means
...
endcase.
*--------------------------------------------------------------
---*
* Purpose:
*
*
*--------------------------------------------------------------
---*
* Author:
* Date:
*
*--------------------------------------------------------------
---*
* Modification Log:
*
* 11/2/96 - Joe Q. Programmer SF2K900002
* Added .....
* 6/14/96 - Joe Q. Programmer SF2K900001
* Changed .....
*--------------------------------------------------------------
---*
ABAP/4 Editor
INSERT D030L-TYPE D030L-DDNAME D030T-DDTEXT D030L-CBNAME
D030L-SEGMENTID D030L-DOCTYPE INTO HEADER.
SELECT * FROM D030L WHERE
"SF2K900001
DDNAME BETWEEN TABLEFR AND TABLETO.
"SF2K900001
CHECK D030L-DDMODIFY NE USR.
"SF2K900001
SELECT * FROM D030T WHERE
"SF2K900001
DDLANGUAGE EQ SY-LANGU AND
"SF2K900001
DDNAME EQ D030L-DDNAME.
"SF2K900001
ENDSELECT.
"SF2K900001
EXTRACT HEADER.
"SF2K900001
ENDSELECT.
"SF2K900001
Validation Rules
Because of the nature of the impact of changes in validation rules to the entire SAP
system operation, any developer who is considering altering a validation rule must
send a message to [email protected] as early in the development
process as possible. At a minimum this notification must be sent one week before
any development is transported to the test and integration system (SF5).
As with changes to validation rules, any configuration changes that alter any
transaction field, must be submitted in a mail message to MIT-
[email protected] as early as possible with a minimum of one week
notification before transport to the test and integration system. Configuration
changes that alter the "required", "optional", or "not permitted" status of fields is
included in this specification.
V. PERFORMANCE STANDARDS
General Performance Standards
1. "Dead" code
Avoid leaving
"dead" code in the
program. Comment
out variables that
are not referenced
and code that is not
executed. To
analyze the
program, use the
Program Analysis
function in SE38 ->
Utilities -> Program
Analysis.
2. Use logical
databases
Choose the most
efficient logical data
base possible.
Study the selection
criteria and which
secondary indexes
are used for that
view. Provide the
appropriate
selection criteria to
limit the number of
data base reads.
Force users to
provide selection
criteria by
evaluating the
selection criteria
entered on the
selection screen
during the AT
SELECTION-
SCREEN event.
Finally, when
possible take
advantage of the
matchcodes to
increase speed.
3. Subroutine usage
For good
modularization, the
decision of whether
or not to execute a
subroutine should
be made before the
subroutine is called.
For example:
This is better:
IF f1 NE 0.
PERFORM sub1.
ENDIF.
FORM sub1.
...
ENDFORM.
Than this:
PERFORM sub1.
FORM sub1.
IF f1 NE 0.
...
ENDIF.
ENDFORM.
4. IF statements
When coding IF
tests, nest the
testing conditions
so that the outer
conditions are those
which are most
likely to fail. For
logical expressions
with AND, place the
mostly likely false
first and for the OR,
place the mostly
likely true first.
5. CASE vs. nested
IFs
When testing fields
"equal to"
something, one can
use either the
nested IF or the
CASE statement.
The CASE is better
for two reasons. It
is easier to read
and after about five
nested IFs the
performance of the
CASE is more
efficient.
6. MOVE-ing
structures
When records a and
b have the exact
same structure, it is
more efficient to
MOVE a TO b than
to MOVE-
CORRESPONDING a
TO b.
MOVE BSEG TO
*BSEG.
is better than
MOVE-
CORRESPONDING
BSEG TO *BSEG.
7. SELECT and
SELECT SINGLE
When using the
SELECT statement,
study the key and
always provide as
much of the left-
most part of the
key as possible. If
the entire key can
be qualified, code a
SELECT SINGLE not
just a SELECT. If
you are only
interested in the
first row or there is
only one row to be
returned, using
SELECT SINGLE can
increase
performance by up
to 3x.
8. Small internal
tables vs.
complete internal
tables
In general it is
better to minimize
the number of fields
declared in an
internal
table. While it may
be convenient to
declare an internal
table using the LIKE
command, in most
cases, programs
will not use all
fields in the SAP
standard table. For
example:
Instead of this:
data: tvbak like
vbak occurs 0
with header line.
Use this:
data: begin of
tvbak occurs 0,
vbeln
like vbak-vbeln,
...
end of
tvbak.
9. Row-level
processing of a
table
Selecting data into
an internal table
using an array fetch
versus a SELECT-
ENDELECT loop will
give at least a 2x
performance
improvement. After
the data has been
put into the internal
data, then row-level
processing can be
done. For
example, use:
select ... from
table <..>
into
<itab>
(corresponding
fields of itab)
where
...
loop at <itab>
<do the row-
level processing
here>
endloop.
instead of using:
is more efficient
than
SORT ITAB.
13. Number of entries
in an internal
table
To find out how
many entries are in
an internal table
use DESCRIBE.
DESCRIBE TABLE
ITAB LINES
CNTLNS.
is more efficient
than
LOOP AT ITAB.
CNTLNS = CNTLNS
+ 1.
ENDLOOP.
14. Length of a field
To find out the
length of a field use
the string length
function.
FLDLEN = STRLEN
(FLD).
is more efficient
than
IF FLD CP ‘* #’.
ENDIF.
FLDLEN = SY-
FDPOS.
15. Performance
diagnosis
To diagnose
performance
problems, it is
recommended to
use the SAP
transaction SE30,
ABAP/4 Runtime
Analysis. The utility
allows statistical
analysis of
transactions and
programs.
16. Nested SELECTs
versus table
views
Since OPEN SQL
does not allow table
joins, often a
nested SELECT loop
will be used to
accomplish the
same
concept. However,
the performance of
nested SELECT
loops is very poor
in comparison to a
join. Hence, to
improve
performance by a
factor of 25x and
reduce network
load, you should
create a view in the
data dictionary then
use this view to
select data.
17. If nested SELECTs
must be used
As mentioned
previously,
performance can be
dramatically
improved by using
views instead of
nested SELECTs,
however, if this is
not possible, then
the following
example of using an
internal table in a
nested SELECT can
also improve
performance by a
factor of 5x:
Use this:
form select_good.
data: tvbak
like vbak occurs
0 with header
line.
data: tvbap
like vbap occurs
0 with header
line.
select * from
vbak into table
tvbak up to 200
rows.
select * from
vbap
for
all entries in
tvbak
where
vbeln=tvbak-
vbeln.
endselect.
endform.
Instead of this:
form select_bad.
select * from
vbak up to 200
rows.
select * from
vbap where vbeln
= vbak-vbeln.
endselect.
endselect.
endform.
18. SELECT * versus
SELECTing
individual fields
In general, use a
SELECT statement
specifying a list of
fields instead of a
SELECT * to reduce
network traffic and
improve
performance. For
tables with only a
few fields the
improvements may
be minor, but many
SAP tables contain
more than 50 fields
when the program
needs only a
few. In the latter
case, the
performace gains
can be
substantial. For
example:
Use:
select vbeln
auart vbtyp from
table vbak
into (vbak-
vbeln, vbak-
auart, vbak-
vbtyp)
where ...
Instead of using:
select * from
vbak where ...
19. Avoid
unnecessary
statements
There are a few
cases where one
command is better
than two. For
example:
Use:
append <tab_wa>
to <tab>.
Instead of:
<tab> = <tab_wa>.
append <tab>
(modify <tab>).
if not <tab>[] is
initial.
Instead of:
describe table
<tab> lines
<line_counter>.
if <line_counter>
> 0.
20. Copying or
appending
internal tables
Use this:
<tab2>[] =
<tab1>[]. (if
<tab2> is empty)
Instead of this:
loop at <tab1>.
append <tab1>
to <tab2>.
endloop.
However, if <tab2>
is not empty and
should not be
overwritten, then
use:
append lines of
<tab1> [from
index1] [to
index2] to
<tab2>.
In general, any custom developed programs or objects should be named with the
‘Z’ for the first character. SAP has designated objects beginning with the letters ‘Y’
and ‘Z’ as customer named objects and insures that this name space will not be
overwritten during an upgrade.
Also, SAP regularly updates the recommended customer name ranges for all
development objects. For objects not included in this guide, please consult this
SAP-created document. It is located on the SAP OSS system in note #16466.
ABAP Reports
Position Usage
Position Usage
6-8 'TOP' if used for global data, data declarations, table declarations
Examples
ZFCCMTOP Credit card TOP Include
ZFCCMF01 Credit card FORM Include
Classification Objects and Class Types
Since classification objects and class types are more like programming data
constructs than they are like configuration data, MIT naming conventions should be
followed when creating new classification objects or class types. To differentiate
between SAP supplied classes and MIT developed classes the prefix 'MIT_' should
be used followed by either the SAP data element or a descriptive abbreviation. For
example, when creating a characteristic for a 'Profit Center' where the data element
is 'PRCTR' the name would be 'MIT_PRCTR'. In addition, SAP recommends to use
only letters from A-Z, numbers 0-9, and the underscore character in the name.
Development Classes
Development classes should only be created when a specific new project requires
all components to be linked for organizational purposes. Before creating a new
development class, please consult with the R3 Admin team ([email protected]).
Most SAP system interfaces using flat ASCII files for input or output should use the
following directory paths for temporary and permanent interface files.
Since there is a limited amount of logical naming space available for function
groups, generally new groups should only be created when it is not possible to add
functions to existing groups.
Position Usage
For example, ZBR0 is the function group for application "BR" for "Bridges" and
number ‘0’ sequentially. Before creating a new function group, please consult with
David Rosenberg ([email protected]).
Function Modules
Function module names should be as descriptive as possible given that there are 30
characters available for naming. They should be formatted as follows:
Position Usage
Module Pools
Position Usage
Position Usage
6 'I' for PAI modules, 'O' for PBO modules, 'F' for subroutines
Typically function modules must specify the exact structure of each parameter they
are passed, hence runtime structures cannot be handled easily in normal function
module creation. However, by using the ABAP programming construct ASSIGN
COMPONENT idx OF STRUCTURE record to <FS>, a function can determine the
structure of a record. For an example of how to develop a function to do this refer
to function Z_LIST_SELECT_OPTIONS which reads the structure of a RANGES table
in a SELECT-OPTION parameter.
Support for one and two-dimensional arrays within ABAP is provided through the
use of internal tables. However, in the case of a 3-dimensional array, ABAP has no
naitive programming constucts. While a method could be devised to index a 3-
dimensional array via internal tables, the following code fragment demonstrates an
alternative approach using field symbols as pointers into data structures:
FIELD-SYMBOLS: <INDIRECT>.
POINTER-STEM = STEM.
POINTER-PART1 = SUB1.
POINTER-PART2 = SUB2.
POINTER-PART3 = SUB3.
Type coercion is typically defined as the means to force a variable of one type to be
another type. In ABAP programming, type coercion is most useful in ABAP for the
ASCII conversion of character data. The following code fragment is an example of
coercion which outputs ASCII character data:
do 224 times.
temp = sy-index + 31.
hex-byte = temp.
char = hex.
write: / 'Decimal =', temp.
write: 'Hex =', hex-byte.
write: 'View =', char.
enddo.
BDC: Formatting date fields to be compatible with user
preferences
When writing BDCs that read dates to be entered into SAP transactions problems
occur when determining what date format to use when entering the data into its
corresponding field. Assume that the ABAP program that must call the transaction
can read the ‘date’ field properly from the input file, but it does not know which
format the data entry screen of the transaction requires as this may change based
on the user’s setup defaults.
Many programs and interfaces will need to convert MIT legacy cost objects and
accounts to the corresponding SAP account or object. Two custom MIT function
modules have been developed for use in this conversion process.
Z_GET_COST_OBJECT
This function will accept a 5-digit account and return the related SAP 7-digit cost
object. Also, by passing a 7-digit SAP cost object into the function, it will verify the
existence of the cost object.
Z_GET_GL_ACCOUNT
This function will accept a 3-digit object code as input and return the related SAP 6-
digit G/L account. Also, by passing a 6-digit G/L account into the function, it will
verify the existence of the account.
For an example of how to call UNIX system commands, look at program ZUNIXCMD
on system SF2. Remember, you can call external programs either synchronously so
that your ABAP program will wait until they complete before continuing, or you can
call them asynchronously so that your ABAP program will continue execution
immediately.
Earlier programs written at MIT used the ‘CALL SYSTEM’ command. In the future,
this command should not be included in any new programs and should be removed
from existing programs when they are revised.
APPENDIX A
Basic ABAP/4 List Report
REPORT ZSKELREP.
*--------------------------------------------------------------
--
* Purpose:
*
*
*
*--------------------------------------------------------------
--
* Author:
* Date:
*--------------------------------------------------------------
--
* Modification Log:
*
*--------------------------------------------------------------
--
TABLES: ...
DATA: ...
SELECT-OPTIONS: ...
PARAMETERS: ...
* 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.
END-OF-PAGE.
START-OF-SELECTION.
GET ...
END-OF-SELECTION.
SORT ...
LOOP ...
AT FIRST.
ENDAT.
AT NEW ...
ENDAT.
AT END OF ...
ENDAT.
AT LAST.
ENDAT.
ENDLOOP.
* Subroutines
*--------------------------------------------------------------
--
*
*
*--------------------------------------------------------------
--
FORM ...
ENDFORM.
SELECT-OPTIONS: ...
PARAMETERS: ...
FIELD-SYMBOLS: ...
FIELD-GROUPS: ...
* Event which occurs before the selection screen is shown to
* the user.
INITIALIZATION.
TOP-OF-PAGE.
START-OF-SELECTION.
GET ...
END-OF-SELECTION.
* Subroutines
*--------------------------------------------------------------
--
*
*
*--------------------------------------------------------------
--
FORM ...
ENDFORM.
SELECT-OPTIONS: ...
PARAMETERS: ...
FIELD-SYMBOLS: ...
START-OF-SELECTION.
GET ...
MOVE ... TO ...
WRITE ... TO ...
UNPACK ... TO ...
TRANSFER ... TO ...
END-OF-SELECTION.
* Subroutines
*--------------------------------------------------------------
--
*
*
*--------------------------------------------------------------
--
FORM ...
ENDFORM.
select-options: ...
parameters: ...
field-symbols: ...
*--------------------------------------------------------------
--*
start-of-selection.
open dataset p_dataset in text mode.
if sy-subrc <> 0.
write: / text-e00, sy-subrc.
stop.
endif.
select-options: ...
parameters: ...
field-symbols: ...
start-of-selection.
*----------- DYNPRO nnn ---------------------------------------
--*
perform bdc_dynpro using 'SAPMxxxx' 'nnn'.
perform bdc_field using 'TABL-FIELD' 'LITERAL'.
*----------- DYNPRO nnn ---------------------------------------
--*
perform bdc_dynpro using 'SAPMxxxx' 'nnn'.
perform bdc_field using 'TABL-FIELD' TAB-VAR.
*--------------------------------------------------------------
--*
call transaction ' ' using trantab mode 'N' update 'S'.
* Message handling
return_code = sy-subrc.
2- Application Name
Character
Abbr.
AR Accounts Receivable
AU Authorization Checks
BR Bridges
CD Change Documents
CO Controlling
FC Credit Card
GL Finance Functions
L* Labor Distribution
System
PM Plant Maintenance
R3 Basis
RQ Requisitions
WF Workflow
WH Warehouse