初歩的な事かもしれませんが...
入力フォームで入力や処理を行います。入力フォームは複数のフォームから呼び出されます。
このとき、入力フォームの処理結果を、呼び出したフォームに渡すにはどうすればいいのでしょうか。
ShowModal で呼び出したなら、呼び出した方が自分をしっているのでは?
Show で呼び出すのなら、呼び出す前に、自分をセットできるようなプロパティーなり、フィールド変数なりをつけておけばいい。
ShowModal で呼び出したなら、ModalResultで判断すればどうでしょうか?
ちょっと質問が、何をするのか分かり難いので、もう少し詳しくしてください。
皆様方、解答ありがとうございます。補足させて頂きますね。
ちょっとした業務アプリを作っているのですが、データの入力に関しては、全ての項目を保持したウィザード風の専用入力フォームを作ります。
項目名を、仮に{郵便番号、都道府県、市町村、市町村コード}とします。
なお、項目とありますが、データベースではありません。
「データを入力する」という局面がいくつかのフォームで必要であり、そのフォーム毎に入力フォームを作るのは大変なので共通の入力用フォームを呼び出して使おう、としています。
しかし、Aフォームでは{郵便番号、都道府県、市町村}だけ、Bフォームでは{郵便番号、都道府県、市町村コード}だけ必要というような場合、呼び出し側フォームから入力フォームを呼び出し、入力フォームでOKボタンを押下したときに呼び出し側フォームに必要な項目値のみを返す、ということを(最終的には)実現したいのです。
できれば、呼び出し側に応じて、入力フォームの不要な項目は利用不能になるようにもしたいです。
これでよろしいでしょうか。
自分も似たアイデア使ったソフト(現場写真管理ソフトウェア、ですが^^;)作りました
共通のフォームは作りませんでしたが^^;
今度自分もそのアイデアを試してみたいと思います。
booleanか、スイッチ代わりの変数を用意して、
(例えばsw:integer;を使ったとして、)
sw=1; //フォーム1からの呼び出しスイッチ、
sw=2; //フォーム2からの呼び出しスイッチ、・・・
等と、変数でフォームの種類を認識させるのはどうでしょうか??
自分はよくこうしてます。
入力フォームは全てのフォームに対応したものを作り、
if sw=1 なら、フォーム1用コンポーネント以外は非表示、
if sw=2 なら、フォーム2用コンポーネントは非表示、・・・
というのはどうでしょうか??
あるいは、簡単に表示非表示を切り替えられるように、
パネルを数枚配置して、
その上に各フォーム向けのインターフェースを作る、
というアイデアはどうでしょうか??
自分はよくそうしてます。
それと具体的なコードなくてすいません^^;
呼び出された方から「データを渡す」というよりは、
入力用フォームの方にpublicなプロパティなりフィールドなりを用意しておいて
呼び出し側のフォームで「データを取り出す」という作りが一般的だと思います。
ポイントは、ダイアログを閉じてもFreeするまではフィールドにアクセスできるということです。
例:
【入力用フォーム側】
type
TData = record
郵便番号, 都道府県, 市町村: String;
end;
TFormB = class(TForm)
...
public
処理結果: TData;
使うフィールド: set of (郵, 都, 市);
...
function ShowModal: Integer; override; // ShowModalをオーバーライドする
end;
function TFormB.ShowModal: Integer;
begin
// 表示前の処理
if 郵 in 使うフィールド then 「郵便番号」を表示
if 都 in 使うフィールド then 「都道府県」を表示
if 市 in 使うフィールド then 「市町村」を表示
// 元のShowModalを実行
Result := inherited ShowModal;
// 必要に応じて処理結果を取り出す。フォーム内の各イベントで個別にやってもよい
処理結果.郵便番号 := 「郵便番号」の入力
処理結果.都道府県 := 「都道府県」の入力
処理結果.市町村 := 「市町村」の入力
end;
【呼び出す側】
var
B: TFormB;
Data: TData;
begin
B := TFormB.Create(Self);
try
// 先に必要な情報を設定
B.使うフィールド := [郵, 都]; // 郵便番号と都道府県だけ表示
// 表示する
if B.ShowModal <> mrOk then Exit;
// 結果を取り出す
Data := B.処理結果;
finally
B.Free;
end;
end;
入力フォームの Public 宣言 で変数を定義すれば
どのFormからも使用できますが。
ShowModal メソッドは,結果を返しますから、
function ShowModal: Integer; virtual;
ボタンのModalResultで判断できます。
結果が、「OKボタン」ModalResult=mrOKの場合、フォームの入力値を
参照すれば良いのではないでしょうか?
if MyDialogBox.ShowModal = mrOK then //フォームをModal表示する。
Beep;
私は、初心者的ですが以下で実装しています。
親FormのPublicに
入力Form用の表示のためのFLGとして
Input_FLG:Integer
データ渡し用の変数
Zip_Code,ToDouFuKen,ShiCyouSon など :String
を定義しておき、
元Formでの呼び出し前に全ての変数を初期化し
Zip_Code := ''; など
入力Formは動的に作成した上で
入力FormのOnCleateにてFLGで判断して必要なコンポーネントを配置します。
入力FormのCloseの前に
Zip_Code,ToDouFuKen,ShiCyouSon など にデータをセットします。
これで目的は十分達成しています。
formBにプロパティを追加すると、フィールドが増えたときに
プロパティの新設が(個人的に)めんどくさいので、全ての
フィールドの値を持ったクラス(TInfo)を定義して、
それを渡して処理します。
Type
//表示するフィールドを選択するための列挙型を準備
TEditField=(ef郵便番号, ef都道府県, ef市町村, ef市町村コード);
TEditFields = set of TEditField;
TInfo=class
EditFields :TEditFields;
郵便番号: String;
都道府県: Integer;
市町村: String;
市町村コード: Integer;
end;
TFormB
public
function Execute(Info: TInfo): Boolean;
end;
【入力フォーム側】
//ModalResult = mrOK となるボタンを配置します
function TFormB.Execute(Info: TInfo): Boolean;
begin
// 表示前の処理
if ef郵便番号 in Info.EditFields then begin
Edit郵便番号.Enavled := True;
Edit郵便番号.Text := Info.郵便番号;
end;
if ef都道府県 in Info.EditFields then begin
Edit都道府県.Enavled := True;
Edit都道府県.Text := IntToStr(Info.都道府県);
end;
//略
//フォームを表示して編集する
Result := ShowModal = mrOK;
//処理結果を編集する
if Result then begin
if ef郵便番号 in Info.EditFields then begin
Info.郵便番号 := Edit郵便番号.Text
end;
if ef都道府県 in Info.EditFields then begin
Info.都道府県 := StrToInt(Edit都道府県.Text);
end;
end;
end;
【呼び出し側】
var
frm: TFormB;
info: TInfo;
begin
frm := TFormB.Create(Self);
info := TInfo.Create;
try
//編集するデータ・フィールドを設定
info.EditFields := [ef郵便番号, ef都道府県, ef市町村];
info.郵便番号 := '123-4567';
info.都道府県 := 9999;
info.市町村 := 'どこかの県';
//表示
if frm.Execute(info) then begin
//編集結果を確認
ShowMessage('郵便番号は' + info.郵便番号 + 'です');
end
else begin
ShowMessage('中断しました');
end;
finally
frm.Free;
info.Free;
end;
end;
他のフォームのコンポーネントの参照方法がわからないぽいけど?
Form2.Edit1.Visible := False;
S := Form2.Edit1.Text;
TForm2 = class(TForm)
private
public
A: Integer;
end;
publicに設定してある変数なら
Form2.A := 100;
I := Form2.A;
で可能
皆さん、どうもありがとうございました。publicを参照する様にしてとりあえず解決しました。
ShowModalにそういう使い方があるのは知りませんでしたので、もっと勉強します。
本当にありがとうございました!
ツイート | ![]() |