Software Development

Unleash the power of macros in ABAP

Like many programming languages, SAP's ABAP makes liberal use of macros. Here are some scenarios that illustrate when using macros in SAP is the best choice.

As programs grow larger and larger, it becomes more difficult for programmers to enhance and debug source code. Luckily, computer languages make developers' lives easier by offering various modularization methods, making program code meaningful and easily understandable.

ABAP, SAP's programming language, is no exception. It leverages various modularization options, each having its own strengths and weaknesses. These options may have local access from a particular program—such as form routines and macros—or they may have global access, such as function modules or include programs.

Although a comprehensive discussion of all the modularization techniques available in ABAP is beyond the scope of this article, we can look at one option—macros—and consider some situations where they work better than other options.

Getting a feel of macros
The basic syntax of macros is as follows:
DEFINE  macro_name.                           "Macro Definition
……………. Statements
……………. Statements
…………………
END-OF-DEFINITION.                            "Macro Definition
 
         macro_name  par1 par2 …par9.        "Macro call -parameters separated by spaces

Within the DEFINE... and END-OF-DEFINITION lies the body of the macro—the statements that you wish to be executed each time the macro is called. These statements may be any valid ABAP statements, such as WRITE, CLEAR, FORM calls, or database statements such as SELECT or UPDATE.

To familiarize yourself with the working of macros, it's necessary to take a close look at exactly what happens when an ABAP program containing a macro call is generated. Consider Listing A.

All ABAP programs must be generated before they can be executed. At the time of program generation, the system supplants each macro call, as shown in Listing A, with the statement(s) placed between the macro definition. Furthermore, the parameters passed at the time of macro calling are copied in place of the any placeholders (numbered &1, &2 …&9) found in the body of the macro definition. The system simply ignores the presence of the macros during the execution of the program—that is, all statements are executed as a single block of code:
        write :  int1.
        write :  int2.
        write :  int3.

Other than readability and meaningfulness, macros also offer performance advantages. For testing purposes, I wrote a macro that incremented the value of a variable by 1 and called the macro N times via a DO loop, as shown here:
DEFINE INCREMENT.
  ADD 1 TO &1.
 END-OF-DEFINITION.
 
 DO N TIMES.
  INCREMENT VAR1.
 ENDDO.

The runtime was measured using an SAP tool known as the Runtime Analyzer (SE30) for different values of N. To check performance, I copied the same program but replaced the macro call and definition with those of form routines. Table A shows a comparison of the performance of both macros and form routines(all times in microseconds). Macros, in this case, were nine times faster than forms routines.

N 1000 10000 100000
Form 731 6974 71236
Macros 74 708 7134

Applying macros to suit business needs
Apart from their readability and efficiency, macros can be more effective than other modularization techniques because of their versatility in replacing different ABAP statements in solving business problems.

ABAP provides only the syntax for creating macros. It's up to the programmer to devise ways that best suit the requirements. The power of macro programming lies in mastering the ways macros can be used in ABAP programs.

Macros can be used for different purposes within the SAP terrain. I have tried to compile the variety of ways I've seen macros adding elegance to ABAP applications. Here's a closer look.

Data declaration
You can use macros to define variables. A simple example is:
DEFINE table.
data: &1 like &2 occurs 0 with header line.
END-OF-DEFINITION.
 
table itab1 lfa1.
table itab2 pernr.

Instead of writing the same data declaration statement each time a new variable is declared, you can simply reuse the code via macros.

Complex WRITE statements
Programs often get unnecessarily verbose and difficult to understand because they contain lengthy and redundant WRITE statements. Macros allow you to maintain readability while writing complex WRITE statements. You can write macros to replace all variants supported by the WRITE statement. Here's a simple example:
DEFINE Write_stat.
Write : &1 no-zero right-justified color &2.
END-OF-DEFINITION.

The example declares a macro write_stat. The macro prints—after truncating their zeros—variables in a right-aligned format in the color specified by number &2. Instead of writing similar WRITE statements repeatedly, you can simply call the macro and pass the desired output specifications as parameters, like this:
Write_stat var1 1.
Write_stat var2 2.       

Reading/changing variable values
You can use macros to replace any set of repetitive statements that check or modify values of variables. Typical examples are simple IF checks or CLEAR statements. For simplicity's sake, I'm showing only how the body of such macros may look:
If not &1 is initial.
Endif.
 
clear: &1,
&2.

Formulas or calculations
You can use macros to define formulas for complex calculations. In this case, the placeholders may be operands (such as +, -), constant values, or local variables. Here's an example:
DEFINE operation.
result = ( &1 &2 &3 ) &4 ( &5 &6 &7 ).
END-OF-DEFINITION.
Operation 5 – 3 / var2 + 9.
Operation var1 + 7 * 6 + 5.

Nesting macros
The ability of macros to call other macros makes them even more powerful. Consider the following example:
DEFINE macro_1.
Write :/'Macro 1 called'.
Macro_2   .
END-OF-DEFINITION.
 
DEFINE macro_2.
Write :/'Macro 2 called'.
END-OF-DEFINITION.
 
  Macro_1.             "Macro Call for Macro 1.

In this example, only the first macro is called by the main program. After executing the write statement of Macro 1, the system executes the body of the second macro as well.

Program flexibility
Macros help you to minimize hard coding to make your applications more flexible. For example, you can call function modules dynamically. Consider the following program segment:
define dynamic_function_call .
CALL FUNCTION   &1
EXPORTING
SECONDS              = '10'.
end-of-definition.
 
dynamic_function_call 'ENQUE_SLEEP'.
dynamic_function_call funcname.

Here, we define a macro that calls a function module whose name is not hard coded, but rather passed as a parameter to be evaluated at runtime. You can use the same approach when making configurable applications. The name of the function may be kept in a database table whose records are read before the macro call. In this manner, program behavior may be adapted without a need to modify source code.

Working with heavy data
Many SAP programs use macros to export and import data to and from the database. Consumption of system resources is optimal if macros are employed, particularly when a large amount of data is involved:
DEFINE EXPORT_MACRO.
Export  &1  &2  &3  to database indx(DB) id 'DATA'.
END-OF-DEFINITION.
 
EXPORT_MACRO itab1 itab2 itab3.

In this example, the data of three internal tables that may each consist of a large number of records is exported to the table INDX. Had we used form routines in this case, you can't imagine the resources (CPU time and memory) that would be consumed while passing tables as parameters.

Determine the best option
Macros are one of the modularization options provided by the ABAP language, and we've focused here on situations where macros are most appropriate. However, macros are not always the best choice. It is up to you to decide which of the modularization techniques suits a particular scenario.
0 comments