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

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

Top of page

構文説明

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

オペランド 構文要素 フォーマット ステートメント参照 ダイナミック定義
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 の現在の値で置き換えられます。 これにより、入力時の言語に応じて、入力処理ごとに異なるサブプログラムを呼び出すことができます。

operand2
パラメータ:

パラメータをサブプログラムに渡す場合、パラメータリストの構成は、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 付きで定義する必要があります。 BY VALUE では(RESULT を使用せずに)、修正されたパラメータ値を呼び出し側オブジェクトに戻すことはできません(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 は、値を呼び出し側オブジェクトからこのようなパラメータに渡すこともできるということを意味します。

Top of page

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

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

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

参照渡し

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

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

値渡し(結果)

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

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

Top of page

例 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                                                                    

Top of page