Professional Documents
Culture Documents
We differentiate between data objects and data types in ABAP. Data types are mere descriptions that are not linked with
an address in the memory. Data objects are instances of data types and occupy memory to store the specific data that a
program uses at runtime.
You can define data objects in a program using the DATA statement. As shown in the figure, the name of the data object
is followed by a TYPE addition. The type is linked to the data object statically and cannot be changed at runtime.
Other syntax variants are available (for legacy reasons). Some of these legacy variants are no longer supported within
classes.
You can declare data objects using the following:
-2,147,483,648 -
I Integer 4 0
+2,147,483,647
Note that data types DECFLOAT16 and DECFLOAT34 exist as of SAP NetWeaver 7.0 EhP2 as a replacement for data
type F.
Data Length in
Description Initial Value Additional Information
Type Bytes/Initial Length
1 … 65535
Sequence of LENGTH addition can be used to specify
C Space
characters 1 length if default length of 1 not required
-Length fixed
00000000
D Date field 8
(YYYYMMDD) -Date calculations possible
-Length fixed
T Time field 000000 (HHMMSS) 6
-Time calculations possible
0…
Sequence of
STRING -Length variable
characters 0
Initial Length in
Data Type Description Additions
Value Bytes/Initial Length
0…
Sequence of bytes in
XSTRING -Length variable
hexadecimal notation 0
The tables above list all the elementary predefined data types provided by the ABAP runtime environment. You can use
the complete types (I, F, DECFLOAT16, DECFLOAT34, D, T, STRING, and XSTRING) to type a data object directly.
Supplement the incomplete types (P, N, C, and X) with a length specification to create a complete type. You can specify
the length in the DATA or TYPES statement, usually by using the LENGTH addition. For example:
Use the DECIMALS addition to define the number of decimal places for type P (packed number).
The numeric data types (I, F, P, DECFLOAT16, and DECFLOAT34) differ primarily in their value ranges, and in the
arithmetic used for calculations.
The major differences among the character data types (N, C, D, and T) are as follows:
The characters that can be used to form the strings of these types
The way they are formatted when output to the screen
Data objects with types D and T are handled in a special way in arithmetic operations
A primary attribute of the string data type is that data objects with this type have variable lengths. The runtime system
adjusts this length to the respective contents dynamically at runtime.
Each predefined data type has its own initial value. This type-specific initial value plays an important role in instantiating
the data objects and executing the CLEAR statement. All numeric data types have 0 as their initial value. The character
data types N, D, and T have a sequence of character 0 as their initial value, while type C has a sequence of spaces. The
variable-length data types have length 0 in their initial state.
Fully generic
Elementary, flat
Numeric
Character-type
Hexadecimal
Byte data type X, and XSTRING
xsequence
In addition to the predefined ABAP types, the runtime environment also provides predefined generic types. Generic types
do not completely define the attributes of a data object, and therefore they cannot be used in the declaration of data
objects.
Instead, generic types are used exclusively to type formal parameters (of subroutines, function modules, or methods) and
field symbols.
I, F, P, DECFLOAT16, DECFLOAT34, C, N, D, T,
Flat No No No deep components
and X
In terms of internal structure, you can distinguish the following data object categories:
Elementary fields
Structures
Internal tables
References
You can nest structures and internal tables to any number of levels. A structure that contains other structures as its
components, or even an entire internal table, is called a nested structure.
In terms of memory requirements and memory management, you can also differentiate between flat and deep data objects,
as follows:
Literals
Literals are data objects that you define in the source code of a program by specifying a string representing a value.
The ABAP runtime environment differentiates among the following types of literals:
Numeric literals
You can define a numeric literal as a sequence of digits in the program text, with or without + or - signs. A numeric
literal has type I if its value lies within the value range of this type (-2^31+1 to 2^31-1), otherwise it has type P.
String literals
You can define a string field literal as a character string that you enclose in back quotation marks (`) in the program
text. String literals have the type string, and their length is limited to 255 characters. They can also have zero length.
In contrast to text field literals, spaces are not suppressed at the end of a string literal.
Hint: To display a single quotation mark within a text field literal, you have to enter it twice. The same applies if you enter
a back quotation in a string literal. No restrictions apply to single quotations in a string literal, or back quotations in a text
field literal.
If the DATA statement appears between FORM and ENDFORM, it defines a local data object of a subroutine.
If the DATA statement appears between FUNCTION and ENDFUNCTION, it defines a local data object of a
function module.
In all other positions, the DATA statement defines a global data object, which is visible in the entire program.
If a global data object and a local data object have the same name, only the local data object is visible within the
modularization unit. In technical terms, it ignores the identically named global data object.
Caution: Data objects in modules and event blocks are always global. If the DATA statement appears between MODULE
and ENDMODULE, the object you define is still a global data object that is visible in the entire program. Likewise, data
objects that you declare in an ABAP event block are visible globally.
To avoid misunderstandings, SAP recommends that you declare such data at the start of the program, and avoid declaring
DATA statements completely in modules and event blocks.
The TABLES statement always creates data objects that are visible throughout the program. Data objects that you create
using the TABLES statement are always visible in the entire program, even if the statement appears within a subroutine or
function module.
If you use objects (instances of ABAP classes) in your application, the visibility of data is determined in a different way.
Data objects that are defined in the declaration part of a class are called attributes.
For attributes, the visibility sections are as follows:
Private attributes
Private attributes are visible only within the object or class. All the methods of the object can read and change the
data. External access to these attributes is possible only when you use a suitably defined method.
Public attributes
Public attributes are also visible and accessible outside of the object or class.
The ABAP language originally had relatively limited support for expressions and was very imperative, leading to the need
for sequences of statements and intermediate variables to calculate results used in subsequent statements. The situation
has improved considerably over the last years, for example with the introduction of method call chaining, lots of new
built-in functions, string expressions with the new concatenation operator && combined with string templates, and the
ability to write expressions at many operand positions.
In SAP NetWeaver 7.40, ABAP has become even more expression-oriented. More expressions and more expression
positions are now possible. ABAP now supports inline data and field symbol declarations, constructor expressions and
table expressions.
This allows you to write ABAP code in a style that corresponds more to what you may be accustomed to in other
programming languages such as C or Java. It allows you to express more about “what” you want to calculate, and less
about “how” you want to calculate it. You do not have to write a statement for each intermediate step in the calculation
and therefore need fewer local variables which are only used once.
In the past, ABAP was a statement-oriented language. With Release SAP NetWeaver 7.02, ABAP took the first step
toward expression enabling.
An expression in a programming language like ABAP is a combination of constants, variables, operators, functions, and
values that is evaluated at runtime and returns a result. It can therefore be used in program statements in places where a
constant or variable could also be used.
Inline Declarations
A very simple example of this is as follows. Without the use of inline declarations, you can write the following ABAP
code:
Inline declarations are a particularly interesting kind of expression. Inline declarations are a new way of declaring
variables and field symbols at operand positions.
In ABAP there are many operand positions, where the value of the operand is changed by the statement. One example of
these write positions is the left hand side lhs of an assignment:
lhs = rhs.
The data objects you can use at these write positions are either parameters of the procedure you are working in (for
example a method), or variables declared using the DATA statement.
In many cases the variables filled by a statement are “helper variables” that you only need temporarily. For each of these
helper variables you have to write a data declaration with the DATA statement and a suitable type.
However, the operand type of most write positions is fixed and known to the ABAP compiler. This is what makes inline
data declarations possible. Inline declarations involve the use of declaration positions (write positions with a fully known
operand type) and the new declaration operator DATA(...).
One of the possible problems with the extensive use of expressions is that your ABAP code becomes very difficult to read
and understand.
Type i
Integer arithmetic
Type p
Fixed-point arithmetic
Type f
Binary floating-point arithmetic
There are five numeric data types in ABAP, which differ in their inner representation of values and maximum value
range. Therefore, the data type that you choose for a data object depends on its required value range. In addition, each of
the five data types is linked to a specific type of arithmetic, which you can use for calculations involving data objects of
the respective type.
Calculations with integer arithmetic are faster than calculations with fixed-point or floating-point arithmetic because the
system executes them directly using the processor’s arithmetic command set.
The system rounds the non-integer results to the next whole number.
Floating point numbers are represented by binary precision floating point numbers. Floating point numbers are
normalized, and both the exponent and the mantissa are stored in binary form. This representation complies with the
Institute of Electrical and Electronic Engineers (IEEE) norm for double precision floating-point numbers (IEEE-754).
Caution: The binary floating point operations of the relevant processors are used for calculations in floating point
arithmetic. Because algorithms are converted to binary, inaccuracies can occur. The extent and effect of these inaccuracies
are difficult to estimate.
The following is an example that can give you a better understanding. Suppose you want to calculate 7.27% of 73050 and
display the result accurate to two decimal places. The answer should be 5310.74 (73050 * 0.0727 = 5310.735).
However, the program returns the following:
pack = float.
Due to these effects, floating-point arithmetic is unsuitable for business calculations because business calculations have to
be exact and comply with legal rounding regulations. You should, therefore, use floating-point numbers only for
approximations. When you compare floating-point numbers, always use intervals and round up the values at the end of
your calculations.
The main advantage of floating-point numbers is their large range of values, from 2.2250738585072014E-308 to
1.7976931348623157E+308, including both positive and negative numbers and zero. In addition, you need to use
floating-point numbers for special aggregation functions of the SELECT statement.
Decimal floating-point arithmetic is used for calculations using data objects of type DECFLOAT16 and DECFLOAT34.
The algorithm for this arithmetic is similar to using "pencil and paper". Interim results use numbers with 16 (decfloat16)
SAP introduced decimal floating-point numbers in SAP NetWeaver 7.0 EhP2 to overcome the drawbacks of binary
floating-point numbers.
Type f data objects cannot represent every decimal number precisely due to the internal binary representation. Results of
calculations may depend on the platform, there is no rounding to a specific number of decimal places, division by powers
of 10 is inexact, and no uniform behavior exists across database systems.
Decimal floating-point numbers have a range larger than type f, while the calculation accuracy is identical to type p.
An arithmetic expression can contain a mix of all the numeric data types. If an arithmetic expression contains at least one
data object with a numeric type, it can also contain character-type data objects, provided their contents can be interpreted
as numbers. The values contained in these character-type objects are converted to numeric type objects.
The system determines the arithmetic to be used based on the data types involved before it performs the calculation.
Different types of arithmetic have different degrees of internal accuracy. Thus, the same arithmetic expression can lead to
different results, depending on the data types involved. The examples in the figure illustrate this.
In order to determine the arithmetic, the system takes into account the data types of all operands along with the data type
of the result field. After determining the arithmetic, the system converts all operands to the numeric type that corresponds
to the chosen arithmetic. The system performs the calculations using these converted values and ultimately converts the
result to the desired result type.
Hint: Remember that conversions affect performance. To avoid conversions, ensure that all operands and the result field
have the same numeric type.
All elementary data objects with a byte-type data type (x, xstring) are byte-type data objects. All elementary data objects
with a character-type data type (c, n, d, t, string) are character type data objects.
In non-Unicode systems, byte-type data objects, as well as all flat structures, can be handled in the same way as character-
type data objects. In Unicode systems, in contrast, you have to differentiate clearly between byte-type and character-type
data objects.
Moreover, you can only handle flat structures as character-type data objects if they consist entirely of character-type
components.
The figure provides an overview of the ABAP statements for processing character-type data objects.
In each of these statements, the operands are treated like type c fields, regardless of their actual field type. They are not
converted. All of the statements apart from TRANSLATE and CONDENSE set system field sy-subrc.
Note: As of SAP NetWeaver 7.0, the statement FIND replaces the statement SEARCH.
With the exception of CONDENSE and OVERLAY, you can also use the statements listed in the figure Overview-
Statements for Character and Byte String Processing to process byte-type data objects. In a Unicode system, you have to
use the IN BYTE MODE addition to ensure that each byte is examined individually, and not in pairs.
The corresponding IN CHARACTER MODE addition is optional for processing character-type data objects.
Subfield Access
You can access a fragment of a character-type or byte-type data object directly by specifying the appropriate offset and
length.
The specifications for length and offset are interpreted as numbers of bytes for byte-type data objects, and as numbers of
characters for character-type objects (that is, one or two bytes, depending on the system setting).
In flat structures, offset access is possible even if they are not completely character-type (that is, only the first field(s) are
character-type), provided the access does not go beyond the character-type area.
Caution: If possible, avoid using this method to access structure contents. Using components and string operations makes
your program much more reliable and easier to read.
Logical Operators
The following operators are available to compare the content of character-type data objects: CO, CN, CA, NA, CS, NS,
CP, and NP. With the introduction of Unicode, corresponding operators with the prefix BYTE- are available for byte-type
data objects.
For input and output, the preferences for the current users are taken into account for formatting of the data.
If a data object with type D is used in arithmetic expressions or assigned to a numeric data object, its contents are
converted to the number of days since January 1, 0001.
If a data object with type T is used in arithmetic expressions or assigned to a numeric data object, its contents are
converted to the number of seconds since midnight.
Caution: If you have to specify start values for date or time fields (in the VALUE addition of the DATA statement), the
value must be supplied as a text literal. This is because numeric literals have type I, which means they would be
interpreted incorrectly as the number of days.
String Functions
As well as ABAP statements, predefined ABAP functions can be used to analyze character strings and byte strings.
ABAP functions are divided into three groups as follows:
As well as those displayed in the figure, the following processing functions are available:
Cmax and cmin – return the values of the largest / smallest character-like argument
Concat_lines_of – concatenates all row contents of an internal table and returns the result as a character string
Escape - takes the content of a character string, and hides certain special characters with escape characters
according to a specified rule
Match - returns a subfield of a character-like argument that matches a regular expression
Repeat - returns a character string that contains content repeated as many times as specified
Reverse – returns a reversed character string
To_lower - converts all letters in the character string to lowercase letters
To_mixed - converts all letters in the character string to lowercase letters from the second position
From_mixed – inserts an underscore before each uppercase letter (from left to right and from the second position).
A different separator can be specified if an underscore is not suitable
Translate – replaces characters in a character string
For full details about all of the processing functions, including their parameters and examples, see the ABAP Keyword
documentation.
Processing functions have a character-like result. They can be declared at general expression positions and character-like
expression positions. The return values have the type string.
Text literals
Embedded expressions such as, data objects, calculated expressions, predefined functions, or function methods
surrounded by { }
Control characters
A string template that starts with “|” must be closed with “|” within the same line of source code. The only exceptions to
this rule are line breaks in embedded expressions.
String templates can only be specified in Unicode programs.
The data type of the expression must be an elementary data type and the value of the expression must be character-type or
must be convertible to a string.
Regular Expressions
Parsing and processing character strings is a frequent programming requirement. ABAP has for a long time provided a
range of functions to do this (for example, FIND, REPLACE, SPLIT, OVERLAY, SEARCH, and so on). In many cases, a
combination of various commands is necessary, mostly with IF queries and the use of loops.
With SAP NetWeaver 7.0, so-called regular expressions were introduced in ABAP to simplify string processing. They are
used to find and, if necessary, replace special character strings that correspond to a pattern in a character string.
Often, the structure of a character string you are analyzing cannot be described precisely, because parts of it are variable.
For this reason, patterns with special placeholders that represent certain characters or sequences must be used. Although it
was possible in the past to use patterns in ABAP for searching (when working with the SEARCH statement, * could be
used to represent any number of characters and + to represent any character), the options were limited and processing
more complex character strings was very complicated.
A regular expression is a literal containing all kinds of characters. However, some characters or character combinations
have a special syntactical meaning.
To describe a single character, the following special character combinations can be used:
Additional special character combinations to describe a character string by a regular expression include the following:
String functions that support the use of regular expressions include the following:
COUNT ()
COUNT_... ()
CONTAINS... ()
FIND ()
FIND_... ()
MATCH ()
MATCHES ()
REPLACE ()
SUBSTRING ()
SUBSTRING_... ()
One of the principle uses of regular expressions is the search for substrings in character strings. In general, a user is
interested in a specific selection of character strings that match a regular expression.
In ABAP, the search of regular expressions is realized using the addition REGEX of the statement FIND, whereby the
substrings found are determined without overlapping according to the leftmost-longest rule:
First, the substring is determined that is the furthest to the left in the character string, and that matches the regular
expression (leftmost). If there are several substrings, the longest sequence is chosen (longest). This procedure is then
repeated for the remaining sequence after the found location.
The special character combinations that support searching in a character string are as follows:
^ Anchor for offset before first character of line.
The character combinations that can be used in the replacement text are as follows:
Internal Tables
Internal tables are among the most complex data objects available in the ABAP environment. The use of internal tables
lets you store dynamic datasets in the main memory. Internal tables are comparable to arrays and they spare the
programmer the effort of program-controlled memory management thanks to their dynamic nature. The data in internal
tables is managed per row, whereas each row has the same structure.
In most cases, internal tables are used for the buffering or formatting of contents from database tables. The type of access
to internal tables plays an important role for performance, as is the case with database tables. Experience shows that the
tuning of internal tables enables similarly major effects as the tuning of database accesses. The negative effects of
inefficient accesses to internal tables for the overall system can be compensated more easily than inefficient database
accesses by adding further CPUs or application servers. Inefficient database accesses affect the database as a central
resource, whereas inefficient accesses to internal tables impact the better scalable application layer.
The following sections first provide a general overview of the internal tables. This is followed by a description of how the
internal tables are organized in the main memory. The subsequent section discusses the different types of internal tables.
The major part of this chapter then details the performance aspects for the processing of internal tables.
In the main memory, the internal tables, just like the database tables, are organized in blocks or pages. In the context of
internal tables, the following sections use the term pages.
When an internal table is declared in an ABAP program, the system only creates a reference (table reference) in the main
memory initially. Only when entries are written to the table does the system create a table header and a table body.
The table header has a reference to the first page of the table body and another reference to page management. Page
management manages the addresses of the pages in the main memory.
The table reference currently occupies 8 bytes of memory space. The table header occupies about 100 bytes of memory
space depending on the platform. The space required for page management depends on the number of pages.
The table body consists of pages that can include the table rows. The first two pages are — depending on the row length
and other factors — usually smaller than the pages 3 to n (if the row lengths are not so long that the maximum page size is
reached already at the beginning).
The table header includes the most important information about an internal table. For example, you can quickly query the
number of rows using DESCRIBE TABLE <itab> LINES <lines> or the integrated function, LINES( itab ), from the table
header.
As very small internal tables with only a few rows can result in wastage due to the memory use of the automatically
calculated first page, INITIAL SIZE is added for the declaration of internal tables. It can provide information on the size
of the first page, so a smaller memory allocation than in the standard case occurs.
However, if considerably more rows are required than originally specified for INITIAL SIZE, the third page is created
faster with the maximum page size. For example, if 4 was specified for INITIAL SIZE, the third page may already be
required as of the 13th row if the second page is twice as large as the first page. Relatively few rows (13, for example)
require relatively much memory (three pages, third page with a size of 8 to 16 KB), whereas one page would have been
sufficient if a higher value (for example, 14) had been specified for INITIAL SIZE. Consequently, for small tables it is
important that INITIAL SIZE is not selected too small. Select a value that provides sufficient space in the first (or first
and second) page for most cases.
INITIAL SIZE should always be specified if you require only a few rows and the internal table exists frequently. For
nested tables, if an internal table is part of a row of another internal table, this is likely for the inner internal table. It can
also occur for attributes of a class if there are many instances of this class.
In conjunction with the APPEND wa SORTED BY comp command, the INITIAL SIZE addition not only has a syntactic
but also a semantic meaning (see documentation). However, don’t use the APPEND wa SORTED BY comp command;
instead, work with the SORT command.
Depending on the table type or type of processing, you also require a management for the access to the row, that is, an
index for the index tables and a hash administration for the hashed tables. At this point, memory may be required for the
management of entries in addition to the pages. This management also occupies memory. Both in the Debugger and in the
Memory Inspector, this memory is added to the table body and not displayed separately. Compared to the user data, this
management can generally be neglected.
But how can you release allocated space in the internal tables again? The deletion of individual or multiple rows from the
internal table using the DELETE itab command doesn’t result in any memory release. The rows concerned are only
“selected” as deleted and not deleted from the pages.
Only when you use the REFRESH or CLEAR statements the system does release the pages of the internal tables again.
Only the header and a small memory area remain.
In this context, released means that the occupied memory can be reused. As the memory allocation from the Extended
Memory (EM) for a user is usually done in blocks (see Section 6.1 in Chapter 6), which are considerably larger than the
pages of an internal table, this is referred to as a two-level release. Release initially means that the pages within an EM
block are released and this space can then be reused by the same user. Only if the EM block is completely empty and
doesn’t contain any data (variables, and so on) of the user any longer is this block returned to the SAP memory
management and available for the other users again.
If an internal table should be reused, it is advisable to use REFRESH or CLEAR instead of FREE because this way the
creation of the first page can be omitted. If a large part of the rows of an internal table was deleted using DELETE and the
occupied memory should be released, it is recommended to copy the table rows. A simple copy to another internal table is
not sufficient because of table sharing, which is discussed in Section 7.4, Performance Aspects. Alternatively, you can
revert to ABAP statements (INSERT or APPEND) or to the EXPORT/IMPORT variants (see Section 6.2.2 in Chapter 6)
for copying. In the context of performance, the “release” of memory only plays a secondary role (as long as no memory
bottleneck exists in the system). In contrast to fragmented database tables, fragmented internal tables have no negative
effects on the performance because the entries can always be addressed efficiently because internal tables are always
managed per row.
Internal tables can be compared to database tables in many respects, but there is one major difference:
Internal tables are always processed on a row basis, whereas database tables are always processed on a set basis. A set-
based processing, possible with Open SQL on database tables, is not possible on internal tables because the single row is
the main processing criterion for internal tables, whereas a set of data records is the main processing criterion for database
tables. Set-based accesses to internal tables, for instance, LOOP ... WHERE or DELETE ... WHERE, are emulated by the
ABAP VM and can be mapped in an optimized way for some table types (see Section 7.4, Performance Aspects). More
complex, set-based operators, such as joins and aggregates,… are not possible on internal tables. They must be
programmed using the existing ABAP language techniques.
After you’ve learned about the organization of internal tables in the main memory, the next section focuses on the
organization of internal tables and discusses the different types of internal tables.
The figure illustrates how access time changes with the size of the table for the various table types. While access times are
similar when tables are small, the more lines that a table contains, the larger the differences become. A notable exception
is that the access times for key access to hashed tables are not dependent on table size.
The type of an internal table is called a table type. Table types can be defined globally, in the ABAP Dictionary, or
locally, within a program.
The figure illustrates a table type declared in the ABAP Dictionary, as well as the program-internal definition of a table
variable with reference to the table type.
The figure illustrates a table type declared locally in the program as well as the internal definition of a table variable in the
program with reference to the locally declared table type.
When you list key fields in the table type, note that the sequence matters for certain types of processing (such as “sort by
key”). For detailed information about declaring local table types, refer to the keyword documentation for the TYPES
statement.
Hint: Instead of defining a table type first you can also define an internal table directly. All you have to do here is use
DATA instead of TYPES.
Caution: A common beginner’s error consists of the following syntax:
DATA gt_itab TYPE TABLE OF <Table type>.
This would result in the definition of an internal table with rows that are internal tables of the specified table type.
For processing single records of an internal table, a structure variable that has the same type as the line type of the internal
table is required. This structure variable is known as the work area.
The figure illustrates the processing of an internal table using the corresponding work area.
The following statements are used to access single records of internal tables:
o APPEND appends the content of a structure to an internal table, and this operation can only be used with
standard tables.
o INSERT inserts the content of a structure into an internal table.
o READ TABLE copies the content of a table row to a structure.
o MODIFY TABLE overwrites an internal table row with the content of a structure.
o DELETE deletes a row of an internal table.
o COLLECT accumulates the content of a structure in row of an internal table that has the same key and in
doing so, only non-key fields are added. Therefore, this statement can only be used for tables whose non-key
fields are all numeric.
For detailed information about the ABAP statements described, refer to the relevant keyword documentation.
o LOOP AT . . . ENDLOOP places the rows of an internal table into the structure specified in the INTO
clause one-by-one. Within the LOOP, the current content of the structure can be output, or you can change
and write the current content back to the table.
o DELETE deletes all rows of the internal table that satisfy the logical condition <condition>.
o INSERT LINES OF copies the content of several rows of an internal table to another internal table.
o APPEND LINES OF appends the content of several rows of an internal table to another standard table.
The following figures are actual examples of syntax for the most common statements.
Insert a row into an internal table by writing the data for the required record into the prepared work area and then inserting
it into the internal table with an INSERT statement.
With standard tables, this content is appended. With sorted tables, the row is inserted in the right place to keep the table
sorted by its key fields and, in hashed tables, it is inserted according to a hash algorithm.
o FREE-This statement deletes the entire content of the internal table and releases the previously used
memory. Use the FREE statement for internal tables that have already been evaluated and are no longer required in
the further course of the program. By this you make the no longer required memory available again.
You should no longer use tables with header lines for the following reasons:
... ,
END OF itab.
Internal tables with header lines are mentioned here because some older programs still use them and you have to work
with such programs from time to time. It is for this purpose that further particularities of the header line are listed.
If an internal table with header line is called "itab" you can use itab-comp to address component "comp" of the header line
(work area).
Standard Tables
Standard tables are managed internally using a table index (line numbers). You can append new lines at the end of the
table or insert them at specific positions. The lines within the internal table can be in any sequence and, consequently, the
system has to search the entire table sequentially during a key access. While this can be done relatively quickly for small
tables, the search effort increases linearly with the number of lines.
Note: If the internal table is explicitly sorted by using the SORT statement, the BINARY SEARCH addition can
significantly speed up access. This will be discussed later in the lesson.
You must never change the sort sequence of a sorted table, even temporarily. In many cases, the system automatically
ensures that the table contents are sorted correctly, such as when a sorted table is specified for a database access
after INTO TABLE or when a MOVE statement copies the contents of a table into a sorted table. The runtime
environment also ensures the correct sort sequence for key accesses.
Like standard tables, sorted tables are managed using a table index. The entries are always sorted in ascending order by
the table key. As a result, the system automatically performs a binary search during table key accesses.
Based on the total number of lines, the runtime environment determines an index in the middle and reads a line by index
access there. By comparing the key field values of this line with the search criteria, the system determines whether the
sought entry is before or after the current line. This step halves the data in a single step and is repeated until the sought
entry is found or the system determines that no entry in the table matches the criteria.
Hint: If the sorted table has a non-unique key, several lines could match the criteria. The result of sorting is that all lines
with the same key are in a contiguous block, and the system always returns the first line of the block, that is, the one with
the smallest index.
Hashed tables are managed internally using a hash algorithm. To enable this, a hash board is created in addition to the
actual table and the memory addresses of the table lines are managed in that table. Whereas the table contents are
completely unsorted, a hash function makes it possible to directly calculate the position of the entry in the hash board
from the key values. Accordingly, the key of a hashed table must always be unique.
The effort required to calculate the position in the hash board and then read the table line is identical for all lines,
regardless of the number of table entries. The entries in the hash board are not consecutive but are instead spread over a
certain memory area. These gaps make it possible to insert additional lines later. The hash function that is used determines
how large the gaps are. If the system calculates that the entries in the hash board are too close to one another when
inserting a line, it reorganizes the hash board. To do so, the positions are calculated with a different hash function that
distributes the entries over a larger memory area.
Hint: Loops (LOOP ... ENDLOOP) ignore the hash board and search the table contents directly. The content is unsorted,
but for this purpose, it can be sorted by using the SORT statement.
When working with the different table types, it is essential to understand the difference between index access and key
access. The system does not allow index access to hashed tables. You must be careful when using index access statements
that modify a sorted table, because doing so may violate the sort sequence, which causes a runtime error.
While the syntax check ensures that no index accesses are made to hashed tables, developers of sorted tables must be able
to spot index accesses that modify the internal table and avoid using them incorrectly.
Single records from internal tables are read using the READ TABLE statement.
Index accesses are characterized by the INDEX addition, which specifies an explicit index. The INDEX addition is not
allowed for hashed tables. Key accesses can be performed with an implicit specification of the key (using
the FROM addition), and an explicit specification (using WITH (TABLE) KEY ). Keys can be either implicit or explicit
as follows:
Key is implicit
When you specify the key implicitly, the key field values are taken from the structure after
the FROM addition. FROM and INTO do not need to have the same structure.
Key is explicit
When the key is specified explicitly, the full table key can be specified using WITH TABLE KEY, or any other key
can be specified using the WITH KEY addition. If you use the WITH TABLE KEY addition, the syntax check
demands that all of the key fields in the table be listed and supplied with a value. If a key field is missing, this causes
a syntax error. If you use the WITH KEY addition, you can specify any column identifier. The syntax check does not
compare them with the key fields.
The addition does not have a direct impact on runtime. When accessing sorted and hashed tables, the system uses the
binary search or hash algorithm respectively, even if you use the WITH KEY addition. The only prerequisite is that you
must specify all the key fields.
By using the optional TRANSPORTING addition, you can copy selected columns instead of the entire line into the
specified structure defined in the program (after INTO).
There are various ways to modify records in internal tables, depending on whether you need to add a new entry, change an
existing entry, or delete an entry. The differences between index access and key access are particularly important because
index access statements that modify a sorted table can cause runtime errors.
Hint: In all single record write accesses by key, the keyword TABLE appears next to the name of the internal table (that
is, INTO TABLE, MODIFY TABLE, and DELETE TABLE). You cannot use this addition for single record write
accesses by index (that is, INTO lt_conn, MODIFY lt_conn, and DELETE lt_conn). Therefore, INDEX and TABLE are
mutually exclusive
DELETE by key
The table key is either implicit (FROM) or explicit (WITH TABLE KEY). WITH KEY is not supported. Depending
on the table type, the system searches for the line to be deleted sequentially, using a binary search, or hash algorithm.
MODIFY by key
Only an implicit key can be used. Depending on the table type, the system determines which line is to be changed
sequentially, using a binary search, or a hash algorithm.
Only non-key fields are changed. The explicit specification of key fields after TRANSPORTING causes a syntax
error with sorted and hashed tables.
INSERT by key
Only an implicit key can be used. For hashed tables, a line is appended to the table contents, an entry is added to the
hash board, and the table is reorganized if necessary. For sorted tables, a binary search determines the insert position.
For standard tables, it simply adds a line to the end.
MODIFY by index
This statement also allows changes to key fields. This is risky for sorted tables because it potentially impacts the sort
sequence.
Using the optional TRANSPORTING addition with MODIFY works in a way similar to using READ TABLE to copy
only selected components to the desired line in the internal table.
When you perform single-record write accesses by index, you can omit the explicit index specification in a loop. In this
case, the system implicitly uses the current value from SY-TABIX. These syntax variants are only relevant within the
loops of the corresponding internal table and can only be used there.
Caution: The constraint that these statements can only be used within loops is not verified by the syntax check. If you use
them outside of loops, it causes a fatal exception (TABLE_ILLEGAL_STATEMENT).
You should be familiar with restrictions using WHERE from processing internal tables in LOOPs. You can also
specify WHERE conditions in special variants of MODIFY and DELETE.
Although key accesses are involved here, you should specify the internal table without the TABLE addition in these
statements.
If you combine MODIFY and WHERE, you must use the TRANSPORTING addition.
In sorted tables, the system optimizes access automatically if the WHERE condition restricts the first n key fields to one
value, when a left-aligned, gap-free part of the key is specified. In this case, the desired entries are not scattered
throughout the table, but instead are in a contiguous block. In this case, the system uses a binary search to determine the
start of the block and then begins sequential processing from there. As soon as an entry that does not match the key fields
is reached, the system completes the block and immediately ends processing.
Hint: Mass access to sorted tables has better performance compared to other table types, as long as the WHERE condition
limits the first n key fields to one value.
Sorted tables with a unique key represent a special application case of this table type. In this case, when you insert a new
line, the system immediately determines whether the table already contains a row with an identical key.
Hint: Ensuring unique keys does not impact performance. When a new line is inserted into a sorted table, the right insert
point needs to be found for non-unique keys as well.
As a result of the sort sequence, the entries that satisfy the WHERE condition are located in a contiguous block.
The READ TABLE ... BINARY SEARCH statement determines the position of the first item in this block through the
contents of system field SY-TABIX. Because the position is required only initially, the TRANSPORTING NO
FIELDS addition can be used.
If several entries satisfy the condition, READ TABLE always returns the first entry.
During the subsequent LOOP, the determined line is used as the starting point (the FROM addition). An explicit
termination (EXIT statement) ends processing as soon as the execution reaches a line that does not satisfy the condition;
that is, a line that lies outside the block.
Note: The source code has shown in the figure implements the same algorithm that the system automatically uses for
sorted tables.
The DELETE ADJACENT DUPLICATES statement lets you remove duplicate lines from an internal table. The system
deletes all lines in which the contents of certain fields are identical to the contents of the immediately preceding lines.
In the example shown in the figure, the internal table contains several instances of multiple lines with the same value in
the CARRID column. The DELETE ADJACENT DUPLICATES statement retains the first line of each group in the
internal table and deletes all the others.
Caution: The comparison only compares adjacent table lines. The table must therefore be sorted by the comparison fields
if the statement is to find and remove all duplicates.
The COLLECT statement is a special technique for filling an internal table. The system aggregates the table during the
insert operation.
If the table does not have a line with the same key yet, the COLLECT statement has the same effect as inserting by key
access. If the table already contains one or more lines with this key, the system sums the values of all non-key fields in the
new line to the corresponding values in the top line.
Hint: The COLLECT statement is only allowed when all non-key fields are numeric. The syntax check reports an error
when this prerequisite is not met.
The simplest way to ensure that all non-key fields are numeric is to define an internal table with a standard key (the WITH
DEFAULT KEY addition). The standard key is defined such that all non-numeric fields are key fields and all non-key
fields have a numeric type.
As of SAP NetWeaver 7.0 EhP2, it is possible to define secondary keys for internal tables. Secondary keys can be hashed
or sorted. A sorted secondary key can be unique or non-unique. The maximum number of secondary keys per internal
table is 15.
You can define secondary keys for table types in the TYPES statement or the DATA statement. For global table types in
ABAP Dictionary, a new Secondary Key tab is available.
You must specify a key name for each secondary key. The key name can be random, but must be unique for this table.
The figure shows how you can use a secondary key in a processing statement by specifying the key name with
additions USING KEY key_name or WITH KEY key_name.
Secondary keys can be used in most processing statements, except for the following:
APPEND
INSERT (either key or index access)
READ TABLE ... WITH TABLE KEY ...
DELETE TABLE ... WITH TABLE KEY ...
A secondary key is not selected automatically. Unless you specify a secondary key during a processing statement, the
system always uses a primary key or primary table index. If you have defined a secondary key for a set of components but
do not use it within a processing statement that is coded for the same set of components, the syntax check issues a
warning.
Hint: When you use a sorted secondary key in an index access, the index you specify is applied according to the sort order
in the secondary key. After an access through a sorted secondary key, the SY-TABIX field contains the position of the
line in the secondary key.
In a key access (single record or with WHERE), the components in the condition must match the components of the
secondary key.
The system does not always update the secondary keys immediately when you change the content of the internal table.
The system treats unique and non-unique secondary keys differently.
A non-unique secondary key is only created when it is used explicitly for the first time. After a write access to the internal
table, the update of the secondary key is delayed until the next statement that explicitly uses this secondary key. This type
of update is referred to as a lazy update.
A unique secondary key forms a boundary condition for the internal table and is therefore treated differently.
For any write access that adds or removes lines, the secondary key is updated immediately. If the uniqueness is violated,
the system raises an exception that can be caught and handled (exception class CX_SY_ITAB_DUPLICATE_KEY).
For MODIFY statements that change the key fields of a unique secondary key, the system updates the secondary key
immediately. If the uniqueness of the key is violated, the system raises an exception that cannot be handled.
The system only delays the update of a unique secondary key for direct changes through field symbols or data references.
Unlike non-unique keys, the system updates the unique secondary key at the successive access to the internal table. In this
context, it is not necessary that this secondary key is actually used in this access.
Use non-unique secondary keys because the system always delays the update and performs the update only when the
respective secondary key is actually used. In addition, when an internal table has a unique secondary key, any write access
to the table risks incurring runtime errors because of a uniqueness violation.
Be careful when using index operations. After an operation that uses a sorted secondary key, SY-TABIX returns the
position of the respective line in this sorted secondary key. To use SY-TABIX to address the line in a subsequent index
access, specify the same secondary key.
Recommendations for Using Secondary Keys
Use secondary keys only when deployed often because they are expensive and pay back only when used
frequently.
Use non-unique secondary keys as the update is always delayed and as there is no danger of runtime errors due to
duplicate entries. The secondary key is updated only when it is used.
Remember that the sort order in secondary keys differs from the sort order in primary keys; SY-TABIX returns
the line index with the secondary key but not with the primary key. The secondary key should, therefore, be used in a
subsequent index access.
The following points are significant when considering the use of secondary keys:
Do not neglect the additional costs of creating or updating the secondary key.
Only use secondary keys when they are used often.
Hint: Building a secondary key is more expensive than sorting a standard table.
Data References
Use the dereferencing operator ->* to dereference statically-typed data objects directly. This means that the dereferencing
operator directly accesses the content of the data object that the reference is pointing to. For compatibility reasons, you
must dereference generically typed data references (TYPE REF TO data) and assign them to a field symbol, which you
then use to access the content.
When you type data references statically with a structure type, you can address the components of the referenced data
object directly. Components are addressed by using the component selector ->.
Data references and object references were introduced alongside field symbols as part of the enhancements in SAP R/3
4.6A. From this point on, ABAP features full “reference semantics”.
Data reference variables contain data references or pointers to data objects.
Use the TYPE REF TO addition for the TYPES statement to define a reference type for a data object. You can specify the
data type explicitly or choose the generic variation by using TYPE REF TO DATA. In this case, your data reference can
point to any type of data object.
The corresponding DATA statement defines the data reference variable. Reference variables are data objects that contain
the address of any other data object of the specified type.
Data references use reference semantics; that is, when a data reference variable is accessed, the data reference is
addressed. This means any changes to the data references affect the addresses.
Data reference variables are handled in ABAP like other data objects with an elementary data type. This means a
reference variable can be defined not only as a single field, but also as the smallest indivisible unit of complex data
objects such as structures or internal tables.
Example:
DATA: gs_flight TYPE sflight,
gr_flight TYPE REF TO sflight.
GET REFERENCE OF gs_flight INTO gr_flight.
gr_flight->fldate = gr_flight->fldate + 5.
WRITE: / gr_flight->seatsmax.
In this case, the component selector corresponds to the hyphen for regular component access to structured data objects.
Use the expression ref IS [NOT] BOUND to query whether the reference variable “ref” contains a valid reference. The
reference variable “ref” must be a data reference variable or an object reference variable.
ref IS [NOT] INITIAL
Field Symbols
Example:
DATA: gv_date TYPE d VALUE '20040101',
Before the introduction of data references, field symbols were used in ABAP as dereferenced pointers. Field symbols
provide symbolic access to an existing data object. All accesses you make to the field symbol are made to the data object
assigned to that field symbol. Therefore, you can only access the content of the data object to which the field symbol
points. This technique is referred to as the value semantics of field symbols.
You declare field symbols using the FIELD-SYMBOLS statement. Note that the angle brackets (<>) in the field symbol
name are part of the syntax. Use the ASSIGN statement to assign a data object to the field symbol.
By specifying a type for the field symbol, you can ensure that only compatible objects are assigned to the field symbol.
Data references and field symbols provide new access options when combined with internal tables.
You can use the statements described in the figure to define field symbols and references that are capable of pointing to
individual lines in an internal table. This makes it possible to use these field symbols, or the dereferencing operator, to
access these records.
Field symbols and references point to the assigned row even after the internal table is re-sorted.
Unless there are compelling reasons to the contrary, always type the field symbols and references using types that are
compatible with the internal table. Generic types are also possible within the dynamic programming framework. However,
in such cases, you cannot use the CASTING addition.
When you read a table row using READ TABLE or a series of table rows using LOOP AT, you can assign the rows of the
internal table to a field symbol by using the ASSIGNING <field_symbol> addition. The<field_symbol> field symbol then
points to the line that you assigned, allowing you to access the field content directly. Consequently, the system does not
copy the entry from the internal table to a work area and back again.
The restrictions for using this technique are as follows:
You can only change the contents of key fields when the table is a standard table.
You cannot reassign field symbols within the loop. The statements ASSIGN TO <fs_line> and UNASSIGN
<fs_line> cause runtime errors.
You cannot use the SUM statement for control level processing.
The same restrictions apply for the variant REFERENCE INTO ref_name, which you can use to point a reference to the
lines.
If you use one of the three statements in the figure to exchange data with the internal table through a work area, you can
also use the optional additions ASSIGNING <field_symbol> and REFERENCE INTO ref_name to point a field symbol
or reference to the processed line.
One group of expressions that can be useful when processing internal tables allows the inline declaration of data objects,
using an expression containing the DATA( ) operator. Because internal tables often go hand in hand with a work area to
allow the individual records to be processed, these inline declarations can be used for this work area.
The equivalent also works for field symbols using the FIELD-SYMBOL( ) operator.
Another particularly helpful group of expressions are table expressions.
Table expressions allow you to access table rows in a similar way to a READ TABLE statement, for example by
specifying the index of the row you want to access, or by specifying the value of a column. You can use table expressions
directly as part of statements, without reading into a work area first. You can also directly reference fields of the resulting
row and chain such expressions.
With table expressions and inline declarations, far fewer READ TABLE statements and individual local variables are
necessary to hold intermediate results, making ABAP code more readable.
The figure shows how relatively long and complicated ABAP code can be simplified through the use of table expressions.
Table Expressions
The internal table itab must be specified directly using its name, a field symbol, or a dereferenced data reference. The
structure component selector - can be used to access components of the row in question and direct chainings [ ... ][ ... ] of
A table expression consists of an internal table itab, followed directly by a row (itab_line) specified in square brackets [ ].
The expression finds the specified row in the internal table and returns it as the result of the corresponding row type,
which can be used as follows:
Reader positions
o A table expression can be specified in general expression positions and functional operand positions with
an appropriate operand type. The result is used here as an operand. The category of the result can be controlled in
operand positions using constructor operators.
o A table expression can be specified as a special expression variant for the memory area in the statement
ASSIGN.
o A table expression can be specified as an argument of the table function line_index and the predicate
function line_exists.
Writer positions
o A table expression can be specified as a writable expression in result positions. Once found, the row in
question can be modified directly here.
The table function line_index returns the number of the row found for the table expression specified. The return value has
the type i.
The predicate function line_exists checks whether the row of an internal table specified in the table expression exists and
returns the appropriate logical value.
In this example, the subquery is supposed to return several lines, each with one value. If you want to compare all the
returned values, use IN. Subqueries whose WHERE condition contains fields from the main query are called correlated
subqueries. If subqueries are nested, each subquery can use all the fields from the higher-level subqueries in the hierarchy.
Query designers should formulate positive subqueries whenever possible; negative formulations may result in
performance-degrading database reads if no adequate index is available.
A subquery is a query within a SELECT, UPDATE, or DELETE statement. It is formulated in the WHERE or HAVING
clause to check whether the data in various database tables or views possess certain attributes.
Parallel Cursors
Using the Open SQL statements OPEN CURSOR, FETCH NEXT CURSOR, and CLOSE CURSOR to program explicit
cursor handling with several database tables concurrently allows you to process the contents of multiple database tables in
parallel without using nested SELECTs.
In the example in the figure, you want the program to process all flights from database table SFLIGHT, and you want to
read the non-canceled bookings in the economy class for each flight from database table SBOOK and process the
bookings together with the flight. The obvious solution is a nested SELECT, but that solution is likely to have poor
performance.
Due to the large data volume involved, you do not want to buffer the bookings completely in an internal table.
For this technique to work correctly, the following prerequisites must be met:
Each fetch for the first cursor (cursor variable GV_CURSOR_SFLIGHT) places the next respective record from
database table SFLIGHT into structure GS_FLIGHT (similar to a SELECT loop).
Each fetch for the second cursor (cursor variable GV_CURSOR_SBOOK) reads the corresponding non-canceled
economy bookings into internal table GT_BOOKINGS. However, these bookings are not actually selected based on
their key. Instead, the next n records are simply read. The value of n corresponds to the value of the seatsocc field in
the record for the flight. Because the selection results are sorted (ORDER BY clause), the next n bookings are the
bookings for the current flight.
Buffering Techniques
Avoiding database accesses in the first place is the simplest way to reduce database load. You can do this by taking table
contents that have already been read and saving them in an internal table (with type SORTED or HASHED, if possible).
In many cases, the application logic does not permit the use of joins. If you need to read data from multiple tables in such
cases, you can use a separate internal table to buffer the read data.
The content of the internal table (driving table) is used as a restriction for the database access, and may depend on the
database system. In general, the database interface takes a certain number of entries in the internal table (in the example it
takes 5) and sends one native SQL statement to the database for each group. In the end, the results of the individual native
SQL statements are combined to form the result of the Open SQL statement. Duplicate entries are automatically removed.
Note that the size of the packages is controlled by a profile parameter.
If you want to read large data volumes, use FOR ALL ENTRIES only in exceptional cases.
SELECT … FOR ALL ENTRIES was created in Open SQL at a time when it was not possible to perform database joins
(this was not supported for all SAP-approved DBMS). The connection between the inner and outer database tables was
created in ABAP.
Nowadays, this technique is often used when some data is already available in an internal table, but additional data is to be
read from the database. In such cases, SELECT … FOR ALL ENTRIES replaces a SELECT SINGLE statement inside a
LOOP over the internal table, and normally shows better performance than such a LOOP.
As a possible scenario, use a program exit in which data can be added to an internal table provided by the standard SAP
program.
The figure illustrates an example of how the statement works.
For normal access to Large Objects (LOBs), use the ABAP data object types string and xstring, into which the entire LOB
is transferred for read access, and from which the entire LOB is taken for write access. Depending on the string length,
this transfer may lead to high memory consumption on the application server. For certain operations on the LOB (for
example, copying the LOB within the database table or storing the LOB in a data object that is not of type string or
xstring), it is not necessary to realize the complete LOB in the ABAP program.
You can reduce memory consumption and improve the program performance with regard to runtime by omitting
unnecessary data transports. You do so by using streaming and/or locator objects (LOB handles).
Hint: SQL streams and locators are supported as of SAP NetWeaver 7.0 EhP 2.
Streams
For read access, read streams can be linked to LOBs using the assignment of corresponding streaming objects. The same
applies for write access and write streams. LOB data can be partially processed using the stream methods.
Specific Instances of ABAP Classes that can be linked to LOBs
CL_ABAP_DB_C_READER
Can be linked to a large string (CLOB), located on a database table. Use this to read CLOBs sequentially.
CL_ABAP_DB_X_READER
Can be linked to a large binary string (BLOB), located on a database table. Use this to read BLOBs sequentially.
CL_ABAP_DB_C_WRITER
Can be linked to a large string (CLOB), located on a database table. Use this to write CLOBs sequentially.
To create a streaming class instance, use a reference variable in the appropriate SQL statement. To read streams, use the
reference variable in the INTO clause of the SELECT statement. An LOB from the result set can be assigned to an LOB
handle component of a work area, or, to an individual reference variable for an LOB handle.
After the execution of the SQL statement, the reference variable points to the LOB handle. The related class is determined
using the data type of the result set column and the static type of the target variable, or using the CREATING addition if
required. The LOB to be read can be evaluated or forwarded using LOB handle methods.
The figure illustrates how to create a structure that contains a reference field for the stream reader, and how to assign the
reader to the LOB during selection.
DATA_AVAILABLE ( )
Check whether input stream is empty
READ( <length> )
Read the next <length> bytes (characters) from the input stream
SKIP( <length> )
Skip the next <length> bytes (characters)
IS_CLOSED( )
Check whether data stream is closed
CLOSE( )
Close data stream
IS_MARK_SUPPORTED( )
Check whether setting a marker is possible
SET_MARK( )
Set marker at current reading position
RESET_TO_MARK( )
Position read cursor to marking position
DELETE_MARK( )
Delete marker
IS_RESET_SUPPORTED( )
Check whether jumping to the beginning of the LOB is possible
RESET( )
Position reading cursor to beginning of LOB
IS_X_READER( )
Check if stream is binary data stream or character data stream
GET_STATEMENT_HANDLE( )
Get object describing SQL statement
Streams – Example
Locators
CL_ABAP_DB_C_LOCATOR
Can be linked to a large string (CLOB), located on a database table. Use these to get metadata related to the string, or
to read a subsequence of the string.
CL_ABAP_DB_X_LOCATOR
Can be linked to a large binary string (BLOB), located in a database table. Use these to get metadata related to the
xstring, or to read a subsequence of the xstring.
The creation of a locator class instance and the assignment of this object to the LOB is similar to the situation for stream
reader classes and stream writer classes.
Important Methods Defined in the Locator Classes
For read and write access, you can link locators to LOBs by assigning the corresponding reference variables. Using the
methods of the locators, you can access the subsequences of LOBs or the properties of LOBs without requiring a complete
realization in the ABAP program. Furthermore, locators enable the copying of LOBs within the database without having
to transport the data between the database and the application server.
The use of locators leads to higher resource consumption in the database system. Additionally, locators are not yet
supported by all databases. In such cases, the locators have to be emulated from the database interface on the application
server.
The use of data streams does not lead to increased resource consumption in the database system, but data streams are
somewhat more limited in their use. In particular, data streams cannot be used if internal tables are being processed in the
Open SQL statements.
Open SQL is a database abstraction layer with an SQL-like syntax. It defines a common SQL semantic for all databases
supported by SAP, (as opposed to being just a subset of SQL commands common to all databases). This common
semantic for all supported DBs ensures that the result of an Open SQL query is independent of the underlying database.
Luckily, as of SAP NetWeaver 7.40 SPS5, these limitations are minimized, because Open SQL has been extended. These
extensions, like the rest of Open SQL, are relevant regardless of the database. (It is worth noting that one scenario where
these extensions are of particular importance is when we think about the performance guidelines for SAP HANA).
Using the new Open SQL features has the following implications:
If you use any of these new features, you have to use the new syntax throughout your statements. For example,
the usage of arithmetic expressions and/or a comma-separated field list implies the escaping of host variables with the
“@” symbol.
The usage of the new Open SQL syntax implies a so-called strict mode, whereby nearly everything that formerly
resulted in a syntax warning now results in a syntax error in the context of Open SQL commands.
To extend Open SQL, it was necessary to define a common semantic for the new features and functionality. Once this had
been settled, the new syntax was incorporated and the available Open SQL syntax was enhanced.
In Open SQL, not all arithmetic expressions are available for all types of variables.
Basic features like ADDITION, SUBTRACTION, MULTIPLICATION or the calculation of the absolute value (ABS) are
available for variables of type I and P (with and without decimals). On the other hand, the MOD function is only available
for variables of type I and type P without decimals. The arithmetic expression CAST is only available for FLOAT-typed
columns or host variables, and FLOOR and CEIL can be used for all variables of type P with decimals (even mixed with
I- and P-types without decimals).
In addition to arithmetic expressions, Open SQL now also features string expressions, and string concatenation using the
&& operator. Spaces are trimmed from columns and host variables, unless you use an ABAP constant which contains
exactly one space.
Another new possibility is the use of a RIGHT OUTER JOIN. It is similar to the LEFT OUTER JOIN, but with switched
roles for the LEFT and the RIGHT tables.
Literals help determine faster if a record exists in a table. Using literals improves performance for the cases where the
number of matches is not important, as opposed to using an aggregate function like COUNT(), which will scan all
matching rows.
You can now use the very powerful CASE expression in Open SQL in the projection list. The ELSE part is optional.
Native SQL
Accessing the database with Native SQL enables you to use database-specific commands. Use of these commands
requires detailed knowledge of their syntax. Programs that use Native SQL commands need additional programming
after they are transported to different system environments (different database systems) because the syntax of the
commands needs to be adjusted on a database-specific basis. Implement database access using Native SQL only if a
Native SQL function that is not available in Open SQL must be used.
Open SQL
You can limit the target quantity to be read from the database using all the Open SQL commands.
SQL commands are available for single record access and multiple records access (or set access). A single set access
usually performs better than multiple single record accesses (except for the MODIFY command) when applied to a certain
number of records of data.
A syntax variant is available for the change operation that you can use to change individual fields in a record. If you have
masked field selections (WHERE <field> LIKE '<search_mask>'), ‘_’ masks an individual character and ‘%’ masks a
character string of any length in record with the SQL standard.
All the Open SQL commands display a message about the success or failure of the database operation performed. The
message is in the form of a return code in the system field sy-subrc. If sy-subrc equals 0, it means that the SQL operation
has been successfully completed. All other values of the field mean that errors have occurred. For further details, refer to
the keyword documentation for the command in question.
In addition, the sy-dbcnt system field displays the number of records for which the desired database operation was actually
carried out.
Note: Open SQL commands do not perform any automatic authorization checks. You need to execute these explicitly in
your program (statement AUTHORITY-CHECK).
If you do not specify the addition CLIENT SPECIFIED in an Open SQL command, no client specification is allowed in
the associated WHERE clause. If the database table contains client-dependent data, the records of the current execution
client are accessed. The database interface automatically adds the corresponding WHERE clause.
If you process data from other clients, specify the addition CLIENT SPECIFIED in the Open SQL command and the
associated client(s) in the appropriate WHERE clause.
Caution: If an Open SQL command contains the addition CLIENT SPECIFIED without a client specification, the system
accesses the datasets of all clients.
Creation of a Record
4 Record could not be inserted because a record with the same key already exists.
Use the statements INSERT, UPDATE, MODIFY, and DELETE to change the content of database tables.
To insert a new record in a database table, enter the command INSERT INTO <dbtab> VALUES <wa>. Before running
this command, you must place the record to be inserted in the structure <wa>. This structure must be of the same type as
the records in the database table concerned.
The client field that may exist in the structure <wa> is used only if the CLIENT SPECIFIED addition is specified. If there
is no CLIENT SPECIFIED addition, the client value of the current logged on client is taken as the default client.
Records can also be inserted using database views. However, the database view must already be created in the ABAP
Dictionary with the maintenance status “read and change” and must only contain fields from a table.
You can use the command INSERT <dbtab> FROM TABLE <itab> to create several records in a database table, as
shown in the figure. In this command, the internal table <itab> must have the same record structure as the corresponding
database table.
The client field that may exist in the internal table <itab> is used only if the CLIENT SPECIFIED addition is specified. If
there is no CLIENT SPECIFIED addition, the client value of the current logged on client is taken as the default client.
If it is possible to create all the records, sy-subrc is set to zero. However, if even one data record cannot be created, the
system triggers a runtime error and the entire insertion operation is discarded (database rollback).
If you want to insert all records, use the command addition ACCEPTING DUPLICATE KEYS. This addition has the
effect that in case of an error, the runtime error and also the database rollback are suppressed. The value of sy-subrc is set
to 4, and all the records without errors are inserted.
The sy-dbcnt system field contains the number of records that were successfully inserted in the database.
4 Record could not be changed because, for example, the specified key did not exist.
You can use two variants of the UPDATE command to update a specific record in a database table, as shown in the figure.
In the case of variant 1, the database record that is specified by the key in <wa> is overwritten by the content of <wa>.
However, the key field mandt that may exist in <wa> is used only if the CLIENT SPECIFIED addition is specified.
Otherwise, the client value of the current logged on client is taken as the default client. Logically, <wa> must have the
same structure as the structure of the database record to be changed.
In the case of variant 2, the system changes the record specified in the WHERE clause. However, only the fields specified
in the SET addition are overwritten by the specified values in the database. In this variant, you must define the record to
be changed in the WHERE clause by specifying all the key field evaluations.
You can specify simple calculation operations as evaluation for numeric database fields in the SET addition “f = g, f = f +
g, f = f - g”.
You can also change the records by using database views. However, the view must already be created in the ABAP
Dictionary with the maintenance status “read and change” and must only contain fields from a table.
If you need to make identical changes to the same fields in several records of a database table, use the syntax of the
UPDATE command specified in the figure.
Using the WHERE clause, you can define the records that are to be changed.
In the SET addition, specify the fields that need to be changed in the records.
It is also possible to perform calculations such as f = g, f = f + g, f = f - g if numeric fields have to be changed.
You can also perform a mass data change by specifying an internal table that has the same structure as the corresponding
database table and the records to be changed.
The mandt field that exists in the specified internal table is used only if the CLIENT SPECIFIED addition is specified.
Otherwise, the client value of the current logged on client is taken as the default client.
The sy-dbcnt system field contains the number of updated records.
The MODIFY command is SAP specific and it covers the following commands:
UPDATE
If the data record specified in the MODIFY statement exists in a table, the system updates the record.
INSERT
If the data record specified in the MODIFY statement does not exist in the table, the system inserts the record.
Using the syntax variants of the MODIFY command, such as the syntax of UPDATE and INSERT, you can process one
or more records.
You can also carry out the update/insert operation on database views. However, the view must exist in the ABAP
Dictionary with the maintenance status “read and change” and must only contain fields from a table.
The sy-dbcnt field contains the number of processed records.
4 Record could not be deleted because, for example, it does not exist in the database.
The syntax for the DELETE command is as specified in the figure above. The last syntax of the DELETE command
enables you to delete a record in a database table. In this syntax, define the record to be changed in the WHERE clause by
exactly specifying all the key field evaluations or any other field combination that uniquely identifies a record of existing
data.
A record can also be deleted from database views. However, the database view must already be created in the ABAP
Dictionary with the maintenance status “read and change” and must only contain fields from a table.
In the syntax DELETE <dbtab> [CLIENT SPECIFIED] FROM <wa>, the structure <wa> must have the same structure as
the records in the respective database table. Also, before calling the command, the structure must be filled with the key
fields of the record that need to be deleted. However, if <dbtab> is client-specific and if the CLIENT SPECIFIED
addition is specified, the client field is taken into consideration (otherwise client value of the current logged on client is
taken as the default client).
subrc Description
4 At least one record could not be deleted (for example, because it did not exist). The other records were deleted.
The syntax variant of the DELETE command that enables you to delete several records in a database table is as show in
the figure above. Here, you can specify the records that are to be deleted in the WHERE clause.
If you delete several records from a database table, you can specify them first in an internal table that has the same
structure as that of the respective database table, and then use the above syntax of the DELETE command. You need to
You can delete all the records in a cross-client database table by using the following syntax:
DELETE FROM <dbtab> WHERE <field> LIKE '%'.
Here, <field> is an arbitrary table field.
If you delete all the records of the execution client from a client-specific database table, you can use the same
syntax, DELETE FROM<dbtab> WHERE <field> LIKE '%'. If you delete all the existing records from a client-specific
database table, you must specify the CLIENT SPECIFIED addition in the command DELETE FROM <dbtab> CLIENT
SPECIFIED WHERE <field> LIKE '%'.
Deleting data records by using conditions produces the following return codes:
4 No record was deleted because, for example, the specified records do not exist.
If an Open SQL statement that implements a change to the database receives a return code different than zero, then ensure
that the database is reset to the same status as the status before you attempted to implement the change. To reset the
database, perform a database rollback, which reverses all changes to the current database LUW (Logical Unit of Work).
There are two ways to cause a database rollback, they are as follows:
An SAP LUW consists of a set of dialog steps from Application Server (AS) ABAP that logically belong together.
Database changes from these steps are bundled within one database LUW. These changes are either fully implemented or
not implemented (“all or nothing principle”).
In general, a business transaction is not represented only by a single SAP LUW. The entire process, for example, from
receipt of a customer order to the issue of an invoice, is split into logical parts, each corresponding to an SAP LUW. The
definition of SAP LUWs depends on the entire process and its modeling.
For further information, refer to the ABAP Editor keyword documentation for the term transactions and logical units of
work.
A database LUW consists of changes that are executed until the database status is sealed (database commit).
Within a database LUW, you can discard all changes that have taken place up to a specific point in the database (database
rollback). When changes are discarded, the database is reset to its original status. The DB ROLLBACK function can be
used to restore the previous (consistent) database status if an error occurs.
The current database status is sealed by a database commit. After the database commit, the current database LUW cannot
be discarded.
A database rollback and database commit can be triggered explicitly or implicitly when processing a program.
An explicit database commit is executed if the following conditions occur:
An explicit database rollback is executed if the ABAP statement ROLLBACK WORK is processed.
Implicit Database Rollback
An implicit database rollback occurs in the following situations:
A runtime error occurs in a program performing the database changes (for example, division by zero).
A termination message is sent by the system in a dialog step. This is typically an A or X message type. However,
in certain cases, termination messages are also generated with I, W, and E messages types, for example, at the Process
Before Output (PBO) event of a screen. Termination messages end the current application or program.
If there is an error during the processing of an SAP LUW, it is possible to restore the consistent database status that
existed before the SAP LUW started. To restore the database status, the SAP LUW must be processed within a single
database LUW.
AS ABAP is based on a client/server architecture with three levels: database server, application server, and presentation
server. This architecture, along with the distribution of user requests (user dispatching), leads to an efficient and cost-
effective multiuser system.
Majority of users with minimum configuration desktop computers can be mapped to a few high-performance work
processes on application servers. Each work process on an application server is assigned a work process on a high-
performance database server.
Distributing user requests to work processes means that individual clients at presentation server level are assigned to a
work process for a particular period after which the request uses another work process. After the work process has
processed the user input in a dialog step, the user and the program context are rolled out of the work process. Another user
can then use the work process.
The three-tier architecture is more scalable than a “fat” client architecture, where the presentation and application levels
run on one server. With a three-tier architecture, the number of database users is lower than the number of users active in
the system. A lower number of database users enables better database performance.
SAP Locking
If multiple users are competing to access the same resource or resources, the access to data must be synchronized to
protect data consistency.
For example, in a flight booking system, you must check whether seats are available. You must also guarantee that critical
data (in this case, the number of available seats) cannot be changed while you are working with the program.
Locks are a method of coordinating competing accesses to a resource. Each user requests a lock before accessing critical
data. When finished with the data resource, the user must release the lock to make the resource accessible for other users.
Database Management System (DBMS) physically locks the table lines read from the database for changing. Other users
will not be able to access the locked record until the system releases the physical lock. In addition, database locks are
automatically set if the database system receives change statements, such as INSERT, UPDATE, MODIFY, and DELETE
from a program.
However, at the end of a database logical unit of work (LUW), with every database commit, the database system releases
all the locks that were set during the database LUW.
For Application Server (AS) ABAP, the database system releases each database lock if an implicit database commit is
triggered. The release happens at the end of each dialog step (if the system displays a new screen) or if a wait situation
occurs (for example, a function module is called using remote function calls (RFC). Therefore, database locks are not
sufficient if data is collected throughout several screens and the respective data records are to be kept locked during the
LUW time frame.
A logical lock is set in the lock table by calling a lock module. A lock module is a special, table-related function module
that is created automatically when a table-related lock object is activated. When the lock module is called, logical locks
are set for entries in the respective table(s).
Lock objects are maintained in the ABAP Dictionary. Customer lock objects must begin with EY or EZ. When a lock
object is created, the table whose entries are to be locked (primary or basis table) needs to be specified. Tables with a
foreign-key relationship to the primary table are referred to as secondary tables, and can also be specified. By doing so,
a combination of table entries that are related through the lock module can be locked. For example, a lock object that
contains the tables SFLIGHT (primary) and SBOOK (secondary) enables you to lock a flight together with its bookings.
The lock module that the system automatically creates contains, as input parameters, the lock parameters contained in the
lock object. Lock parameters are used to communicate to the lock module which records are to have a logical lock set in
the locking table. The system automatically proposes names for the lock parameters for the names contained in the table
key fields. The system-proposed names can be overwritten.
When a lock object is successfully activated, the system automatically generates two lock modules: one for setting locks
for entries in the table(s) specified in the lock object, and one for releasing these locks.
The lock modules have the following name convention: ENQUEUE_<Lock Object Name> orDEQUEUE_<Lock Object
Name>.
SAP Locks
Depending on the lock mode, a lock module is either used to set a logical lock in the lock table or to check whether a lock
can be set.
You can only set a lock if your lock does not collide with entries that already exist in the lock table for the respective table
records. If there is an error, the lock module triggers appropriate exceptions. The application program can then determine
the success or failure of the lock action on the basis of the return code delivered by the lock module and react accordingly.
If there is an error, for example, the current user could receive an error message stating that he or she has been rejected by
the system.
Depending on the technique used for database updates, an application program may need to delete the lock entries it has
created, or have them deleted automatically (if the SAP update technique is used).
If an application program that has created lock entries is terminated, the locks are released automatically.
Program termination takes place if any of the following statements are encountered:
To specify which lock entry is to be created, use the import parameters of an ENQUEUE lock module that correspond to
the key fields in the respective table. The import parameters are called lock parameters.
If the system does not set the lock successfully (sy-subrc <> 0), issue a corresponding dialog message to the current user.
At the end of the dialog program, use the corresponding DEQUEUE lock module to delete the entries from the lock table.
DEQUEUE lock modules do not trigger any exceptions. An attempt to release an entry that is not locked has no effect. To
release all locks that have been set by the current program execution at the end of your dialog program, use the
DEQUEUE_ALL function module. Locks are released automatically at the end of the program and are passed over to
update techniques. Therefore, DEQUE modules are hardly used.
The lock argument is constructed from the values of all lock parameters (key fields of the respective table). The core part
of a lock entry, the lock argument defines which table lines are to be locked.
When calling a lock module, a lock parameter may be set to its initial value, or may not be specified at all. The system
interprets a lock parameter that is not specified as a generic value, interpreting the lock as referring to all table lines to
which the other parameter variants apply. An exception to this rule is the client parameter.
The following conditions apply to the use of SY-MANDT on a lock module call:
If the client parameter is not specified, then the lock applies only to the current execution client (SY-MANDT).
If the client parameter is specified with a specified client, then the call applies only to that client.
If the client parameter is specified with SPACE, then the lock applies to all clients.
The mode_<table name> parameter overrides the default lock mode of the lock module that is in the lock object.
Use the x_<> to specify lock entries where the <lock_parameter> has an initial value. Otherwise, the initial
<lock_parameter> is regarded as a generic parameter.
The _scope parameter defines the validity range of the lock.
For value 1 of the _scope parameter, the lock is related to the program that sets it, and can therefore only be deleted by the
generating program. This mode is used for inline updates.
The _ wait parameter defines whether a lock request is repeated in case the first lock attempt fails. Configure the number
of retries by setting profile parameter ENQUE/DELAY_MAX (default: 5).
Use the _collect parameter to store the lock request in the local lock container until it is dispatched and passed later to the
enqueue server.
Requesting a lock from a program is a communication step with lock administration. If the program sets locks for multiple
objects, the communication effort occurs more than once.
By using the lock container, technical effort required for communication with lock administration can be reduced. To do
this, set the _collect = X parameter whenever a lock module is called. The effect is that the respective lock requests are
stored in the local container for subsequent collective dispatch.
The contents of the lock container can be dispatched to lock management by using the FLUSH_ENQUEUE function
module.
If all the lock requests are successfully issued, the system deletes the entire content of the lock container. If one of the
locks in a container cannot be set, the FLUSH_ENQUEUE function module triggers the FOREIGN_LOCK exception.
When the FOREIGN_LOCK exception is triggered, none of the locks registered in the container are set, and the container
content remains complete for further dispatch attempts.
Hint: Use the RESET_ENQUEUE function module to delete the contents of the lock container.
If a lock is set when calling the respective lock module, the lock mode can be specified to determine the type and purpose
of the lock. If no specification is made, the default in the definition of the respective lock object applies.
Lock modes used to set locks include the following:
Mode “S”
Mode "S" can be used by a dialog program to ensure that other users cannot change the data displayed by the program
during the display time. However, the mode also does not allow you to make any changes to the displayed data.
For example, the program determines a price for a flight, and displays it to a customer. While the customer considers
whether or not to book the flight, you want to ensure that the price will not be changed.
Multiple "S" locks on one lock key can exist. When this is the case, no one can add any exclusive lock with the same
key. As a typical use case for mode "S", do not intend to change the data but make sure that no one else performs a
change. This step can be performed by many in parallel.
Mode “O”
Mode “O” is implemented to display data in the change mode, and provides the option to edit data if necessary.
For example, while displaying a list of flights, you need to add a new booking for one of the flights. Creating a file
booking impacts the number of occupied seats in the chosen flight. Therefore, you want to lock all displayed flights in
a way that does not hinder other users in the system. You also need to create a real write lock if you decide to book
the flight later.
Multiple "O" locks on one key can exist. When this is the case, only one user or program can add or upgrade to an
exclusive lock with the same key.
As a typical use case for lock mode "O", you and other users might intend to change the data. Before changing the
data, again ask the local service to ensure that no one else is in change mode by then.
Mode “E”
Mode “E” sets a lock for changing data and can be accumulated. Accumulation occurs if the same lock is requested
successfully more than once within the same program run, thus with the same lock key. This can happen, for example,
if a program that asked for a lock is calling a function module or a method, which again is requesting the same lock.
Mode “X”
Mode “X” functions similarly to mode ”E” when changing data, with the only difference being that, in mode “X”, the
respective lock does not allow accumulation.
For example, navigation options in a program allow you to enter various functions to edit the flight. To ensure that the
flight can be edited in only one of the dialogs, an exclusive and noncumulative lock is used.
An "X" lock cannot be accumulated. As a typical use case for lock mode "X", you explicitly intend to change data
and therefore you lock exclusively.
If there are existing locks in the system, attempts to set additional locks may arise from the program instance (or from a
method or function module called synchronously from this program instance) that has already set an existing lock.
However, attempts to set additional locks may also arise from a different program instance. A different program instance
may be a second instance of the same program started by the same or (more likely) any other user.
In case the program instance is a second instance of the same program, attempts to set locks are treated as follows:
Existing exclusive locks (“E” or “X”) categorically reject every lock attempt of another program, regardless of the
mode in which the other user attempts to set the lock.
An existing shared lock (“S”) or optimistic lock (“O”) allows other shared locks or optimistic locks for protected
display to be set for the same data record. The system rejects the attempts by other programs to set exclusive locks for
the same data lock entry.
Accumulation is the process when an attempt is made to lock a data record more than once while a program is running.
The lock system reacts in the following ways during this process:
In case of an existing “E” lock, the system accepts “E”, “O”, and “S” locks for the same data record. The system
rejects attempts to set an “X” lock for the same data record.
In case of an existing “X” lock, the system rejects every further attempt to set a lock.
In case of an existing “S” or “O” lock, the system sets these locks for the same data record from within the same
program. In addition, if there are no further shared locks or optimistic locks set by another user for the data record,
you can also set an additional “E” lock.
The system does not set the “X” lock if there is an existing lock for the data set being accessed.
If you want to ensure that you are reading up-to-date data in your program (with the intention of changing the data and
To implement the optimistic lock pattern, the following phases must be carried out:
Phase I
For reading the data, perform the following steps in your program:
1. Attempt to propagate your optimistic lock (type “R”). This will also delete all optimistic locks set by other
program instances for the same data set.
2. Change and save your data.
3. Release the exclusive lock.
When using locks, if the sequence "Lock → Read →Change → Unlock" is not adhered to, the program will read data
from the database currently locked by another program( see the figure for a pessimistic lock pattern). In such a case, even
if the lock is successfully set after the read action, the data that the program reads and displays to the user for change is
already out of date.
The two ways to call other ABAP programs on a synchronous basis from within a program are as follows:
For the following calls, the calling program is interrupted and the called program is executed.
CALL FUNCTION '<FUNCTION MODULE>'
CALL METHOD <class>=><method>
CALL METHOD <object>-><method>
CALL TRANSACTION '<TCODE>'
SUBMIT <program> AND RETURN
For the following calls, the system terminates the calling program and starts the execution of the called program:
LEAVE TO TRANSACTION '<TCODE>'
SUBMIT <program>
Use SUBMIT <program> and SUBMIT <program> AND RETURN to call programs that can be executed (program type
“1” = “executable program”).
Use CALL TRANSACTION '<TCODE>' and LEAVE TO TRANSACTION '<TCODE>' to call transactions.
To call function modules asynchronously to execute processes in parallel, you must supply the call with the addition
STARTING NEW TASK <task name>, where <task name> stands for the name of an individual for the new independent
task in which the function module is processed.
Asynchronously called function modules are processed in parallel to and independent of the calling program. The output
of the function module (addition RECEIVE RESULTS FROM FUNCTION) is received in a later processing phase of the
calling program.
If you call function modules by using the addition STARTING NEW TASK <task name>, you must mark the function
modules as capable of being called remotely (processing type “remote-capable module”) in their properties.
For more information, see the keyword documentation in the ABAP Editor for CALL FUNCTION.
Function modules and methods run in the same SAP LUW as the program that calls them.
Executable programs called by SUBMIT <program> AND RETURN or SUBMIT <program> and transactions called
by CALL TRANSACTION '<TCODE>', or LEAVE TO TRANSACTION '<TCODE>' each run in a separate SAP LUW,
that is, their update requests have separate update keys.
If you use SUBMIT <program> AND RETURN or CALL TRANSACTION '<TCODE>', the system continues the SAP
LUW of the calling program as soon as the called program is completed. The LUWs of calling and called programs run
independently of one another. Update requests and subroutine calls that use the ON COMMIT addition each require an
independent COMMIT WORK in the corresponding SAP LUW.
If you use SUBMIT <program> or LEAVE TO TRANSACTION '<TCODE>', the SAP LUW of the calling program
ends. If you do not conclude the update requests withCOMMIT WORK before the program call, the system does not
create a header for the related update key in the log. This means that the update work process does not execute the update
process for these requests. The same rule applies to subroutines called with the addition ON COMMIT.
Hint: Calling a program with SUBMIT <program> ..., CALL TRANSACTION '<TCODE>', or LEAVE TO
TRANSACTION '<TCODE>' involves an implicit DB commit. Therefore, all inline changes performed by a program are
automatically committed if another executable program or transaction is called.
If you call transactions with nested calls, each transaction needs its own COMMIT WORK because each transaction maps
its own SAP LUW.
The same rule is true for executable programs that are called with SUBMIT <program> AND RETURN.
If you call a transaction from within a program by using CALL TRANSACTION '<TCODE>', the system can execute the
transaction without user dialog (that is, in the background). For this purpose, you need to create an internal table in the
batch-input format (see the online documentation for CALL TRANSACTION) using the USING addition. This table
contains the values for the dynpros and the function code to navigate between the dynpros. For the call with “N” (do not
display), you must specify the MODE parameter.
Other values for the MODE parameter are "A" (display = default), "E" (only display if error), and "P" (display debugger
at break point).
You can overwrite the default update mode for the transaction by using the call parameter UPDATE, which is usually
asynchronous. In this context, the default update mode is the mode that is coded in the called transaction. Therefore, by
calling a transaction that has a coded "A" mode, you can overrule that by calling CALL TRANSACTION <> MODE "S".
If UPDATE = ’S’, the system continues processing the calling program only when the update process triggered by the
called transaction is completed. The system field sy-subrc returns the update status. UseUPDATE = ‘S’ if processing of
the transaction that is called later is dependent on the successful execution of the present transaction.
For more information, refer to the keyword documentation in ABAP Editor for the term CALL TRANSACTION.
A function module that you call asynchronously creates its own SAP LUW and runs in a separate session.
The system briefly interrupts the processing of the calling program. The system continues processing after the function
module is triggered; therefore, registered CALL FUNCTION in the UPDATE TASK and subroutines that have been
called with the ON COMMIT addition are retained.
Note: The asynchronous call of a function module triggers an implicit database commit. Inline changes processed in the
calling program up to that point will be committed in the database.
Any program called by SUBMIT <program> AND RETURN or CALL TRANSACTION '<TCODE>' has its own SAP
LUW. You can use these programs to perform nested (complex) LUW processing.
Function modules and methods are executed within the LUW of the calling program. Therefore, they are suitable for
building up a complex (nested) LUW (for example, report calls various BAPIs = function modules within one LUW, one
COMMIT WORK works for calling report and all BAPIs).
Use asynchronously called function modules to perform tasks that can be processed in parallel. An asynchronously called
function module runs in a new main session, and therefore has its own SAP memory. Use the function module interface to
perform data transfer.
For example, in a program, you want to call up a display transaction that is displayed in a separate window (amodal). You
need to use the statement CALL TRANSACTION '<TCODE>'. Start a new mode by using CF <> STARTING new task
and transfer the data by using the function module interface. Then, call the transaction from within the function module.
The data transfer from the function module to the called transaction can be done by using SAP memory, ABAP memory,
or using the BDC itab within the CALL TRANSACTION statement.
If a type “E” lock is set in the program for a data record, further locks of type “E” set in the same program can be included
in a function module that was called synchronously or in a called method. This process is called accumulation of a lock.
However, you cannot set additional locks to the existing ones from within a program that you have called using SUBMIT
<program> AND RETURN or CALL TRANSACTION '<TCODE>'. Any lock attempts from such calls will be rejected
with the exception FOREIGN_LOCK as this additional lock request comes from a new LUW.
If you call a program by using SUBMIT <program> or LEAVE TO TRANSACTION '<TCODE>', the system terminates
the calling program immediately and deletes all locks set up to that point. This ensures that no lock conflicts arise between
the calling and the called program.
The system treats lock requests from the same user in different main sessions or terminal sessions as lock requests from
different users. As shown in the figure, this is also the case for the same user, main session, and different INTERNAL
sessions that are created by CALL TA or SUBMIT AND RETURN. This starts a new LUW and therefore, the
accumulation is not possible, for example, for an E lock. In other words, accumulation, that is, to receive the same lock
again, only works within the same LUW.
ALV Design
Layout Variants
You can use the is_variant and i_save parameters to determine the options for variant management that are offered to the
user.
The modes that you can define are as follows:
Users can change the current layout variant. To set this mode, assign space to both parameters (default setting).
Users can change the current layout variant and save and manage the existing variants.
To do this, set the is_variant parameter as for the previous mode. The value of the i_save parameter determines the
way in which the user can manage the layout variants.
You can assign the following values to the i_save parameter:
The user can create this parameter on the selection screen that is assigned a type with disvariant-variant. The name of the
layout variant is passed with this parameter. The content of the parameter is assigned to the variant field of the is_variant
parameter before data is displayed in the ALV.
It may be necessary to pass the layout variant to the selection screen of the report, for example, in the case of execution in
the background.
To create a striped pattern for the lines, create a structure gs_layout in your program with ABAP Dictionary type
lvc_s_layo. Then fill in the relevant fields, for example, gs_layout-grid_title, gs_layout-cwidth_opt, and gs_layout-zebra,
and pass on the structure to the is_layout parameter of the set_table_for_first_display method.
Lvc_s_layo Fields
Lvc_s_layo is a global structure type and some of its fields are as follows:
Field Description
sel_mode A setting that determines how many cells, lines, and columns can be selected.
info_fname An additional data table field that contains information about coloring of lines.
ctab_fname An addition data table field that contains information about coloring of individual cells.
Depending on the value you enter in the sel_modefield in the layout structure, users can select individual or several lines
or cells.
To select several entries, press the CTRL key and keep the mouse button pressed while clicking further rows, columns, or
cells.
To select a continuous range of rows, columns or cells, press the SHIFT key and keep the mouse button pressed.
Exception Columns
You can use exceptions to indicate by means of a traffic light whether threshold values have been reached, on a line-by-
line basis.
Sort Criteria
Users can dynamically sort data in the ALV grid. To present the data to the user presorted, you can fill an internal table of
lvc_t_sort type and pass it to the it_sort parameter of the set_table_for_first_display method.
In the internal table, insert a line for each sort criterion that you want to define.
To sort data using sort criteria, enter the column name in the fieldname field. If you use more than one sort criterion, in
each case, enter the sequence in which the sort criterion is evaluated in the sposfield. Alternatively, you can also insert the
fields in the required sequence in the internal table of sort criteria. Enter "X" in the up field if you wish to sort the entries
in ascending order.
If you want to sort the entries in descending order, enter X in the down field.
The formula to color a column is C<color_constant>10, where <color_constant> represents the eight color constants of
the COL type group.
In the info_fname field, enter the component name of your color column for a structure of the lvc_s_layo global type and
pass the structure to the is_layout parameter of the set_table_for_first_display method.
To change the color of a line in the ALV Grid, add an extra field to your data table that contains a code representing the
color of the line. This is a character field with length 4. Add the field at the end of the line type of your internal table. If
you are using a global structure type to describe the contents of the internal table, the color column will not be displayed.
Instead, the ALV uses it to format the line accordingly.
The INCLUDE TYPE or INCLUDE STRUCTURE statement provides a simple way of defining the necessary line type
for the data table, locally in the program.
C111, C170, and C501 are some examples of values of the color field. For an overview of colors, see the online
documentation for the ABAP command FORMAT.
Letter ‘C’
Number of one of the eight colors
1 (intensified display) or 0 (intensified display off)
1 (inversion of foreground and background color) or 0 (no inversion)
Cell Colors
To color a cell in the data table, create an entry for it in the internal table containing the field name and the color code. A
cell color has a higher priority than a row color.
To highlight individual cells using colors, extend the line type of the output data table, adding an internal table of
lvc_t_scol type. The contents of the internal table are not displayed; they contain information that controls the output.
1. Loop through the gt_sbook internal table into the gs_sbook structure. Different cells can be colored for each data
record. If you want colored cells only in one data record, use the READ TABLE statement instead.
2. Fill the gs_colfield help field that contains two fields, fname and color. The fname field is the name of the field to
be colored. Thecolor field is a structure containing the different parts of the color code to be used. It is made up of
the col, int, and invcomponents.
3. Append the gs_colfield help field to the gs_sbook-it_colfields internal table. The gs_sbook-it_colfields internal
table contains information about the cell color combinations.
4. Write the gs_sbooking work area back into the internal data table using the MODIFY command. Complete steps 2
and 3 for each field to be colored.
The line type for the internal table contains the following fields:
color
The color settings for this field are as follows:
o col
One of the eight color constants of the col type group
o int
1 for intense, 0 for not intense
o inv
1 for inverted (the foreground and background colors are switched), 0 for not inverted
o nokeycol
To display a key field as a normal column, and not highlighted.
To extend the output data table, add an internal table of lvc_t_scol type.
The contents of the internal table are not the output, but are included only for the layout.
It is best to loop through the entire table and specify any fields that are to be colored differently.
You must assign the name of the column containing the internal table with the color field information to
thectab_fname field of the layout structure. Transfer the layout structure and the output table using the
set_table_for_first_display method.
The significance of standard functions depends on the application and the data displayed in the ALV grid. You can
display only a subset of the standard functions or hide the entire toolbar.
To hide individual functions, define an internal table with the ui_functions line type. Fill the internal table with the name
of the functions that you need to keep inactive. Inactive functions on the application toolbar are not displayed. Inactive
functions that are assigned to a menu entry are grayed out.
The possible function codes are defined as constants of the cl_gui_alv_grid class. The constants for function codes have
the MC_FC_ prefix. The MC_MB_ prefix represents an entire menu in the toolbar.
Pass the table to the standard functions when you call the set_table_for_first_display method. To deactivate all functions
on the application toolbar, you can use the MC_FC_EXCL_ALL constant.
To hide the entire toolbar, set the no_toolbar parameter of the layout structure to X and pass the layout structure to
set_table_for_first_display.
The field catalog is a format description of the display area for data.
Examples of situations in which you need to use a field catalog include the following:
The internal table containing the data has a line type with an ABAP Dictionary reference, however the display
needs to be different, for example, concerning column positions or titles.
The internal table has columns that are not contained in an ABAP Dictionary structure.
The field catalog must contain a row for every column of the data table that differs from an underlying ABAP Dictionary
structure or a row for every column that is not in the ABAP Dictionary structure at all. This row must contain the
technical properties and other formatting information for the column.
The internal table contains the data to be displayed. This table can have a freely definable row type so that the
representative instance can display the data transferred to it as desired on the screen output or when creating a print list.
To perform this action, the representative instance requires information about the type and formatting of each column.
This is the job of the field catalog.
The representative instance can automatically generate the field catalog. If the structure of the data table corresponds to a
structure that is defined in the ABAP Dictionary, you only need to pass the name of that to the representative instance.
You can also pass this display information to the representative instance using an additional internal table. This additional
table is called the field catalog. The global data type of this internal table is LVC_T_FCAT. The corresponding structure
type (for the work area) is called LVC_S_FCAT.
To generate the data table dynamically (as of SAP Web Application Server 6.10)
Can transfer the structure type as field symbol
Some of the solution approaches also offer additional advantages, such as central maintainability, reusability, and so on.
The INCLUDE TYPE statement has existed from SAP Web AS 6.10. You can use this statement to include Dictionary
types, ABAP types, and self-defined types, directly.
INCLUDE STRUCTURE is still supported for compatibility reasons.
Before you define and fill a field catalog and pass it to the representative instance, consider if you can implement your
requirements in a different way. In some cases, it is simpler or more flexible, to implement these alternative solutions.
The way in which you generate a field catalog depends on how the line type of the data table was defined.
Situations when a field catalog is required include the following:
Other fields of the field catalog can be divided into the following groups with regard to their use when creating a field
catalog:
References to global types, which are structure fields in the ABAP Dictionary, are created using
the ref_field andref_table fields.
All other fields of the field catalog contain values for the properties of the columns.
If you assign values to the ref_table andref_field fields, all type definitions are transferred from the specified structure
fields in the ABAP Dictionary. You can overwrite these values by assigning values to individual fields of the latter group.
If you do not assign values either to ref_field orref_table field, assign values, if necessary, for all fields of the latter group.
1. Define an internal table for the field catalog based on the lvc_t_fcat global table type and a compatible structure
as the work area.
The fieldname column in the field catalog contains the column name from the data table. Every column of the data table
that you want to format must have a corresponding row in the field catalog.
If you want to refer to a field of a global structure with the same name, assign the name of the structure to
the ref_table field. Only add the field name from the structure to ref_field if the name of the data table column and
structure field name are different.
In the figure, the data table consists of fields (columns) of the SBOOK type and two others. You need to describe these
types in the field catalog, along with the column that you want to be hidden.
The figure shows a semiautomatic field description. A part of the field description comes from the ABAP Dictionary
structure (SBOOK) whereas another part is defined in the gt_field_cat field catalog.
Fill the field catalog (internal table) in the program and pass it on with the name of the ABAP Dictionary structure in the
set_table_for_first_display method.
Ensure that the fields of the gt_bookings data table that cannot be read from the SBOOK table are also filled.
You must ensure consistency while constructing the field catalog semi automatically or manually. To perform this, press
the SHIFT key and double-click with the right mouse button in an area of the ALV grid that contains no data (for
example, the header).
You can use ROLLNAME to specify the data element that is used for the F1 help and the text for the column headers,
selection screen, and quick information text if it is not already explicitly set.
If you have not filled the ref_field or the ref_tablefield, there is no adequate reference to the ABAP Dictionary. In this
case, the fields allow you to format the relevant columns for output.
If you want to format the contents of a column according to the formatting options of a currency unit that is
specified in another column of the data table, specify the name of the column in the cfieldnamefield.
If you want to format all values of a column according to a particular currency, specify the relevant currency
abbreviation in thecurrency column.
If the currency field has a value, ignore the entries in the cfieldname field.
Quantity formatting has the following features:
If you want to format the contents of a column according to the formatting options of a unit that is specified in
another column of the data table, specify the name of this column in the qfieldname field.
If you want to format all values of a column according to a particular unit, specify the relevant unit abbreviation
in the quantitycolumn.
If the quantity field has a value, ignore the entries in the qfieldname field.
For more information, see the online documentation.
In the figure, the data table contains the price (the amount to be paid for a flight) and currency columns (currency for the
contents of the price column).
Enter CURRENCY in the cfieldname field of the field catalog for the price column to ensure that contents in
the price column are according to the currency specified in the currency column, for example, USD - two decimal places,
JPY - no decimal places.
The COL_POS field determines the output position of a field. It has the following features:
o To calculate the column position, count the hidden columns as well. However, exceptions do not count as
a column.
o Without explicit positioning, fields that are manually added to the field catalog are positioned before the
other fields of the data table.
You can use the decmlfield and decimals_o fields to define the numbers of decimal places in the same way as for currency
fields. These entries affect numerical content.
If you want to output a column as an icon, set theicon field of the layout structure to X. Run the SHOWICON report to
obtain an overview of icons. Note that not all icons can be printed.
If you want to output a column as a symbol, set thesymbol field of the layout structure to X. Run the SHOWSYMB report
to obtain an overview of symbols.
For more information, see the online documentation.
Make entries in the fields listed if a column has no reference to the ABAP Dictionary, or if you want to define or override
a text.
You can use the value assigned to the colddictxtfield to determine which of the four data element texts are to be used as
the column header (S = short, M = medium, L = long, R = heading). These texts are in the scrtext_s, scrtext_m, scrtext_l,
andreptext fields. If there is no ABAP Dictionary reference, you can set the texts in these fields.
If the colddictxt field has an initial value, set the text of the coltext field as the column header. If thecoltext field also has
an initial value, an appropriate text is automatically used from the four data element texts, depending on the width of the
column.
The texts in selection dialogs, for example, with a filter, behave in the following ways:
The entry in the seltext field has the highest priority. If the text is missing, the longest of the four data element
texts is used. If none of these four texts exists, the contents of the tooltip field are used, or finally, the field name itself
is used.
With the tooltip field, you set the text that is displayed when you put the mouse cursor over the column header
(quick information). If there is no entry in thetooltip field, the longest of the four data element texts is used. If none of
these four texts exist, thecoltext field is used.
You can use the sp_group field to combine multiple fields into a group with a group key. In various dialog boxes (such as
the selection of the sort field), the user can then display all columns or only those of a specific group.
To work with group texts, define an internal table with lvc_t_grp type and fill it with the names and descriptions of the
groups you want to use. Then pass the table to the it_special_groups parameter of the set_table_for_first_display method.
The code for declaring and filling the internal table is as follows:
DATA gt_groups TYPE lvc_t_sgrp.
DATA gs_group TYPE lvc_s_sgrp.
gs_group-sp_group = 'INFO'.
gs_group-text = text-inf.
APPEND gs_group TO gt_group.
You can use the txt_field field to declare additional texts for subtotals. For example, column A contains works numbers
and column B contains the associated long texts. On the list, the associated long texts are also displayed for subtotals of
the works numbers. The name of column B must be in the txt_field for column A (<struc_name>-txt_field = 'B').
The graphical user interface (GUI) in the SAP system is based on SAP GUI windows (screens from the technical view of
the programmer). Every user dialog in the system is implemented using the screens of application programs.
The application program communicates with the screen at runtime using various runtime system services (ABAP
processor and screen processor) and the SAP GUI services, which manage windows and their dialog box levels, data
transfer, and so on.
From SAP R/3 4.5, you can also use screen elements other than those provided in the Screen Painter in SAP GUI
windows. These additional screen elements are known as controls. Controls are standalone binary software components
that are reusable. As a developer, you can integrate one or more controls into your user dialogs and use the functions they
make available.
The communication between the control and the application program is different from that of the classic screen elements.
As of SAP R/3 4.6A, communication for all controls is performed in the same way using the Control Framework (CFW).
The CFW uses special services in the SAP GUI and the runtime system on the application server. These services are the
automation controller on the presentation server and the CFW service on the application server.
Every GUI control that communicates with an application program represents an object, which is an instance of a class, on
the presentation server. The communication with the instances uses the method calls and events of the objects.
From SAP R/3 Release 4.6A, there are representative classes (proxy classes) for all GUI controls in the class library.
These representative classes access the CFW in a uniform way and package the control-specific communication. These
are referred to as control wrappers.
Use of a GUI control in an ABAP program involves the following objects:
The ABAP program communicates with the representative object only (method calls, operations on the
attributes). The representative object performs the associated operations on the presentation server instances using the
CFW.
Actions performed on the presentation server control are forwarded to the representative object, using the CFW.
The representative object then communicates with the ABAP program.
The CFW maintains a list of the active instances with which it is communicating, both at the presentation server and on
the application server.
To pass an event to a presentation server control, the following partner levels are involved:
Basis Services
The basis services forward the information to the representative object in the ABAP program.
Representative Object
The representative object in the ABAP program triggers an ABAP Objects event, informing the instances registered
for the event. These instances then handle the event with an appropriate method also known as a handler method.
An object triggers events to announce a change in its state. Other objects can contain handler methods that are executed
when the event occurs. For the handler methods to be run, they must be registered with the basis services.
When the event is triggered, a basis service ensures that the registered methods are executed. The instance that triggers the
event does not know the event handler, unlike explicit method calls, where the caller has control and knows the method
called. This applies when the event is defined and when the event occurs at runtime.
If you want to receive and handle the events of a GUI control in your program, you must identify the events that the object
can trigger. The associated class for representative objects of the control can provide you with this information.
For information about the representative classes, see the online documentation for the respective controls.
DOUBLE_CLICK
This event is triggered after a double-click with the mouse.
TOOLBAR
This event is triggered when the ALV grid control is created or refreshed, but can also be triggered explicitly with a
method. It allows you to change the composition of the toolbar.
USER_COMMAND
This event is triggered when user-defined function codes are chosen. These codes are assigned to your own buttons in
the toolbar or entries in the context menu. This event allows you to implement your own functions.
For more information about other events, see the online documentation.
Event Handlers
Any class can contain handler methods for the public events of other classes. Event handler methods require the FOR
EVENT <event_name> OF <class_name> addition in the definition part. This addition specifies that this method can react
to <event_name> events of instances of the <class_name> class.
The names of event handler methods should be structured as on_<event_name>, where <event_name> is the name of the
event.
The signature of an event handler method can only contain importing parameters. These parameters are defined within the
corresponding event. The types of the parameters are also copied from the event. However, the event handler method does
not need to import all the parameters passed in the RAISE EVENT statement.
If the user double-clicks the data area, the double_click event is triggered in the calling program.
The export parameters contain information about the data table. Both of these parameters are structures.
The export parameters are as follows:
ES_ROW_NO
You can find the number of the double-clicked row in the row_id field. This corresponds to the correct row number in
the internal table.
E_COLUMN
You can find the name of the double-clicked column in the FIELDNAME field. This corresponds to the correct
column name in the internal table.
If a column has been identified as a hotspot, and the user presses the mouse button in the hotspot column of the data area,
the hotspot_click event is triggered in the calling program. The export parameters are filled in the same way as for the
double_click event.
For more information about these or other mouse operation events, see the online documentation.
A handler method can be a static method, for example, of a local class, or an instance method of an object.
In case of a static method, the local class can be compared with a repository that stores the methods. The difference in the
class method compared with the instance method is that you do not need to instantiate an object for the local class to use
the method.
To create a handler method for an event, first define a local class. The local class requires a public method (in the
PUBLIC SECTION) that is defined as a handler method for a particular event of a certain class. You can use the CLASS-
METHODS statement for this process.
After defining the method, you need to implement it.
The method receives the information provided by the event about the mouse position at the double-click and generates an
information message that displays the row and field of the mouse click.
To generate an instance method, use the METHODS statement when defining the class.
Implement the method in the same way as the class method and then create a reference variable with a reference to your
local class. Finally, create a corresponding object.
By default, an event handler is not processed when an event occurs. The event handler is only called if you register the
event at runtime. When you register events, you must decide if you want to react to the event only if it comes from a
specific instance, or whether it should be processed regardless of which instance has triggered the event.
The SET HANDLER statement links handler methods with the event triggers.
In the figure, there is the on_double_click static method of the lcl_event_handler class. This method is called if the ALV
instance, to which the go_alv_grid object refers, triggers the double_click event.
For more information about registering handler methods for events, refer to the keyword documentation for the SET
HANDLER statement.
In the figure, a static method is used for the handling. To use an instance method, the syntax is SET HANDLER
lcl_event_handler_object->on_double_click FOR go_alv_grid.
Note the different component selectors: => for static methods and -> for instance methods. The SET HANDLER
statement has linked the handler method with the ALV grid control.
Before the standard toolbar is integrated into the ALV grid control, the representative instance triggers the toolbar event.
This happens during the execution of the set_table_for_first_display and refresh_table_display methods.
During the lifetime of the representative instance, you can trigger the toolbar event explicitly by calling the
set_toolbar_interactive method.
To add elements to the standard toolbar, you must implement a handler method for the toolbar event of the
cl_gui_alv_grid class.
The toolbar event has a pointer to an instance of the cl_alv_event_toolbar_set class as an exporting parameter. This
instance of a toolbar contains the public attribute mt_toolbar. This attribute is an internal table with line type stb_button.
You fill this internal table in the handler method to add further buttons or other elements.
If the user chooses an element of the menu buttonor menu type, the representative instance triggers the menu_button
event. This has a parameter e_object with type ref to cl_ctmenu. To add a menu to the toolbar, you must also implement a
handler method in which you create the menu in the same way as a context menu.
You can differentiate between multiple menus by querying the function code.
If the user chooses a function element that has been added to the standard toolbar, the representative instance triggers the
user_command event. This event contains the function code as its e_ucomm export parameter.
To handle the additional function, implement a handler method for the user_command event. You can differentiate
between the function elements by querying the function code.
You can display a field in the ALV Grid as button in the following ways:
You can specify the attribute for a column in the field catalog, using the style parameter.
In the figure, a separate field (btn_text) is defined for the gs_flight structure in which a button is displayed (or not)
depending on other data. You can also use the existing fields of the data structure if they do not have F4 help.
To define the field as a button, you need an internal table with type lvc_t_styl (CT in the preceding figure). For each field
to be displayed as a button, you create an entry in the internal table in which you assign the name of the field to the
fieldname component and the constant cl_gui_alv_grid=>mc_style_button to the style component.
The name of the internal table that contains the information about the buttons is specified in the stylefname component of
the layout structure.
When a user chooses a button in a cell, it triggers the button_click event. The event returns the number of the row and
name of the column in which the button was clicked. This allows an associated handler method to implement a context-
specific reaction.
The print list is automatically generated by the representative instance. This list can be extended by the calling program.
Use the events shown in the figure. By using these events, you can implement the same logical process steps as used in
the classic ABAP list layout. In the event handler methods that you want to be implemented, you can use the usual
statements for ABAP list output and their various additions such as write, skip, uline, and so on.
You can also use the subtotal_text event to define additional texts for subtotals across columns whose output has been
suppressed. For more information, see the online documentation.
For a page break at a control level change in the print list, you must set an indicator in the print structure to ensure that the
user can format the control level change in the print list. This print structure is controlled by the grpchgedit field of the
is_print transfer parameter, which is the lvc_s_prnt structure type.
In the print list display, the user calls the Define Sort Order dialog box. To call the Define Sort Orderdialog box, choose
the Sort button without selecting a column.
The figure shows the settings that the user can set in the dialog box, in the CB field.
This step only works in interactive mode and not in background processing. For background processing, you must specify
the settings for sort order and control level formatting in the it_sort parameter of the set_table_for_first_display method.
To specify these settings, assign * or UL to the GROUP field in the it_sort parameter.
By accessing the Class Builder, the Class cl_gui_alv_grid can be displayed. In the Methods tab any of the methods of this
class can be selected. Using the buttons on this page, the parameters, exceptions, or source code of the selected method
can be viewed. The Class Documentation can be found in the Application Toolbar. The class documentation contains a
Link to SAP Library.
Method Description
The constructor, set_table_for_first_display, and refresh_table_display methods have been discussed earlier.
The set_toolbar_interactive method triggers the toolbar event. You can use this method to construct the toolbar again to
include your own functions.
The set_user_command method allows you to replace the standard functions of the ALV grid control with your own
functions. To replace the function, query the current function code during the before_user_command event and change it
using the set_user_command.
Sometimes, when you implement your own functions, you need to determine the current cell (cursor position). To do so,
use the get_current_cell method.
In the example in the figure, the on_before_user_command handler method handles the before_user_command event.
This event is triggered before a user command (standard command or custom command) is processed.
You can redefine a standard command, for example, if the detailed view is used to display dependent data.
In the handler method, check if the function code for the detailed view was entered (WHEN
cl_gui_alv_grid=>mc_fc_detail). If so, set the function code of your self-defined command (in this case, DIS_BOOK).
Replace the function code.
Context Menus
A context menu is displayed if a user presses the right mouse button (or Shift + F10) and the mouse pointer is positioned
over a GUI control. When a user presses the right mouse button, the ALV grid control triggers the context_menu_request
event. The mouse pointer that is the corresponding control that triggers the alert determines the context.
If the user selects a function from the context menu, the ALV grid control triggers the user_command event. By default,
the ALV grid control has a context menu that you can replace or extend.
CONTEXT_MENU_REQUEST Event
The easiest way to create a context menu is to load a GUI status of type context menu. You can create a context menu in
the object list of the Object Navigator. Use the context menu of the Object Navigator to create a new GUI status with type
context menu and enter the required function codes and their texts in the Menu Painter. You create a submenu by entering
text but no code for a line in the Menu Painter. A small triangle on the right indicates that there is a submenu. You can
create a maximum of three levels.
To load the GUI status into the context menu, use the static method load_gui_status of class cl_ctmenu.
The parameters are assigned the following values:
Program
The program parameter is assigned the name of the ABAP program in which the GUI status was defined. Pass the
system variable sy-cprog if the status of the interface belongs to the interface of the current program.
Status
The status parameter is assigned the name of the predefined GUI status.
Disable
If you want to deactivate functions in the context menu, place the relevant function codes in an internal table with
type ui_functions and pass it to the disable parameter. These functions are then grayed out when the menu is
displayed.
Menu
The menu parameter is the reference to the object of the cl_ctmenu class into which the GUI status needs to be
loaded.
You can extend the context menu that you loaded, using the add_function method of the cl_ctmenu class.
The cl_ctmenu class provides the load_gui_status static method and a range of other methods. You can use these methods
to create or adjust the context menu at runtime by calling them in the handler method. For more information, see the
documentation for the cl_ctmenu class.
If the user chooses a function of the context menu, the user_command event is triggered. The event exports the code of the
function that the user selects using the e_ucomm parameter.
user_command Event
A function code triggered through the context menu is processed in the same way as a function code that is triggered by a
button that you define. You must define, implement, and register a corresponding handler method for the user_command
event of your ALV instance on the application server. You then use the e_ucomm function code within the handler
method to decide the function that you need to execute.