Einzelnen Beitrag anzeigen

taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.990 Beiträge
 
Delphi 7 Professional
 
#28

Re: StringGrid Zeile per Mausclick auslesen

  Alt 5. Okt 2008, 19:20
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:
for i:=0 to Stelle-1 do begin
  seek(ChemDat,0);
  read(ChemDat,Chem) ;
  write(ChemDatH,Chem);
  end;
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.

Vorschlag für neue Variante:

Delphi-Quellcode:
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;
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.

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...


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
Ralph
  Mit Zitat antworten Zitat