フォーム間でのコントロール情報を受渡したいです。
VBで以下のような処理をデルファイで行おうとするとどういう処理に
なるのでしょうか?
VB例
Form1.text1.text = Form2.text2.text
↓ デルファイも同様に
TForm1.edit1.text := TForm2.edit2.text;のような感じでテキストの情報を
受け渡したい。
上記の通りでできます。
できないのなら、Unit2のimplementationより下に
uses Unit1;を追加してください。
ファイルからユニットの追加で簡単に追加できます。
ちょっと不親切でした。
//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節にそれぞれ追加すると循環参照のエラーになりコンパイ
ルできません。
注意が必要です。
返答ありがとうございます。
エディタ上で参照ができたのですが、実行時に上記参照設定処理に来ると
「参照できない値です。」と出ます。これは、コントロール等に何か
参照領域がついていて領域外の参照だからエラーが出ているのでしょうか?
コントロール毎に参照領域を設定する必要があるのでしょうか?
こんにちは、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.
コントロール毎に参照設定の必要はありません。
uses節に参照先のユニット名を記述すれば
コントロールには単純にアクセス出来ます。
Unit2→Unit1なら
Form1.Edit1.Text := Edit1.Text;
てな感じですが。
何でエラーになっているかは、コードを提示
されないと不明です。
ソースですが下記のような形です。
//ユニット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様、プロパティの方も試してみます。どちらかというと、なるべくコーディング
しない方向を考えています。
>//ユニット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;
これはちょっと・・・
>//ユニット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;
これはちょっと・・・
すいません。
前述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
やってみてください。
それと、もしかして
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;
が、原因だと思いますが。
念の為・・・
リョウさんのソースでは、両方のユニットの implementation の直前の
インスタンス宣言がないので、どのユニットからでも From1 と From2 は
参照できません。なぜ、デフォルトで宣言されているモノを削除しているのか
理解に苦しみます。また、From1 や From2 などはデフォルトの Form1 や
Form2 などと紛らわしいのでそんなクラスの型を作らないようにしてください。
すみません、掲示板への書き込みミスです。
>//ユニット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を使用し載せました。ですが、教えてもらう
ために表記に誤りがあるものを載せてしまい大変申し訳ありませんでした。
うーん、簡単なPGで組みなおしたら参照できました。
作成中のものを見直してみます。
いろいろと意見ありがとうございました。
原因が分かりました。フォームはそれぞれ、自動作成の対象ではありません。
それで、それぞれ、ボタンクリック時にFrom1,From2を表示し、それぞれの
コントロールの値を参照しようとすると参照エラーになりました。
それぞれのフォームインスタンスが何故かnilになっているのが原因でした。
最初から自動作成の対象でないと駄目みたいでした。
>それで、それぞれ、ボタンクリック時にFrom1,From2を表示し、それぞれの
>コントロールの値を参照しようとすると参照エラーになりました。
参照するときに、例えば Unit1 の implementation の直前のインスタンス宣言
var
From1:TForm1;
となっていて、このフォームをつくるときにちゃんと From1 にインスタンス参照
を代入していますか?
From1 := TFrom1.Create(Application);
のように。
>それぞれのフォームインスタンスが何故かnilになっているのが原因でした。
上記のようにインスタンス参照を代入していないのではないのですか?
>最初から自動作成の対象でないと駄目みたいでした。
そんなことはありません。同時に表示されていて、インスタンス参照がきちんと
設定されていれば、いつでもアクセスできます。
ご指摘どおりです。おさがわせしました。
From1 := TFrom1.Create(Application);
上記処理で、代入していませんでした。
ありがとうございました。
ツイート | ![]() |