DEFINE [SUBROUTINE]
subroutine-name
|
||
|
statement
|
||
|
|
END-SUBROUTINE [ (subroutine-name) ]
|
|
RETURN
|
||
This document covers the following topics:
For an explanation of the symbols used in the syntax diagram, see Syntax Symbols.
Related Statements: CALL | CALL FILE | CALL LOOP | CALLNAT | ESCAPE | FETCH
| PERFORM
Belongs to Function Group: Invoking Programs and Routines
The DEFINE SUBROUTINE statement is used to define a Natural subroutine. A subroutine
is invoked with a PERFORM
statement.
A subroutine may be defined within the object which contains the PERFORM statement that invokes the
subroutine (inline subroutine); or it
may be defined external to the object that contains the PERFORM statement
(external subroutine). An inline
subroutine may be defined before or after the first PERFORM statement which
references it.
Note
Although the structuring of a program function into multiple external subroutines
is recommended for achieving a clear program structure, please note that a subroutine
should always contain a larger function block because the invocation of the external
subroutine represents an additional overhead as compared with inline code or
subroutines.
No explicit parameters can be passed from the invoking program via the PERFORM statement to an internal
subroutine.
An inline subroutine has access to the currently established global data area as well as to the local data area used by the invoking program.
An external subroutine has access to the currently established global data area. In
addition, parameters can be passed directly with the PERFORM statement from the invoking object to the external
subroutine; thus, you may reduce the size of the global data area.
An external subroutine has no access to the local data area defined in the calling program; however, an external subroutine may have its own local data area.
| Syntax Element | Description |
|---|---|
subroutine-name
|
Name of Subroutine:
For a subroutine name (maximum 32 characters), the same naming conventions apply as for user-defined variables; see Naming Conventions for User-Defined Variables in the Using Natural documentation. The subroutine name is independent of the name of the module in which the subroutine is defined (it may but need not be the same). |
statement |
Statement(s) to be Executed: In place of
statement, you must supply one or
several suitable statements, depending on the situation. For an example of a
statement, see Examples below.
|
|
End of DEFINE SUBROUTINE Statement:
In structured mode, the subroutine definition is terminated with
In reporting mode, |
|
(subroutine-name) |
End-Subroutine Label:
The End-Subroutine label gives you an overview of which
The name of the subroutine must be enclosed in parentheses and positioned only
after The End-Subroutine label must match the subroutine name, otherwise a compiler error occurs. |
Any processing loop initiated within a subroutine must be closed before END-SUBROUTINE is
issued.
An inline subroutine must not contain another DEFINE SUBROUTINE
statement (see Example
1 below).
An external subroutine (that is, an object of type subroutine) must not contain more
than one DEFINE SUBROUTINE statement block (see Example 2 below). However, an
external DEFINE SUBROUTINE block may contain further inline subroutines
(see Example 1
below).
You may not use the name of an external subroutine twice in one library.
The End-Subroutine label must get the same subroutine name as defined with
DEFINE SUBROUTINE. The End-Subroutine label can only be defined with
END-SUBROUTINE (see Example
3 below).
The following construction is possible in an object of type subroutine, but not in any
other object (where SUBR01 would be considered an inline subroutine):
... DEFINE SUBROUTINE SUBR01 ... PERFORM SUBR02 PERFORM SUBR03 ... DEFINE SUBROUTINE SUBR02 /* inline subroutine... END-SUBROUTINE ... DEFINE SUBROUTINE SUBR03 /* inline subroutine... END-SUBROUTINE END-SUBROUTINE END
The following construction is not allowed in an object of type subroutine:
... DEFINE SUBROUTINE SUBR01 ... END-SUBROUTINE DEFINE SUBROUTINE SUBR02 ... END-SUBROUTINE END
The following construction is not allowed:
... DEFINE SUBROUTINE SUBR01 ... END-SUBROUTINE (SUBROUTINE-01) ... DEFINE SUBROUTINE SUBR02 ... RETURN (SUBR02) ...
The following construction is allowed:
... DEFINE SUBROUTINE SUBR01 ... END-SUBROUTINE (SUBR01) /* subroutine label for SUBR01 DEFINE SUBROUTINE SUBR02 ... END-SUBROUTINE /* (SUBR02) /* comment only DEFINE SUBROUTINE SUBR03 ... END-SUBROUTINE /* Subroutine SUBR03 /* comment only
** Example 'DSREX1S': DEFINE SUBROUTINE (structured mode)
************************************************************************
DEFINE DATA LOCAL
1 EMPLOY-VIEW VIEW OF EMPLOYEES
2 NAME
2 ADDRESS-LINE (A20/2)
2 PHONE
*
1 #ARRAY (A75/1:4)
1 REDEFINE #ARRAY
2 #ALINE (A25/1:4,1:3)
1 #X (N2) INIT <1>
1 #Y (N2) INIT <1>
END-DEFINE
*
FORMAT PS=20
LIMIT 5
FIND EMPLOY-VIEW WITH NAME = 'SMITH'
MOVE NAME TO #ALINE (#X,#Y)
MOVE ADDRESS-LINE(1) TO #ALINE (#X+1,#Y)
MOVE ADDRESS-LINE(2) TO #ALINE (#X+2,#Y)
MOVE PHONE TO #ALINE (#X+3,#Y)
IF #Y = 3
RESET INITIAL #Y
PERFORM PRINT
ELSE
ADD 1 TO #Y
END-IF
AT END OF DATA
PERFORM PRINT
END-ENDDATA
END-FIND
*
DEFINE SUBROUTINE PRINT
WRITE NOTITLE (AD=OI) #ARRAY(*)
RESET #ARRAY(*)
SKIP 1
END-SUBROUTINE
*
END
SMITH SMITH SMITH
ENGLANDSVEJ 222 3152 SHETLAND ROAD 14100 ESWORTHY RD.
MILWAUKEE MONTERREY
554349 877-4563 994-2260
SMITH SMITH
5 HAWTHORN 13002 NEW ARDEN COUR
OAK BROOK SILVER SPRING
150-9351 639-8963
Equivalent reporting-mode example: DSREX1R.
** Example 'DSREX2': DEFINE SUBROUTINE (using GDA fields) ************************************************************************ DEFINE DATA GLOBAL USING DSREX2G END-DEFINE * INPUT 'Enter value in GDA field' GDA-FIELD1 * * Call external subroutine in DSREX2S * PERFORM DSREX2-SUB * END
1 GDA-FIELD1 A 2
** Example 'DSREX2S': SUBROUTINE (external subroutine using global data) ************************************************************************ DEFINE DATA GLOBAL USING DSREX2G END-DEFINE * DEFINE SUBROUTINE DSREX2-SUB * WRITE 'IN SUBROUTINE' *PROGRAM '=' GDA-FIELD1 * END-SUBROUTINE * END
** Example 'DSREX3': DEFINE SUBROUTINE with end-subroutine label
************************************************************************
DEFINE DATA LOCAL
1 EMPLOY-VIEW VIEW OF EMPLOYEES
2 NAME
2 FIRST-NAME
2 ADDRESS-LINE (A20/2)
2 PERSONNEL-ID
2 MAR-STAT
2 BIRTH
*
1 #ARRAY (A75/1:6)
1 REDEFINE #ARRAY
2 #ALINE (A25/1:6,1:3)
1 #BIRTHDAY (A25)
1 #FULL-NAME (A25)
1 #MARITAL-STATUS (A25)
1 #X (N2) INIT <1>
1 #Y (N2) INIT <1>
END-DEFINE
*
FORMAT PS=20
LIMIT 5
*
FIND EMPLOY-VIEW WITH NAME = 'SMITH'
/*
PERFORM GET-EMPLOYEES-DATA
/*
IF #Y = 3
RESET INITIAL #Y
PERFORM PRINT-ARRAY
ELSE
ADD 1 TO #Y
END-IF
/*
AT END OF DATA
PERFORM PRINT-ARRAY
END-ENDDATA
END-FIND
/*----------------------------------------------------------------------
/* ------------ End of main program ------------------------------------
/*----------------------------------------------------------------------
DEFINE SUBROUTINE GET-EMPLOYEES-DATA
COMPRESS NAME ',' FIRST-NAME INTO #FULL-NAME LEAVING NO
MOVE EDITED BIRTH (EM=DD.LLL.YYYY) TO #BIRTHDAY
/*
PERFORM MARITAL-STATUS
/*
MOVE #FULL-NAME TO #ALINE (#X,#Y)
MOVE PERSONNEL-ID TO #ALINE (#X+1,#Y)
MOVE #MARITAL-STATUS TO #ALINE (#X+2,#Y)
MOVE #BIRTHDAY TO #ALINE (#X+3,#Y)
MOVE ADDRESS-LINE(1) TO #ALINE (#X+4,#Y)
MOVE ADDRESS-LINE(2) TO #ALINE (#X+5,#Y)
END-SUBROUTINE (GET-EMPLOYEES-DATA) /* end-subroutine label
*
DEFINE SUBROUTINE MARITAL-STATUS
DECIDE ON FIRST VALUE OF MAR-STAT
VALUE 'M'
#MARITAL-STATUS := 'MARRIED'
VALUE 'S'
#MARITAL-STATUS := 'SINGLE'
VALUE 'D'
#MARITAL-STATUS := 'DIVORCED'
VALUE 'W'
#MARITAL-STATUS := 'WIDOWED'
NONE
RESET #MARITAL-STATUS
END-DECIDE
END-SUBROUTINE /* (MARITAL-STATUS) /* just a comment
*
DEFINE SUBROUTINE PRINT-ARRAY
WRITE NOTITLE (AD=OI) #ARRAY(*)
RESET #ARRAY(*)
SKIP 1
END-SUBROUTINE (PRINT-ARRAY) /* end-subroutine label
*
END
SMITH,GERHARD SMITH,SEYMOUR SMITH,MATILDA
40000311 20009300 20014100
DIVORCED SINGLE MARRIED
21.Apr.1976 01.Jan.1970 01.Jan.1970
ENGLANDSVEJ 222 3152 SHETLAND ROAD 14100 ESWORTHY RD.
MILWAUKEE MONTERREY
SMITH,ANN SMITH,TONI
20015400 20018800
WIDOWED SINGLE
07.Nov.1946 14.Dec.1941
5 HAWTHORN 13002 NEW ARDEN COUR
OAK BROOK SILVER SPRING