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

Es tut mir leid Tristan, ich kann dir bei diesem Problem nicht helfen : (

Frag jemand anderem oder suche im Delphi Forum nach.

Grüsse
ZJ

Hallo auch,

ich erkläre erst kurz, was das Problem ist. Die Lösung sollte dir dann eigentlich einfallen. Falls nicht, folgt auch noch ein Lösungsvorschlag.

PROBLEM:

Das Problem bei deinem Code ist, dass du den Text des Edits in Form2 im FormCreate-Event setzt.

Wann ist denn das?

Wenn Du Delphi das Management für die Formulare überlässt, so werden alle Formulare standardmäßig erstellt, BEVOR das Programm die Bearbeitung von Nutzereingaben startet. Das kannst du dir ansehen, wenn du dir mal den Projekt-Quellcode ansiehst (Menu „Projekt / Quelltext anzeigen“). Das sollte bei dir dann etwas so aussehen:

program Projekt1;

uses
 Forms,
 Unit1 in 'Unit1.pas' {Form1},
 Unit2 in 'Unit2.pas' {Form2};

{$R \*.res}

begin
 Application.Initialize;
 Application.CreateForm(TForm1, Form1);
 Application.CreateForm(TForm2, Form2);
 Application.Run;
end.

Nach Application.CreateForm() werden die OnCreate-Event aufgerufen (und evtl. auch OnShow-Events usw). Zu diesem Zeitpunkt hast du als User noch keine Eingabe in einem Editfeld machen können.

Erst in Application.Run wird auf eine Eingabe gewartet und evtl. ausgewertet. Jetzt erst kann z.B. auch ein OnClick-Event eines Buttons auftreten.

LÖSUNG:

Vorschlag 1:

Da Du Form2 anzeigst, nachdem du den Button in Form1 geklickt hast, könntest du das OnShow-Ereignis in Form2 nutzen, um x zu lesen.

Vorschlag 2:

Lass Form2 nicht automatisch erstellen, sondern erstelle es „manuell“ nach dem Klick auf auf den Button in Form1:

procedure TForm1.Button1Click(Sender: TObject);
var
 ClickForm: TForm2;
begin
 x := edit1.text;
 ClickForm := TForm2.Create(self);
 self.hide;
 try 
 ClickForm.Show;
 finally
 ClickForm.Free;
 end;
end;

Vorschlag 3:

Es ist unschön, globale Variablen zu benutzen, wenn sie vermeidbar sind. Bei dir ist „x“ so eine globale Variable, und die ist als solche absolut verzichtbar.

Vor der Anzeige von Form2 im ButtonClick-Event von Form1 kannst du doch direkt den Text von Form1.Edit1 auf Form2.Edit2 übertragen. Die Verwendung von OnCreate- oder OnShow-Events von Form2 ist dann unnötig.

Ganz professionell wird es, wenn du in der Unit2 eine Prozedur (oder besser noch eine Funktion) schreibst, welche den zu setztenden Text dür das Edit2 übernimmt, prüft, das Form2 erstellt oder einen Fehler ausgibt.

Mit ShowModal kannst du in der Prozedur warten, bis Form2 geschlossen wurde.

So könnte diese Prozedur aussehen:

function ShowClickForm(AText:String):Boolean;
var
 ClickForm: TForm2;
 value: Integer;
begin
 // gehen wir erstmal davon aus, 
 // dass die Eingabe nicht ok war.
 Result := False; 
 if AText '' then
 try
 value := StrToInt(AText); 
 ClickForm := TForm2.Create(Application);
 try
 // Übergabe der ermittelten ZAHL als Text
 ClickForm.Edit2.Text := IntToStr(Value);
 ClickForm.ShowModal; 
 Result := True;
 finally
 ClickForm.Free;
 end; 
 except
 // Hier landen wir, wenn zwar ein Text 
 // übergeben wurde, es sich dabei aber 
 // nicht um eine gültige Ganzzahl handelt.
 // Hier steht kein Code. Das ist nur zum 
 // Abfangen eines Fehlers.
 end;
end;

So, in Form1 kann man das zB. so aufrufen:

procedure TForm1.Button1Click(Sender: TObject);
begin
 self.hide;
 if ShowClickForm(Edit1.Text) then
 begin
 // mach irgendwas, wenn alles geklappt hat
 end
 else
 begin
 // mach was anderes, wenn es nicht geklappt hat
 end
 self.show;
end;

Hinweis: Wenn ShowModal verwendet wird, brauchst du eigentlich Form1 nicht zu verstecken, weil der User dann ausschließlich Eingaben in Form2 machen kann.

Das kann man noch ausbauen. Die Funktion könnte zB. auch noch Rückgabewerte liefern (als var Parameter).

Ich hoffe, das hilft erstmal weiter und du hast was gelernt.

VG
Jochen

Hallo Tristan,
Du wirst noch viel mehr Lebenszeit investieren müssen :wink:

Der Fehler besteht darin, dass du x als lokale Variable in der Unit1 gespeichert hast.

Leider habe ich kein Delphi mehr installiert, daher müssen wir jetzt mal „Trockenschwimmen“.

  1. Definiere x in Unit 2 bei Public-Deklaration als „Property“ und dazu eine „Set_Property_X“-Procedure.

Siehe: http://www.delphi-treff.de/object-pascal/zugriff-auf…

Eine Property ist eine Eigenschaft eines Objekts, bei Dir eine Eigenschaft von Form2.

Beim schreiben auf die Property wird eine Set-Procedure ausgeführt, die den Wert übernimmt. In dieser Procedure setzt Du den Wert dann in edit1.Text.

  1. Der Aufruf im Button1Click von Form1 ist so:

procedure TForm1.Button1Click(Sender: TObject);
begin
form2.X = edit1.text; //X ist der Name deiner Property
form2.show;
form1.Hide;
end;

Das mutet zwar etwas umständlich an, aber ist die saubere Lösung - und glaube mir, es lohnt sich immer etwas sauber zu programmieren.

Viel Erfolg!
Nic

Hi,

du weist edit2.text den Wert x im FormCreate von Form2 zu. FormCreate wurde aber schon vorher aufgerufen(nicht von Dir, sondern automatisch).
Mit deinem Button rufst du Form2.show auf. Wenn du also edit2 den Wert von x im show-Event von Form2 zuweist, sollte es funktionieren.

Grüße
Erik

Bei Fragen zu Delphi, kann ich Dir nur das DelphiPraxis Forum empfehlen, da bekommst du meisten sehr schnell kompetente Antworten. :wink:

Hallo Tristan,

der Wert in Form2.Edit1.Text muss natürlich gesetzt werden, damit du dort was vorfinden kannst. Da du auf diesem nicht direkt zugreifen kannst, must du eine public Funktion definieren, z.B:

type
TForm2 = class(TForm)

public
{ Public-Deklarationen }
procedure SetValue(s: string);
end;

procedure TForm2.SetValue(s: string);
begin
Edit1.Text := IntToStr(StrToInt(s)-1);
end;

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

LG
Bernd

Hallo,

Deine Variable x gehört zu Form1 (d.h. sie ist in dieser Klasse deklariert)
Form2 ist eine eigene Klasse, deshalb ist x für sie unsichtbar
–> dies funktioniert nicht:
edit2.Text := x

Lösung (hab’s in Dephi nicht getestet, aber das Prinzip stimmt):
Füge in TForm2 eine öffentliche Methode setX() ein, um den Wert von Form1 an Form2 zu übergeben.

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

var
Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.setX(myString: String)
begin
self.x := myString;
end;

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

end.

In Form1 kannst Du diese Prozedur nun aufrufen:
procedure TForm1.Button1Click(Sender: TObject);
begin
form2.setX(edit1.text);
form2.show;
form1.hide;
end;

Lies am besten mal weiter unter den Stichworten „Kapselung“ und „Sichtbarkeit / information hiding“ in der objektorientierten Programmierung.

Viele Grüße,
Holger

Hallo Tristan,

ist schon Jahre her das ich mit Delphi gearbeitet habe,
bin daher leider keine große Hilfe mehr, aber wenn ich mich recht entsinne, belege die X:String Variable einmal mit „0“ Integer oder ähnlich vor. Dann sollte es klappen. Viel Erfolg, Frank