バージョン 4.2.5
 —  ステートメント  —

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 ステートメントの前/後いずれにでも定義できます。

注意:
プログラム機能を複数の外部サブルーチンで構築すると、プログラム構造が明確になります。ただし、外部サブルーチンの呼び出しは、内部コードまたは内部サブルーチンに比べてオーバーヘッドが多くなるため、常に外部サブルーチンにはできるだけ大きな機能ブロックを含めるようにすることをお勧めします。

Top of page

制限事項

例 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

Top of page

構文説明

subroutine-name

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

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

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

Top of page

サブルーチンで使用可能なデータ

このセクションでは、次のトピックについて説明します。

インラインサブルーチン

明示的なパラメータを、呼び出し元プログラムから PERFORM ステートメントを介して内部サブルーチンに渡すことはできません。

内部サブルーチンからは、呼び出し元のプログラム内で定義してあるローカルデータエリアおよびグローバルデータエリアのデータにアクセスできます。

外部サブルーチン

外部サブルーチンは、現在設定されているグローバルデータエリアにアクセスできます。 また、PERFORM ステートメントで、呼び出し元のオブジェクトから外部サブルーチンにパラメータを直接渡せるため、グローバルデータエリアのサイズを縮小できます。

外部サブルーチンでは、呼び出し元のプログラムで定義したローカルデータエリアは使用できませんが、独自のローカルデータエリアを持つことはできます。

Top of page

例 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                                  

レポーティングモードの例については、ライブラリ SYSEXRM のプログラム 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                                                                    

Top of page