Delphi: Variablen weiterleiten

Hallo erstmal.

Also ich schreibe gereade an einem Program.
Dieses fragt nach einer Zahl und in der nächsten Form muss man so oft ok klicken, wie die eingegebene Zahl war.

Hier mein Code:

unit Unit1;

interface

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

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

var
Form1: TForm1;
x : string;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
x := edit1.text;
form2.show;
form1.Hide;
end;

end.

unit Unit2;

interface

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

type
TForm2 = class(TForm)
Edit2: TEdit;
procedure FormCreate(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;

var
Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.FormCreate(Sender: TObject);
begin
edit2.Text := x
end;

end.

Aber wenn ich nun eine Zahl eingebe und dann ok klicke kommt zwar die nächste Form aber in dem Edit feld steht nichts.

Bitte um Hilfe. Und ja ich hab schon ca 2std meines Lebens verschwendet andere Foren zu dursuchen.

Vielen Dank schonmal im Vorraus
Tristan

hi,

ganz einfach: Du weist im 2. Form in der FormCreate den Wert der Variable zu. Da Du das 2. Form in Unit 1 nicht explizit erzeugts, wird das wohl die Anwendung machen, d.h. das Formular wird schon beim Start der Anwendung erzeugt und da steht in X halt nunmal nichts drin…

Mach bitte folgendes:
Entferne das FormCreate in der 2. Unit und änder TForm1.Button1Click:

Form2.edit2.Text := edit1.text;
form2.showModal;

Form1 „kennt“ ja Form2, damit kannst Du auch auf dessen Eigenschaften zugreifen. Ist zwar nicht schön gemacht, aber es funktioniert. Was ShowModal macht, ließt du besser in der Hilfe nach :smile:

GRüße

Hallo,

Aber wenn ich nun eine Zahl eingebe und dann ok klicke kommt
zwar die nächste Form aber in dem Edit feld steht nichts.

wenn Du das so machen willst, musst Du das FormShow-Ereignis nehmen und nicht das FormCreate.

Die Methode, die Wolfgang beschreibt ist aber die bessere, weil Du die zirkuläre Referenz(Unit1 uses Unit2, Unit2 uses Unit1) und die globale Variable x vermeidest .

Ich verwende globale Variablen fast nur um das Programm an sich zu parametrisieren, aber nicht um sich ständig ändernde Werte hin und her zu schieben. Dann lieber Form2 „manuell“ in einer eigenen Funktion (in unit2) erzeugen und wieder freigeben. An diese Funktion kann dann x als Parameter übergeben werden.

function ShowForm2(Wert: String): TModalResult;
begin
 Form2 := TForm2.Create(Application);
 try
 Form2.edit1.text := Wert;
 Result := Form2.ShowModal;
 finally
 Form2.Free;
 end;
end;

In Form1 brauchst Du dann nur noch aufrufen:

ShowForm2(x);

alternativ:

Erg := ShowForm2(x);

wobei Erg vom Typ Integer bzw TModalResult ist und Informationen über den in Form2 gedrückten Knopf enthält, mit dem das Formular geschlossen wurde.

beachte aber, dass Du Form2 in den Projektoptionen aus der automatischen Erstellung herausnehmen musst.

Gruß, Niels

Also schnmal vielen Dank. Das mit den Variablen klappt jetzt wunderbar. Ich hab jetzt aber ein weiteres Problem, das ich mir nicht erklären kann. Ich hatte das Problem, dass ein Fehler aufgetreten ist mit String und Integer und nach der Behebung funktioniert das Programm garnicht mehr.

Hier mein Programm:

unit Unit1;

interface

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

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

var
Form1: TForm1;
text : string;
zahl : integer;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
text := edit1.Text ;
Form2.edit2.Text := edit1.text;
form1.Hide;
form2.showModal;

end;

end.

nit Unit2;

interface

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

type
TForm2 = class(TForm)
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;

var
Form2: TForm2;

implementation

uses Unit1;

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
edit2.Text := text ;
zahl := StrToInt(text);
zahl := zahl - 1 ;
edit2.Text := FloatToStr(zahl) ;
if zahl = 0 then
form1.close

end;

end.

Wenn ich das Programm starte funktioniert alles wunderbar. Auch wenn ich OK klicke und die 2. Form angezeigt wird ist alles okay. In dem Edit2 steht auch die vorher eingegebene Zahl. Aber wenn ich auf der Form2 den Button betätige kommt diese Fehlermeldung:

Im Projekt Projekt.exe ist ein Exception der Klasse EConvertError aufgetreten. Meldung: "Form2’ ist kein gültiger Integerwert’. Prozess wurde angehalten.

Wenn mir jemand helfen könnte wäre ich sehr dankbar.

MfG

Tristan

1 Like

Hallo,

da bräuchte ich von Dir noch ein paar Infos. Aber als erstes mal folgendes:

  1. Du solltest eine Variable nicht „text“ nennen. Das ist eine veraltete aber immer noch gültige Bezeichnung für eine Variable vom Typ TextFile. Außerdem ist „text“ eine Eigenschaft vieler Komponenten. Nenne sie lieber „MyText“ o.ä.

  2. Die Variable „text“ hat bei Dir nicht wirklich eine Funktion. Du speicherst darin Werte ohne dass das wirklich nötig ist.

  3. Du deklarierst alle Variablen global. Das ist äußerst ungünstig. Spätestens bei umfangreichen Projekten bekommst Du damit Probleme.

unit Unit1;

interface

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

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

var
Form1: TForm1;
text : string;
zahl : integer;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
text := edit1.Text ;

wozu übernimmst Du hier den Wert in die Variable text,…

Form2.edit2.Text := edit1.text;

wenn Du den Wert hier direkt in das edit2 schreibst?

form1.Hide;
form2.showModal;

end;

end.

nit Unit2;

interface

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

type
TForm2 = class(TForm)
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;

var
Form2: TForm2;

implementation

uses Unit1;

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
edit2.Text := text ;

Das hast Du ja schon oben gemacht. Da Du text im weiteren nicht veränderst, wird der Zähler auch nicht weiter runtergesetzt.

zahl := StrToInt(text);

Da text dauerhaft nicht verändert wird, wird zahl hier bei jedem Knopfdruck neu auf den Ausgangswert gesetzt. Diese Zeile gehört in das FormShow-Ereignis. Dann wird es nur einmal zu Anfang ausgeführt.
Nochmal: die Variable text ist in Deinem Programm überflüssig!

ich vermute auch, dass hier das Programm aussteigt. Was steht denn in diesem Moment in text drin? Doch nicht etwa ‚Form2‘? Du kannst Dir das Anzeigen lassen mit ShowMessage(text).

zahl := zahl - 1 ;
edit2.Text := FloatToStr(zahl) ;

nimm IntToStr(zahl), dass ist direkter.

if zahl = 0 then
form1.close

end;

end.

Wenn ich das Programm starte funktioniert alles wunderbar.
Auch wenn ich OK klicke und die 2. Form angezeigt wird ist
alles okay. In dem Edit2 steht auch die vorher eingegebene
Zahl. Aber wenn ich auf der Form2 den Button betätige kommt
diese Fehlermeldung:

Im Projekt Projekt.exe ist ein Exception der Klasse
EConvertError aufgetreten. Meldung: "Form2’ ist kein gültiger
Integerwert’. Prozess wurde angehalten.

Wenn mir jemand helfen könnte wäre ich sehr dankbar.

Ich hoffe, es bringt Dich zumindest weiter.

gruß, Niels

Vielen Dank Niels.
Ich weiss zwar nich genau was ich jetzt großartig verändert habe aber irgendwie hab ich es mit deiner Hilfe hinbekommen.
Das Programm läuft einwandfrei.

Falls es dich interessiert hier nochmal der Quellcode:

unit Unit1;

interface

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

type
TForm1 = class(TForm)
Label1: TLabel;
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);

private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;

var
Form1: TForm1;
zahl : string;
minuszahl : integer;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
zahl := edit1.text;
Form2.edit2.Text := edit1.text;
minuszahl := StrToInt(zahl);
form1.Hide;
form2.show;

end;

end.

unit Unit2;

interface

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

type
TForm2 = class(TForm)
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;

var
Form2: TForm2;
Owner : HWnd;

implementation

uses Unit1;

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
minuszahl := minuszahl - 1 ;
edit2.Text := FloatToStr(minuszahl) ;
if minuszahl = 0 then
form1.close;
Button2.show;
Button1.Hide

end;

procedure TForm2.Button2Click(Sender: TObject);
begin
minuszahl := minuszahl - 1 ;
edit2.Text := FloatToStr(minuszahl) ;
if minuszahl = 0 then
form1.close ;
Button1.show;
Button2.Hide

end;

end.

Ich hab zwei Buttons genommen die beide genau das selbe tun und übereinander liegen, damit man nicht einfach die Entertaste gedrückt halten kann.

Vielen Dank.

MfG

Tristan

1 Like