このドキュメントでは、次のトピックについて説明します。
「フィールドの定義」で説明されているように、プログラムで使用するすべてのフィールドは DEFINE DATA
ステートメントに定義する必要があります。
フィールドは DEFINE DATA
ステートメント内に直接定義できます。または、プログラム外部の別個のデータエリアにフィールドを定義し、DEFINE DATA
ステートメントでそのデータエリアを参照できます。
別個のデータエリアとは、複数の Natural プログラム、サブプログラム、サブルーチン、ヘルプルーチン、ダイアログ、またはクラスで使用できる Natural オブジェクトを指します。 データエリアには、データ定義モジュール(DDM)から取得されるユーザー定義変数、定数、データベースフィールドなどのデータ要素定義が含まれています。
すべてのデータエリアは、データエリアエディタで作成および編集します。
Natural では、次の 3 つのタイプのデータエリアがサポートされます。
ローカルとして定義された変数は、単一の Natural プログラミングオブジェクト内でのみ使用できます。 ローカルデータを定義する方法は次の 2 つです。
プログラム内部に定義します。
プログラム外部の別個の Natural プログラミングオブジェクトに定義します。
ローカルデータエリアは、そのローカルデータエリアを使用するプログラム、サブプログラム、または外部サブルーチンが実行を開始するときに初期化されます。
最初の例では、フィールドはプログラムの DEFINE DATA
ステートメント内に直接定義されています。 2 つ目の例では、同じフィールドが LDA に定義され、DEFINE DATA
ステートメントにはそのデータエリアへの参照のみが指定されています。
DEFINE DATA LOCAL 1 VIEWEMP VIEW OF EMPLOYEES 2 NAME 2 FIRST-NAME 2 PERSONNEL-ID 1 #VARI-A (A20) 1 #VARI-B (N3.2) 1 #VARI-C (I4) END-DEFINE ...
プログラム:
DEFINE DATA LOCAL USING LDA39 END-DEFINE ...
ローカルデータエリア LDA39:
I T L Name F Length Miscellaneous All -- -------------------------------- - ---------- -------------------------> V 1 VIEWEMP EMPLOYEES 2 PERSONNEL-ID A 8 2 FIRST-NAME A 20 2 NAME A 20 1 #VARI-A A 20 1 #VARI-B N 3.2 1 #VARI-C I 4
アプリケーション構造を明確にして管理しやすくするために、通常はプログラム外部のデータエリアにフィールドを定義する方が便利です。
以下では次のトピックについて説明します。
GDA は、Natural データエリアエディタで作成および変更します。 詳細については、『エディタ』ドキュメントの「データエリアエディタ」を参照してください。
Natural プログラミングオブジェクトで参照される GDA は、この GDA を参照するオブジェクトが保存されているものと同じ Natural ライブラリ、またはこのライブラリに定義されている steplib に保存する必要があります。
COMMON という名前の GDA がライブラリに存在する場合は、このライブラリに LOGON
すると、ACOMMON という名前のプログラムが自動的に呼び出されます。
重要:
複数の Natural プログラミングオブジェクトが 1 つの GDA を参照するアプリケーションを構築するときは、この GDA 内のデータ要素定義を変更すると、このデータエリアを参照するすべての Natural プログラミングオブジェクトに影響が及ぶことに注意してください。
したがって、このようなオブジェクトは、GDA を変更した後に CATALOG
または STOW
コマンドを使って再コンパイルする必要があります。
GDA を使用するには、Natural プログラミングオブジェクトで DEFINE DATA
ステートメントの GLOBAL
節を使用して GDA を参照する必要があります。 それぞれの Natural プログラミングオブジェクトは 1 つのグローバルデータエリアのみを参照できます。つまり、DEFINE DATA
ステートメントに複数の GLOBAL
節を含めることはできません。
GDA の最初のインスタンスは、これを参照する最初の Natural プログラミングオブジェクトが実行を開始したランタイムに作成され、初期化されます。
GDA インスタンスが作成されると、この中に含まれるデータ値は、この GDA を参照する(DEFINE DATA GLOBAL
ステートメント)すべての Natural プログラミングオブジェクト、および PERFORM
、INPUT
、または FETCH
ステートメントによって呼び出されるすべての Natural プログラミングオブジェクトで共有できます。 GDA インスタンスを共有するすべてのオブジェクトは、同じデータ要素上で機能します。
次の状況が該当する場合に、新しい GDA インスタンスが作成されます。
いずれかの GDA を参照するサブプログラムが CALLNAT
ステートメントで呼び出された。
GDA を参照しないサブプログラムが、いずれかの GDA を参照するプログラミングオブジェクトを呼び出した。
GDA の新しいインスタンスが作成されると、現在の GDA インスタンスは中断され、含まれていたデータ値はスタックされます。 次にサブプログラムが、新しく作成された GDA インスタンス内のデータ値を参照します。 中断された GDA インスタンス内のデータ値にアクセスすることはできません。
プログラミングオブジェクトは 1 つの GDA インスタンスしか参照できず、以前の GDA インスタンスにアクセスすることはできません。 GDA データ要素は、CALLNAT
ステートメント内でパラメータとして定義することによって、サブプログラムに渡すことのみが可能です。
サブプログラムが、呼び出し元プログラミングオブジェクトに戻ると、参照されていた GDA インスタンスは削除され、それまで中断していた GDA インスタンスがそのデータ値とともに再開されます。
次のいずれかが該当する場合、GDA インスタンスとその内容は削除されます。
次の LOGON
が実行された。
同じレベルで別の GDA が参照された(レベルについてはこのセクションで後述)。
RELEASE VARIABLES
ステートメントが実行された。 この場合、GDA インスタンス内の変数は、レベル 1 のプログラムの実行が終了するか、プログラムが FETCH
または RUN
ステートメントで別のプログラムを呼び出したときにリセットされます。
次のセクションの図は、プログラミングオブジェクトが GDA を参照し、GDA インスタンス内のデータ要素を共有する様子を示しています。
次の図は、GDA を参照するサブプログラムが、呼び出し元プログラムが参照する GDA インスタンス内のデータ値を共有できないことを示しています。 呼び出し元プログラムと同じ GDA を参照するサブプログラムは、この GDA の新しいインスタンスを作成します。 ただし、サブプログラムが参照する GDA に定義されているデータ要素は、このサブプログラムが呼び出したサブルーチンやヘルプルーチンで共有できます。
次の図は、GDA1 の 3 つの GDA インスタンスと、データ要素 #GLOB1
によって各 GDA インスタンスに割り当てられる最終値を示しています。 番号 ~ は、プログラミングオブジェクトの階層レベルを示しています。
次の図は、同じ GDA を参照し、FETCH
または FETCH RETURN
ステートメントを使用してそれぞれを呼び出す複数のプログラムが、この GDA 内に定義されているデータ要素を共有することを示しています。 これらのプログラムのいずれかが GDA を参照しない場合は、以前に参照されていた GDA のインスタンスがアクティブなまま残り、データ要素の値が保持されます。
番号 および は、プログラミングオブジェクトの階層レベルを示しています。
次の図は、プログラムが FETCH
ステートメントを使用して、異なる GDA を参照する別のプログラムを呼び出すと、呼び出し元プログラムが参照する GDA(ここでは GDA1)の現在のインスタンスが削除されることを示しています。 その後、この GDA が他のプログラムから再び参照されると、この
GDA の新しいインスタンスが作成され、その中のすべてのデータ要素にはそれぞれの初期値が指定されます。
FETCH RETURN
ステートメントを使用して、異なる GDA を参照する別のプログラムを呼び出すことはできません。
番号 は、プログラミングオブジェクトの階層レベルを示しています。
呼び出し元プログラム PROG3 および PROG4 によって、GDA インスタンスは次のような影響を受けます。
PROG3 内のステートメント GLOBAL USING GDA2
によって、GDA2 のインスタンスが作成され、GDA1 の現在のインスタンスが削除されます。
PROG4 内のステートメント GLOBAL USING GDA1
によって、GDA2 の現在のインスタンスが削除され、GDA1 の新しいインスタンスが作成されます。 この結果、WRITE
ステートメントで値ゼロ(0)が表示されます。
データストレージスペースを節約するために、データブロックが含まれる GDA を作成できます。
以下では次のトピックについて説明します。
データブロックは、プログラムの実行中に相互に重ねることができるため、ストレージスペースの節約になります。
例えば、次のような階層では、ブロック B とブロック C が同じストレージエリアに割り当てられます。 したがって、ブロック B とブロック C は同時に使用できません。 ブロック B を変更すると、ブロック C の内容が破壊されます。
データブロックはデータエリアエディタで定義します。 どのブロックがどのブロックの下位になるかを指定して、ブロック階層を設定します。これは、ブロック定義のコメントフィールドに "親" ブロックの名前を入力して設定します。
次の例では、SUB-BLOCKB と SUB-BLOCKC が MASTER-BLOCKA の下位になり、SUB-BLOCKD が SUB-BLOCKB の下位になります。
ブロックレベルの最大値は 8(マスタブロックを含む)です。
グローバルデータエリア G-BLOCK
I T L Name F Leng Index/Init/EM/Name/Comment - - - -------------------------------- - ---- --------------------------------- B MASTER-BLOCKA 1 MB-DATA01 A 10 B SUB-BLOCKB MASTER-BLOCKA 1 SBB-DATA01 A 20 B SUB-BLOCKC MASTER-BLOCKA 1 SBC-DATA01 A 40 B SUB-BLOCKD SUB-BLOCKB 1 SBD-DATA01 A 40
特定のブロックをプログラムで使用可能にするには、DEFINE DATA
ステートメント内で次の構文を使用します。
プログラム 1:
DEFINE DATA GLOBAL USING G-BLOCK WITH MASTER-BLOCKA END-DEFINE
プログラム 2:
DEFINE DATA GLOBAL USING G-BLOCK WITH MASTER-BLOCKA.SUB-BLOCKB END-DEFINE
プログラム 3:
DEFINE DATA GLOBAL USING G-BLOCK WITH MASTER-BLOCKA.SUB-BLOCKC END-DEFINE
プログラム 4:
DEFINE DATA GLOBAL USING G-BLOCK WITH MASTER-BLOCKA.SUB-BLOCKB.SUB-BLOCKD END-DEFINE
この構造では、プログラム 1 がプログラム 2、プログラム 3、またはプログラム 4 と MASTER-BLOCKA 内のデータを共有できます。 ただし、プログラム 2 とプログラム 3 は SUB-BLOCKB と SUB-BLOCKC のデータエリアを共有できません。これらのデータブロックは構造と同じレベルにあるため、同じストレージエリアを占有しているからです。
データブロック階層を使用するときは注意が必要です。 3 つのプログラムがデータブロック階層を使用する次のシナリオを想定します。
プログラム 1:
DEFINE DATA GLOBAL USING G-BLOCK WITH MASTER-BLOCKA.SUB-BLOCKB END-DEFINE * MOVE 1234 TO SBB-DATA01 FETCH 'PROGRAM2' END
プログラム 2:
DEFINE DATA GLOBAL USING G-BLOCK WITH MASTER-BLOCKA END-DEFINE * FETCH 'PROGRAM3' END
プログラム 3:
DEFINE DATA GLOBAL USING G-BLOCK WITH MASTER-BLOCKA.SUB-BLOCKB END-DEFINE * WRITE SBB-DATA01 END
説明:
プログラム 1 は、グローバルデータエリア G-BLOCK を MASTER-BLOCKA および SUB-BLOCKB と共同で使用します。 このプログラムは SUB-BLOCKB 内のフィールドを変更して、プログラム 2 を FETCH
しますが、プログラム 2 のデータ定義には MASTER-BLOCKA しか指定されていません。
プログラム 2 は SUB-BLOCKB をリセット、つまりその内容を削除します。 これは、レベル 1 のプログラム(例えば、FETCH
ステートメントで呼び出されたプログラム)は、そのデータ定義に定義されているブロックの下位となるすべてのデータブロックをリセットするからです。
次にプログラム 2 はプログラム 3 を FETCH
します。プログラム 3 はプログラム 1 で変更されたフィールドを表示するものですが、空の画面を返します。
プログラムレベルの詳細については、「呼び出されるオブジェクトの複数レベル」を参照してください。
サブプログラムは、CALLNAT
ステートメントを使用して呼び出されます。 CALLNAT
ステートメントを使用して、パラメータを呼び出し元オブジェクトからサブプログラムに渡すことができます。
このようなパラメータは、サブプログラム内の DEFINE DATA PARAMETER
ステートメントに、次の方法で定義する必要があります。
DEFINE DATA
ステートメントの PARAMETER
節内に直接定義します。
別のパラメータデータエリア(PDA)に定義して、その PDA を参照する DEFINE DATA PARAMETER
ステートメントを指定します。
以下では次のトピックについて説明します。
同様に、PERFORM
ステートメントによって外部サブルーチンに渡されるパラメータは、外部サブルーチン内の DEFINE DATA PARAMETER
ステートメントを使用して定義する必要があります。
呼び出し元オブジェクトでは、サブプログラム/サブルーチンに渡されるパラメータ変数を PDA 内に定義する必要はありません。上記の図では、呼び出し元オブジェクトが使用する LDA に定義されていますが、GDA に定義することも可能です。
呼び出し元オブジェクト内の CALLNAT
/PERFORM
ステートメントで指定されるパラメータの順序、フォーマット、および長さは、呼び出されるサブプログラム/サブルーチンの DEFINE DATA PARAMETER
ステートメントに指定されるフィールドの順序、フォーマット、および長さと正確に一致する必要があります。 ただし、呼び出し元オブジェクト内の変数の名前は、呼び出されるサブプログラム/サブルーチンと同じである必要はありません。パラメータは名前ではなくアドレスで転送されるためです。
呼び出し元プログラムで使用されるデータ要素定義が、サブプログラムまたは外部サブルーチンで使用されるデータ要素定義と同一であることを確実にするために、DEFINE DATA LOCAL USING
ステートメントに PDA を指定できます。 PDA を LDA として使用することにより、PDA と同じ構造を持つ LDA を作成する手間を省くことができます。