フォーム間でのコントロール情報の渡し方

解決


リュウ  2004-08-23 23:19:55  No: 10506

フォーム間でのコントロール情報を受渡したいです。
VBで以下のような処理をデルファイで行おうとするとどういう処理に
なるのでしょうか?

VB例
Form1.text1.text = Form2.text2.text
      ↓  デルファイも同様に
TForm1.edit1.text := TForm2.edit2.text;のような感じでテキストの情報を
受け渡したい。


Syake  2004-08-24 00:27:44  No: 10507

上記の通りでできます。
できないのなら、Unit2のimplementationより下に
uses Unit1;を追加してください。
ファイルからユニットの追加で簡単に追加できます。


Syake  2004-08-24 00:39:05  No: 10508

ちょっと不親切でした。

//Form1は・・・
implementation

uses Unit2;//参照先のユニット名(Form2)

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
   Form2.Show;  //uses節にForm2のユニット名Unit2の記述が無いと
                //参照できないのでコンパイルできないし表示でき
                //ない。
end;

//Form2は・・・
implementation

uses Unit1;//参照先のユニット名(Form1)

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
  Form1.Edit1.Text := Form2.Edit1.Text;
        //これも同じでuses節にForm1のユニット名が無いと
        //Form1のコンポーネントは参照できないのでエラーになる。
end;

といった感じです。

ちなみに、interface  の下にもuses節があります。
使っても良いですが、上記のケースで両方をinterfaceの下の
uses節にそれぞれ追加すると循環参照のエラーになりコンパイ
ルできません。
注意が必要です。


リュウ  2004-08-24 02:55:33  No: 10509

返答ありがとうございます。

エディタ上で参照ができたのですが、実行時に上記参照設定処理に来ると
「参照できない値です。」と出ます。これは、コントロール等に何か
参照領域がついていて領域外の参照だからエラーが出ているのでしょうか?
コントロール毎に参照領域を設定する必要があるのでしょうか?


bob  2004-08-24 03:12:15  No: 10510

こんにちは、bobです。

個人的にはDelphiなら、プロパティ使った方が良いと思いますが...
#ちなみに僕はVB6でもプロパティで受け渡すようにしています。

---Unit1.pas
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
Var
  Form2: TForm2;
begin
  form2 := TForm2.Create(self);
  try
    form2.Edit := Edit1;
    form2.ShowModal;
  finally
    form2.Free;
  end;

end;

end.

---Unit2.pas
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm2 = class(TForm)
  private
    { Private 宣言 }
    FEdit: TEdit;

    procedure SetEdit(Value: TEdit);
  public
    { Public 宣言 }
    property Edit: TEdit write SetEdit;
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

{ TForm2 }

procedure TForm2.SetEdit(Value: TEdit);
begin
  FEdit := Value;
  self.Caption := FEdit.Text;
end;

end.


Syake  2004-08-24 03:29:18  No: 10511

コントロール毎に参照設定の必要はありません。
uses節に参照先のユニット名を記述すれば
コントロールには単純にアクセス出来ます。
Unit2→Unit1なら
Form1.Edit1.Text := Edit1.Text;
てな感じですが。

何でエラーになっているかは、コードを提示
されないと不明です。


リュウ  2004-08-24 04:12:32  No: 10512

ソースですが下記のような形です。

//ユニット1

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids, DBGrids, DB, ADODB, OleCtrls,QDialogs,
  MSScriptControl_TLB;

type
  TFrom1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;

    procedure Button1Click(Sender: TObject);
  
 
  private
    { Private 宣言 }    
  public
    { Public 宣言 }
 
  end;

var

implementation

{$R *.dfm}

uses Unit2;

procedure From1.Button1Click(Sender: TObject);
var a:string;
begin

  From2.Edit1.Text := Edit1.Text;
  //もしくは
  Edit1.Text:='A';
end;

//ユニット2

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids, DBGrids, DB, ADODB, OleCtrls,QDialogs,
  MSScriptControl_TLB;

type
  TFrom2 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;

    procedure Button1Click(Sender: TObject);
  
 
  private
    { Private 宣言 }    
  public
    { Public 宣言 }
 
  end;

var

implementation

{$R *.dfm}

uses Unit1;

procedure From1.Button1Click(Sender: TObject);
var a:string;
begin

  Edit1.Text :=From1.Edit1.Text;
  //もしくは
  a:=From1.Edit1.Text;

end;

Form1でForm2のコントロールに直接データを渡した後、次のForm2でデータを
取り扱う形になるのでしょうか?
Form2で直接、Form1のコントロールの値を参照は出来ないのでしょうか?
bob様、プロパティの方も試してみます。どちらかというと、なるべくコーディング
しない方向を考えています。


Syake  2004-08-24 04:47:17  No: 10513

>//ユニット1
>implementation
>{$R *.dfm}
>uses Unit2;
>procedure From1.Button1Click(Sender: TObject);
>var a:string;
>begin
>  From2.Edit1.Text := Edit1.Text;
これだけで良いです。
>  //もしくは
>  Edit1.Text:='A';
//これは無し
>end;
既にForm2が開いていたらOKのはずです。
開いていないならFrom2.Show;を
From2.Edit1.Text := Edit1.Text;

>//ユニット2
>procedure From1.Button1Click(Sender: TObject);
>var a:string;
>begin
>  Edit1.Text :=From1.Edit1.Text;
>  //もしくは
>  a:=From1.Edit1.Text;
>end;
これはちょっと・・・


Syake  2004-08-24 04:47:17  No: 10514

>//ユニット1
>implementation
>{$R *.dfm}
>uses Unit2;
>procedure From1.Button1Click(Sender: TObject);
>var a:string;
>begin
>  From2.Edit1.Text := Edit1.Text;
これだけで良いです。
>  //もしくは
>  Edit1.Text:='A';
//これは無し
>end;
既にForm2が開いていたらOKのはずです。
開いていないならFrom2.Show;を
From2.Edit1.Text := Edit1.Text;

>//ユニット2
>procedure From1.Button1Click(Sender: TObject);
>var a:string;
>begin
>  Edit1.Text :=From1.Edit1.Text;
>  //もしくは
>  a:=From1.Edit1.Text;
>end;
これはちょっと・・・


Syake  2004-08-24 05:02:29  No: 10515

すいません。
前述2件操作間違えて送信してしまいました。
>//ユニット1
(略)
>implementation
>{$R *.dfm}
>uses Unit2;
>procedure From1.Button1Click(Sender: TObject);
>var a:string;
>begin
>  From2.Edit1.Text := Edit1.Text;
これだけで良いです。
Form2のEditに値が送られます。
>  //もしくは
>  Edit1.Text:='A';
とするなら Form2.Edit1.Text := 'A'; です。
>end;
既にForm2が開いていたらOKのはずです。
開いていないなら
From2.Edit1.Text := Edit1.Text;
From2.Show;
と続けて記述してみてください。

>//ユニット2
(略)
>
>procedure From1.Button1Click(Sender: TObject);
>var a:string;
>begin
>  Edit1.Text :=From1.Edit1.Text;
>  //もしくは
>  a:=From1.Edit1.Text;
>end;
Unit1の記述でうまくいくはずですので、上記の記述は不要です。
また、この場合Unit2にForm1のイベントを記述しても意味はありません。

Form2で単純にForm1の値が参照したいのなら
From2にTButtonを追加してから、Form2.Button1Clickのイベントで
  Edit1.Text := Form1.Edit1.Text;
で取得できます。
この場合は、Unit1での値のやり取りの記述は不要になると思いますが・・・

どうもボキャブラリーに乏しいのでうまく説明できませんm(__)m
やってみてください。


Syake  2004-08-24 05:42:29  No: 10516

それと、もしかして
Form2にButtonのコンポーネントを貼り付けず
>type
>  TFrom2 = class(TForm)
>    Edit1: TEdit;
>    Button1: TButton; //←ここ
>    procedure Button1Click(Sender: TObject);//← ここ
>  private
>    { Private 宣言 }    
>  public
>    { Public 宣言 }
>  end;
な、記述をしてもだめです。

Form2にButtonを貼り付けて、そのOnClickイベントで
  =(略)=
TFrom2 = class(TForm)
    Edit1: TEdit;
    Button1: TButton; 
    procedure Button1Click(Sender: TObject);
=(略)=
implementation
{$R *.dfm}
uses Unit1;

procedure TForm2.Button1Click(Sender: TObject);
begin
    Edit1.Text := Form1.Edit1.Text;
end;
としないと駄目です。

前述のエラーは
>//ユニット2
(略)
>
>procedure From1.Button1Click(Sender: TObject);
>var a:string;
>begin
>  Edit1.Text :=From1.Edit1.Text;
>  //もしくは
>  a:=From1.Edit1.Text;
>end;
が、原因だと思いますが。
念の為・・・


jok  2004-08-24 06:25:19  No: 10517

リョウさんのソースでは、両方のユニットの implementation の直前の
インスタンス宣言がないので、どのユニットからでも From1 と From2 は
参照できません。なぜ、デフォルトで宣言されているモノを削除しているのか
理解に苦しみます。また、From1 や From2 などはデフォルトの Form1 や
Form2 などと紛らわしいのでそんなクラスの型を作らないようにしてください。


リュウ  2004-08-24 07:03:46  No: 10518

すみません、掲示板への書き込みミスです。

>//ユニット2
(略)
>>
>>procedure From1.Button1Click(Sender: TObject);
>>var a:string;
>>begin
>>  Edit1.Text :=From1.Edit1.Text;
>>  //もしくは
>>  a:=From1.Edit1.Text;
>>end;
>Unit1の記述でうまくいくはずですので、上記の記述は不要です。
>また、この場合Unit2にForm1のイベントを記述しても意味はありません。

はい、そうです。例として載せたソースの表記ミスです。すみません。

>>procedure From1.Button1Click(Sender: TObject);

の部分は

procedure From2.Button1Click(Sender: TObject);

です。

完全に書くと以下です。Syakeさんが最後に正しく訂正されているものと同じ。
//ユニット2
(略)

procedure From2.Button1Click(Sender: TObject);
var a:string;
begin
  Edit1.Text :=From1.Edit1.Text;
  //もしくは
  a:=From1.Edit1.Text;
end;

表示しているFrom1のEditコントロールの値をForm2で参照しようとすると
上記エラーになっています。

From1では
From1.Edit1.Text:='A';

From2では
a:=From1.Edit1.Text; ←ここで参照エラー

他フォームのコントロールのデータを上記みたいに参照できないのでしょうか?
必ず、自フォームでデータを受け渡すようにしないと駄目でしょうか?
けど、Syakeさんが最後に書かれたコーディングは同じ方法ですね・・・、うーん。

jokさん、すみません。実際、From1とか使用してコーディングをしてはいません。
ここで、簡単に具体例として、From1を使用し載せました。ですが、教えてもらう
ために表記に誤りがあるものを載せてしまい大変申し訳ありませんでした。


リュウ  2004-08-24 08:47:38  No: 10519

うーん、簡単なPGで組みなおしたら参照できました。
作成中のものを見直してみます。

いろいろと意見ありがとうございました。


リュウ  2004-08-24 09:06:56  No: 10520

原因が分かりました。フォームはそれぞれ、自動作成の対象ではありません。
それで、それぞれ、ボタンクリック時にFrom1,From2を表示し、それぞれの
コントロールの値を参照しようとすると参照エラーになりました。
それぞれのフォームインスタンスが何故かnilになっているのが原因でした。
最初から自動作成の対象でないと駄目みたいでした。


jok  2004-08-24 13:38:37  No: 10521

>それで、それぞれ、ボタンクリック時にFrom1,From2を表示し、それぞれの
>コントロールの値を参照しようとすると参照エラーになりました。

参照するときに、例えば Unit1 の implementation の直前のインスタンス宣言

var
  From1:TForm1;

となっていて、このフォームをつくるときにちゃんと From1 にインスタンス参照
を代入していますか?

From1 := TFrom1.Create(Application);

のように。

>それぞれのフォームインスタンスが何故かnilになっているのが原因でした。

上記のようにインスタンス参照を代入していないのではないのですか?

>最初から自動作成の対象でないと駄目みたいでした。

そんなことはありません。同時に表示されていて、インスタンス参照がきちんと
設定されていれば、いつでもアクセスできます。


リュウ  2004-08-24 21:16:47  No: 10522

ご指摘どおりです。おさがわせしました。

From1 := TFrom1.Create(Application);

上記処理で、代入していませんでした。
ありがとうございました。


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

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






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