![]() |
Adressbuch, aber...
Hallo,
ich muss für eine Bewerbung ein Adressbuch entwickeln. Soweit auch ganz ok, nur hab ich ein Problem: Er gibt mir immer den Fehler EStackOverflow zurück. Das passiert immer, wenn - Er in die auskommentierte for Schleife in Unit1 geht und dort auf den ersten Befehl trifft - oder wenn halt die for schleife auskommentiert bleibt, beim end; von TForm1.Create Warum? Hab schon versucht den Stack größer zu stellen, aber nix. Außerdem würde ich gerne, wenn man im SG eine Zelle auswählt, dass etwas passiert (siehe TForm1.SG_KONTAKTESelectCell). Dazu möchte ich den Inhalt den Arrays "Kontakte[i]" mit dem der Zelle vergleichen, wie geht das? Hiermal der Code:
Code:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids, Unit2; type TForm1 = class(TForm) GB_KONTAKTE: TGroupBox; LB_SUCHEN: TLabel; ED_SUCHEN: TEdit; SG_KONTAKTE: TStringGrid; GB_DETAILS: TGroupBox; LB_VORNAME: TLabel; LB_NACHNAME: TLabel; LB_GEB: TLabel; LB_TELE_PRIV: TLabel; LB_TELE_DIENST: TLabel; LB_HANDY: TLabel; LB_EMAIL: TLabel; ED_VORNAME: TEdit; ED_NACHNAME: TEdit; ED_GEB: TEdit; ED_TELE_PRIV: TEdit; ED_TELE_DIENST: TEdit; ED_HANDY: TEdit; ED_EMAIL: TEdit; GB_BEARBEITEN: TGroupBox; BT_NEU: TButton; BT_BEARBEITEN: TButton; BT_LOESCHEN: TButton; BT_EXTRA: TButton; procedure FormCreate(Sender: TObject); procedure BT_NEUClick(Sender: TObject); procedure SG_KONTAKTESelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; datei: file of TKontakt; zz: string; Kontakte: array of TKontakt; i: integer; pfad: textfile; pfad_string: string; implementation uses Unit3; {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin i := 0; SG_KONTAKTE.Cells[0, 0] := 'Nachname'; SG_KONTAKTE.Cells[1, 0] := 'Vorname'; if (SG_KONTAKTE.Cells[0, 1] = '') AND (SG_KONTAKTE.Cells[1, 1] = '') then begin LB_SUCHEN.Enabled := false; ED_SUCHEN.Enabled := false; end; try AssignFile(pfad, 'C:\pfad.txt'); Reset(pfad); ReadLn(pfad, pfad_string); CloseFile(pfad); AssignFile(datei, pfad_string); Reset(datei); While (eof(datei)=false) do begin i := i + 1; SetLength(Kontakte, i); Read(datei, Kontakte[i]); end; {for i:=0 to High(kontakte) do begin SG_KONTAKTE.Cells[0, i+1] := Kontakte[i].Nachname; SG_KONTAKTE.Cells[1, i+1] := Kontakte[i].Vorname; end;} CloseFile(datei); except MessageDlg('Keine Kontakte gefunden', mtError, [mbOK], 0); end; end; procedure TForm1.BT_NEUClick(Sender: TObject); begin Form3.Visible := True; end; procedure TForm1.SG_KONTAKTESelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); begin for i:=0 to High(Kontakte) do begin if Kontakte[i].Vorname OR Kontakte[i].Nachname = end; end.
Code:
unit Unit2;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids; type TKontakt = record Vorname: String[50]; Nachname: String[50]; Geb_datum: String[10]; Telefon_p: String[20]; Telefon_d: String[20]; Mobil: String[15]; EMail: String[50]; end; implementation end.
Code:
Vielen Dank schonmal
unit Unit3;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Unit1, Unit2; type TForm3 = class(TForm) GB_DETAILS: TGroupBox; LB_VORNAME: TLabel; LB_NACHNAME: TLabel; LB_GEB: TLabel; LB_TELE_PRIV: TLabel; LB_TELE_DIENST: TLabel; LB_HANDY: TLabel; LB_EMAIL: TLabel; ED_VORNAME_NEU: TEdit; ED_NACHNAME_NEU: TEdit; ED_GEB_NEU: TEdit; ED_TELE_PRIV_NEU: TEdit; ED_TELE_DIENST_NEU: TEdit; ED_HANDY_NEU: TEdit; ED_EMAIL_NEU: TEdit; BT_SPEICHERN_NEU: TButton; BT_SCHLIESSEN_NEU: TButton; SD_SPEICHERN: TSaveDialog; procedure BT_SCHLIESSEN_NEUClick(Sender: TObject); procedure BT_SPEICHERN_NEUClick(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form3: TForm3; implementation {$R *.dfm} procedure TForm3.BT_SCHLIESSEN_NEUClick(Sender: TObject); begin Close; end; procedure TForm3.BT_SPEICHERN_NEUClick(Sender: TObject); var i: integer; begin if SD_SPEICHERN.Execute then begin SetLength(Kontakte, (length(kontakte)+1)); Kontakte[High(Kontakte)].Vorname := ED_VORNAME_NEU.Text; Kontakte[High(Kontakte)].Nachname := ED_NACHNAME_NEU.Text; Kontakte[High(Kontakte)].Geb_datum := ED_GEB_NEU.Text; Kontakte[High(Kontakte)].Telefon_p := ED_TELE_PRIV_NEU.Text; Kontakte[High(Kontakte)].Telefon_d := ED_TELE_DIENST_NEU.Text; Kontakte[High(Kontakte)].Mobil := ED_HANDY_NEU.Text; Kontakte[High(Kontakte)].EMail := ED_EMAIL_NEU.Text; try AssignFile(datei, SD_SPEICHERN.FileName); ReWrite(datei); for i:=0 to High(Kontakte) do begin Write(datei, Kontakte[i]); end; AssignFile(pfad,'C:\pfad.txt' ); ReWrite(pfad); WriteLn(pfad, SD_SPEICHERN.FileName); CloseFile(pfad); except MessageDlg('Fehler beim schreiben der Datei', mtError, [mbOK], 0); end; end; end; end. |
Re: Adressbuch, aber...
Erstmal etwas anderes
Delphi-Quellcode:
Du erhöhst i um jeweils 1. Damit schreibst du beginnend für i=1 in Kontakte[1] den ersten Wert.
While (eof(datei)=false) do
begin i := i + 1; SetLength(Kontakte, i); Read(datei, Kontakte[i]); end; Außerdem würde ich dir gerne die Methoden LoadFromFile von TStringList (bzw. TStrings) näher bringen, welche wesentlich effizienter und übersichtlicher arbeiten :) Dann verstehe ich nicht, was in der pfad.txt stehen soll? Wenn es der Pfad zur Anwendung ist solltest du dir mal ParamStr(0) anschauen, welchen den Anwendungspfad enthält. |
Re: Adressbuch, aber...
Stimmt, i müsste ich erst nach dem eintragen ins Array erhöhen.
oder einfach Kontakte[i-1] Ich solls mit einer typisierten Datei machen... Nicht der Anwendungspfad, sondern der Pfad von der "Kontakte.kon". Damit beim Programmstart automatisch die Datei geöffnet wird. Da ich das ganze über den SD_SPEICHERN.Filename Parameter realisieren will, muss ich den Pfad ja irgendwo Speichern, um beim nächsten Start wieder draufzugreifen zu können. Man soll den Speicherort der Kontake.kon Datei ja auswählen können, sonst könnte ich sie ja aeinfach im Pfad der Anwendung speichern. EDIT: Jetzt funktionierts, nachdem ich Kontakte[i-1] gemacht hab ^^ danke :D Next Edit: Außerdem würde ich gerne, wenn man im SG eine Zelle auswählt, dass etwas passiert (siehe TForm1.SG_KONTAKTESelectCell). Dazu möchte ich den Inhalt den Arrays "Kontakte[i]" mit dem der Zelle vergleichen, wie geht das? Und kann man überprüfen durch welchen button ein Formular bzw eine Procedure aufgerufen wurde bzw wird? Will halt ne Fallunterscheidung machen wenn von button 1 dann so bei Button 2 so Update: habs jetzt so probiert, aber er kreidet mir an, dass man AND hier nicht benutzen kann
Delphi-Quellcode:
procedure TForm1.SG_KONTAKTESelectCell(Sender: TObject; ACol,
ARow: Integer; var CanSelect: Boolean); begin for i:=0 to High(Kontakte) do begin if (Kontakte[i].Vorname AND Kontakte[i].Nachname) = (SG_KONTAKTE.Cells[0, ARow] AND SG_KONTAKTE.Cells[1, ARow]) then begin ED_VORNAME.Text := Kontakte[i].Vorname; ED_NACHNAME.Text := Kontakte[i].Nachname; ED_GEB.Text := Kontakte[i].Geb_datum; ED_TELE_PRIV.Text := Kontakte[i].Telefon_p; ED_TELE_DIENST.Text := Kontakte[i].Telefon_d; ED_HANDY.Text := Kontakte[i].Mobil; ED_EMAIL.Text := Kontakte[i].EMail; end; end; end; |
Re: Adressbuch, aber...
Hallo,
wenn Du jedem Datensatz eine eindeutige ID-Nummer zuweist, ist der Zugriff auf die Daten einfacher.
Delphi-Quellcode:
Du musst natürlich beim Hinzufügen neuer Daten sicher stellen, dass die neue ID noch nicht vergeben ist. (Einmal StreamFile durchlaufen und vergleichen)
TKontakt = record
ID: String[6]; Vorname: String[50]; Nachname: String[50]; Geb_datum: String[10]; Telefon_p: String[20]; Telefon_d: String[20]; Mobil: String[15]; EMail: String[50]; end; Erste ID-Nr = 000001 usw. Die ID's würde ich dann im ListView als Caption übernehmen. Gruß RoGa |
Re: Adressbuch, aber...
Zitat:
Delphi-Quellcode:
Damit der Compiler weis, das es eine Bedingung und keine Operation ist, die einzelnen Bedingungen nochmal Klammern, wenn Sie durch einen Operator/Vergleich erst Ihren boolschen Wert bekommen.
if (Kontakte[i].Vorname AND ( Kontakte[i].Nachname) =
(SG_KONTAKTE.Cells[0, ARow] ) AND (SG_KONTAKTE.Cells[1, ARow] = ?????) ) then Wobei ich glaube, Du verwendest die Operatoren falsch:
Delphi-Quellcode:
oder
if (Kontakte[i].Vorname + Kontakte[i].Nachname) = (SG_KONTAKTE.Cells[0, ARow] + SG_KONTAKTE.Cells[1, ARow]) then
Delphi-Quellcode:
if (Kontakte[i].Vorname = SG_KONTAKTE.Cells[0, ARow]) AND (Kontakte[i].Nachname) = SG_KONTAKTE.Cells[1, ARow]) then
|
Re: Adressbuch, aber...
Zitat:
Was ist ein StreamFile? Danke Satty67 die Lösung
Delphi-Quellcode:
hat gefunzt.
if (Kontakte[i].Vorname = SG_KONTAKTE.Cells[0, ARow]) AND (Kontakte[i].Nachname) = SG_KONTAKTE.Cells[1, ARow]) then
Hat noch jemand ne Antowort dazu? Kann man überprüfen durch welchen button ein Formular bzw eine Procedure aufgerufen wurde bzw wird? Will halt ne Fallunterscheidung machen wenn von button 1 dann so bei Button 2 so |
Re: Adressbuch, aber...
Dafür ist der Parameter Sender da, der bei Ereignissen immer mit übergeben wird. Du kannst entweder direkt mit einem bestimmten Button vergleichen oder auf TButton z.B. casten und die Eigenschaften des Buttons abfragen.
Delphi-Quellcode:
procedure TFormX.ButtonXClick(Sender: TObject);
begin if Sender = Button1 then ...
Delphi-Quellcode:
if Sender is TButton then
ShowMessage(TButton(Sender).Caption); |
Re: Adressbuch, aber...
Scheint zu funzen, dankeee
Leider doch nicht ^^ Wenn ich jetzt auf Speichern klicke, macht er einfach NIX
Delphi-Quellcode:
Nochn Problem:
procedure TForm3.BT_SPEICHERN_NEUClick(Sender: TObject);
var i: integer; begin if sender = Form1.BT_NEU then begin if SD_SPEICHERN.Execute then begin SetLength(Kontakte, (length(kontakte)+1)); Kontakte[High(Kontakte)].Vorname := ED_VORNAME_NEU.Text; Kontakte[High(Kontakte)].Nachname := ED_NACHNAME_NEU.Text; Kontakte[High(Kontakte)].Geb_datum := ED_GEB_NEU.Text; Kontakte[High(Kontakte)].Telefon_p := ED_TELE_PRIV_NEU.Text; Kontakte[High(Kontakte)].Telefon_d := ED_TELE_DIENST_NEU.Text; Kontakte[High(Kontakte)].Mobil := ED_HANDY_NEU.Text; Kontakte[High(Kontakte)].EMail := ED_EMAIL_NEU.Text; try AssignFile(datei, SD_SPEICHERN.FileName); ReWrite(datei); for i:=0 to High(Kontakte) do begin Write(datei, Kontakte[i]); end; AssignFile(pfad,'C:\pfad.txt' ); ReWrite(pfad); WriteLn(pfad, SD_SPEICHERN.FileName); CloseFile(pfad); except MessageDlg('Fehler beim schreiben der Datei', mtError, [mbOK], 0); end; end; end; if sender = Form1.BT_BEARBEITEN then begin if SD_SPEICHERN.Execute then begin Kontakte[Unit1.selected_row].Vorname := ED_VORNAME_NEU.Text; Kontakte[Unit1.selected_row].Nachname := ED_NACHNAME_NEU.Text; Kontakte[Unit1.selected_row].Geb_datum := ED_GEB_NEU.Text; Kontakte[Unit1.selected_row].Telefon_p := ED_TELE_PRIV_NEU.Text; Kontakte[Unit1.selected_row].Telefon_d := ED_TELE_DIENST_NEU.Text; Kontakte[Unit1.selected_row].Mobil := ED_HANDY_NEU.Text; Kontakte[Unit1.selected_row].EMail := ED_EMAIL_NEU.Text; try AssignFile(datei, SD_SPEICHERN.FileName); ReWrite(datei); for i:=0 to High(Kontakte) do begin Write(datei, Kontakte[i]); end; AssignFile(pfad,'C:\pfad.txt' ); ReWrite(pfad); WriteLn(pfad, SD_SPEICHERN.FileName); CloseFile(pfad); except MessageDlg('Fehler beim schreiben der Datei', mtError, [mbOK], 0); end; end; end; end; Ich will ne suche realisieren, die direkt bei der eingabe schon die unpassenden ergebnisse rausfiltert. Ich hab mir das so vorgestellt, das ich mit ner for schleife von 1 (wegen fixedrow) bis rowcount durchgeh und jeden Eintrag auf eine evtl vrhandene Gleichheit überprüfe. Wenn er in der einen Row keine übereinstimmung gefunden hat soll er sie einfach löschen Bei Backspace soll er halt wieder entsprechende Einträge hinzufügen Habs grade probier aber ich schaffs einfach nicht :/ Mittlerweile brennen auch meine Augen ganz schön, weil ich seit ungf. 14 Uhr an dem Ding sitz. Helft mir bitte!!! |
Re: Adressbuch, aber...
Zitat:
Komplett wird dir das keiner lösen. Denn wenn du das für eine Bewerbung brauchst, dann soll das deine eigene Leistung wiederspiegeln und nicht unsere. |
Re: Adressbuch, aber...
Delphi-Quellcode:
Soweit hab ichs. Aber ich kenn keinen Befehl mit dem man eine Row löschen kann.
procedure TForm1.ED_SUCHENChange(Sender: TObject);
begin for i:=1 to SG_KONTAKTE.RowCount do begin if (ED_SUCHEN.Text = SG_KONTAKTE.Cells[0, i]) OR (ED_SUCHEN.Text = SG_KONTAKTE.Cells[1, i]) then begin //row stehen lassen, also nix machen end else //Row löschen end; end; end; Und leider hab ich noch keine Ahnung wie man das ganze Rückwärts, sprich bei Backspace realisieren könnte. Oder kennt jemand vllt noch eine andere Lösung? ich hab mir auch überlegt, einfach das Ereignis "ON KEY PRESS" zu nehmen und halt jeden Buchstaben einzelnd abzufragen, ist aber eher nicht so toll glaub ich. Und auch hier hab ich das Problem, dass ich nicht weiss wie ich bei einem Backspace reagieren soll. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:26 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 by Thomas Breitkreuz