CALLNAT

 

   

               

     

 

M

 

CALLNAT operand1 [USING] operand2 (AD= O )
    A  
    nX            
                   

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

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

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

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


関数

CALLNAT ステートメントは、Natural サブプログラムを実行するために呼び出します。Natural サブプログラムは、CALLNAT ステートメントによってのみ呼び出すことができます。サブプログラムを単独で実行することはできません。

CALLNAT ステートメントを実行すると、呼び出し元オブジェクト(CALLNAT ステートメントを含んでいるオブジェクト)は中断され、呼び出したサブプログラムが実行されます。サブプログラムの実行は、END ステートメントに到達するまで、または ESCAPE ROUTINE ステートメントの実行によってサブプログラムの処理が停止されるまで続きます。どちらの場合でも、呼び出し元オブジェクトのその後の処理は、CALLNAT ステートメントの次にあるステートメントから継続されます。

注意:

  1. サブプログラムは、他のサブプログラムを交互に呼び出すことができます。
  2. サブプログラムには、呼び出し側オブジェクトが使用するグローバルデータエリアへのアクセスがありません。サブプログラムからサブルーチンやヘルプルーチンを呼び出す場合は、サブプログラムで独自のグローバルデータエリアを作成して、サブルーチンまたはヘルプルーチンと共有することができます。

構文説明

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

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

構文要素の説明:

構文要素 説明
operand1
呼び出すサブプログラム:

operand1 として、呼び出すサブプログラムの名前を指定します。名前は、1~8 文字の定数または変数で指定できます。プログラムロジックによって呼び出すサブプログラムが異なる場合は、長さ 1~8 の英数字の変数として指定します。

サブプログラム名にアンパサンド(&)を含むこともできます。実行時にこの文字は、システム変数 *LANGUAGE の現在の値に対応する 1 文字コードで置き換えられます。これにより、入力時の言語に応じて、入力処理ごとに異なるサブプログラムを呼び出すことができます。

operand2
Parameters:

パラメータをサブプログラムに渡す場合、パラメータリストの構成は、DEFINE DATA PARAMETER ステートメントで定義する必要があります。CALLNAT ステートメントで指定したパラメータだけが、呼び出し元オブジェクトからサブプログラムに有効なデータです。

デフォルトでは、パラメータは参照によって渡されます。つまり、データはアドレスパラメータを介して転送され、パラメータ値自体は移動されません。ただし、パラメータを値によって渡す、つまり実際のパラメータ値を渡すこともできます。これを行うには、サブプログラムの DEFINE DATA PARAMETER ステートメントで、これらのフィールドを BY VALUE または BY VALUE RESULT オプションを指定して定義します(DEFINE DATA ステートメントの説明にある parameter-data-definition を参照)。

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

  • パラメータが値により渡される場合、以下が適用されます。呼び出し元オブジェクトのパラメータは、呼び出し先サブプログラムの DEFINE DATA PARAMETER 構造の順序と正確に一致している必要があります。呼び出し元オブジェクトの変数のフォーマットと長さは、サブプログラムの変数と異なっていてもかまいません。ただし、データ転送の互換性が必要です(詳細については、『プログラミングガイド』の「演算割り当てのルール」、「データ転送」にある対応表を参照)。呼び出し元オブジェクトと呼び出されるサブプログラムで異なる変数名を使用できます。サブプログラムで変更されたパラメータの値を呼び出し元オブジェクトに戻す場合、これらのフィールドを BY VALUE RESULT 付きで定義する必要があります。RESULT を指定せずに BY VALUE を指定すると、修正されたパラメータ値を呼び出し側オブジェクトに返すことはできません(AD 指定にかかわりません。以下も参照してください)。

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

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

operand2 としてグループを指定すると、グループ内にある個々のフィールドがサブプログラムに渡されます。つまり、これらの各フィールドに対応するフィールドを、サブプログラムのパラメータデータエリアに定義する必要があります。

呼び出されたサブプログラムのパラメータデータエリアでは、グループの再定義は REDEFINE ブロック内だけで行うことができます。

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

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

COMPOPT コマンドのオプション PCHECKON に設定すると、CALLNAT ステートメントで指定されたパラメータの数値、フォーマット、長さ、および配列の添字の限度がコンパイラによってチェックされます。また、DEFINE DATA PARAMETER ステートメントの OPTIONAL 機能もパラメータチェックで考慮されます。

AD=
属性定義:

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

AD=O

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

注意:
内部的には、AD=OBY VALUE と同様に処理されます(DEFINE DATA ステートメントの説明にある parameter-data-definition を参照)。

AD=M

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

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

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

表記 nX を使用して、次の n パラメータを省略するように指定できます。例えば、1X は次のパラメータを省略し、3X は次の 3 つのパラメータを省略します。これは、次の n パラメータに、サブプログラムに渡す値がないことを意味します。n の値の有効範囲は 1 - 4096 です。

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

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

ダイナミック変数は、呼び出されたプログラムオブジェクト(CALLNATPERFORM)へのパラメータとして渡すことができます。ダイナミック変数の値スペースは連続しているので、参照による呼び出しが可能です。値による呼び出しを使用すると、呼び出し元の変数定義がソースオペランドとして割り当てられ、パラメータ定義が応答先オペランドとして割り当てられます。さらに、値による呼び出しは、結果として反対方向への動作を変更します。参照による呼び出しを使用する場合、変数定義およびパラメータ定義は DYNAMIC である必要があります。そのうちの 1 つだけが DYNAMIC の場合、ランタイムエラーが発生します。値による呼び出し(の結果)の場合は、すべての組み合わせが可能です。

次の表は、パラメータの転送に関して、呼び出し元のスタティックおよびダイナミックに定義された変数と、スタティックおよびダイナミックに定義されたパラメータの有効な組み合わせを示しています。

参照渡し

operand2(呼び出し元) パラメータ定義
スタティック ダイナミック
スタティック ×
ダイナミック ×

ダイナミック変数 A または B のフォーマットは一致している必要があります。

値渡し(結果)

operand2(呼び出し元) パラメータ定義
スタティック ダイナミック
スタティック
ダイナミック

注意:
スタティック/ダイナミックまたはダイナミック/スタティック定義を使用する場合は、割り当ての際にデータ転送の規則によって値が切り捨てられることがあります。

例 1

呼び出す側のプログラム:

** Example 'CNTEX1': CALLNAT                                            
************************************************************************
DEFINE DATA LOCAL                                                       
1 #FIELD1 (N6)                                                          
1 #FIELD2 (A20)                                                         
1 #FIELD3 (A10)                                                         
END-DEFINE                                                              
*                                                                       
CALLNAT 'CNTEX1N' #FIELD1 (AD=M) #FIELD2 (AD=O) #FIELD3 'P4 TEXT' 
*                                                                       
WRITE '=' #FIELD1 '=' #FIELD2 '=' #FIELD3                               
*                                                                       
END

呼び出される側のサブプログラム CNTEX1N:

** Example 'CNTEX1N': CALLNAT  (called by CNTEX1)                       
************************************************************************
DEFINE DATA PARAMETER                                                   
1 #FIELDA (N6)                                                          
1 #FIELDB (A20)                                                         
1 #FIELDC (A10)                                                         
1 #FIELDD (A7)                                                          
END-DEFINE                                                              
*                                                                       
*                                                                       
#FIELDA := 4711                                                         
*                                                                       
#FIELDB := 'HALLO'                                                      
*                                                                       
#FIELDC := 'ABC'                                                        
*                                                                       
WRITE '=' #FIELDA '=' #FIELDB '=' #FIELDC '=' #FIELDD                   
*                                                                       
END

例 2

呼び出す側のプログラム:

** Example 'CNTEX2': CALLNAT                                            
************************************************************************
DEFINE DATA LOCAL                                                       
1 #ARRAY1  (N4/1:10,1:10)                                               
1 #NUM     (N2)                                                         
END-DEFINE                                                              
*                                                                       
*                                                                       
CALLNAT 'CNTEX2N' #ARRAY1 (2:5,*)                                   
*                                                                       
FOR #NUM 1 TO 10                                                        
  WRITE #NUM #ARRAY1(#NUM,1:10)                                         
END-FOR                                                                 
*                                                                       
END

呼び出される側のサブプログラム CNTEX2N:

** Example 'CNTEX2N': CALLNAT  (called by CNTEX2)                       
************************************************************************
DEFINE DATA                                                             
PARAMETER                                                               
1 #ARRAY (N4/1:4,1:10)                                                  
LOCAL                                                                   
1 I      (I2)                                                           
END-DEFINE                                                              
*                                                                       
*                                                                       
FOR I 1 10                                                              
  #ARRAY(1,I) := I                                                      
  #ARRAY(2,I) := 100 + I                                                
  #ARRAY(3,I) := 200 + I                                                
  #ARRAY(4,I) := 300 + I                                                
END-FOR                                                                 
*                                                                       
END