GELÖST : Zeile aus TextFile löschen

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Bernie110
Beiträge: 140
Registriert: Mo 10. Feb 2020, 17:43

GELÖST : Zeile aus TextFile löschen

Beitrag von Bernie110 »

Hallo,

ich möchte aus einer CheckListBox mehrere Formulare die geöffnet sind schliessen. ( mittels checkbox)
( Der Eintrag in die Textfile erfolgt beim öffnen des jeweiligen Formulars )

Jetzt habe ich diesen Code gebastelt : Teste einfach nur rum. Keine Ahnung ob das clever ist. Aber sonst lern ich es wohl nie. :mrgreen:
In der Ziele mit : Index := sl.IndexOfName('Frm_USER_UEBERSICHT');
läuft er mir in einen Fehler.
Er sagt mir aber leider nicht was das Problem ist.
Kann mir vll jemand helfen und erklären was hier das Problem ist ?

Code: Alles auswählen

var
  i, i2, i3 : integer;
  MainRoot : String;
  Index : integer;
  sl :TStringList;

begin
  MainRoot := ExtractFilePath(Application.ExeName) + '\Programm_Dateien\TXT_OpenForms.txt';

  // Formulare schliessen
  BoxStyle := MB_ICONQUESTION + MB_YESNO;
  Reply := Application.MessageBox('Möchten Sie diese Formulare schliessen?', 'MessageBoxDemo', BoxStyle);
  if Reply = IDYES then
      begin
         for i:=0 to CheckListBox1.Count-1 do
         if  CheckListBox1.Items[i] = 'Frm_USER_UEBERSICHT' then
             begin
               Frm_USER_UEBERSICHT.close;
             end;

      end;



  // Eintrag in TxtFile löschen
      for i2:=0 to CheckListBox1.Count-1 do

         if  CheckListBox1.Items[i] = 'Frm_USER_UEBERSICHT' then
             begin

             MainRoot := ExtractFilePath(Application.ExeName) + '\Programm_Dateien\TXT_OpenForms.txt';
             if FileExists(MainRoot) = True then
                begin
                Index := sl.IndexOfName('Frm_USER_UEBERSICHT');

                       sl:=TStringList.Create;
                       sl.LoadFromFile(MainRoot);
                       for i := 0 to sl.Count-1 do
                       sl.Delete(index);
                       sl.SaveToFile(MainRoot);

                       sl.free;
                end;
             end; 
Danke für euer Antworten.
Lg Bernie
Zuletzt geändert von Bernie110 am Do 29. Aug 2024, 16:27, insgesamt 1-mal geändert.

Mathias
Beiträge: 6899
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Zeile aus TextFile löschen

Beitrag von Mathias »

Du muss noch prüfen, ob Index -1 ist, wen ja, wurde kein Eintrag gefunden.
Wen du weiter unten ein sl.Delete(-1) machst, dann knallte es.
Bei sl.Delete muss immer ein gültiger Wert sein.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Bernie110
Beiträge: 140
Registriert: Mo 10. Feb 2020, 17:43

Re: Zeile aus TextFile löschen

Beitrag von Bernie110 »

@Matthias
danke für deine Antwort.
Wie kann Index -1 sein ?
Ich weiss, dass der Eintrag in der Liste ist.
Sehe es ja weil mein CheckListBox1 auch aus diesem Textfile befüllt wird.
Wie meinst du das genau ?
Lg

shokwave
Beiträge: 475
Registriert: Do 15. Nov 2007, 16:58
OS, Lazarus, FPC: Win11/Ubuntu Budgie (L 3.0 FPC 3.2.2)
CPU-Target: i386, x64
Wohnort: Gera

Re: Zeile aus TextFile löschen

Beitrag von shokwave »

Bernie110 hat geschrieben: So 25. Aug 2024, 18:04 Wie kann Index -1 sein ?
Ich weiss, dass der Eintrag in der Liste ist.
Ich habe es jetzt nicht ausprobiert, aber wenn ich mich recht entsinne braucht du sl.IndexOf und nicht sl.IndexOfName, um den Index des Eintrags zu ermitteln.
mfg Ingo

wp_xyz
Beiträge: 5129
Registriert: Fr 8. Apr 2011, 09:01

Re: Zeile aus TextFile löschen

Beitrag von wp_xyz »

Bernie110 hat geschrieben: So 25. Aug 2024, 17:38 läuft er mir in einen Fehler.
Er sagt mir aber leider nicht was das Problem ist.
Aber uns könntest zumindest die Fehlermeldung mitteilen. Sonst wird das ein heiteres "Fehler-Raten".

Bernie110
Beiträge: 140
Registriert: Mo 10. Feb 2020, 17:43

Re: Zeile aus TextFile löschen

Beitrag von Bernie110 »

wp_xyz hat geschrieben: So 25. Aug 2024, 18:56 Aber uns könntest zumindest die Fehlermeldung mitteilen. Sonst wird das ein heiteres "Fehler-Raten".
Sorry natürlich : Hier :
Bild

paweld
Beiträge: 85
Registriert: So 11. Jun 2023, 16:01
OS, Lazarus, FPC: Lazarus trunk, FPC fixes

Re: Zeile aus TextFile löschen

Beitrag von paweld »

Sie versuchen, einen Index in einer Liste abzurufen, die noch nicht existiert (Sie erstellen diese TStringList erst im nächsten Schritt). Aus diesem Grund erhalten Sie eine "Access violation".
Grüße / Pozdrawiam
paweld

Mathias
Beiträge: 6899
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Zeile aus TextFile löschen

Beitrag von Mathias »

Ich habe es jetzt nicht ausprobiert, aber wenn ich mich recht entsinne braucht du sl.IndexOf und nicht sl.IndexOfName, um den Index des Eintrags zu ermitteln.
Da hast du vollkommen recht, indexOF muss man nehmen.
Und wen der String nicht auffindbar ist, wird -1 ausgespuckt.
Daher immer Prüfen, vor allem in deinem Fall, wo eine Datei eingelesen wird.
Sie versuchen, einen Index in einer Liste abzurufen, die noch nicht existiert (Sie erstellen diese TStringList erst im nächsten Schritt). Aus diesem Grund erhalten Sie eine "Access violation".
Dies war bei seinem ersten Post noch nicht da, aber sowas knallt natürlich.
Zuletzt geändert von Mathias am So 25. Aug 2024, 20:00, insgesamt 1-mal geändert.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10856
Registriert: Mo 11. Sep 2006, 19:01

Re: Zeile aus TextFile löschen

Beitrag von theo »

paweld hat geschrieben: So 25. Aug 2024, 19:20 Sie versuchen, einen Index in einer Liste abzurufen, die noch nicht existiert (Sie erstellen diese TStringList erst im nächsten Schritt). Aus diesem Grund erhalten Sie eine "Access violation".
Das ist das eine. Dann rattert er durch die Stringlist mit "i", löscht dann aber zig mal "index".

Code: Alles auswählen

 for i := 0 to sl.Count-1 do
                       sl.Delete(index);
Auch wenn er tatsächlich sl.Delete(i) läschen würde, würde er sich alles unter den Füssen weg löschen.
Also nochmal über die Bücher! :wink:

Benutzeravatar
kralle
Lazarusforum e. V.
Beiträge: 1193
Registriert: Mi 17. Mär 2010, 14:50
OS, Lazarus, FPC: Manjaro Linux, Mint und Windows 10 ,Lazarus 3.99, FPC-Version: 3.3.1
CPU-Target: 64Bit
Wohnort: Bremerhaven
Kontaktdaten:

Re: Zeile aus TextFile löschen

Beitrag von kralle »

Moin,

Bei Schleifen mit den in einer Liste was gelöscht wird, immer vom höhsten Wert nach Null zählen lassen.
Wenn Du einen Eintrag in der Liste löscht, steht der Zeiger beim nächsten Durchlauf nicht dort wo Du Ihn erwartest.
Löscht Du z.B. den vorletzten Eintrag, dann ist die Anzahl der Elemente in der Liste: Anzahl minus 1. Beim Versuch das letzte Element zu löschen, gibt es dann einen Fehler.

Gruß Heiko
OS: Manjaro Linux, Linux Mint und Windows 10
FPC-Version: 3.3.1 , Lazarus 3.99
+ Delphi XE7SP1

Bernie110
Beiträge: 140
Registriert: Mo 10. Feb 2020, 17:43

Re: Zeile aus TextFile löschen

Beitrag von Bernie110 »

theo hat geschrieben: So 25. Aug 2024, 19:58 Also nochmal über die Bücher! :wink:
Bücher ? Eine ganze Ausbildung wäre wohl eher zielführend ;) Aber leider lässt mein derzeitger Beruf soviel Zeit nicht zu.
Jetzt bleibt mir nur noch übrig es irgend wie zu verstehen.
Mit Sting List, TextFiles und CheckListBoxen hat man, wenn man von MS Access kommt, nicht viel zu tun. Da hat man es mit einer integrierten Tabellenstruktur viel einfach so etwas umzusetzen.
Egal..
ich geb nicht auf .. :mrgreen:
so würde es zumindestens funktionieren
Allerdings auch nur am Beispiel von einem Forumlar. Geht bestimmt auch schöner.

Code: Alles auswählen

procedure TFrm_Admin_OpenForms.BitBtn1Click(Sender: TObject);
var
  ix, i, i2, i3 : integer;
  MainRoot : String;
  Index : integer;
  List :TStringList;

begin
  MainRoot := ExtractFilePath(Application.ExeName) + '\Programm_Dateien\TXT_OpenForms.txt';


  // Frage                                        .
  BoxStyle := MB_ICONQUESTION + MB_YESNO;
  Reply := Application.MessageBox('Möchten Sie diese Formulare schliessen?', 'MessageBoxDemo', BoxStyle);
  if Reply = IDYES then
      begin

          // File load
          if FileExists(MainRoot) = True then
            begin
              List:=TStringList.Create;
                 try
                  List.LoadFromFile(MainRoot);


                    // Formulare schliessen
                    for ix := 0 to CheckListBox1.Items.Count - 1 do
                       begin
                          if CheckListBox1.Checked[ix] then
                              begin

                              end else
                              begin
                               exit;
                              end;


                               for i:=0 to CheckListBox1.Count-1 do
                               if  CheckListBox1.Items[i] = 'Frm_USER_UEBERSICHT' then
                                   begin
                                     Frm_USER_UEBERSICHT.close;
                                      for i2 := 0 to List.Count-1 do
                                        Index := List.IndexOf('Frm_USER_UEBERSICHT');
                                        //ShowMessage('USER : ' +IntToStr(Index));
                                        List.Delete(index);
                                        List.SaveToFile(MainRoot);
                                   end;

                              CheckListBox1.DeleteSelected;
                              end;
                      finally
                         List.free;
                      end;
           end;

   end;// Frage Ende

end; // Ende Sub  


Jetzt funktioniert das nur mit einem Formular. Wenn ich aber 1:n Formulare habe wie hier, wird es schon schwieriger?
Bild


Man müsste vermutlich zuerst ab hier if CheckListBox1.Checked[ix] then den Namen auslesen
und ihn einer Variablen übergeben, welche es zulässt, das Formular zu schliessen oder ?
Wie heisst dann so was ?

Bitte nicht böse sein, Bin kein Profi. Hab aber voll Bock auf den Kram hier :D
Vielen Danke für jegliche Antworten.
Lg Bernie

Benutzeravatar
theo
Beiträge: 10856
Registriert: Mo 11. Sep 2006, 19:01

Re: Zeile aus TextFile löschen

Beitrag von theo »

Keine Ahnung, was du meinst.

Ich kann dir nur mal zwei Punkte in deinem Code zeigen, die nicht gut sind:

Code: Alles auswählen

                          if CheckListBox1.Checked[ix] then
                              begin

                              end else
                              begin
                               exit;
                              end;
Mal komplett ungeachtet des Zusammenhangs, kann man die vielen Zeilen so abkürzen:

Code: Alles auswählen

                          if not CheckListBox1.Checked[ix] then exit;
Exit ist aber immer etwas brachial und für solche Fälle nicht geeignet. Besser wäre es, die Logik zu ändern.


Das ist Quatsch:

Code: Alles auswählen

                                      for i2 := 0 to List.Count-1 do
                                        Index := List.IndexOf('Frm_USER_UEBERSICHT');
List.IndexOf sucht dir den Eintrag in der Liste. Da brauchst du die Liste nicht noch zusätzlich mit "for" durchlaufen.

Wie gesagt, ein Grundkurs in Programmierung wäre nicht schlecht. Via Forum ist das etwas schwierig.

nummer8
Beiträge: 52
Registriert: Sa 30. Apr 2016, 10:20
OS, Lazarus, FPC: Windows 8 -11 ; linux Debian 12; Mac
CPU-Target: 32bit 64bit

Re: Zeile aus TextFile löschen

Beitrag von nummer8 »

Um das Problem mit der Löschung in einer Stringliste zu umgehen Kannst du die Schleife andersherum laufen lassen.

Code: Alles auswählen

for i2:= CheckListBox1.Count-1 downto 0 do
begin
  list.delete(i2);
end;
Dies verhindert, dass du ein Problem mit dem Index bekommst.

Benutzeravatar
Zvoni
Beiträge: 363
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Zeile aus TextFile löschen

Beitrag von Zvoni »

Ich versuche gerade zu verstehen, was das EIGENTLICHE Ziel von OP ist.

Für mich klingt das so, als ob er versucht den Zustand aller geöffneten Fenster zu speichern, damit beim nächsten Start diesselben Fenster wieder offen sind.
Kann aber mit meiner Vermutung auch voll daneben liegen.

Was ich nicht verstehe: Er hat eine CHECKListBox.
Wieso zum Henker versucht er NOCHMAL per IndexOf den index in der StringList ("Items") zu finden???
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Bernie110
Beiträge: 140
Registriert: Mo 10. Feb 2020, 17:43

Re: Zeile aus TextFile löschen

Beitrag von Bernie110 »

@Theo. Danke für die Hinweise.
theo hat geschrieben: Mo 26. Aug 2024, 10:34 List.IndexOf sucht dir den Eintrag in der Liste. Da brauchst du die Liste nicht noch zusätzlich mit "for" durchlaufen.
Und was wenn es einen mehrmaligen Eintrag mit dem gleichen Namen gibt ?
theo hat geschrieben: Mo 26. Aug 2024, 10:34 Keine Ahnung, was du meinst.
Ok akzeptiert. Ich verrenne mich da in einen falschen Code. Schon verstanden.
Im Prinzip, möchte ich jeden Formularnamen von jedem Formular, welches aktuell geöffnet ist, in einer Liste angezeigt bekommen. siehe : CheckListBox1

Mittels Flag in der CheckListBox1 möchte ich bestimmen, welches Formular geschlossen werden soll.

Ich habe ein Textfile angelegt. Jedes geöffnete Formular fügt dort seinen Namen an.
Wird ein Formular geschlossen, wird der Name des Forms aus der Textfile gelöscht.
Um gleichzeitig mehrere Formular schließen zu können gibt es ein Formular mit dieser checklistbox1
Die ChecklistBox1 wird mittels dieser Textfile befüllt.
So werden nun alle geöffneten Formular-Namen dort angezeigt.

Der Code soll nun die Checklistbox1 durchlaufen und die mit Haken gekennzeichneten Formularnamen schliessen´und dann diesen Formnamen aus der Textfile löschen.

Und ich versuchte zu fragen, wie man einen Variable für einen Formnamen definiert.
irgend wie so :
VariableFormName = Flag_ja_in_Checklistbox1
VariableFormName.close;


Lg Bernie

Antworten