TValueListEditor - wie speichern? [gelöst]

Für Fragen von Einsteigern und Programmieranfängern...
and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

TValueListEditor - wie speichern? [gelöst]

Beitrag von and4more »

Hallo liebes Forum, habe lange gegoogelt aber leider nichts Passendes finden können. Leider befassen sich auch Bücher kaum bis gar nicht mit TValueListEditor. Aber vielleicht kennt sich ja einer gut damit aus?!? Zum Editieren eine Ini-Datei habe ich eine kleine Form, in der nur die TValueListEditor-Komponente und oben noch eine Menüleiste ist. Aktuell versuche ich Folgendes:

Code: Alles auswählen

 
//Laden einer INI-/Conf-Datei
ValEdIni.Strings.LoadFromFile(IniPfad+'ORC'+ext);  //klappt, Inhalt erscheint im Fenster, schön mit zwei Spalten
 

wenn ich aber nach durchgeführten Änderungen Folgendes versuche:

Code: Alles auswählen

 
ValEdIni.SaveToFile(IniPfad+'ORC'+ext);
 

passiert rein gar nichts, also keine Fehlermeldung, aber leider auch keine Speicherung in die Datei. Ich habe mir auch die Ini-Datei selbst angesehen - keine Änderung. Also scheint es kein Aktualisierungsproblem während des Programmablaufs zu sein (geänderte Datei wird nicht angezeigt). Im Programm selbst lässt sich die Ini-Datei ändern und beschreiben über Ini.Update, also kein Schreibproblem. Entweder bin ich da zu naiv oder die Speichern-Funktion tut nicht das was ihrer Beschreibung entspricht. Weiß jemand Rat? Muss ich vielleicht vorher die TIniFile-Instanz schließen, da diese Schreibzugriffe blockiert?
Zuletzt geändert von and4more am Mi 5. Apr 2017, 09:31, insgesamt 1-mal geändert.
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: TValueListEditor - wie speichern?

Beitrag von Warf »

and4more hat geschrieben:Hallo liebes Forum, habe lange gegoogelt aber leider nichts Passendes finden können. Leider befassen sich auch Bücher kaum bis gar nicht mit TValueListEditor. Aber vielleicht kennt sich ja einer gut damit aus?!? Zum Editieren eine Ini-Datei habe ich eine kleine Form, in der nur die TValueListEditor-Komponente und oben noch eine Menüleiste ist. Aktuell versuche ich Folgendes:

Code: Alles auswählen

 
//Laden einer INI-/Conf-Datei
ValEdIni.Strings.LoadFromFile(IniPfad+'ORC'+ext);  //klappt, Inhalt erscheint im Fenster, schön mit zwei Spalten
 

wenn ich aber nach durchgeführten Änderungen Folgendes versuche:

Code: Alles auswählen

 
ValEdIni.SaveToFile(IniPfad+'ORC'+ext);
 

passiert rein gar nichts, also keine Fehlermeldung, aber leider auch keine Speicherung in die Datei. Ich habe mir auch die Ini-Datei selbst angesehen - keine Änderung. Also scheint es kein Aktualisierungsproblem während des Programmablaufs zu sein (geänderte Datei wird nicht angezeigt). Im Programm selbst lässt sich die Ini-Datei ändern und beschreiben über Ini.Update, also kein Schreibproblem. Entweder bin ich da zu naiv oder die Speichern-Funktion tut nicht das was ihrer Beschreibung entspricht. Weiß jemand Rat? Muss ich vielleicht vorher die TIniFile-Instanz schließen, da diese Schreibzugriffe blockiert?

wie wäre es mit ValEdIni.Strings.SaveToFile(IniPfad+'ORC'+ext);

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: TValueListEditor - wie speichern?

Beitrag von and4more »

...hatte ich vorher, klappt leider auch nicht.
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: TValueListEditor - wie speichern?

Beitrag von Warf »

Check mal das OnEditingDone Event aus ob du auch wirklich eine Änderung durchführst, denn die Komponente verwendet zum Speichern einfach eine StringList welche geupdated wird bevor dieses Event gefeurt wird. Und bei dir wird anscheinend die StringList nicht geupdated (ich denke mal die StringList SaveToFile funktion wird korrekt sein, sonst wäre das ein bekanntes Problem)

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

Re: TValueListEditor - wie speichern?

Beitrag von wp_xyz »

Ich habe gerade das nachprogrammiert, und es funktioniert einwandfrei. Es muss an deinem Code liegen: Rufst du die Speicherroutine überhaupt auf? Setze einfach Breakpoints, dann siehst du gleich, ob Code ausgeführt wird.

Übrigens: die von ValueListEditor.Strings.SaveToFile erzeugte Datei ist keine "richtige" Ini-Datei, da sie keine Abschnitte mit Bezeichnern in eckigen Klammern enthält, nur die Name=Wert Paare. Wenn du diese Datei einer TIniFile übergibst, wird sie nichts darin finden! Andererseits, wenn du eine "echte" ini-Datei mit Abschnittsbezeichnern in eckigen Klammern per ValueListEditor.Strings.LoadfromFile einliest, erscheinen die Abschnittsbezeichner in der Werte-Spalte, die Namens-Spalte ist leer.

Wenn du wirklich im Format einer ini-Datei speichern willst, musst sie schon selbst schreiben. Aber das sind nur ein paar Zeilen mehr:

Code: Alles auswählen

procedure TForm1.ButtonLesenClick(Sender: TObject);
var
  sl: TStringList;
begin
  sl := TStringList.create;
  sl.LoadFromFile('d:\vle-s.ini');
  sl.Delete(0);
  ValueListEditor1.Strings.Assign(sl);
  sl.Free;
end;
 
procedure TForm1.ButtonScheibenClick(Sender: TObject);
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  sl.Add('[Abschnitt]');
  sl.AddStrings(ValueListEditor1.Strings);
  sl.SaveToFile('d:\vle-s.ini');
  sl.Free;
end;
{ oder:
var
  stream: TStream;
  s: String;
begin
  stream := TFileStream.Create('d:\vle-s.ini', fmCreate);
  s := '[Abschnitt]';
  stream.WriteBuffer(s[1], Length(s));
  ValueListEditor1.Strings.SavetoStream(stream);
  stream.Free;
end;
}

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: TValueListEditor - wie speichern?

Beitrag von and4more »

@wp_xyz
Ich verstehe nur den Umweg über die StringList nicht. Ich dachte TValueListEditor leitet sich von StringList ab? Warum sind dann die Funktionen LoadFromFile und SaveTo File überhaupt vorhanden, wenn sie nicht direkt nutzbar sind? Das erscheint mir reichlich unlogisch. Wofür ist denn dann TValueListEditor überhaupt zu gebrauchen, wenn ich alles dann doch über eine StringList machen muss. Für diese Aufgabe hatte ich nämlich ursprünglich bereits eine Funktion mit einer StringList geschrieben, aber wieder verworfen, weil ich fand das aber reichlich "unelegant". Ich dachte es wäre "passender" eine spezifische Klasse zu benutzen. Habe ich da irgendwie einen Denkfehler?

Nachtrag: ...und Einlesen der Daten klappt ja auch ohne Probleme ohne Umweg über die StringList. Wenn ich jetzt Dein Beispiel aufgreife müsste ich quasi die im ValueEditor vorhandenen Daten erstmal einer StringList zuweisen, um dann die Daten in der StringList wieder in die Datei zu speichern?
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

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

Re: TValueListEditor - wie speichern?

Beitrag von wp_xyz »

Der ValueListEditor liest die selbst beschriebenen Dateien natürlich korrekt. Aber wenn du diese von TIniFile lesen oder schreiben lässt, gibt es Probleme, weil die Schlüsselwerte (die Zeilen in eckigen Klammern) von beiden unterschiedlich behandelt werden: TIniFile braucht sie, aber ValueListEditor mag sie nicht.

Den Umweg über die StringList habe ich gewählt, dass der valueListEditor einen einleitenden Schlüsselwert in die Datei schreiben kann, die die Ini-Datei benötigt. Umgekeht beim Lesen hat der ValueListEditor die Möglichkeit diesen herauszufiltern.

Wenn du nicht vorhast, die vom ValueListEditor geschriebene Datei als echte Ini-Datei zu verwenden (also von TIniFile einlesen zu lassen), kannst du das alles vergessen.

P.S.
Die Aussage oben, "ValueListEditor leitet sich von TStringList ab", ist nicht richtig. ValueListEditor ist ein Kind von TStringGrid.

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: TValueListEditor - wie speichern?

Beitrag von and4more »

Ok, das mit der Ableitung von StringList hatte ich irgendwie falsch im Hinterkopf. Habe jetzt das Programm in die alte Richtung wieder verändert (die leider auch nicht funktionierte):

Code: Alles auswählen

 
procedure TFrmIniEdit.SaveINI;
var
  StrBuff:TStringList;
begin
  StrBuff:=TStringList.Create;
  try
    StrBuff.AddStrings(ValEdIni.Strings);
    StrBuff.SaveToFile(IniPfad+'ORC'+ext);   
  finally
    StrBuff.Free;   
  end;
end;
 

...und leider immer noch nicht funktioniert. :(
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

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

Re: TValueListEditor - wie speichern?

Beitrag von wp_xyz »

Das mit der StringList und der Format der Ini-Datei ist ja nur Nebengeplänkel. Bist du sicher, dass die Speicherroutine überhaupt aufgerufen wird?

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: TValueListEditor - wie speichern?

Beitrag von and4more »

...sorry, aber ich verstehe den Hinweis nicht so richtig. Was heißt "dass die Speicherroutine überhaupt aufgerufen wird"?
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: TValueListEditor - wie speichern?

Beitrag von and4more »

...habe einen Screenshot mit der Form beigefügt. Die Funktion wird bei Betätigung der entsprechenden Menüpunkte aufgerufen

IniEditor.jpg
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

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

Re: TValueListEditor - wie speichern?

Beitrag von wp_xyz »

Nur allein die tasache, dass auf dem Formular z.B. ein Menüpunkt "Speichern" ist, heißt nicht, dass etwas gespeichert wird. Oder sogar die Tatsache, dass du eine Prozedur FormMenuSpeichernClick geschrieben hast, heißt nicht, dass sie auch ausgeführt wird - sie muss auch mit dem MenuItem verbunden werden (im Objekt-Inspektor). Oder zwischen dem Mausclick und der Speicherroutine können noch Bedingungen abgefragt werden, die vielleicht falsch definiert sind, so dass das Programm nicht zur Speicherroutine kommt. Es gibt 1000 Möglichkeiten...

Setze einfach in der Speicherroutine einen Breakpoint. Starte das Programm und mache das was nötig ist, um die Valuelist zu speichern. Wenn das Programm am Breakpoint anhält, wird die Routine ausgeführt. Wenn nicht, muss du suchen, warum. Ich kenne ja dein Programm nicht, und kann keine konkreteren Hinweise geben. Wann soll den die ValueList gespeichert werden? Gibt es dafür ein Ereignis? Setze einen Breakpoint in dieser Ereignisroutine und dann, wenn das Programm hier angehalten hat, gehe schrittweise weiter. Prüfe jedesmal, ob der aktuelle Schritt ausgeführt werden soll oder nicht. Oft ist eine Bedingung falsch gesetzt und das Programm verzweigt nicht in die richtige Routine.

Falls du noch nie mit dem Debugger gearbeitet hast, such dir am besten ein entsprechendes Tutorial oder Video, z.B. das hier: https://www.youtube.com/watch?v=LZ90IBa9_8M

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: TValueListEditor - wie speichern?

Beitrag von and4more »

Ok, danke für die Hinweise. Ganz so blöd wie ich vielleicht von meinem Geschreibsel her klinge bin ich dann aber hoffentlich doch nicht :wink:
Also in der "SaveIni"-Funktion steht ganz oben ein "ShowMessage('Funktion xyz')". Das hab' ich jetzt natürlich nicht im Codebeispiel genannt, ist quasi mein individualisierter Breakpoint. Und ja, die Funktion wird betreten und ausgeführt. Die Menüpunkte sind so implementiert:

Code: Alles auswählen

 
procedure TFrmIniEdit.MenIt_SaveClick(Sender: TObject);
begin
  SaveINI;
end;
 
procedure TFrmIniEdit.MenIt_SaveNCloseClick(Sender: TObject);
begin
  SaveINI;
  Close;
end;
 


Habe aber zur Sicherheit nochmal zusätzlich vor jede der Einzelfunktionen einen Breakpoint gesetzt und es wird jede Funktion ausgeführt, allerdings kommt während der Laufzeit die Meldung, dass TStringList keine Members mit Namen 'AddStrings' und 'SaveToFile' habe. Interessanterweise ist auch die Funktion während des Debuggens verändert, es wird nämlich der komplette erste Abschnitt/Absatz der Ini-Datei gelöscht, aber sonst erfolgt weiter keine Speicherung. Ist der Debugger aus (keine Breakpoints) werden auch keine Teile der Ini-Datei gelöscht.
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

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

Re: TValueListEditor - wie speichern?

Beitrag von wp_xyz »

Entschuldige, wenn ich Sachen geschrieben habe, die für dich selbstverständlich sind. Aber es ist wirklich schwer auf diese Weise eine Lösung zu finden. Du solltest dein Projekt so weit wie möglich eindampfen, so dass nur die Sache mit den ValueListEditor übrig bleibt, und dann das Projekt hochladen. Ohne zu sehen, was du genau machst, hat man keine Chance... Bitte im Projekt alles außer pas, lfm, lpi und lpr Dateien weglassen, diese zu einem zip packen und hier hochladen.

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: TValueListEditor - wie speichern?

Beitrag von and4more »

@wp_xy
...alles o.k., hab's nicht böse gemeint. Die Idee mit der Beispieldatei ist glaube ich auch der beste Vorschlag, also hab ich mein Programm mal eben schnell stark verkleinert und als ZIP-Datei beigelegt.

IniChk.zip
(141.68 KiB) 59-mal heruntergeladen
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

Antworten