PERFORM

PERFORM Syntax Diagram

Variants:

1. PERFORM form.
2. PERFORM form(prog).
3. PERFORM form IN PROGRAM prog.
4. PERFORM n OF form1 form2 form3 ... .
5. PERFORM n ON COMMIT.


1. ... USING p1 p2 p3 ...
2. ... CHANGING p1 p2 p3 ...
3. ... TABLES itab1 itab2 ...

Effect

Calls the subroutine form specified in the FORM statement. On completion, processing in the main program resumes after the PERFORM statement. The parameters in the form are position parameters, and must be given in the call as specified in the FORM definition.

Example

PERFORM HELP_ME. 
... 
FORM HELP_ME. 
  ... 
ENDFORM.

The PERFORM statement calls the subroutine HELP_ME.

Effect

These additions are equivalent to each other. For documentation reasons however, you should use the same one as with the associated FORM definition.
Both additions pass the parameters p1 p2 p3 ... to the called subroutine. You can use as many parameters as you like.
Sequence is important here because the first parameter of the PERFORM call is passed to the first parameter of the FORM definition, the second to the second and so on.

Parameter offset and length can be passed as variables. The addition '...USING p1+off(*)' causes parameter p1 to be passed with offset off so that the field limits of p1 are not exceeded.

Example

DATA: NUMBER_I TYPE I VALUE 5, 
	NUMBER_P TYPE P VALUE 4, 
	BEGIN OF PERSON, 
		NAME(10)	VALUE 'Paul', 
		AGE TYPE I	VALUE 28, 
	END   OF PERSON, 
	ALPHA(10)	 VALUE 'abcdefghij'. 
FIELD-SYMBOLS POINTER. 
ASSIGN NUMBER_P TO POINTER. 
PERFORM CHANGE USING 1 
					 NUMBER_I 
					 NUMBER_P 
					 POINTER 
					 PERSON 
					 ALPHA+NUMBER_I(<POINTER>). 
 
FORM CHANGE USING VALUE(PAR_1) 
				PAR_NUMBER_I 
				PAR_NUMBER_P 
				PAR_POINTER 
				PAR_PERSON STRUCTURE PERSON 
				PAR_PART_OF_ALPHA. 
  ADD PAR_1 TO PAR_NUMBER_I. 
  PAR_NUMBER_P = 0. 
  PAR_PERSON-NAME+4(1) = ALPHA. 
  PAR_PERSON-AGE = NUMBER_P + 25. 
  ADD NUMBER_I TO PAR_POINTER. 
  PAR_PART_OF_ALPHA = SPACE. 
ENDFORM.

Field contents after the PERFORM call are as follows:

NUMBER_I = 6
NUMBER_P = 6
POINTER = 6
PERSON-NAME = 'Paula'
PERSON-AGE = 25
ALPHA = 'abcde j'

If you want to pass the body of an internal table with header line itab as an actual parameter, you must use the notation itab[] (see data objects). If you omit the brackets, the header line of the table is passed.

Effect

You use TABLES to pass

internal tables to subroutines.

Example

DATA: BEGIN OF ITAB OCCURS 100, 
		TEXT(50), 
		NUMBER TYPE I, 
	END   OF ITAB. 
	STRUC LIKE T005T. 
... 
PERFORM DISPLAY TABLES ITAB 
				USING  STRUC. 
 
FORM DISPLAY TABLES PAR_ITAB STRUCTURE ITAB 
			 USING  PAR STRUCTURE T005T. 
  DATA LOC_COMPARE LIKE PAR_ITAB-TEXT. 
 
  WRITE: / PAR-LAND1, PAR-LANDX. 
  ... 
  LOOP AT PAR_ITAB WHERE TEXT = LOC_COMPARE. 
	... 
  ENDLOOP. 
  ... 
ENDFORM.

Within the subroutine DISPLAY, you can apply all the available table operations to the internal tables passed.

Note

TABLES must always appear first in the PERFORM call. It must not be preceded by an addition.

1. ... USING p1 p2 p3 ...
2. ... CHANGING p1 p2 p3 ...
3. ... TABLES itab1 itab2 ...
4. ... IF FOUND

Effect

Calls the subroutine form defined in the program prog (i.e. external PERFORM).

Parameter passing to the external subroutine is the same as in variant 1.

Effect

Calls the specified subroutine only if it already exists. Otherwise, the statement is ignored.

The specified program is loaded as long as it exists (even if the subroutine does not exist).


1. ... USING p1 p2 p3 ...
2. ... CHANGING p1 p2 p3 ...
3. ... TABLES itab1 itab2 ...
4. ... IF FOUND

Effect

Similar to variant 2 (external PERFORM), except that here you can specify both the subroutine and the program dynamically (at runtime); in this case, you must enclose the variables form or prog in parentheses. The names in form and prog must be uppercase, otherwise, a runtime error occurs. If no other additions follow (such as USING), you can omit the program specification after IN PROGRAM.

Example

DATA: RNAME(30) VALUE 'WRITE_STATISTIC', 
	PNAME(8)  VALUE 'ZYX_STAT'. 
PERFORM WRITE_STATISTIC(ZYX_STAT). 
PERFORM (RNAME)		 IN PROGRAM ZYX_STAT. 
PERFORM WRITE_STATISTIC IN PROGRAM (PNAME). 
PERFORM (RNAME)		 IN PROGRAM (PNAME).

All four of the above PERFORM statements have the same effect, i.e. they call the subroutine 'WRITE_STATISTIC' defined in the program 'ZYX_STAT'.

Notes

This dynamic PERFORM requires more CPU time, since the system has to search for the subroutine each time.

Notes

Runtime errors:

PERFORM_NOT_FOUND: The specified subroutine was not found.

LOAD_PROGRAM_NOT_FOUND: The specified program was not found.

Effect

Calls the specified subroutine only if it already exists. Otherwise, the statement is ignored.

Effect

Drives a subroutine specified by the index n from a list of subroutine names listed in the statement. At runtime, the variable n must contain a value between 1 (first name) and the total number of subroutines specified (last name). Up to 256 subroutine names are possible.


1. ... LEVEL idx

Effect

Executes the specified subroutine when a COMMIT WORK occurs. This allows you to execute a subroutine only if the logical transaction has ended successfully. The subroutine is not executed until the key word COMMIT WORK is called. FORMs specified several times are executed only once on COMMIT WORK (see COMMIT WORK).
If you call ROLLBACK WORK, you delete all the specified routines.

Note

With PERFORM ... ON COMMIT, you cannot transfer any data with USING/CHANGING. To do this, you must either store the data in global variables or store it temporarily with EXPORT ... TO MEMORY.

Effect

The addition LEVEL, followed by a field, defines the order in which the subroutines are executed after COMMIT WORK . They are called in ascending order of level. If there is no addition LEVEL, the subroutine always has the level zero. If the level is the same, the order of calls determines the order of execution. Level assignment occurs during development, e.g. by defining constants in an include program. The level must be of type I.