DEFINE
[SUBROUTINE]
subroutine-name
|
||
|
statement
|
||
|
|
END-SUBROUTINE [ (subroutine-name)
]
|
|
RETURN
(nur im Reporting Mode)
|
||
Dieses Dokument 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