![]() |
StringGrid Zeile per Mausclick auslesen
Hallo Leute,
bin ein Newbie und habe folg. Problem: Über Editfelder werden Daten in ein StringGrid eingelesen, gespeichert und sortiert. Habe auch `ne Suche, die gewünschte Datensätze in den Editfeldern ausgibt. Möchte nun zusätzlich, dass beim anklicken einer Zeile die Editfelder mit den entsprechenden Daten gefüllt werden. Wie krieg ich das hin? (Options.goRowSelect ist true) |
Re: StringGrid Zeile per Mausclick auslesen
Hallo,
du könntest mit dem Event/Ereignis OnSelectCell arbeiten:
Delphi-Quellcode:
Dort wird dir die markierte Zeile und Spalte übergeben.
procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol,
ARow: Integer; var CanSelect: Boolean); begin end; Grüße Klaus |
Re: StringGrid Zeile per Mausclick auslesen
Danke für den Tipp,
komme heute leider nicht mehr dazu, es auszuprobieren. Melde mich morgen wieder mit dem Ergebnis. Schönes WE |
Re: StringGrid Zeile per Mausclick auslesen
Nach reichlich Bastelei bin jetzt soweit, das was ausgegeben wird.
Aber: wg. zeile
Delphi-Quellcode:
wird immer der erste Datensatz ausgegeben.
ARow:=Filepos(ChemDat)+1;
Wie krieg ich den aktuellen (angeklickten) Datensatz? Hier der Code
Delphi-Quellcode:
Wäre prima, wenn jemand `nen Tipp hätte.
procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean); begin If CanSelect=True then seek(ChemDat,0); with Chem do ARow:=Filepos(ChemDat)+1; begin read(ChemDat,Chem); EditNr.Text:=(StringGrid1.Cells[1,ARow]); EditName.Text:=StringGrid1.Cells[2,ARow]; DateTimePicker1.Date:=StrToDate(StringGrid1.Cells[4,ARow]); end; end; |
Re: StringGrid Zeile per Mausclick auslesen
Zitat:
|
Re: StringGrid Zeile per Mausclick auslesen
Oh Mann was bin ich doof.
Zeile entfernt und schon klappt es. Besten Dank BTW Möchte den in den Edit-Feldern angezeigten Datensatz im StringGrid löschen. Wie stelle ich das an? |
Re: StringGrid Zeile per Mausclick auslesen
Spontan würde ich sagen:
- StringGrid zeilenweise durchlaufen und Inhalte vergleichen - wenn gefunden, dann nachfolgende Zeilen aufrücken lassen und RowCount neu setzen |
Re: StringGrid Zeile per Mausclick auslesen
Ein Datenvergleich ist m.E. nicht nötig. Habe die Daten im Edit. Demzufolge müsste der Zeiger doch auf diesen bzw. den nächsten Datensatz zeigen.
Ergo: Filepos irgendwie auswerten und anschließend RowCount um 1 zuurücksetzen und dann das Grid neu einlesen. Soweit meine Idee. Aber mit der Umsetzung haperts. |
Re: StringGrid Zeile per Mausclick auslesen
Nochmal zum Verständnis: wenn Du eine Zelle im StringGrid anklickst, werden dessen Daten in den Edits angezeigt?
|
Re: StringGrid Zeile per Mausclick auslesen
Habs nochmal gecheckt. Egal, welche Zelle ich anklicke, der entsprechende Datensatz wird in den Edits gezeigt.
|
Re: StringGrid Zeile per Mausclick auslesen
Und das soll ja so sein, oder? Nun soll diese entsprechende Zeile gelöscht werden?
|
Re: StringGrid Zeile per Mausclick auslesen
korrekt.
Zur Info: Soll als Beleg zum Thema Dateiarbeit ein Proggi schreiben. Da ich Chemielehrer bin, versuch ich eine Chemikalienverwaltung (Zu- und Abgänge; Bestand). Da es ja mal passieren kann, dass eine Chemikale nicht mehr verwendet wird oder Fehleingaben passieren, soll dieser Datensatz gelöscht werden können. |
Re: StringGrid Zeile per Mausclick auslesen
Dann versuch es mal ganz simpel mit
Delphi-Quellcode:
Sollte eigentlich so funktionieren, hab ich aber nicht ausprobiert, ich mache zu wenig mit StringGrid.
StringGrid.Rows.Delete(StringGrid.Row);
|
Re: StringGrid Zeile per Mausclick auslesen
Danke für den Tipp.
Melde mich Dienstag abend mit dem Ergebnis. Schönen Sonntag noch. |
Re: StringGrid Zeile per Mausclick auslesen
Zitat:
Delphi-Quellcode:
type
TMyStringGrid = class(TStringGrid); procedure TForm1.Button1Click(Sender: TObject); begin TMyStringGrid(StringGrid1).DeleteRow(ZeilenIndex); end; |
Re: StringGrid Zeile per Mausclick auslesen
Dann eben so ;)
|
Re: StringGrid Zeile per Mausclick auslesen
Hat etwas länger gedauert.
Zunächst mal danke für die Tipps. Als ich am Basteln war stellte ich fest: Fehler in der Denke! Ich mache Folgendes: -Edits auslesen -Datensätze in Datei schreiben -anschließend wieder auslesen und im StringGrid ausgeben Ergo: Durch Löschen im StringGrid ändert sich ja nichts am Dateiinhalt. Da ich nicht alles ummodeln wollte bin ich auf folg. Prozedur gekommen:
Delphi-Quellcode:
Funktioniert auch fast. Datensatz wird gelöscht. In der "Hilfsdatei" ChemDatH fehlt dann der gelöschte Datensatz.
procedure TForm1.DatenLoeschenClick(Sender: TObject);
var i:SmallInt; begin seek(ChemDat,0); Assignfile(ChemDatH,'Hilf'); rewrite(ChemDatH); for i:=0 to Stelle-1 do begin read(ChemDat,Chem) ; write(ChemDatH,Chem); end; seek(ChemDat,Stelle+1); while not eof (Chemdat) do begin read(ChemDat,Chem); write(ChemDatH,Chem); end; // bis hierhin klappts seek(ChemDat,0) ; seek(ChemDatH,0); begin read(ChemDatH,Chem); write(ChemDat,Chem); closefile(ChemDatH); end; end; Mit der den letzten Read/Write-Befehlen will ich die aktualisierten Daten wieder in die Ursprungsdatei schreiben. Das tuts aber nicht. Weshalb? 2.Frage: Wie krieg ich die "Hilfsdatei" wieder gelöscht? 3.Frage: Mir scheint das Hin-und Herschreiben etwas umständlich zu sein. Gibts eine elegante Variante? |
Re: StringGrid Zeile per Mausclick auslesen
Moin, Moin.
Nun, vielleicht nicht 2x kopieren, sondern die Originaldatei nach dem ersten Kopieren löschen und die Hilfsdatei umbenennen. Also DeleteFile() und RenameFile() verwenden. // edit: Buchstabendreher, da muss man bei einem Lehrer ja aufpassen :shock: |
Re: StringGrid Zeile per Mausclick auslesen
Muss nachfragen: Du meinst folgendes:
-ChemDat (hat alte Daten) CloseFile und dann DeleteFile anschließend -ChemDatH (hat neue Daten) Closefile und dann Rename und dann Assignfile (brauch sie ja wieder geöffnet)? //bin kein Krümelkacker :lol: |
Re: StringGrid Zeile per Mausclick auslesen
Jooo :thumb:
|
Re: StringGrid Zeile per Mausclick auslesen
Probiers gleich mal aus.
Wäre prima, wenn du mir die Syntax für RenameFile verraten könntest. Sag schon mal Danke :) |
Re: StringGrid Zeile per Mausclick auslesen
Delphi-Quellcode:
Einfach "RenameFile" eintippen, Caret drauf setzen und F1 drücken, dann zeigt die Hilfe (meist) was du wissen möchtest.
function RenameFile(const OldName,NewName:String):Boolean;
|
Re: StringGrid Zeile per Mausclick auslesen
Bin wie gesagt ein absoluter Newbie (bis vor `nem halben Jahr lag Delphi in Griechenland) und auch nicht mehr der Jüngste. Mache das Ganze Nebenbei. Deshalb bleibts nicht aus, dass ich mich dusselig anstelle. Bin auf folg. Probleme gestoßen:
-habe Dateiname folgendermaßen deklariert
Delphi-Quellcode:
Dann müsste
Dateiname:=Opendialog1.FileName;
If Dateiname<>'' then begin AssignFile(ChemDat,Dateiname+'.dat'); rewrite(chemdat); end;
Delphi-Quellcode:
korrekt sein
DeleteFile(Dateiname+'.dat');
-Hilfsdatei wurde über
Delphi-Quellcode:
erstellt
Assignfile(ChemDatH,'Hilf');
Ergo müsste
Delphi-Quellcode:
die Umbenennung erledigen
RenameFile('Hilf',Dateiname+'.dat');
-vor dem Delete hab ich beide Dateien per CloseFile geschlossen -Nun noch
Delphi-Quellcode:
Und es sollte gehen. Tuts aber leider nicht.
AssignFile(ChemDat,Dateiname+'.dat');
edit: Merke gerade: Kann ja gar nicht gehen. Woher soll er den neuen Namen kennen? Oder liege ich da falsch? |
Re: StringGrid Zeile per Mausclick auslesen
Tja, das könnte an (unterschiedlichen) Pfadangaben liegen. TOpenDialog gibt einen Dateiname inklusive eines Pfades zurück. Diese Information verwendest du für "Dateiname". Den Namen der Hilfsdatei erstellst du direkt im Programmcode - aber ohne eine Pfadangabe. Dadurch wird die Hilfsdatei im gerade aktuellen Verzeichnis angelegt. In diesem Verzeichnis wird die Hilfsdatei dann auch umbenannt. Das könnte das gleiche Verzeichnis sein, wird's aber wohl nicht. Die erneute Verwendung von "Dateiname" greift dann ins Leere, da sich die umbenannte (ehemalige) Hilfsdatei ganz woanders befindet.
So, das ist jetzt natürlich Spekulation. Um besser Helfen zu können, musst du konkreter berichten, was nicht funktioniert. |
Re: StringGrid Zeile per Mausclick auslesen
Die Hilf-Datei liegt im selben Pfad wie die eigentliche Datei. Ich poste hier nochmal die komplette Prozedur. Vermutlich hab ich einen Syntaxfehler gemacht, den der Debugger nicht zeigt.
Delphi-Quellcode:
Das Programm wird in einem anderen Verzeichnis gestartet. Die Dateien werden z.Zt. direkt auf Laufwerk D abgelegt. Dort finde ich sowohl die angelegte Datei als auch die Hilf-Datei.
procedure TForm1.DatenLoeschenClick(Sender: TObject);
var i:SmallInt; begin seek(ChemDat,0); Assignfile(ChemDatH,'Hilf'); rewrite(ChemDatH); for i:=0 to Stelle-1 do begin read(ChemDat,Chem) ; write(ChemDatH,Chem); end; seek(ChemDat,Stelle+1); while not eof (Chemdat) do begin read(ChemDat,Chem); write(ChemDatH,Chem); end; // bis hierhin klappts CloseFile(ChemDat) ; CloseFile(ChemDatH) ; DeleteFile(Dateiname+'.dat'); RenameFile('Hilf',Dateiname+'.dat'); AssignFile(ChemDat,Dateiname+'.dat'); end; Allerdings muss ich mich jetzt verabschieden. Mein Kind braucht einen Chauffeur. Werd mal drüber schlafen. Melde mich morgen wieder. Vielen Dank für deine bisherige Hilfe. |
Re: StringGrid Zeile per Mausclick auslesen
Zitat:
Anmerkung: Du arbeitest offenbar gern mit globalen Variablen, z.B. Chem, ChemDat, ChemDatH - ist vielleicht am Anfang recht bequem. Man sollte es aber tunlichst vermeiden (und sich gar nicht erst angewöhnen)! Wird das Programm umfangreicher sind das die "besten" Fehlerquellen. Auch gehört zum "rewrite()" eine Fehlerbehandlung, schau' mal in die DelphiHilfe unter dem Stichwort "IOResult". |
Re: StringGrid Zeile per Mausclick auslesen
@taaktaak
Sorry, hat ein bisschen länger gedauert. Dein Hinweis zur Globalisierung hat insofern geholfen, dass ich einen anderen Fehler beseitigen konnte. Da du den Quelltext für Fehlerfrei erachtet hast, bin ich nochmal alles durchgegangen und siehe da, der Fehler lag woanders. Beim Löschen schließe ich die Datei. Der nachfolgende Aufruf im Programm erwartet aber eine geöffnete Datei. Da ich Probleme mit dem Umbenennen hatte bin ich wieder zur ursprünglichen Variante zurückgekehrt. Funktioniert theoretisch. Folgendes Problem: -Reihenfolge der eingegebenen Datensätze: zeile1 / zeile2 / losch/ zeile3 / zeile4 -nach Aufruf der Löschprozedur für Datensatz losch lautet die Reihenfolge: zeile2 / zeile2 / losch/ zeile3 / zeile4 -in der Hilf-Datei steht die Reihenfolge: zeile2 / losch/ zeile3 / zeile4 Schlußfolgerung: In der ChemDat wurde statt des 3.Datensatzes der 1. gelöscht und der 2. Datensatz als 1. eingetragen. Vielleicht kannst du rausfinden wo es da hakt. Hier zunächst die Prozedur für die verwendete Suchfunktion:
Delphi-Quellcode:
Folg. Quellcode soll löschen (Hab mal kommentiert, was ich damit erreichen will):
procedure suchNam(Name:string; var ex:boolean; var Position:SmallInt);
//Chemikaliensuche nach Namen begin seek(ChemDat,0); while not Eof(ChemDat) do begin read(ChemDat,Chem); If Name=Chem.Name then begin ex:=true; Position:=Filepos(ChemDat)-1; end; end; end;
Delphi-Quellcode:
Die Hilfsdatei habe ich nach deinem Tipp lokal definiert. Die ChemDat muss m.E. global bleiben, da viele Prozeduren darauf zugreifen.
procedure TForm1.DatenLoeschenClick(Sender: TObject);
var such:string; exist:boolean; Stelle:SmallInt; i:SmallInt; z,s:Integer; ChemDatH: TChemDat; begin Stelle:=0; seek(ChemDat,0); Assignfile(ChemDatH,'Hilf'); rewrite(ChemDatH); such:=EditName.Text; suchNam(Chem.Name, exist, Stelle); //Aufruf Suchprozedur (s.o.) If exist then for i:=0 to Stelle-1 do begin seek(ChemDat,0); read(ChemDat,Chem) ; //Bis zur gesuchten Stelle (Name aus Edits) write(ChemDatH,Chem); //Bis dahin gelesenes in die Hilfsdatei schreiben end; seek(ChemDat,Stelle+1); // zu löschenden Datensatz überspringen while not eof (Chemdat) do begin read(ChemDat,Chem); //Rest lesen und schreiben write(ChemDatH,Chem); end; seek(ChemDatH,0); read(ChemdatH,Chem); // HilfsDatei auslesen seek(ChemDat,0); write(ChemDat,Chem); //ChemDat neu schreiben CloseFile(ChemDatH); //Erase(ChemDatH); seek(ChemDat,0); for i:=0 to FileSize(ChemDat)-1 do begin StringGrid1.Cells[0,i]:=IntToStr(FilePos(ChemDat)); read(ChemDat,Chem); with Chem do //komplette ChemDat lesen und im StringGrid ausgeben begin StringGrid1.Cells[1,i+1]:=IntToStr(Chem.BNum); StringGrid1.Cells[2,i+1]:=Chem.Name; StringGrid1.Cells[3,i+1]:=IntToStr(Chem.Bestand); StringGrid1.Cells[4,i+1]:=Chem.Datum; end; Gruß Michael |
Re: StringGrid Zeile per Mausclick auslesen
Moin, Moin Michael.
Zur Suchfunktion: Du hast eine Prozedur daraus gemacht. Typischerweise würde das tatsächlich eine Funktion sein, die als Ergebnis die gefundene Position zurückgibt. Wird der Datensatz nicht gefunden, wäre das Ergebnis -1 (da der erste Datensatz die Position 0 hat). Die Lösch-Prozedur ist zumindest an dieser Stelle falsch:
Delphi-Quellcode:
Da in jedem Schleifendurchlauf seek() aufgerufen wird, bewegst du dich nicht durch die Datei, sondern bleibst immer an der ersten Position. Das Auslesen der Hilfsdatei und (Neu)Schreiben von ChemDat ist falsch, da nur der erste Datensatz gelesen und geschrieben wird.
for i:=0 to Stelle-1 do begin
seek(ChemDat,0); read(ChemDat,Chem) ; write(ChemDatH,Chem); end; Vorschlag für neue Variante:
Delphi-Quellcode:
Wesentlicher Unterschied ist vielleicht, das die Prozedur in mehrere "Häppchen" unterteilt ist. Das ist in diesem Fall vielleicht übertrieben, hilft aber immer, den Überblick zu behalten und Fehler zu vermeiden oder schneller eingrenzen zu können. Auch werden die Dateien in jeder Funktion/Prozedur geöffnet und wieder geschlossen. Auch das vermeidet Fehler. Das assignfile() müsste natürlich nicht jedesmal wieder erfolgen, schadet aber auch nicht. Es gibt für den Grad der Unterteilung wohl kein RICHTIG und FALSCH, das muss jeder für sich entscheiden.
procedure TForm1.DatenLoeschenClick(Sender:TObject);
var DelPos : Integer; function NamePos(Name:String):Integer; begin Result:=-1; assignfile(ChemDat,Dateiname+'.dat'); reset(ChemDat); while not Eof(ChemDat) do begin read(ChemDat,Chem); if Chem.Name=Name then begin Result:=FilePos(ChemDat); Break end end; closefile(ChemDat) end; procedure DeleteRecord(DelIdx:Integer); var RecIdx : Integer; begin assignfile(ChemDat,Dateiname+'.dat'); reset(ChemDat); assignfile(ChemDatH,'Hilf'); rewrite(ChemDatH); RecIdx:=-1; while not Eof(ChemDat) do begin read(ChemDat,Chem); inc(RecIdx); if RecIdx<>DelIdx then write(ChemDatH,Chem) end; closefile(ChemDat); closefile(ChemDatH) end; procedure RebuildDataFile; begin assignfile(ChemDat,Dateiname+'.dat'); rewrite(ChemDat); assignfile(ChemDatH,'Hilf'); reset(ChemDatH); while not(eof(ChemDatH)) do begin read(ChemDatH,Chem); write(ChemDat,Chem); end; closefile(ChemDat); closefile(ChemDatH); erasefile(ChemdatH) end; procedure RefillGrid; var i : Integer; begin assignfile(ChemDat,Dateiname+'.dat'); reset(ChemDat); for i:=1 to FileSize(ChemDat) do begin read(ChemDat,Chem); with StringGrid1 do with Chem do begin Cells[0,i1]:=Format('%.3d',[i]); Cells[1,i1]:=IntToStr(BNum); Cells[2,i1]:=Name; Cells[3,i1]:=IntToStr(Bestand); Cells[4,i1]:=Datum end end; closefile(ChemDat); end; begin DelPos:=NamePos(EditName.Text); if DelPos>=0 then begin DeleteRecord(DelPos); RebuildDataFile; RefillGrid end end; Den Code konnte ich nicht testen, da es ja nur ein Ausriss ist. Würde mich auch wundern, wenn gar kein "Fehlerchen" drin ist. Aber wenn, dann sollte er schnell zu entdecken sein. Lass mich mal überraschen, ob es dir hilft... :hi: PS: Meine Codeformatierung weicht vom Standard ab. Das mache ich aber schon so lange so, dass ich in meinem Alter davon nicht mehr abweichen mag |
Re: StringGrid Zeile per Mausclick auslesen
@ taaktaak
Großes Dankeschön für deine Mühe. Kann das Ganze aber leider erst am WE testen (büffel z. Zt. für `ne Klausur). Melde mich, sobald ich ein Ergebnis habe. Schönen Abend noch! Michael PS: Deine Formatierung erscheint mir logischer, aber da der Empfänger des Proggis die Formatierung so möchte, mach ich es halt so. PPS: Habe in einigen Tagen das 46. Jahr geschafft. Und jetzt gehts in die Heia. |
Re: StringGrid Zeile per Mausclick auslesen
Guten Morgen Ralph,
die Neugier hat mich nicht losgelassen. Du hattest recht, mit ein paar kleinen Änderungen läuft deine Prozedur prima durch. Habe noch ein kleines Problem, für das ich nach 3 Stunden probieren noch keine Lösung habe: Beim Refill wird der dem gelöschten Datensatz nachfolgende Datensatz doppelt im StringGrid ausgegeben. In der Rebuild-Datei (und auch in 'Hilf') ist alles i.O. Beim Schließen der Datei lasse ich das StringGrid entsprechend der Anzahl der Einträge leeren. Wg. dem doppelten Datensatz bleibt dann aber der letzte im StringGrid stehen und ist dann beim erneuten öffnen der Datei natürlich immer noch da. Wäre super, wenn du mir noch ein letztes Mal helfen könntest. Irgendwie bin ich blind und finde den Fehler nicht. Meines Erachtens sollte er ja in der Refill-Prozedur stecken. Nachfolgend der aktuelle Quelltext deiner Löschprozedur. Die kommentierten Zeilen habe ich geändert.
Delphi-Quellcode:
Übrigens habe ich deine Prozedur zum Anlass genommen, das Programm zu überarbeiten. Mittlerweile ist mir klar, warum das Proggi, je länger es wurde, umso mehr Fehlermeldungen produzierte. Habe rigoros reset und closeFile benutzt. Und schon verringerte sich die Fehlerzahl.
procedure TForm1.DatenLoeschenClick(Sender: TObject);
var DelPos : Integer; ChemDatH : TChemDat; //nicht mehr global function NamePos(Name:String):Integer; begin Result:=-1; //assignfile(ChemDat,Dateiname+'.dat'); //Fehlermeldung - nach auskommentieren i.O. reset(ChemDat); while not Eof(ChemDat) do begin read(ChemDat,Chem); if Chem.Name=Name then begin Result:=FilePos(ChemDat)-1; //Filepos -1 (löscht sonst nachfolgenden Satz) Break end end; closefile(ChemDat) end; procedure DeleteRecord(DelIdx:Integer); var RecIdx : Integer; begin //assignfile(ChemDat,Dateiname+'.dat'); //Fehlermeldung - nach auskommentieren i.O. reset(ChemDat); assignfile(ChemDatH,'Hilf'); rewrite(ChemDatH); RecIdx:=-1; while not Eof(ChemDat) do begin read(ChemDat,Chem); inc(RecIdx); if RecIdx<>DelIdx then begin write(ChemDatH,Chem) end; end; closefile(ChemDat); closefile(ChemDatH); end; procedure RebuildDataFile; begin assignfile(ChemDat,Dateiname); //+'.dat' entfernt , da er sonst lauter dat anhängt rewrite(ChemDat); assignfile(ChemDatH,'Hilf'); reset(ChemDatH); while not(eof(ChemDatH)) do begin read(ChemDatH,Chem); write(ChemDat,Chem); end; closefile(ChemDat); closefile(ChemDatH); // erase(ChemdatH) nur auskommentiert, um Inhalt zu checken end; procedure RefillGrid; var i : Integer; begin assignfile(ChemDat,Dateiname); reset(ChemDat); for i:=1 to FileSize(ChemDat) do begin read(ChemDat,Chem); with StringGrid1 do with Chem do begin Cells[1,i]:=IntToStr(BNum); Cells[2,i]:=Name; Cells[3,i]:=IntToStr(Bestand); Cells[4,i]:=Datum end end; closefile(ChemDat); end; begin DelPos:=NamePos(EditName.Text); if DelPos>=0 then begin DeleteRecord(DelPos); RebuildDataFile; RefillGrid end ; EditNr.Clear; EditName.Clear; EditZugang.Text:=IntToStr(0); EditAbgang.Text:=IntToStr(0); DateTimePicker1.Date:=Date(); end; Beste Grüße Michael PS: hatte beim nochmaligen durchlesen gerade `ne Idee fürs RefillGrid: vorher alles leeren(habe RowCount festgelegt). Dann sollte es doch leer sein. Probiere es aber erst heute nachmittag aus. |
Re: StringGrid Zeile per Mausclick auslesen
Guten Morgen Michael.
Freut mich, dass ich dir schon etwas weiterhelfen konnte. Die Anzeige der überflüssigen Zeile im Grid ist logisch, da ich es im Code leider nicht berücksichtigt habe. Das Grid verhält sich allerdings anders, als man vielleicht erwartet: Durch Verringerung von RowCount werden die Inhalte der reduzierten Zeilen nicht gelöscht. Vergrößert man RowCount anschließend wieder, werden die vermeintlich entfernten Zeileninhalte wieder angezeigt. Tatsächlich gelöscht werden Einträge mit "StringGrid.Rows[..].Clear". In deinem konkreten Fall gibt es (wie fast immer) verschiedene Möglichkeiten, das gewünschte zu erreichen. Als "Hau-Ruck-Methode" könnte man vor dem erneuten Füllen des Grids alle vorhandenen Zeilen löschen, die Zeilenanzahl des Grids aber konstant lassen.
Delphi-Quellcode:
Alternativ könnte die Zeilenanzahl immer exakt der Anzahl der Datensätze+FixedRows entsprechen, d.h. nach einer Löschoperation "RowCount:=RowCount-1". Ich mag es aber z.B. nicht, wenn weniger Gridzeilen gezeichnet werden, als bei der verfügbaren Höhe des Controls darstellbar wären. In diesem Fall füge ich immer eine entsprechende Anzahl von Leerzeilen ein - aber das ist Geschmackssache.
procedure RefillGrid;
var i : Integer; begin assignfile(ChemDat,Dateiname); reset(ChemDat); with StringGrid1 do begin for i:=FixedRows to RowCount-1 do Rows[i].Clear; // löscht ALLE Zeilen // oder // RowCount:=RowCount-1; // alternativ for i:=1 to FileSize(ChemDat) do begin read(ChemDat,Chem); with Chem do begin Cells[1,i]:=IntToStr(BNum); Cells[2,i]:=Name; Cells[3,i]:=IntToStr(Bestand); Cells[4,i]:=Datum end end; closefile(ChemDat); end; Mich würde mal interessieren, wieviele Datensätze in deinem Grid voraussichtlich gespeichert werden sollen. Spätestens, wenn du einige Tausend Datensätze im Grid sortieren oder filtern möchtest, wirst du die begrenzten Möglichkeiten des StringGrids an spürbar langen Sortierzeiten erkennen. Wenn derartige Größenordnungen bei dir anfallen, dann sollte das ganze entweder mit einer Datenbank gelöst oder die Datenspeicherung in einer Liste erfolgen und das Grid nur noch zur Anzeige der sichtbaren Daten genutzt werden. |
Re: StringGrid Zeile per Mausclick auslesen
Hallo Ralph,
zu deiner Frage. Ich schrieb am Anfang, dass ich ein Newbie bin. Und zwar absolut. Da ich mit dem Rechner einigermaßen umgehen und ihn auch mal reparieren kann (selbst angeeignet) hab ich beschlossen, berufsbegleitend Informatik zu studieren. Im 2.Semester war Delphi das Thema (1.Semester LOGO). Vorlesung und Seminar im Wechsel. Hauptinhalt: Algorithmierung. Umsetzung in Quelltext sollte in Hausarbeit erfolgen. Hinweis der Seminarleiter: Wenn sie was nicht wissen, nutzen sie die Hilfe (Delphi 2005). Daher rühren auch meine zum Teil naiven Fragen, da diese "Hilfe" nur wenig hilft. Als Beleg sollte über die Semesterpause ein Programm zu einem selbstgewählten Thema/Inhalt angefertigt werden. Vorgabe: Einbinden von Dateiarbeit (wurde im letzten Seminar kurz angeschnitten). Meine Kommilitonen haben größtenteils mathemat. Hintergrund. Ergo: Mathematische Berechnungen. Da ich aus der Chemie komme, hab ich mich für eine Chemikalienbestandsverwaltung entschieden. Normalerweise sollte das eine Datenbank sein. Da wir so was noch nie gemacht haben (und freies Delphi keine DB-Komponente enhält) blieb nur ein StringGrid. Ich habe es auf 200 Datensätze ausgelegt. Also recht klein. Verwenden werde ich das Programm nicht - es gibt recht gute und viel komfortablere Lösungen (auch kostenfrei) am Markt. Ich habe es als Übung angesehen, um sich mit Delphi als Programmierwerkzeug vertraut zu machen. Ich hätte allerdings nicht gedacht, dass es so viel Zeit kostet (arbeite seit Ende Sommersemester dran). Lag vermutlich an meinerseits nicht vorhandener Projektplanung. Im Laufe der Entwicklung wurde es auch immer umfangreicher. Wenn ich das Ganze nicht nächste Woche abgeben müsste, würde ich glatt nochmal von vorn anfangen und vieles anders machen. Stattdessen hab ich mit Hilfe deiner Tipps etwas Struktur in den Quelltext gebracht. Werde mich am WE mal mit dem Abfangen von Fehleingaben weiter beschäftigen. (Ist auch eine Forderung für den Beleg). Wie du siehst: Noch reichlich Arbeit. Bin aber froh, dass es im Großen und Ganzen funktioniert. Wünsche ein angenehmes WE Michael |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:14 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