Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi TIniFile und DeleteKey (https://www.delphipraxis.net/77910-tinifile-und-deletekey.html)

newuser01 26. Sep 2006 18:04


TIniFile und DeleteKey
 
Hallo

Ich möchte gerne mit "DeleteKey" ein Eintrag aus der ini löschen funktioniert nur leider nicht :( wo liegt der Fehler?

Delphi-Quellcode:
procedure TfMain.btnDeleteClick(Sender: TObject);
var
i:integer;
Ini:TIniFile;
begin

//Ausgewählter Eintrag ist zu löschender Key in 'Properties'
for i := 0 to ListBox1.Count -1 do
begin

  if ListBox1.Selected[i] = true then
  begin
  Ini := TIniFile.Create(ExtractFilePath(Application.ExeName)+'setting.ini');
  ListBox1.Items.Delete(i);
  Ini.DeleteKey('Properties',ListBox1.Items.Strings[i]);
  end
    else
        begin
  end;//if

end;//for

Ini.Free;

mkinzler 26. Sep 2006 18:12

Re: TIniFile und DeleteKey
 
Kommt ein Fehler?

Hawkeye219 26. Sep 2006 18:14

Re: TIniFile und DeleteKey
 
Hallo Holger,

du erhältst beim Testen deines Codes eine Meldung der Form "Listenindex überschreitet das Maximum", richtig?
Schaue einmal in diesen diesen Thread hinein.

Gruß Hawkeye

newuser01 26. Sep 2006 18:34

Re: TIniFile und DeleteKey
 
Hallo

Problem gelöst :-D

Lösung:

"Ini.DeleteKey('Properties',ListBox1.Items.Str ings[i])" muss vor "ListBox1.Items.Delete(i)" gesetzt werden denn wenn es danach gesetzt wird ist ja ListBox1.Items nicht mehr aktuell weil beretis ein Eintrag gelöscht wurde

Delphi-Quellcode:
procedure TfMain.btnDeleteClick(Sender: TObject);
var
i:integer;
Ini:TIniFile;
begin

//Ausgewählter Eintrag ist zu löschender Key in 'Properties'
for i := 0 to ListBox1.Count -1 do
begin

  if ListBox1.Selected[i] = true then
  begin
  Ini := TIniFile.Create(ExtractFilePath(Application.ExeName)+'setting.ini');
  Ini.DeleteKey('Properties',ListBox1.Items.Strings[i]);//vor ListBox1.Items.Delete(i) gesetzt
  ListBox1.Items.Delete(i);
  end
    else
        begin
  end;//if

end;//for

Ini.Free;
DANKE an alle

Hawkeye219 26. Sep 2006 18:50

Re: TIniFile und DeleteKey
 
Zitat:

Zitat von newuser01
Problem gelöst :-D

noch nicht ganz:
  • Du erzeugst für jeden markierten Eintrag ein TIniFile-Objekt, gibst aber nach der Schleife nur das zuletzt erstellte Objekt frei.
  • Falls die Liste leer oder kein Eintrag markiert ist, versuchst du trotzdem ein TIni-Objekt freizugeben.
  • Du gehst immer noch vorwärts durch die Schleife und nicht rückwärts.
Ganz fertig bist du also noch nicht :wink:

Gruß Hawkeye

newuser01 26. Sep 2006 19:50

Re: TIniFile und DeleteKey
 
Delphi-Quellcode:
procedure TfMain.btnDeleteClick(Sender: TObject);
var
i:integer;
Ini:TIniFile;
begin

Ini := TIniFile.Create(ExtractFilePath(Application.ExeName)+'setting.ini');

for i := 0 to ListBox1.Count -1 do
begin

  if ListBox1.Selected[i] = true then
  begin
  Ini.DeleteKey('Properties',ListBox1.Items.Strings[i]);//vor ListBox1.Items.Delete(i) gesetzt
  ListBox1.Items.Delete(i);
  Ini.Free;
  end
    else
        begin
  end;//if

end;//for
so vielleicht ?

Khabarakh 26. Sep 2006 20:11

Re: TIniFile und DeleteKey
 
Nicht wirklich ;) . Free hast du nun zwar in die Schleife gepackt, den Konstruktoraufruf aber unsinnigerweise ausgelagert, wodurch ein und diesselbe Instanz mehrmals freigegeben wird. Hawkeyes dritten Punkt solltest du ebenfalls beachten.

marabu 26. Sep 2006 20:17

Re: TIniFile und DeleteKey
 
Hallo Holger,

ich habe deinen Code etwas überarbeitet und alle Hinweise berücksichtigt. Jede Änderung hat ihren speziellen Grund und ist es wert, dass du darüber nachdenkst.

Delphi-Quellcode:
uses
  IniFiles;

const
  INI_NAME = 'Settings.ini';
  PROPS_SECTION = 'Properties';

procedure TDemoForm.btnDeleteClick(Sender: TObject);
var
  i: Integer;
  fn: TFileName;
  ini: TMemIniFile;
begin
  fn := ExtractFilePath(Application.ExeName) + INI_NAME;
  ini := TMemIniFile.Create(fn);
  with lbKeys do
  begin
    Items.BeginUpdate;
    for i := Pred(Items.Count) downto 0 do
      if Selected[i] then
      begin
        ini.DeleteKey(PROPS_SECTION, lbKeys.Items[i]);
        Items.Delete(i);
      end;
    Items.EndUpdate;
  end;
  ini.UpdateFile;
  ini.Free;
end;
Getippt und nicht getestet.

Gute Nacht

marabu

newuser01 26. Sep 2006 21:43

Re: TIniFile und DeleteKey
 
Ich hab bis jetzt noch nicht so recht begriffen warum es besser ist die Schleife rückwärts laufen zu lassen :gruebel: es hat bei mir noch nicht so richtig klick gemacht :mrgreen: Ich vermute mal wenn in der Rückwärtsversion "i" immer ListBox1.Count ist dann ist ja "i" somit auch immer aktuell oder ? denn wenn in der Vorwärtsversion "i" nur hochzählen würde aber ListBox1.Count nun plötzlich nicht mehr stimmt dann FEHLER oder ?

Delphi-Quellcode:
procedure TfMain.btnDeleteClick(Sender: TObject);
var
i:integer;
Ini:TIniFile;
begin

Ini := TIniFile.Create(ExtractFilePath(Application.ExeName)+'setting.ini');

for i := ListBox1.Count -1 downto 0 do
begin

  if ListBox1.Selected[i] = true then
  begin
  Ini.DeleteKey('Properties',ListBox1.Items.Strings[i]);
  ListBox1.Items.Delete(i);
  end
    else
        begin
  end;//if

end;//for

Ini.UpdateFile;
Ini.Free;

marabu 27. Sep 2006 06:12

Re: TIniFile und DeleteKey
 
Guten Morgen.

Hawkeye hatte es ja in dem verlinkten thread schon erklärt. Bei einer vorwärts laufenden Zählschleife sägst du an dem Ast auf dem du sitzt - bildlich gesprochen. Der Endwert der Laufvariable in einer Zählschleife wird nur einmal ganz am Anfang ermittelt.

Nimm eine Liste mit zwei items, der Index läuft von 0 bis 1. Wenn das erste item innerhalb der Zählschleife gelöscht wird, passiert folgendes: die Liste verschiebt das zweite item an die Position des ersten, der maximale Listenindex ist nun 0, die Laufvariable wird von 0 auf 1 erhöht, das Abbruchkriterium der Schleife (Laufvariable größer als Endwert) ist nicht erfüllt (1 > 1 ist Falsch) und ein Zugriff auf das nicht mehr vorhandene item mit dem Index 1 (welches durch die Verschiebung nach dem Löschen jetzt den Index 0 hat) findet statt - und scheitert mit einer Exception.

Leicht nachzuvollziehen, warum das bei rückwärts laufenden Zählschleifen nicht passieren kann - oder?

Grüße vom marabu


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:46 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz