フォームを複数のユニットから利用するには?

解決


ぴーこ  2009-02-12 18:32:05  No: 33323

初歩的な事かもしれませんが...
入力フォームで入力や処理を行います。入力フォームは複数のフォームから呼び出されます。
このとき、入力フォームの処理結果を、呼び出したフォームに渡すにはどうすればいいのでしょうか。


うんと  2009-02-12 19:01:53  No: 33324

ShowModal で呼び出したなら、呼び出した方が自分をしっているのでは?

Show で呼び出すのなら、呼び出す前に、自分をセットできるようなプロパティーなり、フィールド変数なりをつけておけばいい。


HOta  2009-02-12 20:53:55  No: 33325

ShowModal で呼び出したなら、ModalResultで判断すればどうでしょうか?
ちょっと質問が、何をするのか分かり難いので、もう少し詳しくしてください。


ぴーこ  2009-02-12 22:10:57  No: 33326

皆様方、解答ありがとうございます。補足させて頂きますね。

ちょっとした業務アプリを作っているのですが、データの入力に関しては、全ての項目を保持したウィザード風の専用入力フォームを作ります。
項目名を、仮に{郵便番号、都道府県、市町村、市町村コード}とします。
なお、項目とありますが、データベースではありません。

「データを入力する」という局面がいくつかのフォームで必要であり、そのフォーム毎に入力フォームを作るのは大変なので共通の入力用フォームを呼び出して使おう、としています。

しかし、Aフォームでは{郵便番号、都道府県、市町村}だけ、Bフォームでは{郵便番号、都道府県、市町村コード}だけ必要というような場合、呼び出し側フォームから入力フォームを呼び出し、入力フォームでOKボタンを押下したときに呼び出し側フォームに必要な項目値のみを返す、ということを(最終的には)実現したいのです。
できれば、呼び出し側に応じて、入力フォームの不要な項目は利用不能になるようにもしたいです。

これでよろしいでしょうか。


delphi大好き  2009-02-12 23:08:20  No: 33327

自分も似たアイデア使ったソフト(現場写真管理ソフトウェア、ですが^^;)作りました
共通のフォームは作りませんでしたが^^;
今度自分もそのアイデアを試してみたいと思います。

booleanか、スイッチ代わりの変数を用意して、
(例えばsw:integer;を使ったとして、)
sw=1;  //フォーム1からの呼び出しスイッチ、
sw=2;  //フォーム2からの呼び出しスイッチ、・・・

等と、変数でフォームの種類を認識させるのはどうでしょうか??
自分はよくこうしてます。

入力フォームは全てのフォームに対応したものを作り、
if  sw=1  なら、フォーム1用コンポーネント以外は非表示、
if  sw=2  なら、フォーム2用コンポーネントは非表示、・・・

というのはどうでしょうか??

あるいは、簡単に表示非表示を切り替えられるように、
パネルを数枚配置して、
その上に各フォーム向けのインターフェースを作る、
というアイデアはどうでしょうか??

自分はよくそうしてます。
それと具体的なコードなくてすいません^^;


mix  2009-02-12 23:30:38  No: 33328

呼び出された方から「データを渡す」というよりは、
入力用フォームの方に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;


TS  2009-02-12 23:37:04  No: 33329

入力フォームの Public 宣言 で変数を定義すれば
どのFormからも使用できますが。


HOta  2009-02-12 23:41:58  No: 33330

ShowModal メソッドは,結果を返しますから、
function ShowModal: Integer; virtual;
ボタンのModalResultで判断できます。
結果が、「OKボタン」ModalResult=mrOKの場合、フォームの入力値を
参照すれば良いのではないでしょうか?

  if MyDialogBox.ShowModal = mrOK then  //フォームをModal表示する。
    Beep;


maru3  2009-02-13 01:06:02  No: 33331

私は、初心者的ですが以下で実装しています。
親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  など  にデータをセットします。

これで目的は十分達成しています。


ofZ  2009-02-13 02:41:49  No: 33332

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;


KHE00221  2009-02-13 05:33:54  No: 33333

他のフォームのコンポーネントの参照方法がわからないぽいけど?

Form2.Edit1.Visible := False;
S := Form2.Edit1.Text;

  TForm2 = class(TForm)
  private
  public
    A: Integer;
  end;

  publicに設定してある変数なら

Form2.A := 100;
I := Form2.A;

で可能


ぴーこ  2009-02-13 22:14:50  No: 33334

皆さん、どうもありがとうございました。publicを参照する様にしてとりあえず解決しました。
ShowModalにそういう使い方があるのは知りませんでしたので、もっと勉強します。

本当にありがとうございました!


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加