formの値を別のformに渡す

解決


deldel  2009-04-17 23:03:26  No: 34028

はじめまして、宜しくお願い致します。
form間の値渡しで質問です。
たとえばform1のedit1に入力した値をform2で受け取り、
form2で別のボタンをクリックした時にその値を使って
form2のedit2と比較したいのですが
どうすればいいでしょうか?

調べたところ、useにunit名を追加すれば使えるとのことですが
できませんでした。

初歩的な事だと思いますので、簡単なキーワードでも結構です。
ご教授お願い致します。


はて  2009-04-17 23:18:49  No: 34029

どう記述してできませんでしたか?


はて  2009-04-17 23:27:21  No: 34030

form1の値を参照するのであれば、form1のインスタンスが必要。
単純に usesにunit1を追加したら使えるというものではない。

ただし、通常は自動生成されるフォームのため、グローバル変数が
宣言されていることから、usesするだけで参照することは可能。
implementation の上のほうに以下のような記述あるでしょう?

var
  Form1: TForm1;

したがって、unit1をusesに追加しておけば、form2から、
form1.Edit1.Text のように参照可能である。


はてはて  2009-04-17 23:52:57  No: 34031

deldel(3号?)さん、初投稿のようですが...
↑こういう名前は誰でも思いつくようで^^; もっとユニークなものに変えた方がいいかと。
https://www.petitmonte.com/bbs/answers?question_id=3953

>form2で別のボタンをクリックした時にその値を使って
>form2のedit2と比較したいのですが

>調べたところ、useにunit名を追加すれば使えるとのことですが

自分で追加しなくても、form2のedit2のクリックイベントで、
 if Form1.Edit1.Text = Edit2.Text then ShowMessage('同じ');
とか書けば、コンパイル時か実行時に「Form1への参照を追加する」とかいう
問い合わせがあって、自動的に usesのコードがソースに書き加えられるはずだけど。


deldel3号かもしれない  2009-04-18 00:14:28  No: 34032

ちょっぴり名前変えました。指摘ありがとうございます。
コードですがform1は
unit1(form1)にはeditボタンを用意して
その入力したものを数値に変換ということで下記

abcd := Edit1.Text;
  efgh := StrToInt(abcd);

その数値をunit2(form2)で利用して比較するためにedit2を作成する
ということでform2のコードは下記となります

uses unit1;
procedure TForm2.btnClick(Sender: TObject);
var
  form1:Tform1;
ijkl := Edit2.Text;
  mnop := StrToInt(ijkl);
if (mnop= efgh) then 処理  

こんな感じですが、このunit2の箇所まで進むとコンパイルエラーで
未定義の識別子efghと出ます。


Delphi大好き  2009-04-18 00:42:02  No: 34033

はてはてさんと同意見です。
ただ自分はまだまだ初心者ですが^^;

ユニットを参照する時Usesは、implementationの下に書きます。
こうすると、循環参照エラーは出ません。

ファイル→ユニットを使う  で、自動で追加されます。

あるいは、はてはてさんのご指摘されたように、
コード補完を利用して、実行ボタンを押して、
全自動で追加するか、になると思います。

以下は自分が試しに書いたサンプルです

implementationからコピペします。

//ユニット1
implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  form2.Show;
end;

//ユニット2
implementation

uses Unit1;

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
  if Form1.Edit1.Text = form2.Edit1.Text then
    caption := '一致しました'//(elseの前に、;をつけるとエラーになります)
  else  //でなければ
    caption := '一致しませんでした';
end;


Delphi大好き  2009-04-18 01:26:54  No: 34034

書き込みすれ違いでしたね^^;
数値で比較されるんですね?
deldel3号かも知れないさんのと、同じ変数名で書いてみました。

//ユニット1
var
  Form1: TForm1;
  abcd:string;
  efgh:integer;
implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  try//もし以下のコードにエラーがあれば (edit1が数値でなければ)
    abcd := edit1.Text;//edit1の中身を変数abcdに代入
    efgh := strtoint(abcd);//abcdの中身をInteger変数efghに代入
    //efgh := strtoint(edit1.text);//でも大丈夫ですよ^^
    form2.Show;
  except//もしエラーなら
    caption := '数値を入力してください';
  end;
end;

//ユニット2
var
  Form2: TForm2;

implementation

uses Unit1;

{$R *.dfm}

procedure TForm2.btnClick(Sender: TObject);
var
  ijkl:string;
  mnop:integer;
  //↑で宣言した変数はブロック(begin  end;間)内でしか使えません
begin
  try//もし以下にエラーがあれば(edit1が数値でなければ)
    ijkl := form2.Edit1.Text;//判りやすくする為にform2をつけてみましたそのままedit1.textでも大丈夫です。
    mnop := strtoint(ijkl);
    //mnop := strtoint(form2.edit1.text);//でも大丈夫ですよ
    if efgh = mnop then
    begin
      //一致した場合ここが実行されます
      caption := '一致しました';
    end else begin
      //一致しなかった場合ここが実行されます
      caption := '一致しませんでした';
    end;
  except//もしエラーなら
    caption := '数値を入力してください';
  end;
end;

になります。
どうでしょうか?


deldel3号かも知れない  2009-04-18 02:29:49  No: 34035

はてはてさん、Delphi大好きさん本当に返信ありがとうございます。
ただ、まだ未解決です・・・。
変数の値を調べたところ、edit1のプロパティのtextに
4と入れているのでunit1の段階でabcd := edit1.Textのabcdには
文字列4が入ってほしいのですが、実際は空白が入っています。
これはtextに入れたものはabcd := edit1.Textという
書き方では4を返すのに間違った記述なのでしょうか?


Delphi大好き  2009-04-18 05:01:50  No: 34036

問題は、どこで、何のコードが、変数を空白にしてしまうかですね。
代入の文法は間違っていないかと思いますよ?

あと、変数を他のUnitで使用するには?  の、
グローバル変数は専用ユニットに  さんの変数管理法を、
参考にしてみてはどうでしょうか?
これは自分も勉強させていただきました。
自分が先ほど書いた例には活かされて無いですが^^;;

試しに、
以下のタイマーを埋め込んではどうでしょうか?

var
  Form1: TForm1;
  abcd:string='0';//試しに最初から0を入れてみる
  efgh:integer=0;
...

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  //これなら、どこで、何が動いて空白にされるか、解り易いと思います。
  //Formの適当なところに、Timerイベントを作って以下を埋め込んでみてはどうでしょうか?。
  //beepが少しうるさいですが^^;
  //何かの参考になるかも知れません。
  if abcd = '4' then
    windows.Beep({音域}700,{長さ}300);
  if abcd = '' then
    windows.Beep(500,300);
  if abcd = ' ' then
    windows.Beep(500,300);
  if abcd = '0' then
    windows.Beep(400,300);

  form1.caption := 'abcd' + abcd +' ' + 'efgh' + inttostr(efgh);
  form2.caption := 'abcd' + abcd +' ' + 'efgh' + inttostr(efgh);
end;


通りすがり  2009-04-18 07:05:19  No: 34037

変数宣言を、両方のユニットに記述している予感・・・


みんみん  2009-04-18 09:01:58  No: 34038

>こんな感じですが、このunit2の箇所まで進むとコンパイルエラーで
>未定義の識別子efghと出ます。

if (mnop= efgh) then 処理を

if (mnop= Form1.efgh) then 処理
         ~~~~~~
に変えてみたらどうなりますか?


deldel3号かも知れない  2009-04-20 03:31:30  No: 34039

>>みんみんさん
[DCC エラー] FORM1.PAS(529): E2003 未定義の識別子 : 'efgh'となりました。
次はDelphi大好きさんを参考にさせていただいて試してみます。


deldel3号かも知れない  2009-04-20 03:38:54  No: 34040

>>とおりすがりさん
変数宣言というのはabcd:stringやefgh:integerの部分ですよね?
Unit1で
var
  Form1: TForm1;
  abcd:string;
  efgh:integer;
implementation
の箇所しかしていません。Unit2ではif (mnop= efgh) then  の箇所にしか
efghは使用していません。


deldel3号かも知れない  2009-04-20 03:48:00  No: 34041

すみません。unit2でuseにunit1を宣言していませんでした。
ただ宣言したところコンパイルで[DCC エラー] UNIT2.PAS(15): F2047 'Unit2' の循環参照エラー
とでました。


deldel3号かも知れない  2009-04-20 04:08:27  No: 34042

何度も連続での書き込み申し訳ないです。
このusesはどちらのunitにimplementationの上と下で2箇所
もとから記述があるのですが、場所は関係あるのでしょうか?
どちらも下に記述すると[DCC エラー] FORM1.PAS(529): E2003 未定義の識別子 : 'efgh'となり、
unit2でimplementationの上に記述すると[DCC エラー] UNIT2.PAS(15): F2047 'Unit2' の循環参照エラーとなるようです。

教えていただいたunit1、unit2ともにimplementationの下にusesを書いた際のエラーが[DCC エラー] UNIT2.PAS(529): E2003 未定義の識別子 : 'efgh'
であるのでグローバル変数の宣言がうまくいってないのだと自分では
考えていますがどうでしょうか?


Delphi大好き  2009-04-20 20:12:53  No: 34043

自分の場合ですが…。
コンパイラがご機嫌斜めでうまくいかない時・・・。

Delphiを二つ起動して、
ひとつを今開発している、うまくいかないソフト、
もうひとつを、不調と思われる部分を切り出したサンプル、

これを同時に編集し、色々試します。
そしてサンプルが成功したら、
メインと色々比較して違いを確かめます。

自分の場合ですが、
これで結構便利にやってます^^。

もしかするとそれが普通なのかもですが^^;

最悪、サンプルにメインのを移植して解決事する事も度々です^^;

直接のアドバイスではなくてごめんですが^^;

色々な参考書にも書かれているのですが、
コードの可読性の高い記述法、
これが、メンテナンスを含めたソフトを作るうえで、大切だそうです。
思わぬところにバグが潜んでしまうからだそうです。

参考になれば幸いです。
因みに自分も中々耳が痛い言葉です^^;


deldel3号かも知れない  2009-04-20 20:36:27  No: 34044

みなさん、ありがとうございました。
解決しました。方法としてはこういった形に
なります
unit2でif (mnop= efgh) then 処理を修正して

abcd:form1.Edit1.Text;
efgh:=StrToInt(abcd);
if (mnop= Form1.efgh) then 処理でうまくいきました。

みなさんの回答を元にコンパイルをいろいろ試して、
たどり着けました。とてもたすかりました。ありがとうございました。

うまくいかなった理由ですが、別のunitにedit5があったから
だと推測してます。


deldel3号かも知れない  2009-04-21 05:58:54  No: 34045

一応解決とさせていただきます。


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

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






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