DEFINE [SUBROUTINE] subroutine-name |
||
| statement |
||
|
|
END-SUBROUTINE (ストラクチャードモードのみ) |
|
RETURN (レポーティングモードのみ)
|
||
このドキュメントでは、次のトピックについて説明します。
構文図で使用されている記号については、「構文記号」を参照してください。
関連ステートメント:CALL | CALL FILE | CALL LOOP | CALLNAT | ESCAPE | FETCH | PERFORM
関連機能グループ:プログラムおよびルーチンの呼び出し
DEFINE SUBROUTINE ステートメントは、Natural サブルーチンを定義するために使用します。サブルーチンは PERFORM ステートメントによって呼び出されます。
サブルーチンは、PERFORM ステートメントを含むオブジェクトの中でも(内部サブルーチン)、PERFORM を含むオブジェクトの外でも(外部サブルーチン)定義できます。内部サブルーチンは、それを参照する最初の PERFORM ステートメントの前/後いずれでも定義できます。
注意:
プログラム機能を複数の外部サブルーチンで構築すると、プログラム構造が明確になります。ただし、外部サブルーチンの呼び出しは、内部コードまたは内部サブルーチンに比べてオーバーヘッドが多くなるため、常に外部サブルーチンにはできるだけ大きな機能ブロックを含めるようにすることをお勧めします。
明示的なパラメータを、呼び出し元プログラムから PERFORM ステートメントを介して内部サブルーチンに渡すことはできません。
内部サブルーチンからは、呼び出し元のプログラム内で定義してあるローカルデータエリアおよびグローバルデータエリアのデータにアクセスできます。
外部サブルーチンは、現在設定されているグローバルデータエリアにアクセスできます。また、PERFORM ステートメントで、呼び出し元のオブジェクトから外部サブルーチンにパラメータを直接渡せるため、グローバルデータエリアのサイズを縮小できます。
外部サブルーチンでは、呼び出し元のプログラムで定義したローカルデータエリアは使用できませんが、独自のローカルデータエリアを持つことはできます。
サブルーチン内で開始した処理ループは、すべて END-SUBROUTINE を発行する前に閉じる必要があります。
内部サブルーチンの中で、別の DEFINE
SUBROUTINE ステートメントを指定することはできません(下記の「例 1」を参照)。
外部サブルーチン(サブルーチンタイプのオブジェクト)に、複数の DEFINE SUBROUTINE ステートメントブロックを指定することはできません(下記の「例 2」を参照)。ただし、外部の DEFINE SUBROUTINE ブロックの中に内部サブルーチンを指定することはできます(下記の「例 1」を参照)。
1 つのライブラリに外部サブルーチンの名前を 2 回使用することはできません。
次のような構造は、タイプがサブルーチンのオブジェクトでは有効ですが、その他のオブジェクト(SUBR01 が内部サブルーチンとみなされます)の場合は無効です。
... DEFINE SUBROUTINE SUBR01 ... PERFORM SUBR02 PERFORM SUBR03 ... DEFINE SUBROUTINE SUBR02 /* inline subroutine... END-SUBROUTINE ... DEFINE SUBROUTINE SUBR03 /* inline subroutine... END-SUBROUTINE END-SUBROUTINE END
次の構造は、オブジェクトタイプがサブルーチンの場合には無効です。
... DEFINE SUBROUTINE SUBR01 ... END-SUBROUTINE DEFINE SUBROUTINE SUBR02 ... END-SUBROUTINE END
| 構文要素 | 説明 |
|---|---|
subroutine-name |
サブルーチンの名前:
サブルーチン名(最大 32 文字)の命名規則は、ユーザー定義変数名の規則と同じです。『Natural の使用』ドキュメントの「ユーザー定義変数の命名規則」を参照してください。 サブルーチン名は、該当のサブルーチンが定義されているモジュールの名前に依存しません(同じ名前にすることは可能ですが、同じ名前にする必要はありません)。 |
statement |
実行するステートメント: 状況に応じて、statement の代わりに、1 つ以上の適切なステートメントを指定する必要があります。ステートメントの例については、下記の「例」を参照してください。
|
|
DEFINE SUBROUTINE ステートメントの終了:
ストラクチャードモードでは、サブルーチン定義は レポーティングモードでは、 |
** 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
レポーティングモードの例については、次のプログラムを参照してください: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