ページサブフォームはカレントサブレコードのデータやコンテキストに基づく関連する値 (変数やピクチャーなど) を表示できます。ページサブフォームを使用する利点の一つは、上級機能を使用できるようになることであり、親フォームと直接に相互作用を行うことができるようになります。ページサブフォームには特別なプロパティやイベントがあり、プログラムから完全に制御することができます。
注: サブフォームを使用して追加の機能を提供するコンポーネントを生成できます。詳細は4Dコンポーネントの開発とインストール を参照してください。
サブフォームのページモードを有効にするには、プロパティリストの出力サブフォームのオプションのチェックを外します。この場合、リストサブフォームの設定に関連するプロパティ (選択モード、ダブルクリック時の動作等) は表示されなくなります:
ページサブフォームは"詳細フォーム"プロパティで指定されたフォームを使用します。リストサブフォームと異なり、使用されるフォームは親フォームと同じテーブルでもかまいません。またプロジェクトフォームを使用することもできます。実行時、ページサブフォームは入力フォームと同じ標準の表示特性を持ちます。リストフォームのメカニズム (マーカーの管理など) は無効になります。
親フォームへの統合と相互作用を容易にする特別なプロパティを使用してページサブフォームを管理します。
サブフォームオブジェクトに変数をバインドできます。デフォルトでこの変数名は"Subform"となっています。変数には型があり (後述) 親フォーム内で標準変数として表示できます。この変数を変更するとフォームイベントが生成され、親フォームとサブフォームの値を同期することができます:
On Data Change フォームイベントを使用して、サブフォーム内で変数値が変更されたことをサブフォームコンテナに値が変更されたことを通知できます。On bound variable change フォームイベントを使用して、親フォーム内で変数値が変更されたことをサブフォーム (サブフォームのフォームメソッド) に通知します。
このプロパティを使用して、サブフォームオブジェクトにバインドされる変数の型を指定できます。デフォルトで文字型に設定されています。変数タイププロパティは、この変数を通して親フォームとサブフォームの間で交換される値の性質を決定します。 タイプを"なし"に設定することもできます。この場合4Dは実行時に自動で型を決定しますが、コンパイル時に型指定エラーとなる点に留意してください (ランゲージリファレンスの変数 、"ダイナミック変数"参照)。
このプロパティでは異なるタイプのソースを選択できます:
<なし> : サブフォームとしてプロジェクトフォームやコンポーネントフォームを使用する場合に選択します。これらのサブフォームはページサブフォームでのみ利用できます。"出力サブフォーム"オプションが選択されているとこれらのフォームは使用できません。 コンポーネント内で公開されているコンポーネントフォームは"詳細フォーム"リストに表示されます (サブフォームを公開 (コンポーネント) 参照)。テーブル名 : テーブルフォームを使用するためにはこのオプションを選択します。
サブフォームオブジェクトにオブジェクトメソッドを記述し、(生成されるイベントに基づき) その機能を制御することができます。ページサブフォームにより管理されるイベントに関する説明はForm event コマンドの説明を参照してください。
特別なメカニズムを使用して、サブフォームオブジェクトの内容と親フォームの内容との相互作用を管理しなければならない点に留意してください (上級フォーム間通信プログラム 参照)。
サブフォームにバインドされた変数を使用して2つのコンテキスト (フォームとサブフォーム) をリンクし、洗練されたインターフェースを作成することができます。例えばサブフォームに時計を置くとします。サブフォームが置かれる親フォームには時間型の入力可変数が置かれています:
両オブジェクト (時間変数とサブフォームコンテナ) には同じ変数名が割り当てられています 。この場合、親フォームを開いたとき、4Dは自動で両方の値を同期化します。変数の値が複数の場所で設定されている場合、4Dは最後にロードされた値を使用します。以下のロード順が適用されます: 1-サブフォームのオブジェクトメソッド 2-サブフォームのフォームメソッド 3-親フォームのオブジェクトメソッド 4-親フォームのフォームメソッド
親フォームが実行されるとき、開発者は適切なフォームイベントを使用して変数ので同期を処理しなければなりません。2タイプの相互作用、親フォーム->サブフォーム、またはサブフォーム->親フォームが発生します。
ケース1: 親フォームの変数の値が更新され、この更新をサブフォームに反映させる必要があります。この例ではParis Time 変数の値がユーザー入力、あるいは動的に (例えばCurrent time コマンドで) 12:15:00に変更されています。
この場合On bound variable change フォームイベントを使用します。このイベントはサブフォームプロパティで選択されなければなりません。このイベントはサブフォームのフォームメソッドで生成されます。
On bound variable change フォームイベントは以下のときに生成されます:
親フォームの変数に値が割り当てられたとき (同じ値が代入された場合でも) で、 サブフォームが0ページまたはカレントフォームページにおかれているとき。 先の例のとおり、直接変数名ではなく、サブフォームコンテナへのポインターを返す OBJECT Get pointer コマンドの利用を推奨します。親フォームに同じサブフォームを複数配置することが可能だからです (例えば複数の時間帯を表示ために複数の時計を表示するウィンドウ)。この場合ポインターを使用することでのみ、どのサブフォームコンテナがイベントの生成元かを知ることができます。
ケース2: サブフォームの内容が更新され、その更新を親フォームに反映させる必要があります。この例ではユーザーが時計の針を手動で動かすことができるようなケースです。
この場合、サブフォームから、親サブフォームコンテナの変数にオブジェクトの値を割り当てなければなりません。先の例の通り、OBJECT Get pointer コマンドをObject subform container セレクターで使用し、サブフォームコンテナのポインターを得ることをお勧めします。
変数に値を割り当てると親サブフォームコンテナのオブジェクトメソッドでOn Data Change フォームイベントが生成され、メソッドによるアクションを実行できます。このイベントはサブフォームコンテナのプロパティリストで選択されていなければなりません。
注: 時計の針を手動で動かすと、サブフォーム中のclockValue 変数のオブジェクトメソッドでOn Data Change フォームイベントが生成されます。
親フォームとサブフォームインスタンス間の通信では、バインドした変数を通して値を交換する以上のことを行うこともできます。実際親フォームで行われたアクションに基づきサブフォーム中の変数を更新したり、またはその逆を行いたい場合があるでしょう。先の"動的な時計"タイプのサブフォームの例で言えば、各時計ごとにアラーム時刻を複数設定したい場合があります。
このようなニーズにこたえるため、4Dは以下のメカニズムを実装しています:
Object subform container セレクターに加え、OBJECT Get pointer コマンドは第二引数に指定した名前を持つオブジェクトを検索する際に、どのサブフォーム内を検索するか指定するための引数を受け入れます。このシンタックスはObject named セレクターが渡された場合のみ使用できます。
例えば以下の式は:
"MySubForm"サブフォームオブジェクト中の"MyButton"オブジェクトに割り当てられた変数へのポインターを返します。このシンタックスを使用すれば親フォームからサブフォーム内のオブジェクトにアクセスできます。 またOBJECT Get name コマンドを使用すればフォーカスを持つオブジェクトの名前を取得できます。
CALL SUBFORM CONTAINER コマンドを使用すると、サブフォームインスタンスからサブフォームコンテナオブジェクトにイベントを送信できます。その結果親フォームのコンテキストで処理が可能となります。イベントはコンテナオブジェクトメソッドで受信されます。(クリックやドラッグ&ドロップなど) サブフォームにより検知されたすべてのイベントの発生元となりえます。
送信するイベントコードに制限はありません (例えば20000や-100など)。既存のイベントに対応するコード (例えばOn Validate に対応する3) を使用することも、カスタムコードを使用することもできます。前者のケースでは、サブフォームコンテナのプロパティリストでチェックを入れたイベントのみを使用できます。後者の場合、使用するコードは既存のフォームイベントに対応してはいけません。将来の4Dバージョンで番号が衝突しないようにするために、負数を使用することをお勧めします。
詳細はCALL SUBFORM CONTAINER コマンドの説明を参照してください。
EXECUTE METHOD IN SUBFORM コマンドを使用するとフォームやオブジェクトから、(サブフォーム変数やオブジェクト等にアクセスできる) サブフォームインスタンスのコンテキストでメソッドの実行をリクエストできます。このメソッドは引数を受け取れます。
このメカニズムを図示すると以下のようになります:
詳細はEXECUTE METHOD IN SUBFORM コマンドの説明を参照してください。
GOTO OBJECT はサブフォームから実行されても、親フォームオブジェクトから目的のオブジェクトを検索します。