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

Re: TValueListEditor - wie speichern?

Beitrag von and4more »

...ja richtig, da gebe ich Dir vollkommen recht, aber eigentlich würde ich ja aus meiner naiven Ansichtsweise heraus vermuten, dass eine Klasse, die eigentlich spezialisiert auf eine Aufgabe zugeschnitten ist (sein sollte) dann letztlich auch die Funktionen bietet, die man erwarten dürfen müsste, nämlich die geänderten Daten auch zu speichern ohne einen Umweg über Hilfskonstrukte (z. B. StringList) nehmen zu müssen. Das würde doch dem intuitiven Arbeiten entsprechen? Oder sehe ich das falsch? Und dann ist da ja auch eine Funktion 'SaveToFile' deren Name, zumindest für mich, den Eindruck hinterlässt, ich könnte das was ich da geändert habe in eine Datei schreiben.
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 macht er (der ValueListEditor) doch. ValueListEditor.Strings.SaveToFile speichert die in der Liste angezeigten Werte im Stringlisten-Format als Name=Wert Paare ab. Aber du willst in einer Ini-Datei speichern, das ist etwas anderes, wegen der [Abschnitte]! Es geht natürlich auch, aber dafür musst du halt ein paar Zeilen Code schreiben.

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 »

...hmm, aber wo liegt denn das Problem beim Speichern von Sections, das sind doch letztlich auch nur Strings, nur eben ohne '='. Vielleicht steh' ich auf der Leitung, aber ich erkenne nicht so wirklich das Problem, warum ein ValueListEditor nicht in der Lage ist Strings (gleich welcher Art) in einer 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 »

Ich denke an die eckigen Klammern - die musst du entfernen (was du ja auch machst). Und das = Zeichen muss man sich kümmern: Wenn es fehlt, steht der Eintrag in der rechten Werte-Spalte, wo es m.E. nicht sein sollte (ich denke, es gehört in die linke Namens-Spalte. Da sind Bezeichner, die vielleicht im Programm eine Rolle spielen; und eigentlich sollte FixedCols = 1 sein, so dass der User keine Möglichkeit hat, das zu ändern - aber das ist Ansichtssache). Und dann entfernst du auch noch Leerzeilen. Das alles ist dein Code. Wenn das nicht so klappt wie gewünscht, darfst du den ValueListEditor nicht dafür verantwortlich machen.

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 »

...ich glaube fast wir reden etwas aneinander vorbei. Die Vorgänge was da softwaremäßig passiert sind mir, glaub' ich zumindest, schon klarer geworden, deswegen hab' ich ja auch die Änderung im Code eingeführt, dass die Zeichen mittels replace entfernt werden, sodass ein Zeichen,welches beim zweiten Durchlauf der Schleife noch vorhanden ist, ebenfalls wieder entfernt wird. Und der Code funktioniert auf jeden Fall in der gewünschten Weise (nicht unbedingt elegant :wink: ), wenngleich eine Akkumulation von Leerzeilen vorkommen kann, da TIniFile keine Funktion bereithält um die Darstellung zu "verschönern", was aber eigentlich nur im optischen / kosmetischen Sinne stört, die Funktionalität nicht beeinflusst. "Schöner" (für's Auge) wär's halt schon auch die Leerzeilen (bis auf eine zwischen den Sections) zu eliminieren. Und das was mich eben dabei stört ist, dass man diese nicht einfach im ValueListEditor löschen und die geänderten Daten dann auch über diesen abspeichern kann. Das entspricht meines Erachtens einem effektiven Workflow. Also mit anderen Worten, die Hilfskonstruktionen mit StringLists oder was auch immer empfinde ich als sehr umständlich und unelegant und mir ist klar, dass wir das hier nicht lösen können.
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 »

...ich glaube eine gute Möglichkeit wäre auch ein Array von 2 StringArrays, in der ersten Ebene die Sections, in der zweiten Dimension die Wertepaare. Allerdings kenne ich mich mit StringArrays (noch) nicht so richtig aus, werde aber mal durchprobieren. Wenn ich eine entsprechende Lösung habe werde ich den Code mal posten. Damit könnte man dann auch das Problem mit den Leerzeilen beheben.
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 »

Soo, habe jetzt 'ne Weile rumgeknobelt und um das Ganze zum Abschluss zu bringen poste ich hier den endgültigen Code.

Code: Alles auswählen

 
var
  SLBuff,SLIniContent:TStringList;
  strSection,strKey,strVal,strX: String;
  i,iKeyLen:Integer;
 
begin
  SLBuff:=TStringList.Create;
  SLIniContent:=TStringList.Create;
  strKey:='';
  strVal:='';
  try
    SLBuff.AddStrings(ValEdIni.Strings);
    for i:=0 To SLBuff.Count-1 do begin
      strX:=Trim(SLBuff.Strings[i]);
      if Pos('[',strX)<>0 then begin  //wenn Section...
        strSection:=StringReplace(strX,'=','',[]);
        strSection:=StringReplace(strSection,'[','',[rfReplaceAll]);
        strSection:=StringReplace(strSection,']','',[rfReplaceAll]);
        SLIniContent.Add('['+strSection+']');
      end else
      begin          //wenn normaler Text...
        iKeyLen:=Pos('=',strX)-1;
        strKey:=Copy(strX,1,iKeyLen);
        if (strKey<>'') then begin
          strVal:=Copy(strX,iKeyLen+2,Length(strX)-iKeyLen+2);
          SLIniContent.Add(strKey+'='+strVal);
        end;
      end;
    end;
    SLIniContent.SaveToFile(IniPfad+'ORC'+ext);
    ValEdIni.Strings.LoadFromFile(IniPfad+'ORC'+ext);
  finally
    SLBuff.Free;
    SLIniContent.Free;
  end;
end;
 

Schlussendlich war's dann doch nicht so kompliziert und auch das Stringarray ist nicht erforderlich. Die Funktion liest den Inhalt des ValueEditors ein, die geänderten Werte werden in der Form einer Ini-Datei in einer StringList abgelegt und dann wird die alte Ini-Datei einfach überschrieben und anschließend neu eingelesen. Offensichtlich stört sich der ValueEditor nicht an den fehlenden Leerzeilen, diese werden beim Einlesen der Ini-Datei neu angelegt.
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? [gelöst]

Beitrag von and4more »

...habe leider gerade bemerkt, dass das Speichern der StringList nicht funktioniert. Vielleicht weil die Datei geöffnet ist. Allerdings erfolgt keinerlei Rückmeldung, dass der Speichervorgang nicht funktioniert. Nur beim erneuten Öffnen der Datei sind die Werte leider unverändert. Klappt also doch nicht. :(
Das Ganze ist etwas seltsam. Es wird offensichtlich während des Programmablaufs die StringList korrekt gespeichert, denn beim Öffnen der Datei mit dem Windows-Editor ist zu sehen, dass die Änderungen eingetragen sind. Allerdings wird die Datei beim Beenden des Programms offensichtlich erneut geändert und in den alten Zustand zurückversetzt. Kann ich mir aktuell nicht erklären, auch mit dem Debugger komme ich da nicht weiter...
Zuletzt geändert von and4more am Mi 5. Apr 2017, 11:43, insgesamt 1-mal geändert.
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? [gelöst]

Beitrag von wp_xyz »

Setze einen Breakpoint am letzten "end" deines Codes im vorigen Beitrag. Wenn das Programm angehalten hat, öffne die nun fertig geschriebene Datei, und du wirst sehen, dass alles richtig drin steht (ok -- sollte, denn deinen Code habe ich nicht geprüft).

Ich denke,du hast immer noch das Problem, dass die ini-Datei noch irgendwo anders geladen ist, so dass die Änderungen überschrieben werden. Nochmals (zum letzten Mal): eine TIniFile geöffnet zu halten und dabei die DATEI zu editieren, ist eine schlechte Idee, weil TIniFile diese Änderungen nicht mitkriegt und beim Schließen die Datei neu schreibt, d.h. ÜBERschreibt. Dein Ini-Editor muss die Änderungen in TIniFile zurückschreiben.

Generell ist das alles sehr fehlerträchtig. Ich würde TIniFile nie global verfügbar machen und permanent offen halten, sondern immer nur lokal öffnen, wenn ich etwas daraus brauche.

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? [gelöst]

Beitrag von and4more »

...danke an wp_xyz, ich denke, das ist die Erklärung. Werde das Ganze mal "umstricken", dass die Ini-Datei nur bei Bedarf geladen wird. Ich hoffe, ich hab's jetzt kapiert.
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? [gelöst]

Beitrag von and4more »

...habe jetzt einen Testlauf gemacht mit getrennt erzeugten Ini-Files, und Super!!!
Alles funktioniert.
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

Antworten