Entwickler-Ecke
Datenbanken - Record anzeigen
Systanas - Di 15.12.09 12:26
Titel: Record anzeigen
Hallo liebe Delphi-Community,
ich soll für unseren Lehrer, der uns Datenbanken über Records anfertigen lässt, eine selbige erstellen.
Ich habe nun das Problem das ich irgendwie auf dem Schlauch stehe und nicht weiß wie ich den gespeicherten Text in das StringGrid ausgeben lasse. Könnt ihr mir helfen damit ich endlich weiter machen kann und mich dann am speichern und laden probieren kann :D .
MfG Sys
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85:
| unit UTRaid;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Grids, StdCtrls;
type tVerbund = record dkp : Integer; Name : String; Item : String; Boss : String; end; tFeld = array[0..1000] of tVerbund;
TForm1 = class(TForm) Raid1: TStringGrid; DSatz: TLabel; Button1: TButton; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Edit4: TEdit; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Button2: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private public end;
var Form1: TForm1; Raid : tFeld; datensatznummer : Integer;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject); var i : Integer; begin Raid1.Cells[1,0] := 'Name'; Raid1.Cells[2,0] := 'DKP'; Raid1.Cells[3,0] := 'Item'; Raid1.Cells[4,0] := 'Boss';
FOR i:=1 to 9 DO Raid1.Cells[0,i] := IntToStr(i); datensatznummer := 1; DSatz.Caption := IntToStr(datensatznummer); end;
procedure TForm1.Button1Click(Sender: TObject); begin DSatz.Caption := IntToStr(datensatznummer);
Raid[datensatznummer].Name := Edit1.Text; Raid[datensatznummer].DKP := StrToInt(Edit2.Text); Raid[datensatznummer].Item := Edit3.Text; Raid[datensatznummer].Boss := Edit4.Text;
inc(datensatznummer); DSatz.Caption := IntToStr(datensatznummer);
Edit1.Text := ''; Edit2.Text := ''; Edit3.Text := ''; Edit4.Text := ''; end;
procedure TForm1.Button2Click(Sender: TObject); begin end;
end. |
Moderiert von
Narses: Anhang als Code eingefügt.
ZeitGeist87 - Di 15.12.09 12:29
Und dein Lehrer spielt World of Warcraft? (=
Systanas - Di 15.12.09 12:36
Nee, der spielt sowas nicht :D ! Wir durften uns ein Thema aussuchen und da ich gelegentlich mal für meinen Bruder spiele hab ich mir gedacht verbinde ich das nützliche mit dem praktischen und mach ne Raid Datenbank ^^ unserm Lehrer is das schnupee Hauptsache eine Datenbank.
LG
Wolle92 - Di 15.12.09 13:01
dann bring ihn dazu, WoW zu spielen... mit dem ganzen kurs... Info-LK@Ulduar bockt doch :P
Systanas - Di 15.12.09 13:54
Ne lieber nich ... wenn wir wipen bekommen wir ne 6 oder so ^^.
@Wolle92 glückwunsch zum 4. Platz :D
@Topic ... weiß einer wie man das macht? Das ausgeben im StringGrid (Name: 'Raid' ^^).
.pas Datei ist ja im Anhang!
ZeitGeist87 - Di 15.12.09 14:32
Du lässt einfach eine Schleife über Raid laufen fügst mit jedem Durchlauf die Daten aus Raid[datensatznummer].<Feld> in Grid.cells[x,y] ein :)
Der Nachteil an dem Aufbau in deiner .pas:
Du hast die Größe des Records fix auf 1.000 gestellt. Sind weniger Datensätze drin, werden dennoch 1.000 aufgelistet.
Hast du mehr als 1.000 bekommst du eine Zugriffsverletzung.
Abhilfe schaffen
DYNAMISCHE ARRAYS
LG
Stefan
Systanas - Di 15.12.09 15:02
Boah ich bin ein Knubb ^^,
Danke!
Jetzt klappts :D , jetz muss ich irgendwie noch das Speichern und Laden in eine .txt Datei realisieren!
MfG
ZeitGeist87 - Di 15.12.09 15:05
Willst du das StringGrid speichern oder den Record ;-)
Systanas - Di 15.12.09 15:10
Tja ich glaube da hab ich mir für mein wissen ein wenig zuviel vorgenommen :'(
Ich denke ich will das StringGrid speichern d.h. irgendwie in einer Datei Speichern sodass ich das im StringGrid wieder abrufen kann beim nächsten start.
Ich werde da wohl bissl warten müssen bis da mein wissens stand wächst denn was ich nicht im ansatz selbst machen kann hilft mir ja auch nich :D ABER es wäre cool wenn mir das jemand erklären bzw. im Quellcode aufschreiben kann sodass mein programm funktioniert und ich das nutzen kann, wird dann natürlich nicht für meinen Lehrer implementiert ist ja nicht meine arbeit :)
LG
ZeitGeist87 - Di 15.12.09 15:24
Mir fallen gerade zig Ansätze ein.
Ein Beispiel, bei dem du auch was über INIfiles lernst.
Du schreibst oben in deine
uses noch die
INIFILES dazu.
Wie INI benutzen
Deklariere eine globale Variable
INI vom Type
TINIFile.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| function erzeugeINI(Datei: String): Boolean; begin; result:= false; try INI:= TINIFile.create(Datei); finally result:= true; end; end; |
Der Übergabeparameter ist so gehalten, dass du das Ganze mit einem Opendialog kompinieren kannst.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| if opendialog1.execute then begin if erzeugeINI(opendialog1.filename) then begin end else begin messagebox(application.handle, pchar('Beim Erzeugen der INI gab es Probleme'), pchar('INI erzeugen'), MB_IconWARNING); exit; end; end; |
Danach kannst du deine Daten speichern, indem du für jede Datensatznummer deines Records eine neue Sektion in der INI anlegst
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| function speichereDatensatz(Nummer: Integer): Boolean; begin; result:= false; try
INI.WriteString(IntToStr(Nummer), 'Raid', <DeinRecord>[Nummer].Raid); INI.WriteString(IntToStr(Nummer), 'DKP', <DeinRecord>[Nummer].DKP); INI.WriteString(IntToStr(Nummer), 'Boss', <DeinRecord>[Nummer].Boss); finally result:= true; end; end; |
Zu guter Letzt schließen wir die INI,
nachdem alles geschrieben ist.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| function closeINI: Boolean; begin; result:= false; try INI.free; finally result:= true; end; end; |
Anmerkung:: Der Ansatz ist sehr sehr rudimentär und ich würde auch davon abraten, INI global zu nutzen und von Funktion zu Funktion offen zu halten.
Das Laden funktioniert analog über
INI.READSTRING.
LG
Stefan
Systanas - Di 15.12.09 15:57
Ok, soweit mir das möglich war hab ich das im großen und ganzen verstanden. Das einzigste was ich nicht zuordnen kann ist
der OpenDialog. Das ist mir noch völlig unklar 1. Was das ist 2. Wohin das kommt (Quelltext) und 3. Wozu das gut ist?
EDIT: Achso, das schließen der INI. Wie soll ich das denn benutzen? In den Speicher Button mit rein schreiben ? :?:
Wäre noch nett wenn du mir das erklären könntest den rest versuche ich nachher mal zu implementieren und zu testen!
Danke schon einmal für die Mühe!
LG
ZeitGeist87 - Di 15.12.09 16:00
Kein Problem.
Der Opendialog ist ein Objekt, welches du oben im Reiter "Dialoge" findest.
Du kennst doch diese Fenster, die sich öffnen, wenn du etwas speichern/öffnen möchtest.
Genau das ist der Dialog ;-)
Zu deiner zweiten Frage:
Ich drücks mal grob aus
1. INI erzeugen
2. Schleife über Raid laufen lassen
3. Speichern des Datensatzes
4. alles gespeichert -> INI schließen.
LG
Stefan
Systanas - Di 15.12.09 17:11
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143:
| unit UTRaid;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Grids, StdCtrls,INIFiles;
type tVerbund = record dkp : Integer; Name : String; Item : String; Boss : String; end; tFeld = array[0..1000] of tVerbund;
TForm1 = class(TForm) Raid1: TStringGrid; DSatz: TLabel; Button1: TButton; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Edit4: TEdit; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Button2: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private public end;
var Form1: TForm1; Raid : tFeld; datensatznummer : Integer; INI : TIniFile;
implementation
{$R *.dfm}
function erzeugeINI(Datei: String): Boolean; begin result:= false; try INI:= TINIFile.create(Datei); finally result:= true; end; end;
procedure TForm1.FormCreate(Sender: TObject); var i : Integer; begin Raid1.Cells[1,0] := 'Name'; Raid1.Cells[2,0] := 'DKP'; Raid1.Cells[3,0] := 'Item'; Raid1.Cells[4,0] := 'Boss';
FOR i:=1 to 9 DO Raid1.Cells[0,i] := IntToStr(i); datensatznummer := 1; DSatz.Caption := IntToStr(datensatznummer); end;
procedure TForm1.Button1Click(Sender: TObject); begin DSatz.Caption := IntToStr(datensatznummer);
Raid[datensatznummer].Name := Edit1.Text; Raid[datensatznummer].DKP := StrToInt(Edit2.Text); Raid[datensatznummer].Item := Edit3.Text; Raid[datensatznummer].Boss := Edit4.Text;
inc(datensatznummer); DSatz.Caption := IntToStr(datensatznummer);
Edit1.Text := ''; Edit2.Text := ''; Edit3.Text := ''; Edit4.Text := ''; end;
procedure TForm1.Button2Click(Sender: TObject); var i:integer; begin Raid1.rowcount:=datensatznummer; Raid1.ColCount:=5; for i:=1 to datensatznummer do begin Raid1.Cells[1,i]:= Raid[i].Name; Raid1.Cells[2,i]:= floattostr(Raid[i].dkp); Raid1.Cells[3,i]:= Raid[i].Item; Raid1.Cells[4,i]:= Raid[i].Boss; end;
end;
function speichereDatensatz(datensatznummer: Integer): Boolean; begin; result:= false; try INI.WriteString(IntToStr(datensatznummer), 'Name', Raid[datensatznummer].Name); INI.WriteString(IntToStr(datensatznummer), 'DKP', IntToStr(Raid[datensatznummer].DKP)); INI.WriteString(IntToStr(datensatznummer), 'Boss', Raid[datensatznummer].Boss); INI.WriteString(IntToStr(datensatznummer), 'Item', Raid[datensatznummer].Item); finally result:= true; end; end;
function closeINI: Boolean; begin; result:= false; try INI.close; finally result:= true; end; end; end. |
Ok, dafür bin ich iwie zu dumm das versteh ich noch nicht :( .
Hoffe trotzdem das wir das zusammen iwie fixen und zum laufen bekommen. Also so wie der Text oben steht hab ich erstmal die functions rein kopiert und umgeschrieben bekomme aber ziemlich viele Fehler:
Quelltext
1: 2: 3: 4: 5: 6: 7:
| Build [Hint] UTRaid.pas(52): Value assigned to 'erzeugeINI' never used [Hint] UTRaid.pas(109): Value assigned to 'speichereDatensatz' never used [Error] UTRaid.pas(124): Undeclared identifier: 'close' [Error] UTRaid.pas(135): Undeclared identifier: 'Nummer' [Error] UTRaid.pas(135): Incompatible types: 'String' and 'Integer' [Fatal Error] TRaid.dpr(5): Could not compile used unit 'UTRaid.pas' |
Puuh ganz schön schwer ich hab noch einen langen weg vor mir!
Bitte erleuchte mich weiser Mann ! :D
LG
Moderiert von
Narses: Code- durch Delphi-Tags ersetzt
JDF - Di 15.12.09 19:03
Hallo Systanas!
Du hast sehr gute Hilfen von ZeitGeist87 erhalten.
Bitte denke mal über folgend Punkte nach:
1. die Gültigkeitsbereiche deiner Variablen und Funktionen,
2. Objekte kann man nur nutzen wenn man sie erzeugt hat,
3. "Nummer" ist nicht gleich "datensatznummer".
die Variablen sollten private Variablen des Formulars sein:
Delphi-Quelltext
1: 2: 3:
| Raid : tFeld; datensatznummer : Integer; INI : TIniFile; |
diese Funktionen sollten als Methoden des Formulars definiert sein:
Delphi-Quelltext
1: 2: 3: 4:
| function erzeugeINI(Datei: String): Boolean; function speichereDatensatz(datensatznummer: Integer): Boolean; function closeINI: Boolean; function ladeDatensatz(datensatznummer: Integer): Boolean; |
Gruß
Jürgen
Systanas - Di 15.12.09 19:21
JDF hat folgendes geschrieben : |
Bitte denke mal über folgend Punkte nach:
1. die Gültigkeitsbereiche deiner Variablen und Funktionen,
2. Objekte kann man nur nutzen wenn man sie erzeugt hat,
3. "Nummer" ist nicht gleich "datensatznummer".
Delphi-Quelltext 1: 2: 3:
| Raid : tFeld; datensatznummer : Integer; INI : TIniFile; |
diese Funktionen sollten als Methoden des Formulars definiert sein:
|
Hi Jürgen,
jah der Zeitgeist ist ein ganze netter! Allerdings hab ich ja schon zugegeben das ich noch nicht so die Ahnung davon habe und ich es mal versuchen würde aber mir die HIntergründe noch fehlen ich mich trotzdem freuen würde wenn ich das Programm zu meiner unterstützung nutzen könnte.
Also,
1. Wie meinst du das? :D
2. Worauf genau bezogen (welches Obejekt?)
3. nicht? was ist es dann?
Zu den Variablen die sind unter var in den globalen drinne!
Zu den methoden: Die hatte ich unter Public deklariert, allerdings hatte er trotzdem gemeckert deswegen hab ich sie rausgenommen.. was er jetz aber immernoch macht >.<
Ich bitte euch nicht so streng zu sein :D
LG
JDF - Mi 16.12.09 10:20
Hi Systanas!
zu 3. bezieht sich auf eine Fehlermeldung
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| [Error] UTRaid.pas(135): Undeclared identifier: 'Nummer'
function ladeDatensatz(datensatznummer: Integer): Boolean; begin; result:= false; try INI.ReadString(IntToStr(datensatznummer), 'Name', Raid[Datensatznummer].Name); INI.ReadString(IntToStr(datensatznummer), 'DKP', Raid[N U M M E R].DKP); INI.ReadString(IntToStr(datensatznummer), 'Boss', Raid[Nummer].Boss); INI.ReadString(IntToStr(datensatznummer), 'Item', Raid[datensatznummer].Item); finally result:= true; end; end; |
zu 2. Das TIniFile-Objekt.
Du hast in deinem Programm die Funktion "erzeugeINI" nicht aufgerufen.
Die Objektfreigabe gehört ebenfalls zu einem guten Programm, also den Aufruf
der Funktion "closeINI" nicht vergessen.
zu 1.
In der ObjektOrientiertenProgrammierung sollte man globale Variablen nur mit größter Vorsicht einsetzen.
z.B. Du erstellst mehrere Instanzen deines Formulars und Alle greifen auf die eine INI-Variable zu
--> Bei angenommenen 4 Formular-Instanzen würden 3 TIniFile-Instanzen im Nirvana verschwinden, da die
INI-Variable nur die Referenz zu einem Objekt halten kann.
Also: die INI-Variable in den "privat"-Bereich deines Formulars.
Und stell Dir mal das Durcheinander mit dem Satzzeiger "datensatznummer" und dem "Raid"-Record vor.
Darum: wenn Objektorientiert, dann alle intern verwendeten Variablen ins Formular!
Mit den Funktionen verhält es sich ähnlich:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| type TForm1 = class(TForm) ... private INI : TIniFile; function erzeugeINI(Datei: String): Boolean; ... public ... end;
function TForm1.erzeugeINI(Datei: String): Boolean; begin ... end; |
Gruß
Jürgen
ZeitGeist87 - Mi 16.12.09 11:59
Wunderschönen guten Morgen!
Danke Jürgen, dass du weitergemacht hast ;-)
Ich hab nicht mehr viel hinzuzufügen außer, dass in der Funktion closeINI es INI.free; heißen muss :)
In aller Eile hab ich das vollkommen übersehen.
LG
Stefan
elundril - Mi 16.12.09 12:03
Kleine Frage, warum INIs anstelle von typisierten Dateien? Würden die sich bei einem Record nicht geradezu aufdrängen?
lg elundril
ZeitGeist87 - Mi 16.12.09 12:15
ZeitGeist87 hat folgendes geschrieben : |
Mir fallen gerade zig Ansätze ein.
Ein Beispiel, bei dem du auch was über INIfiles lernst.
...
|
JDF - Mi 16.12.09 13:04
Hi elundril!
Die Frage nach den typisierten Dateien hatte ich mir auch gestellt.
Aber die Definition des Records
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| tVerbund = record dkp : Integer; Name : String; Item : String; Boss : String; end; |
ist mit den großen Strings angelegt.
Das Speichern in typisierten Dateien ist aber nur mit ShortStrings (1..255 Zeichen, z.B. String[255] ) problemlos ausführbar.
Die Änderung des Record wäre bestimmt nicht das Problem, aber bei eventuellen Erweiterungen der Record-Struktur passen die bereits erfassten Daten nicht mehr. Und die Einarbeitung in die Dateiarbeit ist auch nicht ohne.
Für einen Beginner sind das zu viele Stolperfallen.
Wir wollen doch einen begeisterten Delphi-Programmierer gewinnen.
Gruß
Jürgen
ZeitGeist87 - Mi 16.12.09 13:07
Beim Beispiel hier mit World of Warcraft würde es sogar funktionieren, da die Namen der Gegner und Gegenstände ziemlich kurz gehalten sind und nicht über 255 hinausgehen.
Aber wie gesagt, ich fand diese Möglichkeit mit eine der einfachsten.
Somit lernt er gleich für die Zukunft.
Wer jetzt sagt, Inifiles sind out, der denkt nicht nach. ;-)
elundril - Mi 16.12.09 15:23
Sag ich nicht, sag ich nicht, ich speichere die Einstellungen all meiner Programme immer noch in INI-Files weil diese Einfach am Portabelsten sind und auch besser zu löschen als irgendwelche Registryeinträge. Ich dachte mir nur das es sicher erwähnenswert ist, da man auch dann tieferen Einblick in Dateioperationen bekommt und es sicher für die Fähigkeiten förderlich ist.
lg elundril
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!