PERFORM

PERFORM subroutine-name

 

 

M

 

operand1 (AD= O )
    A  
nX            

このドキュメントでは、次のトピックについて説明します。

構文図で使用されている記号については、「構文記号」を参照してください。

関連ステートメント:CALL | CALL FILE | CALL LOOP | CALLNAT | DEFINE SUBROUTINE | ESCAPE | FETCH

関連機能グループ:プログラムおよびルーチンの呼び出し


関数

PERFORM ステートメントは、Natural サブルーチンを呼び出すために使用します。

PERFORM ステートメントのネスト構造

呼び出し先サブルーチン内で他のサブルーチンを呼び出すための PERFORM ステートメントを指定することもできます(ネストのレベル数は、要求されるメモリのサイズによって制限されます)。

サブルーチンは自分自身を呼び出すことができます(再帰サブルーチン)。再帰的に呼び出される外部サブルーチン内にデータベース処理が含まれている場合、Natural はデータベース処理が論理的に分割されるようにします。

ダイナミック変数を使用したパラメータ引き渡し

CALLNAT ステートメントを参照してください。

構文説明

オペランド定義テーブル:

オペランド 構文要素 フォーマット オペランド参照 ダイナミック定義
operand1 C S A G   A U N P I F B D T L C G O

構文要素の説明:

構文要素 説明
subroutine-name
呼び出すサブルーチン:

サブルーチン名(最大 32 文字)については、ユーザー定義変数と同じ命名規則が適用されます。

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

呼び出すサブルーチンは、DEFINE SUBROUTINE ステートメントで定義しておく必要があります。インラインサブルーチンまたは外部サブルーチンとして指定できます(DEFINE SUBROUTINE ステートメントを参照)。

1 つのオブジェクト内で 50 個までの外部サブルーチンを参照できます。

サブルーチンで使用可能なデータ
  • インラインサブルーチン
    呼び出し側オブジェクトからインラインサブルーチンに明示パラメータを渡すことはできません。インラインサブルーチンは、同一オブジェクトモジュール内に定義されたローカルデータエリアや現在設定されているグローバルデータエリアにアクセスできます。

  • 外部サブルーチン
    外部サブルーチンは、現在設定されているグローバルデータエリアにアクセスできます。さらに、PERFORM ステートメントで呼び出し側オブジェクトから外部サブルーチンにパラメータを渡すことができるため(operand1 を参照)、グローバルデータエリアのサイズを削減できます。

operand1
渡されるパラメータ:

PERFORM ステートメントで外部サブルーチンを呼び出すとき、PERFORM ステートメントで呼び出し側オブジェクトから外部サブルーチンに 1 つ以上のパラメータ(operand1)を渡すことができます。インラインサブルーチンでは、operand1 は指定できません。

パラメータを渡す場合、DEFINE DATA ステートメントでパラメータリストの構造を定義する必要があります。

デフォルトでは、パラメータは"参照によって"渡されます。つまり、データはアドレスパラメータを介して転送され、パラメータ値自体は移動されません。ただし、パラメータを"値によって"渡す、つまり実際のパラメータ値を渡すこともできます。そのためには、これらのフィールドをサブルーチンの DEFINE DATA PARAMETER ステートメントに BY VALUE または BY VALUE RESULT オプション付きで定義します。

  • パラメータが"参照により"渡される場合、以下が適用されます。呼び出し元オブジェクトのパラメータの順序、フォーマット、および長さは、呼び出し先サブルーチンの DEFINE DATA PARAMETER 構造の順序、フォーマット、および長さと正確に一致している必要があります。変数の名前が呼び出し側オブジェクトとサブルーチンで異なる場合があります。

  • パラメータが"値により"渡される場合、以下が適用されます。呼び出し元オブジェクトのパラメータの順序は、呼び出し先サブルーチンの DEFINE DATA PARAMETER 構造の順序と正確に一致している必要があります。呼び出し側オブジェクトの変数のフォーマットと長さは、サブルーチンの変数と異なっていてもかまいません。ただし、データ転送の互換性が必要です。変数の名前が呼び出し側オブジェクトとサブルーチンで異なる場合があります。サブルーチンで変更されたパラメータ値を呼び出し側オブジェクトに戻す場合、これらのフィールドを BY VALUE RESULT 付きで定義する必要があります。BY VALUERESULT なし)では、AD 指定(下記も参照)に関係なく、変更したパラメータ値を呼び出し側オブジェクトに戻すことはできません。

注意:
BY VALUE では、パラメータ値の内部コピーが作成されます。サブルーチンはこのコピーにアクセスし、それを変更できますが、その変更は呼び出し側オブジェクトの元のパラメータ値には影響しません。BY VALUE RESULT では、同様に内部コピーが作成されます。ただし、サブルーチンの終了後、元のパラメータ値はコピーの(変更された)値で上書きされます。

いずれのパラメータ引き渡し方法にも、次が適用されます。

  • 呼び出し先サブルーチンのパラメータデータエリアでは、グループの再定義は REDEFINE ブロック内でのみ許可されます。

  • 配列を渡す場合、サブルーチンのパラメータデータエリア内の次元数とオカレンス数は PERFORM パラメータリストと同じにする必要があります。

注意:
インデックス付きグループの一部として定義された配列の複数オカレンスを PERFORM ステートメントで渡す場合、サブルーチンのパラメータデータエリア内の対応するフィールドを再定義しないでください。再定義すると、不正なアドレスが渡されます。

AD=
属性:

operand1 が変数の場合は、次のいずれかの方法でマークすることができます。

AD=O

変更不可。セッションパラメータ AD=O を参照してください。

注意:
内部的に、AD=OBY VALUE と同じ方法で処理されます(operand1を参照)。

AD=M

変更可。セッションパラメータ AD=M を参照してください。

これはデフォルト設定です。

AD=A 入力のみ。セッションパラメータ AD=A を参照してください。
operand1 が定数の場合は、AD を明示的に指定することはできません。定数には常に AD=O が適用されます。
nX
省略されるパラメータ:

表記 nX を使用して、次の n パラメータを省略するように指定できます。例えば、1X は次のパラメータを省略し、3X は次の 3 つのパラメータを省略します。これは、次の n パラメータに、外部サブルーチンに渡す値がないことを意味します。

省略されるパラメータは、サブルーチンの DEFINE DATA PARAMETER ステートメントでキーワード OPTIONAL を使用して定義する必要があります。OPTIONAL は、値を呼び出し側オブジェクトからこのようなパラメータに渡すこともできるということを意味します。

例 1 - インラインサブルーチンとしての PERFORM

** Example 'PEREX1': PERFORM   (as inline subroutine)                   
************************************************************************
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                                                              
*                                                                       
LIMIT 5                                                                 
FIND EMPLOY-VIEW WITH CITY = 'BALTIMORE'                                
  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

プログラム PEREX1 の出力:

JENSON                   LAWLER                   FORREST          
2120 HASSELL             4588 CANDLEBERRY AVE     37 TENNYSON DRIVE
 #206                    BALTIMORE                BALTIMORE        
998-5038                 629-0403                 881-3609         
                                                                   
ALEXANDER                NEEDHAM                                   
409 SENECA DRIVE         12609 BUILDERS LANE                       
BALTIMORE                BALTIMORE                                 
345-3690                 641-9789

例 2 - 外部サブルーチンとしての PERFORM

PERFORM ステートメントを含むプログラム:

** Example 'PEREX2': PERFORM (as external subroutine)                   
************************************************************************
DEFINE DATA LOCAL                                                       
1 EMPLOY-VIEW VIEW OF EMPLOYEES                                         
  2 NAME                                                                
  2 ADDRESS-LINE  (A20/2)                                               
  2 PHONE                                                               
*                                                                       
1 #ALINE   (A25/1:4,1:3)                                                
1 #X       (N2)            INIT <1>                                     
1 #Y       (N2)            INIT <1>                                     
END-DEFINE                                                              
*                                                                       
LIMIT 5                                                                 
*                                                                       
FIND EMPLOY-VIEW WITH CITY = 'BALTIMORE'                                
  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 PEREX2E #ALINE(*,*)           
    /*                                    
  ELSE                                    
    ADD 1 TO #Y                           
  END-IF                                  
  AT END OF DATA                          
    /*                                    
    PERFORM PEREX2E #ALINE(*,*)           
    /*                                    
  END-ENDDATA                             
END-FIND                                  
*                                         
END

プログラム PEREX2 から呼び出されるパラメータを含む外部サブルーチン PEREX3

** Example 'PEREX3': SUBROUTINE (external subroutine with parameters)   
************************************************************************
DEFINE DATA                                                             
PARAMETER                                                               
1 #ALINE  (A25/1:4,1:3)                                                 
END-DEFINE                                                              
*                                                                       
DEFINE SUBROUTINE PEREX2E
  WRITE NOTITLE (AD=OI) #ALINE(*,*)                                     
  RESET #ALINE(*,*)                                                     
  SKIP 1                                                                
END-SUBROUTINE                                                          
*                                                                       
END

プログラム PEREX2 の出力:

JENSON                    LAWLER                    FORREST          
2120 HASSELL              4588 CANDLEBERRY AVE      37 TENNYSON DRIVE
 #206                     BALTIMORE                 BALTIMORE        
998-5038                  629-0403                  881-3609         
                                                                     
ALEXANDER                 NEEDHAM                                    
409 SENECA DRIVE          12609 BUILDERS LANE                        
BALTIMORE                 BALTIMORE                                  
345-3690                  641-9789