DEFINE SUBROUTINE

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 回使用することはできません。

例 1

次のような構造は、タイプがサブルーチンのオブジェクトでは有効ですが、その他のオブジェクト(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

例 2(無効)

次の構造は、オブジェクトタイプがサブルーチンの場合には無効です。

...
DEFINE SUBROUTINE SUBR01   
...
END-SUBROUTINE
DEFINE SUBROUTINE SUBR02
...
END-SUBROUTINE
END

構文説明

構文要素 説明
subroutine-name
サブルーチンの名前:

サブルーチン名(最大 32 文字)の命名規則は、ユーザー定義変数名の規則と同じです。『Natural の使用』ドキュメントの「ユーザー定義変数の命名規則」を参照してください。

サブルーチン名は、該当のサブルーチンが定義されているモジュールの名前に依存しません(同じ名前にすることは可能ですが、同じ名前にする必要はありません)。

statement
実行するステートメント:
状況に応じて、statement の代わりに、1 つ以上の適切なステートメントを指定する必要があります。ステートメントの例については、下記の「」を参照してください。

END-SUBROUTINE
RETURN

DEFINE SUBROUTINE ステートメントの終了:

ストラクチャードモードでは、サブルーチン定義は END-SUBROUTINE.で終了します。

レポーティングモードでは、RETURN でもサブルーチンを終了できます。

例 1 - サブルーチンの定義

** 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

プログラム 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

レポーティングモードの例については、次のプログラムを参照してください:DSREX1R

例 2 - GDA フィールドを使用する外部サブルーチンのサンプル構造

** 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

プログラム DSREX2 によって使用されるグローバルデータエリア DSREX2G:

1 GDA-FIELD1                       A    2

プログラム DSREX2 によって呼び出されるサブルーチン 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