バージョン 6.3.3
 —  プログラミングガイド  —

ダイアログエレメントのクライアントデータの保存および取得

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


はじめに

このセクションでは、任意のユーザー定義情報("クライアントデータ")とダイアログまたはダイアログエレメントとの関連付けについて説明します。 この関連付けを実現するためのさまざまな補完的方法があります。これらの方法の詳細については、以降のセクションで説明します。 Natural のクライアントデータ操作に関連する属性やアクションは、以下のとおりです(このドキュメントでの説明順)。

Top of page

整数データ

多くのダイアログエレメントのタイプでは、CLIENT-DATA 属性を使用して、単一の任意の 4 バイト整数値をダイアログエレメントに関連付けることができます。 これは、データを特定のダイアログエレメントにリンクするのに便利です。 例えば、リストボックス項目は、データベースレコードの ISN を受け渡しできます。 CLIENT-DATA 属性値は随時変更できます。

このための Natural コードは以下のようになります。

DEFINE DATA  
LOCAL 
  1 #LBITEM-1 HANDLE OF LISTBOXITEM 
    
  1 #ISN (I4) 
   ... 
END-DEFINE 
... 
READ... 
   #LBITEM-1.CLIENT-DATA:= #ISN 
END-READ 
...

注意:
ダイアログの CLIENT-DATA 属性はダイアログ ID のために予約されています。ユーザー定義のクライアントデータには使用しないでください。

Top of page

ハンドルデータ

整数データと同様に、多くのダイアログエレメントについて、CLIENT-HANDLE 属性は任意の GUI オブジェクトハンドルを取ることができます。 例えば、「ダイアログバーコントロールの操作」では、ダイアログ内で使用されるツールバーコントロールおよびダイアログバーコントロールのそれぞれに対してエントリが組み込まれたコンテキストメニューを構築する、一般的なサンプルコードが記載されています。このコードを使用すると、ユーザーはこれらのダイアログエレメントを個別に表示したり非表示にしたりできます。 この例では、各メニュー項目の CLIENT-HANDLE 属性を、対応するツールバーまたはダイアログバーのハンドルに設定しています。これにより、メニュー項目がクリックされると、その項目を直接かつ簡単に取得できます。

Top of page

キー付き英数字クライアントデータ

注意:
"キー付き" という用語は、特定のダイアログエレメントに対し、複数の項目情報を設定できることを意味します。各項目情報は、一意の取得キーに基づいて格納されます。

また、CLIENT-KEY 属性および CLIENT-VALUE 属性の組み合わせを使用することにより、最大 253 文字の英数字文字列としてクライアントデータを設定したり取得したりすることもできます。

Start of instruction setダイアログエレメントに特定の文字列を設定するには

  1. ダイアログエレメントの CLIENT-KEY 属性に必要な値が設定されていない場合はまず、この属性に値を割り当てます。 これにより、文字列をダイアログエレメントに格納する際のキーが決定します。

  2. 次に、英数字の文字列をダイアログエレメントの CLIENT-VALUE 属性に割り当てます。

これにより、1 つのダイアログエレメントに多くのキー/値のペアを格納できます。

例:

#LB-1.CLIENT-KEY:= 'ANYKEY' 
#LB-1.CLIENT-VALUE:= 'ANYSTRING'        /* The string to be stored

注意:
上記の例および以降のすべての例において、ハンドル変数 #LB-1 が使用されています。この変数は、通常は(規則に従って)リストボックスを参照します。 ただし、CLIENT-DATA 属性には例外があり、タイマやシグナルなどのユーザーインタフェースを持たないものを含め、あらゆるタイプの GUI オブジェクトにクライアントデータを関連付けることができます。

Start of instruction setダイアログエレメントを特定の文字列でクエリするには

  1. この属性に必要な値が含まれていない場合は、最初に CLIENT-KEY 値をダイアログエレメントに割り当ててください。

  2. 次に、ダイアログエレメントの CLIENT-VALUE 属性をクエリして、対応する値を取得します。

CLIENT-KEY に対応する CLIENT-VALUE をクエリした結果、ダイアログエレメントにそのようなキー/値のペアがなかった場合、空の文字列(" ")が返されます。

例:

#LB-1.CLIENT-KEY:= 'ANYKEY' 
IF #LB-1.CLIENT-VALUE EQ 'ANYSTRING' THEN 
... 
END-IF

英数字以外のデータを格納および取得する場合は少し複雑となり、以下の例のように、データを元のフォーマットに戻します。

例:

DEFINE DATA LOCAL
01 #DATE (D)
...
END-DEFINE

#LB-1.CLIENT-KEY := 'ANYKEY' 
/* Store the current date
#LB-1.CLIENT-VALUE := *DATX

/* Retrieve it as a date (D) field
STACK TOP DATA #LB-1.CLIENT-VALUE
INPUT #DATE

STACK ステートメントは、英数字フォーマットでクライアント値を取得し、Natural スタックに格納します。INPUT ステートメントはスタックからその値を取り出し、暗黙的に英数字フォーマットから日付フォーマットに変換して、指定された変数 #DATE に格納します。 また、クライアント値を取得して英数字変数に格納することもできます。この場合、格納後に MOVE EDITED ステートメントを使用して、明示的に日付フィールドに変換します。 ただし、日付フォーマット(DTFORM)に依存せず、中間的な英数字変数も必要としないため、前述のアプローチの方が適しています。

日付や時刻など、データタイプによっては、CLIENT-VALUE 属性で指定されているデフォルトの英数字表記が、元のデータタイプの情報すべてに対応していない場合があります。 例えば、時間(T)の値を表すデフォルトの英数字表記には時間、分、秒のみが含まれ、日付や 1/10 秒などは含まれません。 同様に、日付(D)の値を表すデフォルトの英数字表記には、世紀の情報は含まれません。 したがって、上記の例で正しい世紀を使用するには、プログラムを実行する前に "スライディングウィンドウ"(YSLW)パラメータを正しく設定する必要があります。

ダイナミック文字変数を使用して CLIENT-VALUE 属性値を直接受け取る場合、受け取った値は 253 文字の長さになり、必要に応じて空白が埋め込まれます。 これは、A253 フォーマットの属性バッファが内部的に使用されているためです。これについては、後で説明します。 明示的に A253 で定義されているフィールドをダイナミック変数に割り当てるときも同様です。 どちらの場合も、ダイナミック変数の末尾に空白が格納されることを回避するには、以下の例のように、単純な MOVE や割り当ての代わりに COMPRESS ステートメントを使用する必要があります。

DEFINE DATA LOCAL 01 #DYN (A) DYNAMIC ... END-DEFINE 
#DYN := 'ANYSTRING' /* Set the client data #LB-1.CLIENT-KEY := 'ANYKEY' #LB-1.CLIENT-VALUE 
:= #DYN /* Retrieve value as 253-character string: #DYN := #LB-1.CLIENT-VALUE 
/* Retrieve value without trailing blanks: COMPRESS #LB-1.CLIENT-VALUE INTO #DYN 

このようにすると、どちらのアプローチを使用したかに関係なく、CLIENT-VALUE 属性の値を取得および格納しても、ダイナミック英数字変数の末尾に空白は埋め込まれません。

Start of instruction setダイアログエレメントから特定の文字列を削除するには

  1. この属性に必要な値が含まれていない場合は、最初に CLIENT-KEY 値をダイアログエレメントに割り当ててください。

  2. ダイアログエレメントの CLIENT-VALUE 属性を RESET するか、または明示的に空白値を割り当てて、対応する値を削除します。

例:

#LB-1.CLIENT-KEY:= 'ANYKEY' RESET #LB-1.CLIENT-VALUE

Top of page

ネイティブフォーマットのキー付きクライアントデータ

CLIENT-KEY 属性および CLIENT-VALUE 属性の組み合わせを使用してクライアントデータを英数字文字列に設定する代わりに、SET-CLIENT-VALUE アクションおよび GET-CLIENT-VALUE アクションを使用すると、クライアントデータをそのままのフォーマットで変換せずに、直接格納したり取得したりできます。 ただし、この値は圧縮形式で格納される場合があります。 特に非ダイナミック英数字データの末尾の空白は、スペースを節約するため、格納されません。 例えば、"FRED" という値とこれに続く 249 文字の空白文字が格納されている A253 フィールドを指定すると、A4 値の "FRED" のみがクライアントデータとして内部的に格納されます。 この最適化は、CLIENT-VALUE 属性経由で格納されたクライアントデータにも適用されます。

これらの 2 つの手法は、一緒に使用できます(1 つの手法をデータの設定に使用し、もう 1 つの手法をデータの取得に使用するなど)。 ただし、アクションの使用には、属性を使用する以上に多くの利点があります。この点については、以降のセクションで説明します。

Start of instruction setアクションベースの手法を使用して、ダイアログエレメントのクライアントデータを更新するには

例:

#LB-1.CLIENT-KEY := 'ANYKEY' /* The following three statements are equivalent 
ways of setting the same /* information: /* (1) attribute-based approach: #LB-1.CLIENT-VALUE 
:= 'ANYVALUE' /* (2) action-based approach, with explicitly-specified key PROCESS 
GUI ACTION SET-CLIENT-VALUE WITH #LB-1 'ANYVALUE' 'ANYKEY' GIVING *ERROR /* (3) 
action-based approach without key; CLIENT-KEY attribute implicitly used PROCESS 
GUI ACTION SET-CLIENT-VALUE WITH #LB-1 'ANYVALUE' GIVING *ERROR

SET-CLIENT-VALUE アクションを使用してクライアントデータを格納する大きな利点は、CLIENT-VALUE 属性を使用する場合と異なり、英数字(A253)フォーマットに中間的に変換する必要がないという点です。 このことを以下の図で説明します。フォーマット X は任意のデータタイプを表し、フォーマット An は末尾の空白が除去された英数字値を表します。

Update client data

この図の矢印 "(1)" および "(2)" で示されているように、CLIENT-VALUE 属性を使用したクライアントデータの格納と取得には 2 つの手順を実行する必要があります(Natural のすべての属性で同じことが当てはまります)。また、属性に定義されているフォーマットに対応する属性バッファ(この場合は A253)も使用します。 一方、SET-CLIENT-VALUE アクションおよび GET-CLIENT-VALUE アクションを使用すると、属性バッファとソースフィールドまたはターゲットフィールドとの変換を行わずに、単一の手順で、手順 "(2)" と同じ処理を効率よく実行できます。 これにより、(処理がいくらか高速になる以外に)以下の利点がもたらされます。

その他に、クライアントデータの格納にアクションベースのアプローチを使用することには、以下のような利点があります。

Start of instruction setアクションベースの手法を使用して、ダイアログエレメントのクライアントデータをクエリするには

例:

DEFINE DATA LOCAL 01 #VALUE (A253) ... END-DEFINE PROCESS GUI ACTION GET-CLIENT-VALUE 
WITH #LB-1 #VALUE 'ANYKEY' GIVING *ERROR IF #VALUE <> ' ' /* Value found ... ELSE 
/* Value not found ... END-IF

値を受け取るために指定するフィールドのフォーマットは、格納する値のフォーマットとの MOVE での互換性が必要であることに注意してください。

指定したダイアログエレメントに対して指定したキーが見つからない場合、値フィールドは RESET されます。 例えば、英数字フォーマットの受け取りフィールドは空白で充填され、数値フォーマットの受け取りフィールドはゼロに設定されます。

ただし、このような値はプログラムで明示的にキーに対して設定できますが、この値のみを使用して必要なクライアントデータが見つかったかどうかを判断することはできません。

Start of instruction setリセットされた値が明示的に格納されている場合にクライアントデータをクエリするには

例:

DEFINE DATA LOCAL 01 #VALUE (A253) 01 #FOUND (L) ... END-DEFINE * PROCESS GUI 
ACTION GET-CLIENT-VALUE WITH #LB-1 #VALUE 'ANYKEY' #FOUND GIVING *ERROR * IF #FOUND 
... END-IF

GET-CLIENT-VALUE アクションを使用してクライアントデータを読み込む主な利点もやはり、CLIENT-VALUE 属性を使用する場合と異なり、属性バッファを介さない(前述の図を参照)、つまり、英数字(A253)フォーマットとの中間的な変換を行う必要がないという点です。 代わりに、格納されているデータは値を受け取るフィールドのフォーマットに直接変換されます。 これにより、以下の利点がもたらされます。

また、空白のみで構成される、格納する英数字値を認識できます。 CLIENT-VALUE 属性では、この値と暗黙的な "データなし" 値とを区別できないため、この属性経由では実行できません。

Start of instruction setアクションベースの手法を使用して、ダイアログエレメントのクライアントデータを削除するには

例:

/* No value supplied => delete any existing value for specified key PROCESS GUI 
ACTION SET-CLIENT-VALUE WITH #LB-1 1X 'ANYKEY' GIVING *ERROR /* Alternatively, 
a mixed attribute/action approach can be used: #LB-1.CLIENT-KEY := 'ANYKEY' PROCESS 
GUI ACTION SET-CLIENT-VALUE WITH #LB-1 GIVING *ERROR

Top of page

キーの列挙

これまでのセクションでは、クライアントキーおよびクライアント値データの作成、更新、クエリ、および削除について説明してきました。 ほとんどの場合はこれで十分です。 ただし、場合によっては、ダイアログエレメントで使用されているキーを読み込むコード側でそのキーが認識できない場合や、デバッグやテストで想定されるキーの検証が必要な場合があります。 特定のダイアログエレメントで現在使用されているキーを取得する繰り返しのプロセスを、キーの列挙と呼びます。

Start of instruction setダイアログエレメントのクライアントキーを列挙するには

  1. ENUM-CLIENT-KEYS アクションを呼び出し、キーパラメータは省略して、クライアントキーを列挙するダイアログエレメントのハンドルを渡します。 これにより、ダイアログエレメントの列挙カーソル(つまり、位置)が内部キーリストの先頭にリセットされます。 列挙カーソルはダイアログエレメントが作成されるときに初期化されるため、ダイアログエレメントに対する最初のキーの列挙では、この手順は厳密には必要ありません。 ただし、状況に関係なく列挙できるようにするために、このようにカーソルを明示的にリセットするのはよい習慣です。

  2. ENUM-CLIENT-KEYS アクションを再度呼び出し、ダイアログエレメントのハンドル、および返される最初のキー(存在する場合)を受け取るキーパラメータを渡します。

  3. 上記の呼び出しによって、キーフィールドが内部的に空白に RESET される場合、これはそれ以上キーが残っていないことを意味するため、プログラムは列挙プロセスを終了する必要があります。

  4. そうでない場合、手順 2 に戻って次のキー(存在する場合)を取得します。

例:

 /* Enumerate and output all client keys in use by 
control #LB-1: /* (1) Reset enumeration cursor: PROCESS GUI ACTION ENUM-CLIENT-KEYS 
WITH #LB-1 GIVING *ERROR /* (2) Enumerate and delete the keys one-by-one: REPEAT 
PROCESS GUI ACTION ENUM-CLIENT-KEYS WITH #LB-1 #LB-1.CLIENT-KEY GIVING *ERROR 
IF #LB-1.CLIENT-KEY <> ' ' RESET #LB-1.CLIENT-VALUE /* delete the key END-IF WHILE 
#LB-1.CLIENT-KEY <> ' ' END-REPEAT

この例は、列挙プロセス中にキーが削除されても ENUM-CLIENT-KEYS アクションは対応可能であることを示しています。 この例のように、最後に列挙された、つまり "現在の" キーが削除されると、Natural によって自動的に、内部の列挙カーソルがそのキーの前の列挙シーケンスに移されるか、または先行するキーがない場合はリセットされます。 どちらの場合も、ENUM-CLIENT-KEYS によって返される次のキーは、前のキーが削除されなかった場合に返されるキーと同じキーになります。

注意:
キーが列挙されるシーケンスは実装に依存しているため、将来の Natural のバージョンで同一である保証はありません。 したがって、特定の列挙シーケンスに依存するようなコードをプログラムに記述しないようにしてください。

Top of page