Entwickler-Ecke

Dateizugriff - Ini Inhalt in Listbox


chickenfigt1989 - Di 28.02.12 06:38
Titel: Ini Inhalt in Listbox
Hallo,

Ich hab ein Eingabeformular das meine Daten in einer Ini Datei Speichern.

Die Ini Einträge sehen so aus:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
[1]
Vorname=Max 
Nachname=Mustermann
Straße=Musterstraße
Nr=4
Plz=50000
Ort=Musterhausen
Vorwahl=051
Rufnummer=455645
Anrede=Herr

[2]
Vorname=Max 
Nachname=Mustermann
Straße=Musterstraße
Nr=4
Plz=50000
Ort=Musterhausen
Vorwahl=051
Rufnummer=455645
Anrede=Herr

[3]
Vorname=Max 
Nachname=Mustermann
Straße=Musterstraße
Nr=4
Plz=50000
Ort=Musterhausen
Vorwahl=051
Rufnummer=455645
Anrede=Herr


Die Einträge werden mit aufsteigender Nummer mittels einen Zähler gespeichert.
Jeder Eintrag wird eine Nummer höher gespeichert.

Wie kann ich nun die Einträge aus der Ini Datei in ein Listview einlesen lassen?

Ist es möglich die Einträge aus der Ini in einer Listbox ausgeben zu lassen wobei dann jeder Eintrag ein OnKlick Ereignis hat und wen ja wie würde man so etwas Realisieren?

Danke schonmal für eure Hilfe

lg

Moderiert von user profile iconNarses: Titel geändert, war: "Ini Inhalt in Listview".


jaenicke - Di 28.02.12 07:18

Eigentlich ist das relativ trivial, aber für mich stellt sich erst einmal die Frage wo denn das Problem liegt:
Beim Auslesen der Datei oder beim Anzeigen in der ListView? :gruebel:


Narses - Di 28.02.12 15:34

Moin!

user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:
Ich hab ein Eingabeformular das meine Daten in einer Ini Datei Speichern.
INI-Dateien sind kein Datenlager, jedenfalls keine gute Lösung wenn es um mehr als eine Handvoll geht oder performant sein soll. :idea: Ganz heißer Tipp, auch wenn dich das vermutlich eh nicht interessiert: Nimm TMemIniFile, nicht TIniFile :!:

user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:
Die Ini Einträge sehen so aus:
Genau hier ist dein Problem, das Konzept ist nicht geeignet. Mach das besser so:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
[Daten]
Count=2

Vorname1=Max 
Nachname1=Mustermann
Straße1=Musterstraße
Nr1=4
Plz1=50000
Ort1=Musterhausen
Vorwahl1=051
Rufnummer1=455645
Anrede1=Herr

Vorname2=Max 
Nachname2=Mustermann
Straße2=Musterstraße
Nr2=4
Plz2=50000
Ort2=Musterhausen
Vorwahl2=051
Rufnummer2=455645
Anrede2=Herr
Vor dem Ausgeben ein .EraseSection('Daten'); absetzen, dann die Anzahl schreiben und die Daten hinterher. :idea:

user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:
Wie kann ich nun die Einträge aus der Ini Datei in ein Listview einlesen lassen?
Auslesen konzeptionell so:

Delphi-Quelltext
1:
2:
3:
4:
5:
Anzahl := IniFile.ReadInteger('Daten''Count'0);
for i := 1 to Anzahl do begin
  Name := IniFile.ReadString('Daten''Name'+IntToStr(i), '');
  //...
end;

user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:
Ist es möglich die Einträge aus der Ini in einer Listbox ausgeben zu lassen wobei dann jeder Eintrag ein OnKlick Ereignis hat und wen ja wie würde man so etwas Realisieren?
Ja. :D

Aber wie jaenicke schon treffend sagte, wo genau liegt das Problem, und geht´s nun um eine ListBox oder ein ListView? :nixweiss: Vorab schonmal: bitte nicht in diesem Thread die ListBox/-View Problematik weiter ansprechen, dafür ist ein neuer Thread unter VCL aufzumachen! :idea: Hier sollte es nur um den Datenzugriff gehen. Danke! ;)

cu
Narses


jaenicke - Di 28.02.12 18:03

Wobei das Konzept bei INIs ja damals schon oft so benutzt wurde (wobei Count gar nicht nötig ist):

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
[Information]
Count=2

[Setting1]
Data=Foo

[Setting2]
Data=Foo
Oder auch nur mit den Sektionen. Aber natürlich ging es da in der Tat um Konfigurationsdaten.

Jedenfalls kann man einfach eine Liste der Sektionen holen und dann in jeder Sektion die Einträge ansprechen. Die können dann ja ruhig alle gleich heißen, das ist ja korrekt. Und genauso funktioniert es ja auch heutzutage mit XML-Dateien (nur einfacher halt).

Also sprich so ca., wenn es darum geht eine Liste mit Einstellungen zu füllen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
var
  FileContents: TMemIniFile;
  Sections, SectionContents: TStringList;
  CurrentSection: string;
  MySettings: TObjectList<TSetting>;
begin
  ...
  FileContents.ReadSections(Sections);
  Sections.Delete(Sections.IndexOf('Information')); // Informations-Sektion löschen
  for CurrentSection in Sections do
  begin
    FileContents.ReadSectionValues(CurrentSection, SectionContents);
    MySettings.Add(TSetting.Create(SectionContents));
  end;
  ...
Und im Konstruktor von TSetting können die Einstellungen dann aus der TStringList gelesen werden. Alternativ kann man natürlich auch die INI direkt übergeben:

Delphi-Quelltext
1:
2:
3:
  for CurrentSection in Sections do
    MySettings.Add(TSetting.Create(FileContents, CurrentSection));
  ...


chickenfigt1989 - Di 28.02.12 22:52

Hey,

Hab nun meine Speichermethode Abgeändert nun sieht die Ini so aus wie Narses vorgeschlagen hat:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
[Daten]
Count=2
Vorname1=Sepp 
Nachname1=Maier
Straße1=Harrerstr.
Nr1=9
Plz1=5465123
Ort1=Berlin
Vorwahl1=051
Rufnummer1=54652
Anrede1=Herr
Vorname2=Sepp
Nachname2=Maier
Straße2=Schwimmbadstr.
Nr2=8
Plz2=645646
Ort2=Hamburg
Vorwahl2=068
Rufnummer2=546231
Anrede2=Herr


Nun wollte ich nach Narses vorschlag gehen mit:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TForm2.Button1Click(Sender: TObject);
var
anzahl:String;
i:string;
begin
Anzahl := TIniFile.ReadInteger('Daten''Count'0);
for i := 1 to Anzahl do begin
  Listbox1.Items := TIniFile.ReadString('Daten''Name'+IntToStr(i), '');

end;


Allerdings bekomm ich folgende Fehler:


Delphi-Quelltext
1:
2:
3:
[Error] Unit2.pas(34): This form of method call only allowed for class methods
[Error] Unit2.pas(35): For loop control variable must have ordinal type
[Error] Unit2.pas(36): There is no overloaded version of 'IntToStr' that can be called with these arguments


Woran liegt das und wie kann ich die beheben?

lg


Narses - Di 28.02.12 23:03

Moin!

user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:
Woran liegt das und wie kann ich die beheben?
Das sollte schonmal weiterbringen. ;)

cu
Narses


chickenfigt1989 - Di 28.02.12 23:18

Nun sieht mein Code so aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure TForm2.Button1Click(Sender: TObject);
var
anzahl:Integer;
i:Integer;
iniFile:TIniFile;
 filename: String;
begin
filename := ExtractFilePath(ParamStr(0)) + 'adressen.ini';
  TIniFile.Create(filename);
Anzahl := IniFile.ReadInteger('Daten''Count'0);
for i := 1 to Anzahl do begin
  Listbox1.Items := IniFile.ReadString('Daten''Name'+IntToStr(i), '');

end;


Hoffe es ist halbwegs richtig

Jetzt bekomme ich nur noch folgenden Fehler:

Delphi-Quelltext
1:
[Error] Unit2.pas(40): Incompatible types: 'TStrings' and 'String'                    


Narses - Di 28.02.12 23:27

Moin!

user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:
Hoffe es ist halbwegs richtig
Naja, wenn du den Code etwas besser formatierst, kann man ihn auch besser lesen. Einrücken ist nicht nur für Mädchen! :tongue:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure TForm2.Button1Click(Sender: TObject);
  var
    Anzahl: Integer;
    i: Integer;
    IniFile: TIniFile;
    Filename: String;
begin
  Filename := ExtractFilePath(ParamStr(0)) +'adressen.ini';
  TIniFile.Create(filename);
  Anzahl := IniFile.ReadInteger('Daten''Count'0);
  for i := 1 to Anzahl do begin
    Listbox1.Items.Add(IniFile.ReadString('Daten''Name'+IntToStr(i), ''));
  end;

user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:
Jetzt bekomme ich nur noch folgenden Fehler:
Das liegt daran, dass die Eigenschaft .Items einer Listbox kein String ist, du musst neue Elemente mit der Methode .Add() der Klasse TStrings einfügen/anhängen (habe ich oben schon mit drin). :idea:

cu
Narses


chickenfigt1989 - Di 28.02.12 23:34

Jap Danke hab es gerade bemerkt.
Allerdings gibt es jetzt ne Acces Violation


Delphi-Quelltext
1:
Anzahl := IniFile.ReadInteger('Daten''Count'0);                    


Irgendwas stimmt wohl nicht mit dieser Zeile


Narses - Di 28.02.12 23:36

Moin!

user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:
Allerdings gibt es jetzt ne Acces Violation

Delphi-Quelltext
1:
Anzahl := IniFile.ReadInteger('Daten''Count'0);                    
Irgendwas stimmt wohl nicht mit dieser Zeile
Nein, mit dieser Zeile ist alles OK, das "Problem" liegt in der Zeile davor. :idea: Ich wollte mal sehen, ob zu weißt, was du da tust, deshalb hab ich das so gelassen... 8)

Und, Vorschläge? :nixweiss:

cu
Narses


chickenfigt1989 - Di 28.02.12 23:40

Naja Vorschlag nicht wirklich aber ich denk mal weil ich die instanz nicht mit einer Datei verbunden habe?


Narses - Di 28.02.12 23:43

Moin!

user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:
ich denk mal weil ich die instanz nicht mit einer Datei verbunden habe?
Nö, das ist OK, du übergibst im Konstruktor ja den Dateinamen, das reicht dafür aus.

Was könnte es noch sein?

cu
Narses


chickenfigt1989 - Di 28.02.12 23:44

Weil ich die Typenbezeichnung von TIniFile benutz?

Naja wenn es dass auch nicht ist werde ich erstmal ins Bett gehen und Morgen nochmal in ruhe drüber schauen.


Narses - Di 28.02.12 23:47

Moin!

user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:
Weil ich die Typenbezeichnung von TIniFile benutz?
Auch das ist korrekt so, du verwendest ja einen Konstruktor, da muss man das genau so machen.

user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:
Naja wenn es dass auch nicht ist werde ich erstmal ins Bett gehen und Morgen nochmal in ruhe drüber schauen.
Mach das, schadet nicht. ;)

Ich geb dir mal einen Tipp für den guten Schlaf mit: wo legst du denn in deinem Code fest, welchen Inhalt diese Variable haben soll:

Delphi-Quelltext
1:
2:
var
  IniFile: TIniFile;
:?:

cu
Narses


chickenfigt1989 - Di 28.02.12 23:52

Ja hier mit der oder?

Delphi-Quelltext
1:
 Anzahl := IniFile.ReadInteger('Daten''Count'0);                    


Narses - Di 28.02.12 23:54

Moin!

user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:
Ja hier mit der oder?
Hm :? hab ich mich vielleicht nicht gut genug ausgedrückt. Nochmal:
user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
Anzahl := IniFile.ReadInteger('Daten''Count'0);                    
Ich meine den Inhalt der markierten Variablen, mit der Zeile legst du den Inhalt von Anzahl fest (zur Erinnerung: Zuweisung schreibt auf den linken Teil vom ':=').

cu
Narses


chickenfigt1989 - Di 28.02.12 23:56

Ja das ist mir klar aber wieso muss ich der Variable IniFile was zuweisen?

Den ich weis ja den Inhalt der Ini der Variable Anzahl zu

oder bin ich da auf den Holzweg?
lg


Narses - Mi 29.02.12 00:02

Moin!

user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:
Ja das ist mir klar aber wieso muss ich der Variable IniFile was zuweisen?
Weil du in der Zeile, in der es die Exception gibt, auf diese Variable zugreifst (sie steht auf der rechten Seite vom ':='). Wenn du nie was reingeschrieben hast (also diese Variable nie auf der linken Seite eines ':=' aufgetaucht ist), was sollte dann (sinnvolles) drin stehen? :idea: :lupe:

user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:
Den ich weis ja den Inhalt der Ini der Variable Anzahl zu

oder bin ich da auf den Holzweg?
Du bist zielmäßig nicht auf dem Holzweg, genau das soll da passieren. ;) Der Teufel steckt hier eher etwas im Detail. Ich denke, der Tipp oben mit der Frage nach dem "Inhalt" von IniFile (damit ist offensichtlich nicht der Dateiinhalt gemeint, sondern was anderes) sollte dich weiter bringen. :les:

cu
Narses


chickenfigt1989 - Mi 29.02.12 00:06

Hab grad nochmal durchgeschaut und ich glaub ich hab den fehler gefunden.


Delphi-Quelltext
1:
inifile := TIniFile.Create(filename);                    


Aufjedenfall wird mir jetzt in der Listbox der Vorname angezeigt :)

Wenn es richtig ist bedank ich mich Recht herzlich für deine Bemühungen


Narses - Mi 29.02.12 00:08

Moin!

user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:
Aufjedenfall wird mir jetzt in der Listbox der Vorname angezeigt :)
:zustimm:

user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:
Wenn es richtig ist bedank ich mich Recht herzlich für deine Bemühungen
:beer:

cu
Narses


chickenfigt1989 - Mi 29.02.12 00:13

Ich hätte noch ne kleine Frage.

Wie kann ich nun den gerade eingelesenen Eintrag in der Listbox ein Onklick Ereignis zuweisen?

Mein Ziel ist es wenn ich den ersten Namen anklicke das die Komplette Adresse angezeigt wird.


Narses - Mi 29.02.12 00:16

Moin!

user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:
Ich hätte noch ne kleine Frage.
Hatte ich nicht schon am Anfang was dazu gesagt, dass die VCL-Problematik in einem neuen Thread angefasst werden sollte? :| :?


user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:
Wie kann ich nun den gerade eingelesenen Eintrag in der Listbox ein Onklick Ereignis zuweisen?

Mein Ziel ist es wenn ich den ersten Namen anklicke das die Komplette Adresse angezeigt wird.
Ich weiß, hast du ja schon geschrieben. ;) Kurz: man kann bei einer Listbox einzelnen Einträgen kein (eigenes) Ereignis zu weisen. :nixweiss: Es gibt bei der Kompo nur ein OnClick-Ereignis und die Eigenschaft .ItemIndex, mit der man den aktuell ausgewählten Eintrag bestimmt.

Mehr dazu in einem eigenen Thread (du kannst ja hierhin linken). :idea:

cu
Narses


chickenfigt1989 - Mi 29.02.12 00:20

Dankeschön mir ist es wieder eingefallen :)

Und damit du merkst ich Denk auch selber nach hier mein Code:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure TForm2.ListBox1Click(Sender: TObject);
var i: integer;
begin
  for i := 0 to ListBox1.Count - 1 do
    if ListBox1.Selected[i] then label2.Caption := Listbox1.Items[i];
end;


Kannst Closen :)

lg


Narses - Mi 29.02.12 00:25

Moin!

Jetzt mach ich auch noch selbst mit, nach meiner eigenen Ermahnung... :nut: :? Nja, passt jetzt aber hier.

Was hälst´n davon: ;)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TForm2.ListBox1Click(Sender: TObject);
  var
    i: Integer;
begin
  i := ListBox1.ItemIndex;
  if (i >= 0then
    Label2.Caption := Listbox1.Items.Strings[i]
  else
    Label2.Caption := '';
end;


user profile iconchickenfigt1989 hat folgendes geschrieben Zum zitierten Posting springen:
Und damit du merkst ich Denk auch selber nach hier mein Code:
Super Einstellung, weiter machen! :zustimm:

cu
Narses