DEFINE [SUBROUTINE]
subroutine-name
|
||
|
statement
|
||
|
|
END-SUBROUTINE
[ (subroutine-name) ]
|
|
RETURN
(nur im Reporting Mode)
|
||
Dieser Abschnitt behandelt folgende Themen:
Eine Erläuterung der in dem Syntax-Diagramm verwendeten Symbole entnehmen Sie dem Abschnitt Syntax-Symbole.
Verwandte Statements: CALL | CALL FILE | CALL LOOP | CALLNAT | ESCAPE | FETCH
| PERFORM
Gehört zur Funktionsgruppe: Aufrufen von Programmen und Subprogrammen
Das Statement DEFINE SUBROUTINE dient dazu, eine Natural-Subroutine zu
definieren. Aufgerufen wird eine Subroutine mit einem PERFORM-Statement.
Eine Subroutine kann entweder innerhalb des Natural-Objekts definiert werden, das das
sie aufrufende PERFORM-Statement
enthält (interne Subroutine), oder
sie kann in einem anderen Natural-Objekt definiert werden als dem, welches das
aufrufende PERFORM-Statement enthält (externe Subroutine). Eine interne
Subroutine kann entweder vor oder nach dem ersten PERFORM-Statement, mit
dem sie aufgerufen wird, definiert werden.
Anmerkung
Die Verwendung externer Subroutinen empfiehlt sich zwar, um eine klar gegliederte
Anwendungsstruktur zu erhalten, allerdings verursachen externe Subroutinen einen
Verarbeitungsmehraufwand. Daher sollten nur größere funktionale Blöcke in externen
Subroutinen untergebracht werden.
An eine interne Subroutine können mit dem PERFORM-Statement keine Parameter vom aufrufenden
Programm übergeben werden.
Eine interne Subroutine kann auf auf den aktuell eingerichteten globalen Datenbereich (Global Data Area) sowie den vom aufrufenden Programm verwendeten lokalen Datenbereich (Local Data Area) zugreifen.
Eine externe Subroutine hat Zugriff auf den aktuell eingerichteten globalen
Datenbereich (Global Data Area). Außerdem können Parameter direkt mit dem PERFORM-Statement vom aufrufenden Objekt
an die externe Subroutine übergeben werden. Dadurch kann die Größe des globalen
Datenbereichs gering gehalten werden.
Eine externe Subroutine kann nicht auf den im aufrufenden Programm definierten lokalen Datenbereich (Local Data Area), allerdings kann eine externe Subroutine einen eigenen lokalen Datenbereich haben.
Syntax-Element-Beschreibung:
| Syntax-Element | Beschreibung |
|---|---|
subroutine-name
|
Name der Subroutine:
Für den Namen einer Subroutine (maximal 32 Zeichen lang) gelten die gleichen Namenskonventionen wie für Benutzervariablen. Siehe Namenskonventionen für Benutzervariablen in der Dokumentation Natural benutzen. Der Name einer Subroutine ist unabhängig vom Namen des Moduls, in dem sie definiert ist (beide Namen können, müssen aber nicht, gleich sein). |
END-SUBROUTINE
|
Ende des DEFINE SUBROUTINE-Statements:
Im Structured Mode muss die Definition einer Subroutine mit dem Schlüsselwort
Im Reporting Mode kann die Definition einer Subroutine mit dem Schlüsselwort
|
RETURN oder END-SUBROUTINE |
|
(subroutine-name)
|
End-Subroutine-Label:
Das End-Subroutine-Label verschafft Ihnen einen Überblick, welches
Der Name der Subroutine muss in Klammern gesetzt werden und darf erst nach dem
Das End-Subroutine-Label muss mit dem Namen der Subroutine übereinstimmen, sonst gibt es einen Compilerfehler. |
Eine in einer Subroutine initiierte Verarbeitungsschleife muss vor dem END-SUBROUTINE-Statement
wieder geschlossen werden.
Eine interne Subroutine darf ihrerseits kein weiteres DEFINE
SUBROUTINE-Statement enthalten (siehe Beispiel 1 unten).
Eine externe Subroutine (d.h. ein Objekt vom Typ Subroutine) darf nicht mehr als
einen DEFINE SUBROUTINE-Statement-Block enthalten (siehe Beispiel 2 unten). Ein
externer DEFINE SUBROUTINE-Block darf jedoch seinerseits interne
Subroutinen enthalten (siehe Beispiel
1 unten).
Der Name einer externen Subroutine darf in einer Bibliothek nur einmal verwendet werden.
Das End-Subroutine-Label muss denselben Subroutinen-Namen erhalten, der mit
DEFINE SUBROUTINE definiert wurde. Das End-Subroutine-Label kann nur
mit END-SUBROUTINE definiert werden (siehe Beispiel 3 unten).
Die folgende Konstruktion ist in einem Objekt vom Typ Subroutine möglich, aber nicht in
einem anderen Objekt (in dem SUBR01 als interne Subroutine gälte):
... DEFINE SUBROUTINE SUBR01 ... PERFORM SUBR02 PERFORM SUBR03 ... DEFINE SUBROUTINE SUBR02 /* inline subroutine... END-SUBROUTINE ... DEFINE SUBROUTINE SUBR03 /* inline subroutine... END-SUBROUTINE END-SUBROUTINE END
Die folgende Konstruktion ist in einem Objekt vom Typ Subroutine nicht erlaubt:
... DEFINE SUBROUTINE SUBR01 ... END-SUBROUTINE DEFINE SUBROUTINE SUBR02 ... END-SUBROUTINE END
... DEFINE SUBROUTINE SUBR01 ... END-SUBROUTINE (SUBROUTINE-01) ... DEFINE SUBROUTINE SUBR02 ... RETURN (SUBR02) ...
... 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
Ausgabe des Programms DSREX1S:
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
Äquivalentes Reporting-Mode-Beispiel: 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
Vom Programm DSREX2 benutzte Global Data Area DSREX2G:
1 GDA-FIELD1 A 2
Vom Programm DSREX2 aufgerufene Subroutine DSREX2S:
** 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