Autor Beitrag
adfontes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 82

Win7 (64bit), WinXP
Delphi 2010 Prof, Delphi XE2 (Trial)
BeitragVerfasst: Do 01.09.05 16:46 
huhu :) .... hab mal wieder ne frage (Dateien machen mir noch bisschen probleme)...

Ich habe jetzt eine Benutzer Datei angelegt, worin XXX benutzer mit name, vorname, status... über ein record gespeichert sind. Von den Elementen der Datei würde ich nun gern eines löschen, der rest soll aber erhalten bleiben...

bisher hab ich schon versucht die Elemente, ab dem gesuchten element einfach immer eins nach vorne zu verschieben, nur irgendwie funktioniert das gar nicht.... ich glaub der code ist auch total confus, weil ich nicht wirklich weiß wie ich da ran gehn soll :(

ausblenden 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:
procedure TForm2.BitBtn13Click(Sender: TObject);
begin
  AssignFile(DATEI_U,'C:\User.dat');
  Reset(DATEI_U);
  While NOT EOF(DATEI_U) DO
  Begin
    Read(DATEI_U,Benutzer);
    if (ComboBox2.Text=Benutzer.BName) THEN
    begin
      while NOT EOF(Datei_U) DO
      begin
        read(Datei_U,Benutzer);
        seek(DATEI_U,(filepos(DATEI_U)-1));
        write(Datei_U,Benutzer);
        seek(DATEI_U,(filepos(DATEI_U)+1));
      end;

      Label29.Visible:=True;
      Label29.Caption:='Benutzerdaten unwiederruflich gelöscht';

    end;
   end;
  closefile(DATEI_U);
end;


bitte helft mir (und sorry für den miesen code, nur ich kanns nicht besser :( )

greetz
adfontes
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 01.09.05 16:49 
Entweder alle Elemente um eins nach vorne verschieben, oder den letzten an die Stelle des zu löschenden Datensatzes kopieren und das Array um eins verkürzen. Allerdings hat das den Nachteil, dass die eventuell vorhandenen Sortierung verloren geht.
adfontes Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 82

Win7 (64bit), WinXP
Delphi 2010 Prof, Delphi XE2 (Trial)
BeitragVerfasst: Do 01.09.05 19:08 
kannst du mir auch erklären, wie das funktioniert, weil der code von mir da oben zeigt ja nich wirklich ne sinnvolle wirkung...
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Do 01.09.05 19:20 
Auf meiner HP findest du ein Tutorial mit Source zu typisierten Dateien. Dort ist auch eine Variante zum löschen dabei.
adfontes Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 82

Win7 (64bit), WinXP
Delphi 2010 Prof, Delphi XE2 (Trial)
BeitragVerfasst: Do 01.09.05 20:27 
ausblenden volle Höhe 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:
procedure TfrmMain.btnLoeschenClick(Sender: TObject);
var
  aktPos : Integer; // aktuelle Datei-Position
  NeuePos : Integer; // Position für die Verschiebung eines Datensatzes
begin
  aktPos := FilePos(F);
  NeuePos := aktPos;
  Seek(F, aktPos+1); // Gehe zum nächsten Datensatz
  while not eof(F) do begin // Bis zum Datei-Ende alle Datensätze um eins nach vorne verschieben
    Read(F, Adresse); // Datensatz einlesen
    Seek(F, NeuePos); // Gehe an die neue Position für diesen Datensatz
    Write(F, Adresse); // Undd an die neue Position schreiben
    NeuePos := FilePos(F); // Neue Position für den nächsten Datensatz merken
    Seek(F, NeuePos+1); // Gehe zum nächsten Datensatz, der verschoben werden muss
  end;
  Seek(F, FileSize(F)-1); // Gehe zum letzten Datensatz
  Truncate(F); // Den letzten Datensatz abschneiden
  Seek(F, aktPos);
  if eof(F) then begin // Sonderfall: der letzte Datensatz wurde gelöscht
    if FileSize(F) > 0 then begin // Sind überhaupt noch Daten da?
      Seek(F, FileSize(F)-1); // Gehe zum letzten gültigen Datensatz
      Read(F, Adresse);
    end
    else begin // Datei ist leer
      // Initialisierung
      RecordInitialisieren;
    end;
  end
  else begin
    // Datensatz einlesen und an die richtige Position gehen
    Read(F, Adresse);
    Seek(F, FilePos(F)-1);
  end;
  FensterAktualsierung;
end;


ich nehm ja mal an, das da ist der Code-Teil, den ich mir ansehen sollte von deiner HP oder user profile iconjasocul ?

Ist ja gut und schön, wenn ich jetzt einen Code Teil habe, ... nich ich würds gern auch verstehn, sonst bringts mich auch nicht richtig weiter... aus dem grund ein paar fragen zu dem Code, die mir hoffentlich einer beantworten kann...


1.
ausblenden Delphi-Quelltext
1:
  Truncate(F); // Den letzten Datensatz abschneiden					


Habe in der Hilfe mal nach Truncate gesucht, da kommen ne menge Hilfe Themen, aber keins, wo ich so wirklich verstehe, was das ding macht... vor allem ist da überwiegend die Rede von Blob-Daten und ich hab nicht wirklich ne Ahnung was das sein soll :( ... Es steht zwar im Code dahinter "Den letzten Datensatz abschneiden" aber dennoch weiß ich nicht, wie die funktion da überhaupt arbeitet, was ja doch ganz nützlich wäre, wenn ich schon damit arbeite.

2.
Wenn ich den Code oben versuche in meinem bisherigen Code einzubauen bzw. meine Fehler im Vergleich zu dem Code auszubauen, dann bekomm ich immer die Anzeige "INITIALIZATION erwartet ... bekommen" , egal was ich in die zeile nach der Bedingung, in der Truncate steht, schreibe, mal abgesehn von dem "if EOF..." wie es in dem Orginal Code steht, nur ich versteh das nicht so wirklich.

3.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
  if eof(F) then begin // Sonderfall: der letzte Datensatz wurde gelöscht
    if FileSize(F) > 0 then begin // Sind überhaupt noch Daten da?
      Seek(F, FileSize(F)-1); // Gehe zum letzten gültigen Datensatz
      Read(F, Adresse);
    end
    else begin // Datei ist leer
      // Initialisierung
      RecordInitialisieren;
    end;
  end
  else begin
    // Datensatz einlesen und an die richtige Position gehen
    Read(F, Adresse);
    Seek(F, FilePos(F)-1);
  end;
  FensterAktualsierung;


Der Teil ist mir zwar klar, was das meiste macht, aber *bahnhof* wieso ???


*Verzweifel*


:( NEED HELP :(

greetz
adfontes
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Fr 02.09.05 08:43 
user profile iconadfontes hat folgendes geschrieben:

1.
ausblenden Delphi-Quelltext
1:
  Truncate(F); // Den letzten Datensatz abschneiden					


2.
Wenn ich den Code oben versuche in meinem bisherigen Code einzubauen bzw. meine Fehler im Vergleich zu dem Code auszubauen, dann bekomm ich immer die Anzeige "INITIALIZATION erwartet ... bekommen" , egal...

3.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
  if eof(F) then begin // Sonderfall: der letzte Datensatz wurde gelöscht
    if FileSize(F) > 0 then begin // Sind überhaupt noch Daten da?
      Seek(F, FileSize(F)-1); // Gehe zum letzten gültigen Datensatz
      Read(F, Adresse);
    end
    else begin // Datei ist leer
      // Initialisierung
      RecordInitialisieren;
    end;
  end
  else begin
    // Datensatz einlesen und an die richtige Position gehen
    Read(F, Adresse);
    Seek(F, FilePos(F)-1);
  end;
  FensterAktualsierung;


Der Teil ist mir zwar klar, was das meiste macht, aber *bahnhof* wieso ???

zu 1. Mit Truncate schneidest du den Rest der Datei ab. Für die Routine aus meinem Source stellt man die Datei-Position also vor den letzten Datensatz und ruft Truncate auf. Dadurch wird der letzte Datensatz abgeschnitten.

zu 2. Vermutlich ein Copy&Paste-Fehler deinerseits. Das kann man so nicht erkennen.

zu 3. Eigentlich ganz einfach. Im Normalfall wird der Record eingelesen und der Datensatzzeiger steht HINTER dem Record. Damit du aber beim ändern des Records gleich wieder an der richtigen Stelle stehst (z.B. zum Speichern) wird mit Seek und FilePos an die richtige Position gesprungen.
Wenn du was anderes meinst, was du nicht verstanden hast, dann formuliere nach mal deine Frage etwas genauer.
adfontes Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 82

Win7 (64bit), WinXP
Delphi 2010 Prof, Delphi XE2 (Trial)
BeitragVerfasst: Fr 02.09.05 11:59 
soweit ist das nun schon mal klar, danke :) .... wegen 2. war logisch, hab ne zeile vergessen ~.~


wegen dem 3. das was du erklärt hast, versteh ich nun schon mal, aber das
ausblenden Delphi-Quelltext
1:
2:
3:
4:
    else begin // Datei ist leer  
      // Initialisierung  
      RecordInitialisieren;  
    end;


wozu soll das gut sein ? ... die procedure RecordInitialisieren macht doch nur alle Elemente des Records auf '' setzen oder ?!? ... bringt das der nun abgeschnittenen datei ?


greetz
adfontes
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Fr 02.09.05 16:16 
Falls es keine Datensätze mehr gibt (Datei ist leer, weil der letzte Datensatz gelöscht wurde), würden sonst die Reste des letzten Records dadrin stehen. Also muss es initialisiert werden.
adfontes Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 82

Win7 (64bit), WinXP
Delphi 2010 Prof, Delphi XE2 (Trial)
BeitragVerfasst: So 04.09.05 10:14 
huhu und danke, klappt jetzt super :)

besonderen Danke natürlich an user profile iconjasocul für die arbeit mit mir und das Tutorial ...


greetz
adfontes
adfontes Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 82

Win7 (64bit), WinXP
Delphi 2010 Prof, Delphi XE2 (Trial)
BeitragVerfasst: So 04.09.05 15:46 
ausblenden volle Höhe 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:
procedure TForm2.BitBtn13Click(Sender: TObject);
begin
  AssignFile (DATEI_U,'C:\User.ini');
  Reset(DATEI_U);
  While NOT EOF(DATEI_U) DO
  Begin
    Read(DATEI_U,Benutzer);
    if (ComboBox1.Text=Benutzer.BName) THEN
      begin
        aktPos := FilePos(DATEI_U);
        Seek(DATEI_U,filepos(DATEI_U)+1); 
        while not eof(DATEI_U) do begin 
          Read(DATEI_U,Benutzer);
          Seek(DATEI_U, Filepos(DATEI_U)-1);
          Write(DATEI_U, Benutzer);
          Seek(DATEI_U, Filepos(DATEI_U)+1);
        end;
        Seek(DATEI_U, FileSize(DATEI_U)-1);
        Truncate(DATEI_U);
        Seek(DATEI_U, aktPos);
        if eof(DATEI_U) THEN
        begin
          if FileSize(DATEI_U) > 0 THEN
          begin
            Seek(DATEI_U, FileSize(DATEI_U)-1);
            Read(DATEI_U, Benutzer);
          end
          else
          begin
            Benutzer.Bname := '';
            Benutzer.NName := '';
            Benutzer.VName := '';
            Benutzer.Pw := '';
            Benutzer.Status := '';
            Benutzer.Stufe := '';
            Benutzer.Gesperrt := False;
            Benutzer.GDate := '';
          end;
        end;
  end;
end;
ComboBox2.Text:='';
ComboBox1.Text:='';
Label43.Visible:=False;
Label44.Visible:=False;
Label45.Visible:=False;
Label46.Visible:=False;
Label47.Visible:=False;
closefile(DATEI_U);
end;



das da hab ich nu als procedure da stehn... aber irgendwie klappt das nich so wirklich wies klappen soll.....
Folgendes Problem: er löscht zwar, aber nicht, den in der ComboBox ausgewählten Record sondern den letzten... ist mir jetzt erst aufgefallen übers rumprobieren, als ich mehr als 3 benutzer eingegeben hatte und immer nur der letzte gelöscht wurde :(

kann mir jemand einen Tipp geben, wo ich gucken muss, also in welcher Zeile das Problem liegt, weil ich glaub ich guck schon so lange auf den quellcode, dass ich nichmehr weiß wo ich anfangne soll :(


greetz
adfontes
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: So 04.09.05 20:00 
ausblenden volle Höhe 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:
procedure TForm2.BitBtn13Click(Sender: TObject);
begin
  AssignFile (DATEI_U,'C:\User.ini');
  Reset(DATEI_U);
  While NOT EOF(DATEI_U) DO
  Begin
    Read(DATEI_U,Benutzer);
    if (ComboBox1.Text=Benutzer.BName) THEN
      begin
// hier ist ein Fehler. Es fehlt:
        Seek(DATEI_U,filepos(DATEI_U)-1); 
// unten erkläre ich warum
        aktPos := FilePos(DATEI_U);
        Seek(DATEI_U,filepos(DATEI_U)+1); 
        while not eof(DATEI_U) do begin 
          Read(DATEI_U,Benutzer);
          Seek(DATEI_U, Filepos(DATEI_U)-1);
          Write(DATEI_U, Benutzer);
          Seek(DATEI_U, Filepos(DATEI_U)+1);
        end;
        Seek(DATEI_U, FileSize(DATEI_U)-1);
        Truncate(DATEI_U);
        Seek(DATEI_U, aktPos);
        if eof(DATEI_U) THEN
        begin
          if FileSize(DATEI_U) > 0 THEN
          begin
            Seek(DATEI_U, FileSize(DATEI_U)-1);
            Read(DATEI_U, Benutzer);
          end
          else
          begin
            Benutzer.Bname := '';
            Benutzer.NName := '';
            Benutzer.VName := '';
            Benutzer.Pw := '';
            Benutzer.Status := '';
            Benutzer.Stufe := '';
            Benutzer.Gesperrt := False;
            Benutzer.GDate := '';
          end;
        end;
  end;
end;
ComboBox2.Text:='';
ComboBox1.Text:='';
Label43.Visible:=False;
Label44.Visible:=False;
Label45.Visible:=False;
Label46.Visible:=False;
Label47.Visible:=False;
closefile(DATEI_U);
end;

Da du im Prinzip meine Routine zum Löschen verwendet hast, bekommst du ein "Zählproblem" mit dem Dateizeiger. In den Sourcen meines Tutorials gehe ich immer davon aus, dass der Dateizeiger vor dem gerade angezeigten Datensatz steht. Durch dein Read stehst du aber hinter dem eingelesenen Datensatz.
adfontes Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 82

Win7 (64bit), WinXP
Delphi 2010 Prof, Delphi XE2 (Trial)
BeitragVerfasst: So 04.09.05 20:29 
*vor kopf hau* so eine kleinigkeit, aber dennoch sehr "folgenträchtig"... danke danke danke :)) endlich gehts *freu*


greetz
adfontes