TValueListEditor - wie speichern? [gelöst]

Für Fragen von Einsteigern und Programmieranfängern...
wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: TValueListEditor - wie speichern?

Beitrag von wp_xyz »

Du hast eine Datei (IniPfad+'ORC'+ext), die du zweimal öffnest: Einmal im TFrmMain.FormCreate über IniF := TInifile.Create(...) als "echte" Ini-Datei - IniF bleibt bis zum Programmende bestehen. Und einmal im IniEdit, wo sie in die Strings eines ValueListEditor eingelesen wird. Die Strings werden im Ini-Editor bearbeitet und wieder als StringList gespeichert. Abgesehen davon, dass wie ich oben schon geschrieben habe eine "echte" ini-Datei nicht als Stringliste geschrieben werden darf, weil damit die Struktur zerstört wird, ist im FrmMain immer noch die alte geladen. Wenn du dann das Programm beendest, schreibt TIniFile den alten Inhalt wieder in die Datei.

So kann das nicht funktionieren. Ich weiß nicht, was du alles vorhast. Aber wenn die Ini-Datei IniF immer global im Projekt existieren muss, darfst du die Datei im Ini-Editor nicht erneut von Platte einlesen, sondern du musst dir die Strings des zu bearbeitenden Schlüssels aus IniF holen. TIniDatei hat dafür die Methode ReadSectionValues (im Unterschied zu ReadSection bleiben dabei die Name=Wert Paare erhalten). Das Einlesen der Ini-Strings im FormShow von TFrmIniEdit wird damit zu

Code: Alles auswählen

procedure TFrmIniEdit.FormShow(Sender: TObject);
begin
  IniF.ReadSectionValues('RISIKO', ValEdIni.Strings);
end;

Da hier nur eine Section übertragen wird, würde ich dir empfehlen noch eine Listbox in den IniEditor aufzunehmen, in dessen Items du per IniF.ReadSections die Abschnittsbezeichnungen einliest (das sind die Zeilen mit eckigen Klammern). Durch Klick auf einem Listboxeintrag kannst du dann wie oben die Section-Werte in den ValueListEditor übertragen. Aber nicht vergessen, vorher den bisherigen Abschnitt zu sichern - wie das geht, kommt gleich. Alternativ kannst du auch alle Sections in den ValuelistEditor einlesen, wobei der Schlüsselname ohne Wert in der rechten Spalte auftauchen sollte. Etwa so (ist in meinen Augen sehr unübersichtlich. Besser wäre ein StringGrid mit einer zusätzlichen Spalte für den Schlüsselnamen, oder noch besser ein VirtualTreeView, um die nicht interessierenden Abschnitte zuklappen zu können):

Code: Alles auswählen

procedure TFrmIniEdit.FormShow(Sender: TObject);
var
  L: TStringList;
  sections: TStringList;
  i, j: Integer;
begin
  L := TStringList.Create;
  sections := TStringList.Create;
  try
    IniF.ReadSections(sections);
    for i:=0 to sections.Count-1 do begin
      if sections[i] = '' then
        Continue;
      ValEdIni.Strings.Add(sections[i] + '=');
      IniF.ReadSectionValues(sections[i], L);
      for j := 0 to L.count-1 do
        ValEdIni.Strings.Add(L[j]);
    end;
  finally
    L.Free;
    sections.Free;
  end;
end;

Die SaveINI-Methode muss die Werte aus dem ValueListEditor in IniF übertragen. Leider gibt es dafür keine kompakte Methode a la ReadSectionValues, sondern man muss die Stringpaare einzeln in IniF zurückschreiben. Aber das ist nicht der Rede wert:

Code: Alles auswählen

procedure TFrmIniEdit.SaveINI;
var
  i: Integer;
begin
  IniF.EraseSection('RISIKO');
  for i:=0 to ValEdIni.Strings.Count-1 do
    IniF.WriteString('RISIKO', ValEdIni.Strings.Names[i], ValEdIni.Strings.ValueFromIndex[i]);
  IniF.UpdateFile;
end

Falls du das mit der Listbox machst, musst du natürlich statt "RISIKO" den in der Listbox ausgewählten Schlüsselnamen verwenden.
 
MakeIniFile hat auch ein Problem, Du willst hier eine neue Ini-Datei auf der Platte anlegen. Dazu löschst du die alte und versuchst per IniF := TIniFile.Create(...) eine neue zu erzeugen. Aber das erzeugt keine Datei, sondern eine neue Instanz der Klasse TIniFile! Die alte (die in FormCreate erzeugt wurde) existiert übrigens weiterhin, nachdem du den Pointer auf die Instanz überschrieben hast, kannst du auf die alte Instanz nicht mehr zugreifen und sie inbesondere nicht mehr freigeben, so dass du ein Speicherleck erzeugt hast. Andererseits die Instanz zu zerstören, ist auch nicht ohne, da hier der Inhalt von IniF auf die Platte geschrieben und beim Create wieder eingelesen wird. Wie geht's richtig? Ich würde die Instanz beibehalten und im Speicher aufräumen durch Aufruf von IniF.EraseSection(...):
 

Code: Alles auswählen

procedure TFrmIniEdit.MakeIniFile;
// INI-Datei erstellen
var
  L: TStringList;
  i: Integer;
begin
  L := TStringList.Create;
  try
    IniF.ReadSections(L);
    for i:=0 to L.Count-1 do IniF.EraseSection(L[i]);
  finally
    L.Free;
  end;
 
  try
    IniF.WriteString('RISIKO','Multiple WK-Fx','2')
  ....

Daneben habe ich noch einige Probleme gesehen. Aber der Post ist eh schon so lang...

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 »

Wow, eine wirklich umfassende Antwort. Vielen Dank für die viele Mühe, die Du Dir da gemacht hast, phantastisch. Ich werde allerdings ein bisschen Zeit benötigen, um das alles zu erfassen und korrekt zu implementieren, aber ich denke, das ist die Lösung und ich muss das Programm jetzt ein wenig umstricken. Falls alles klappt werde ich das Thema als gelöst markieren, ansonsten würd' ich nochmal nachhaken, wenn ich darf :wink:
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 »

...sooo, habe nun jetzt versucht den Vorschlag von wp_xyz umzusetzen. Irgendwie klappt das aber nicht so wirklich. Habe mir dann selber was überlegt:

Code: Alles auswählen

 
procedure TFrmIniEdit.SaveINI;
var
  strBuff:TStringList;
  strSection,strKey,strVal: String;
  i,iKeyLen:Integer;
 
begin
  strBuff:=TStringList.Create;
  try
    strBuff.AddStrings(ValEdIni.Strings);
    for i:=0 To strBuff.Count-1 do begin
      if Pos('[',strBuff.Strings[i])<>0 then
        strSection:=Copy(strBuff.Strings[i],Pos('[',strBuff.Strings[i])+1,Pos(']',strBuff.Strings[i])-2);
      else begin
        iKeyLen:=Pos('=',strBuff.Strings[i])-1;
        strKey:=Copy(strBuff.Strings[i],1,iKeyLen);
        strVal:=Copy(strBuff.Strings[i],iKeyLen+2,Length(strBuff.Strings[i])-iKeyLen+2);
      end;
      IniF.WriteString(StrSection,strKey,StrVal);
      IniF.UpdateFile;
      Next;
    end;
  finally
    strBuff.Free;   
  end;
end;
 


...klappt fast. Allerdings ist mir noch unklar warum beim Speichern nach einer Änderung alle Sections ein zusätzliches ']' hinten dran gehängt bekommen. Wie krieg' ich das weg?
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 ist wieder ein schönes Beispiel für Kaffeesatzleserei. Niemand hier weiß weder was du sonst machst noch was im ValueListEditor steht. Dein gezeigter Code sieht vernünftig aus (abgesehen von der Unstimmigkeit, dass du offenbar damit rechnest, dass die öffnende eckige Klammer nicht das 1.Zeichen des Strings ist, aber dann dennoch im letzten Parameter der copy-Aktion den konstanten Wert 2 von der Position der schließenden Klammer subtrahierst. Und wofür ist das "Next"?).

Hast du eigentlich schon mal versucht, den Debugger einzusetzten?
Zuletzt geändert von wp_xyz am Di 21. Mär 2017, 13:21, insgesamt 1-mal geändert.

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

Re: TValueListEditor - wie speichern?

Beitrag von wp_xyz »

[ Beitrag entfernt ]
Zuletzt geändert von wp_xyz am Di 21. Mär 2017, 10:42, insgesamt 1-mal geändert.

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 »

Außer der oben genannten Änderung und der vorgeschlagenen Änderung für "MakeIniFile"

Code: Alles auswählen

 
var
  SL:TStringList;
  i:Integer;
begin
  //ShowMessage('FrmIniEdit.MakeIniFile');
  SL:=TStringList.Create;
  try
    //zuerst alten Inhalt löschen
    IniF.ReadSections(SL);
    for i:=0 To SL.Count-1 do IniF.EraseSection(SL[i]);
  finally
    SL.Free;
  end;
 

stimmt alles mit dem bereits geposteten Code überein, ich habe also nur "SaveIIN" wie beschrieben angepasst. Der Code ist deshalb so, weil mir aufgefallen war, dass hin und wieder vor [RISIKO] ein '=' stand und das wollte ich auf diese Weise ausschließen. Und die Subtraktion von 2 erfolgt, da ich annahm, dass bei Subtraktion von 1 die schließende Klammer ']' mitkopiert würde, hat sich aber nicht verändert, es wird beim Speichern immer eine zusätzliche schließende Klammer angefügt und damit auch der Inhalt doppelt in der INI-Datei angelegt, der untere Teil zeigt alle Sections mit 2 abschließenden ']]'. Ich bin davon ausgegangen, dass Sections mit der schließenden Klammer enden, daher die Subtraktion von 2 am Ende. 'Next' habe ich schlichtweg vergessen, es stand vorher eine while-Bedingung dort.
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 »

Poste bitte trotzdem den aktuellen Code, ich habe meine Änderungen schon gelöscht.

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 »

Klar, hier nochmal die Datei (habe zwischenzeitlich auch das 'Next' entfernt).
Dateianhänge
ChkIni.zip
(118.67 KiB) 50-mal heruntergeladen
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 »

Ok, hier wie gewünscht auch noch die persönliche Mail-Anfrage an wp_xyz, wo ich um Vorschläge zur weiteren Verbesserung des Codes gebeten hatte:

[text]
 
Hallo wp_xyz, nochmals Danke für die Hilfe. Du hast geschrieben, dass Du noch einige andere Fehler/Probleme im Code gesehen hast. Wäre es vielleicht möglich mir diese zu schreiben? Es müssen nicht unbedingt Lösungen sein, vielleicht nur die Punkte, die Probleme machen können. Evtl. finde ich dann ja auch selbst eine Lösung. Ich hab's halt so gut gemacht wie ich konnte, nur leider fehlt mir als Autodidakt der komplette Background was Algorithmen und saubere Programmierung angeht. Manches davon ist mir einfach noch nicht ganz klar. Falls es nicht zuviel Arbeit ist wäre ich total dankbar dafür.
 
Liebe Grüße
 
[/text]
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 »

Bei dem Schlüssel-Wert steht in den vom Ini-Editor übernommenen Strings der Wert "=[RISIKO]". Nachdem dein Code in der Berechnung der herauszukopierenden Zeichenanzahl davon ausgeht, dass die öffnende Klammer an Position 1 sitzt, bleibt die schließende Klammer dran.

Übersichtlicher wird es mit Zwischenvariablen:

Code: Alles auswählen

var
  s: String;
  p1, p2, p3: Integer; 
[...]
    for i:=0 To strBuff.Count-1 do begin
      s := strBuff.Strings[i];
      p1 := Pos('[', s);
      if p1 > 0 then begin
        p2 := Pos(']', s);
        strSection := trim(Copy(s, p1 + 1, p2 - p1 - 1))
          // Du hast hier im letzten Parameter p2 - 2, was nur richtig ist, wenn p1=1.
          // Aber bei "=[RISIKO]" ist p1 = 2
      end else
      begin          //wenn normaler Text...
        p3 := Pos('=', s);
        iKeyLen := p3 - 1;
        strKey := trim(Copy(s, 1, iKeyLen));
        strval := trim(Copy(s, p3+1, MaxInt));
      end;
      strTMP.Add('['+strSection+']: '+strKey+'='+strVal);   
[...]

Außerdem würde ich zur Sicherheit die herauskopierten Strings, wie oben bereits enthalten, durch die Trim-Routine laufen lassen, damit ggfs vor und nach dem = Zeichen vorhandene Leerzeichen entfernt werden.

Nochmals der Hinweis, den Debugger zu benutzen oder WriteLn-Anweisungen einzufügen. Solche Fehler kannst du jederzeit selbst finden. Für die Debuggernutzung sind Hilfsvariablen sinnvoll, denn den String-Wert einer Stringliste abzufragen, wird sonst ziemlich umständlich.

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 »

Zur Überprüfung des Codes hatte ich ein Memofeld noch unten angehängt und teilweise auch 'ShowMessage' - Klauseln im Code, die ich wieder entfernt habe, bin aber leider nicht auf das gekommen, was Du richtigerweise festgestellt hast. Mit dem Debugger habe ich auch schon versucht zu arbeiten, bin da aber leider noch am Anfang und kann ihn bestimmt auch nicht so gut ausreizen. Hatte mir in diesem Zusammenhang auch das empfohlene YouTube-Video angeschaut, was ich übrigens sehr gut finde.
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 »

Zur Überprüfung des Codes hatte ich ein Memofeld noch unten angehängt und teilweise auch 'ShowMessage' - Klauseln im Code, die ich wieder entfernt habe, bin aber leider nicht auf das gekommen, was Du richtigerweise festgestellt hast. Die strTMP-Variable ist auch noch ein Überbleibsel, da ich deren Inhalt ins Memofeld kopiert hatte. Mit dem Debugger habe ich auch schon versucht zu arbeiten, bin da aber leider noch am Anfang und kann ihn bestimmt auch nicht so gut ausreizen. Hatte mir in diesem Zusammenhang auch das empfohlene YouTube-Video angeschaut, was ich übrigens sehr gut finde.
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 Debugger hat den Vorteil, dass du den Code Zeile für Zeile durchgehen kannst, und dabei immer prüfen kannst, ob sich alles richtig verhält. WriteLn und Memo-Ausgabe dagegen überschütten dich mit Information, und es ist schwer die relevante Zeile zu finden. Meine Codevariante ist sehr debugger-freundlich. Mach doch mal folgendes:
  • Setze einen Break-Point in der Zeile nach "s := strBuff.Strings[i]" - dazu klickst du etwas links von der Zeilennummer im Editor, so dass ein roter Punkt erscheint und die Zeile rot hinterlegt ist.
  • Starte das Programm und führe die Aktionen zum Speichern aus.
  • Das Programm hält am Breakpoint.
  • Die aktuell grau hinterlegte Zeile ist diejenige, die noch nicht ausgeführt ist.
  • Fahre mit der Maus über die Variable "i" - es erscheint ein Popup-Hint mit der Anzeige "i = 0". Nun weißt du, dass i aktuell den Wert 0 hat.
  • Fahre mit der Maus über die Variable "s" - das Popup-Fenster würde in deinem alten Code nun 's = '=[RISIKO]' anzeigen (natürlich muss die Hilfsvariable s eingeführt sein - wiegesagt, den Wert direkt aus der Stringliste zu erhalten, ist kompliziert..).
  • Drücke F8 (oder Menü "Start" / "Einen Schritt weiter") - damit geht das Programm um 1 Zeile weiter. Hier wird die Zeile "p1 := Pos('[', s)" ausgeführt
  • Prüfe mit der Mausmethode, welchen Wert die Variable p1 hat: in diesem Fall ist p1 = 2, denn die eckige Klammer ist an der 2. Zeichenposition.
  • Das nächste F8 führt "if p1 > 0" aus: da p1 = 2 ist, muss diese Bedingung wahr sein, und das nächste F8 muss in den Block der IF-Bedingung hineinführen (andernfalls würde die graue Zeile in den ELSE-Zweig springen).
  • usw.
  • Spätestens wenn dass strSection berechnet ist, würdest du mit deinem alten Code (p2 - 2 in der Copy-Anweisung) sehen, dass strSection hier falsch ist.
  • Mit Taste F9 (oder Menü "Start" / "Start") wird das Programm normal fortgesetzt. Da der Breakpoint in einer Schleife sitzt, wird es wieder am Breakpoint anhalten, nun bei i = 1.
  • Um den Breakpoint zu entfernen, klicke auf den roten Punkt in der Breakpoint-Zeile. Oder rechts-klicke auf dem roten Punkt und wähle "Haltepunkt deaktivieren" - damit wird die Zeile grün, der Breakpunkt ist inaktiv. Dieses Vorgehen kannst du wählen, wenn du bestimmte Bedingungen für den Breakpoint angegeben hast, und das bei einem erneuten Testlauf nicht neu eingeben willst.
  • Um das Programm zu beenden (denn eigentlich hast du ja den Fehler schon gefunden), drücke CTRL+F2 (oder Menü "Start" / "Halt")

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 »

Hallo, zunächst mal Entschuldigung, dass ich mich erst so spät melde, aber irgendwie hatte ich ständig so einen mysql --irgendwas Zugriffsfehler beim Aufrufen der Seite. Also ich habe zwischenzeitlich mit dem Debugger gearbeitet und mir so gut wie ich es kann die einzelnen Codezeilen mit den Variablen angeschaut. Dabei war mir aufgefallen, dass aus irgendeinem mir unerklärlichen Grund beim zweiten Durchlauf der Schleife bei den Sections immer ein [ vorangestellt wird und habe mich daher für folgende Lösung entschieden:

Code: Alles auswählen

 
procedure TFrmIniEdit.SaveINI;
var
  strBuff:TStringList;
  strSection,strKey,strVal,strX: String;
  i,iKeyLen:Integer;
 
begin
  strBuff:=TStringList.Create;
  try
    strBuff.AddStrings(ValEdIni.Strings);
    for i:=0 To strBuff.Count-1 do begin
      strX:=Trim(strBuff.Strings[i]);
      if strX='='  then strX:=#10#13;   //wenn nur '=' dann mit #10#13 ersetzen
      if Pos('[',strX)<>0 then begin
        strSection:=StringReplace(strX,'=','',[]);  //entfernt alle Sonderzeichen ?!?
        strSection:=StringReplace(strSection,'[','',[rfReplaceAll]);
        strSection:=StringReplace(strSection,']','',[rfReplaceAll]);
      end else begin
        iKeyLen:=Pos('=',strX)-1;
        strKey:=Copy(strX,1,iKeyLen);
        strVal:=Copy(strX,iKeyLen+2,Length(strX)-iKeyLen+2);
      end;
{      if (strKey<>'') then begin
        IniF.WriteString(StrSection,strKey,StrVal);
        IniF.UpdateFile;
      end else IniF.DeleteKey(strSection,strKey);
    end;
}  finally
    StrBuff.Free;
  end;
end;
 


Wie Ihr sehen könnt habe ich auch noch versucht irgendwie die Leerzeilen in der Ini-Datei zu entfernen, aber leider klappt das auf diesem Weg nicht, das Speichern der geänderten Ini-Datei jetzt allerdings schon. Natürlich wäre auch der Weg möglich, die ganze Ini-Datei in ein oder zwei StringList einzulesen, bei diesen dann "aufzuräumen" und das ganze nach Löschen der Quell-Ini-Datei wieder neu einzulesen.
Finde ich aber sehr viel Aufwand dafür, dass man mit einem sogenannten ValueListEditor arbeitet, wo der Name suggeriert man könne hier was editieren und die Klasse auch noch zu allem Überfluss eine Speicherfunktion anbietet, die dann aber doch irgendwie nicht nutzbar ist.
Also ich frage mich wozu ein Auto wenn ich dann doch einen Traktor vorspannen muss damit es fährt?
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 »

and4more hat geschrieben:Also ich frage mich wozu ein Auto wenn ich dann doch einen Traktor vorspannen muss damit es fährt?

Gutes Beispiel. Aber es ist anders herum. Du versuchst ein Auto zum Pflügen eines Ackers zu verwenden. TValueListEditor (das Auto) ist da, um eine Liste von Name=Wert-Paaren zu bearbeiten, und das kann das Auto wunderbar. Du willst damit aber eine Ini-Datei mit mehreren Sections bearbeiten - denn da stammen die Zeilen mit den eckigen Klammern her -, und dafür ist das Auto nicht unbedingt gebaut und muss es entsprechend umgerüstet werden.

Antworten