![]() |
Record an 2tes Formular übergeben
Hallo Leute,
ich möchte von einem Formular das mit Recorddaten gefüllten Stringgrid durch doppelklicken den ausgewählten Datensatz in einem 2ten Formular bearbeiten. Durch klicken auf OK soll dann der Record gespeichert werden, bzw. durch Abbruch die Änderungen verworfen werden. Hänge jetzt schon den ganzen Nachmittag an dem Problem und werde einfach nicht fündig nach der Lösung. Vielleicht kann mir jemand unter die Arme greifen. Formular1:
Delphi-Quellcode:
Formular2:
unit PUnit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Grids; type TForm1 = class(TForm) StringGrid1: TStringGrid; procedure StringGrid1DblClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure StringGridInit; private { Private-Deklarationen } public { Public-Deklarationen } end; TPerson = record id: integer; vorname: string[20]; nachname: string[30]; geburtstag: TDateTime; end; var Form1: TForm1; personen: array[1..9] of TPerson; implementation uses PUnit2; {$R *.dfm} procedure TForm1.StringGrid1DblClick(Sender: TObject); begin //Werte an Form2 übergeben (wie besser lösbar?) form2.edit1.text := personen[StringGrid1.Row].vorname; form2.edit2.text := personen[StringGrid1.Row].nachname; form2.edit3.text := DateToStr(personen[StringGrid1.Row].geburtstag); form2.Show; end; procedure TForm1.FormCreate(Sender: TObject); var i: Integer; begin //Felder mit beispielwerten füllen for i := 1 to 9 do begin personen[i].id := i; personen[i].vorname := 'Willi ' + IntToStr(i); personen[i].nachname := 'Mustermann'; personen[i].geburtstag := StrToDate('31.12.1999'); end; StringGridInit; end; procedure TForm1.StringGridInit; var i: Integer; begin with StringGrid1 do begin RowCount := length(personen)+1; Cells[0,0] := 'ID'; Cells[1,0] := 'Vorname'; Cells[2,0] := 'Name'; Cells[3,0] := 'Geburtsdatum'; end; for i := 1 to length(Personen) do with StringGrid1 do begin Cells[0,i] := IntToStr(personen[i].id); Cells[1,i] := personen[i].vorname; Cells[2,i] := personen[i].nachname; Cells[3,i] := DateToStr(personen[i].geburtstag); end end; end.
Delphi-Quellcode:
unit PUnit2;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm2 = class(TForm) Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Save: TButton; Cancel: TButton; procedure CancelClick(Sender: TObject); procedure SaveClick(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form2: TForm2; implementation {$R *.dfm} uses PUnit1; procedure TForm2.SaveClick(Sender: TObject); begin //Werte in Record speichern und wieder zu Form1 zurückkehren //Problem: Auf Record von Form1 kann nicht zugegriffen werden { Edit1.Text := personen[id].vorname; Edit2.Text := personen[id].nachname; Edit3.Text := personen[id].geburtsdatum; } Form2.Close; Form1.StringGridInit; // Stringgrid aktualisieren end; procedure TForm2.CancelClick(Sender: TObject); begin // Bei Abbruch Werte nicht speichern, nur Formular schließen Form2.Close; end; end. |
AW: Record an 2tes Formular übergeben
Ich würde den Record in einer eigenen Unit deklarieren und diese in beiden Units einbinden. Form2 bekommt dann eine Property vom Typ dieses Records spendiert, welche dann von Form1 zugewiesen wird.
|
AW: Record an 2tes Formular übergeben
Hi und willkommen in der DP ;-)
Einmal abgesehen davon, dass ich das ganze nicht mit einem Record und einem Array, sondern mit Objekten in einer (Object-)List lösen würde, würde ich dein konkretes Problem vermutlich so lösen: Das zweite Formular wird standardmäßig nicht erzeugt, sondern nur dynamisch. Nach dem Schließen wird es dann wieder freigegeben. Mach dir bei deiner Form1 eine neue Methode:
Delphi-Quellcode:
Im Form2 brauchst du dann im OnClick vom Save-Button nur noch folgendes:
procedure DatenAendern(nummer : integer);
var dlg: TForm2; begin //-- if (nummer >= Low(personen)) and (nummer <= High(personen)) then begin dlg := TForm2.Create(self); // dlg.Edit1.Text := personen[nummer].vorname; // oder was auch immer //... if dlg.ShowModal = mrOK then begin personen[nummer] := dlg.Edit1.Text; //... end; // dlg.free; end; end;
Delphi-Quellcode:
Self.ModalResult := mrOK;
Ich hoffe, es wurde einigermaßen klar, was ich meine. (Nicht vergessen, dass in den Projektoptionen eingestellt werden muss, dass Form2 standardmäßig nicht erzeugt wird!) mfg, Patti |
AW: Record an 2tes Formular übergeben
Wieso unbedingt dynamisch? Und weshalb wird da direkt auf VCL-Controls zugegriffen? Was passt Dir an meinem Property-Vorschlag nicht?
|
AW: Record an 2tes Formular übergeben
Zitat:
Zitat:
Zitat:
|
AW: Record an 2tes Formular übergeben
Sicher müssen die Daten angezeigt werden, aber weshalb von außen? IMO sollte das Form2 schon selbst machen.
|
AW: Record an 2tes Formular übergeben
Willkommen in der :dp:
Was dir fehlt ist ![]() Um mal die Komplett-lern-lösung zu geben: Form1:
Delphi-Quellcode:
unit Unit1;
interface uses SysUtils, Classes, Controls, Forms, uConst, Grids, Unit2; type TForm1 = class(TForm) strngrd1: TStringGrid; procedure strngrd1DblClick(Sender: TObject); procedure FormCreate(Sender: TObject); private personen: array[1..9] of TPerson; procedure StringGridInit; public end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); var i: Integer; begin //Felder mit beispielwerten füllen for i := 1 to 9 do begin personen[i].id := i; personen[i].vorname := 'Willi ' + IntToStr(i); personen[i].nachname := 'Mustermann'; personen[i].geburtstag := StrToDate('31.12.1999'); end; StringGridInit; end; procedure TForm1.StringGridInit; var i: Integer; begin with strngrd1 do begin RowCount := length(personen) + 1; Cells[0, 0] := 'ID'; Cells[1, 0] := 'Vorname'; Cells[2, 0] := 'Name'; Cells[3, 0] := 'Geburtsdatum'; end; for i := 1 to length(Personen) do with strngrd1 do begin Cells[0, i] := IntToStr(personen[i].id); Cells[1, i] := personen[i].vorname; Cells[2, i] := personen[i].nachname; Cells[3, i] := DateToStr(personen[i].geburtstag); end end; procedure TForm1.strngrd1DblClick(Sender: TObject); var frm2: TForm2; begin frm2 := TForm2.Create(Self); frm2.edt1.text := personen[strngrd1.Row].vorname; frm2.edt2.text := personen[strngrd1.Row].nachname; frm2.edt3.text := DateToStr(personen[strngrd1.Row].geburtstag); case frm2.ShowModal of mrOk: begin personen[strngrd1.Row].vorname := frm2.edt1.text; personen[strngrd1.Row].nachname := frm2.edt2.text; personen[strngrd1.Row].geburtstag := StrToDate(frm2.edt3.text); with strngrd1 do begin Cells[1, strngrd1.Row] := personen[strngrd1.Row].vorname; Cells[2, strngrd1.Row] := personen[strngrd1.Row].nachname; Cells[3, strngrd1.Row] := DateToStr(personen[strngrd1.Row].geburtstag); end; end end; frm2.Free; end; end. Form2:
Delphi-Quellcode:
unit Unit2;
interface uses Classes, Controls, Forms, StdCtrls; type TForm2 = class(TForm) btnCancel: TButton; btnSave: TButton; edt1: TEdit; edt2: TEdit; edt3: TEdit; procedure btnCancelClick(Sender: TObject); procedure btnSaveClick(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form2: TForm2; implementation {$R *.dfm} procedure TForm2.btnCancelClick(Sender: TObject); begin ModalResult := mrCancel; end; procedure TForm2.btnSaveClick(Sender: TObject); begin ModalResult := mrOk; end; end. uConst: (Gemeinsme Dinge um uses-Konflikten vorzubeugen)
Delphi-Quellcode:
unit uConst;
interface type TPerson = record id: integer; vorname: string[20]; nachname: string[30]; geburtstag: TDateTime; end; implementation end. |
AW: Record an 2tes Formular übergeben
Nimm bitte eine Property um den Datensatz zu übergeben. Wenn du am zweiten Formular was änderst kannst du das auch gleich im Quellcode vom ersten machen. Übergibst du nur den Record über eine Property, brauchst du nur am zweiten Formular was ändern. Und der Quellcode im ersten Formular wird übersichtlicher.
|
AW: Record an 2tes Formular übergeben
:-D Wow, das ging ja schnell. Vielen Dank an alle. Jetzt funktionierts und ich kann weiter machen.
@Luckie & DeddyH: Das mit den Property hatte ich heute schon probiert, bin aber nicht zurecht damit gekommen. Hast du mir ein Beispiel? Ich würde gerne diese Möglichkeit auch testen wollen. |
AW: Record an 2tes Formular übergeben
|
AW: Record an 2tes Formular übergeben
Ich habe das mit den Property nun so umgesetzt, wahrscheinlich aber viel zu umständlich:
Formular 1:
Delphi-Quellcode:
Formular 2:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Grids, uConst; type TForm1 = class(TForm) StringGrid1: TStringGrid; procedure StringGrid1DblClick(Sender: TObject); procedure FormCreate(Sender: TObject); function Get_personen(Index: Integer): TPerson; procedure Set_personen(Index: Integer; Rec: TPerson); private procedure StringGridInit; public property personen[index: Integer]: TPerson read Get_personen write Set_personen; end; var Form1: TForm1; fpersonen: array[1..9] of TPerson; implementation uses Unit2; {$R *.dfm} function TForm1.Get_personen(index: Integer): TPerson; begin Result := fpersonen[index]; end; procedure TForm1.Set_personen(index: Integer; Rec: TPerson); begin fpersonen[index] := Rec; end; procedure TForm1.StringGrid1DblClick(Sender: TObject); var form2: TForm2; begin form2 := TForm2.Create(Self); //ID an Form2 übergeben form2.edit4.text := IntToStr(personen[StringGrid1.Row].id); case form2.ShowModal of mrOk: begin fpersonen[StringGrid1.Row].vorname := form2.edit1.text; fpersonen[StringGrid1.Row].nachname := form2.edit2.text; fpersonen[StringGrid1.Row].geburtstag := StrToDate(form2.edit3.text); StringGridInit; end end; form2.Free; end; procedure TForm1.FormCreate(Sender: TObject); var i: Integer; begin //Felder mit beispielwerten füllen for i := 1 to 9 do begin fpersonen[i].id := i; fpersonen[i].vorname := 'Willi ' + IntToStr(i); fpersonen[i].nachname := 'Mustermann'; fpersonen[i].geburtstag := StrToDate('31.12.1999'); end; StringGridInit; end; procedure TForm1.StringGridInit; var i: Integer; begin with StringGrid1 do begin RowCount := length(fpersonen)+1; Cells[0,0] := 'ID'; Cells[1,0] := 'Vorname'; Cells[2,0] := 'Name'; Cells[3,0] := 'Geburtsdatum'; end; for i := 1 to length(fpersonen) do with StringGrid1 do begin Cells[0,i] := IntToStr(fpersonen[i].id); Cells[1,i] := fpersonen[i].vorname; Cells[2,i] := fpersonen[i].nachname; Cells[3,i] := DateToStr(fpersonen[i].geburtstag); end end; end.
Delphi-Quellcode:
uConst:
unit Unit2;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, uConst; type TForm2 = class(TForm) Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Save: TButton; Cancel: TButton; Edit4: TEdit; procedure CancelClick(Sender: TObject); procedure SaveClick(Sender: TObject); procedure FormActivate(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form2: TForm2; implementation {$R *.dfm} uses Unit1; procedure TForm2.SaveClick(Sender: TObject); begin ModalResult := mrOK; end; procedure TForm2.CancelClick(Sender: TObject); begin // Bei Abbruch Werte nicht speichern, nur Formular schließen ModalResult := mrCancel; end; procedure TForm2.FormActivate(Sender: TObject); begin edit1.text := fpersonen[StrToInt(edit4.text)].vorname; edit2.text := fpersonen[StrToInt(edit4.text)].nachname; edit3.text := DateToStr(fpersonen[StrToInt(edit4.text)].Geburtstag); end; end.
Delphi-Quellcode:
unit uConst;
interface type TPerson = record id: integer; vorname: string[20]; nachname: string[30]; geburtstag: TDateTime; end; implementation end. |
AW: Record an 2tes Formular übergeben
Zitat:
|
AW: Record an 2tes Formular übergeben
Wir hatten das anders herum gemeint: eine Property vom Typ TPerson in Form2 deklarieren, von Form1 aus zuweisen und bei ModalResult mrOK übernehmen.
Delphi-Quellcode:
Form2 := TForm2.Create(nil);
try Form2.Person := Personen[Index]; if Form2.ShowModal = mrOK then Personen[Index] := Form2.Person; finally Form2.Release; end; |
AW: Record an 2tes Formular übergeben
Ich würd' dann noch Folgendes ändern.
.Free statt .Release Lokale Variable frm statt globale Variable Form2 verwendet Private Methode EditPerson - damit wird im Code klar ausgedrückt, was hier passieren soll
Delphi-Quellcode:
procedure TForm1.EditPerson(var person:TPerson);
var frm : TForm2; begin frm := TForm2.Create(nil); try frm.Person := person; if frm.ShowModal = mrOK then person := frm.Person; finally frm.Free; end; end; |
AW: Record an 2tes Formular übergeben
Welchen Mehrwert soll die lokale Variable bringen? Und zum Free:
Zitat:
![]() |
AW: Record an 2tes Formular übergeben
Zitat:
(Dass Delphi automatisch pro Formular eine globale Variable anlegt ist eine sehr grosse Unschönheit an Delphi. Es verleitet die Programmierer dazu immer diese globalen Variablen zu benützen und lässt manche auch glauben Formularklasse und Formular wäre das Gleiche.) Diese Variable sollte man einfach auskommentieren, wenn man im Vorraus weiss, dass man TForm2 nur als modales Formular benützen wird. Wenn man die globale Variable Form2 benützt, dann hinterlässt man eine Art von Tretmine. Irgendein unbedarfter Programmier könnte schreiben Form2.Show und schon würde man auf Speicher zugreifen, der schon freigegeben wurde. Zitat:
Release braucht man nur dann, wenn man das eigene Formular aus einer Ereignisbehandlungsroutine freigeben möchte. Für andere Formulare, die nicht zur Formularklasse gehören in dessen Kontext man sich gerade befindet, trifft das nicht zu. Wenn man also irgendwo Code wie diesen sieht
Delphi-Quellcode:
, dann hat man einen Fehler entdeckt. Nur
IrgendeinForm.Release
Delphi-Quellcode:
oder
Release
Delphi-Quellcode:
wäre ein sinnvoller Aufruf.
self.Release
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:30 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz