Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Problem mit LixtBox, Stringlist und Memofeld (https://www.delphipraxis.net/148318-problem-mit-lixtbox-stringlist-und-memofeld.html)

punnzall 27. Feb 2010 15:15


Problem mit LixtBox, Stringlist und Memofeld
 
-> Problem halb gelöst, Bitte Beitrag 9 lesen :)
Tag

ich habe ein Problem mit einer Listbox, einer MemoListe und einer Stringlist.
ich bekomme immer einen Zugriffsfehler, egal was ich am Code tue, kommt diese Meldung.
ich habe schon viele Verianten versucht, aber es will nicht funktionieren.

ich möchte gerne dass wenn der user eine Reihe in einer Listbox auswählt,
das Programm den dazu passenden Record suchen geht, und aus diesem eine Stringlist
in ein Memofeld einfügt.

// Es handelt sich Um Records, die sich in einem Array befinden

Habe es mir so gedacht, dass auf einem Click Event auf die Listbox den angewählten Eintrag
(welche Namen Darstellen) mit den namen der Records (.name) verglichen werden,
und wenn der name passt, wird die Stelle (array) zwischengespeichert.
Danach dachte ich mir folgende Methode um die Stringlist in das Memofeld zu bekommen:
Delphi-Quellcode:
// C ist der passende Record Eintrag für den angewählten Eintrag
for I:=1 to Record[C].Txt.count-1 do memMain.Lines.add(Record[C].Text[J]);
Einen Code für das vergleichen und den passenden Eintrag zu posten kann ich schlecht,
da meine letzten Varianten nur "Spielereien" waren.

Wie gesagt, kommt bei der for-loop aber auch bei meinen Varianten zu vergleichen immer Zugriff Fehler.

---
Frage:
Wie macht man es richtig, den angewählten (angeklickten) Eintrag einer Listbox zu entnehmen,
den passenden Record zu finden, und später aus diesem Record eine Stringlist in ein Memofeld zu schreiben ?

Mfg

DeddyH 27. Feb 2010 15:19

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Ich bin zwar nicht sicher, ob ich Dich richtig verstanden habe, aber IMHO machst Du es Dir unnötig schwer. TListbox.Items ist vom Typ TStrings, welcher wiederum über eine Methode AddObject verfügt. Du könntest also Deine Stringlisten direkt in den Listboxeinträgen hinterlegen und musst dann später nicht in irgendwelchen Array of Record herumsuchen.

punnzall 27. Feb 2010 16:19

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Kann ich damit nur Stringlisten hinzufügen ?

DeddyH 27. Feb 2010 16:22

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Nein, Du kannst alles dort einfügen, was von TObject abstammt, somit also jede Art von Klasse.

punnzall 27. Feb 2010 19:33

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Sorry, aber hab Probleme das mit dem AddObjekt zu verstehen :S
Was muss ich angeben wenn ich gerne ein record hinter einem Eintrag setzen will und wie greif ich darauf zurück ?
Mfg

Meta777 27. Feb 2010 19:49

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Hallo,

du kannst auch alles andere hinzufügen, du hast ja 4 Byte (SizeOf(TObject) [ein pointer halt]) "platz".
um ein record hinzuzufügen müsstes du manuell erstellen mit "New(Pointer variable vom Record)" und hinzufügen. Bei löschen und freigeben der Liste musst du die records vorher manuell freigeben mit z.B. Dispose().
Delphi-Quellcode:
type
  TMyRecord = packed record
    FBlah: Integer;
    FFoo: ShortString;
    FBar: Smallint;
  end;
  PMyRecord = ^TMyRecord;

procedure CreateOrInitFooBarOrso;
var
  LPMyRec: PMyRecord;
begin
  myList := TStringList.Create;
  myList.OwnsObject := FALSE; //wichtig da "objects" ja keine TObject-nachfahren beinhaltet
 
  for what so ever do
  begin
    //Record erstellen
    New(LPMyRec)
    LPMyRec^.FBlah := 123456789
    LPMyRec^.FFoo := 'Huhu ich bin ein shortstirng';
    LPMyRec^.FBar := 1;
    myList.AddObject('ein String', TObject(LPMyRec));
  end;
end;

procedure FreeIt;
var
  LPRec: PMyRecord;
begin
  while MyList.Count > 0 do
  begin
    LPRec := PMyRecord(myList.Objects[0]);
    Dispose(LPRec);
  end;
  myList.Free;
end;

punnzall 27. Feb 2010 19:55

Re: Problem mit LixtBox, Stringlist und Memofeld
 
PMyRecord = ^TMyRecord;
Diese Zeile ist ja überflüssig ?
Dh in meinem Code muss ich in ein packed record ändern?
Und warum Kommt der Rekord in eine Stringlist ?
Denn meine Stringlist ist im Record drinne.
Und das ganze soll ja in eine Listbox.

Meta777 27. Feb 2010 21:39

Re: Problem mit LixtBox, Stringlist und Memofeld
 
sorry,
hatte den ersten beitrag nicht gelesen. mein post bezogt sich auf deine letzte frage (post #5).
in der tat kann ich wie daddyh deine gedanken nicht ganz nachvollziehen. "Normalerweise" würde ich einen Reocrd in einer Liste hinzufügen nicht anderesrum.
shalom

punnzall 27. Feb 2010 22:06

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Will ich ja, ich möchte auch gern ein record in eine liste setzen, jedoch soll .name das feld sein, das vom record in der liste angezeigt wird.
Beim anklicken soll dann zB eine stringlist vom record in ein Memo Feld geladen werden.
Ich hoffe ich konnte es jetzt besser erklären.
Mfg

// Edit:
Also das mit dem richtigen Record zu finden hab ich gelöst
Delphi-Quellcode:
J := Liste.ItemIndex;
memMain.Lines.add(Record[J].name);
Dies bringt den passenden Inhalt.
Nun ist nur noch das Problem, wie ich am besten ein Memofeld zwischenspeichere,
und dieses später wieder in das Memo Feld reinbekomme.
Evt wichtig zu sagen ist, dass ich es in ein Record zwischenspeicheren will, welcher gespeichert wird.

DeddyH 28. Feb 2010 09:25

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Hier mal ein Beispiel für AddObject. Auf dem Formular befinden sich nur eine ListBox und ein Memo.
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var Liste: TStringlist;
begin
  //3 Stringlisten erzeugen und per AddObject in den Listbox-Items ablegen
  Liste := TStringlist.Create;
  Liste.Text := 'Dies ist der Inhalt der ersten Liste.';
  ListBox1.Items.AddObject('Eins',Liste);
  Liste := TStringlist.Create;
  Liste.Text := 'Dies ist der Inhalt der zweiten Liste.';
  ListBox1.Items.AddObject('Zwei',Liste);
  Liste := TStringlist.Create;
  Liste.Text := 'Dies ist der Inhalt der dritten Liste.';
  ListBox1.Items.AddObject('Drei',Liste);
end;

procedure TForm1.FormDestroy(Sender: TObject);
var i: integer;
begin
  //die Objekte in der Listbox freigeben
  for i := ListBox1.Items.Count - 1 downto 0 do
    ListBox1.Items.Objects[i].Free;
end;

procedure TForm1.ListBox1Click(Sender: TObject);
var Liste: TStringlist;
begin
  //die Stringliste zum aktuellen Listbox-Eintrag in Memo anzeigen
  if ListBox1.ItemIndex > -1 then
    begin
      Liste := ListBox1.Items.Objects[ListBox1.ItemIndex] as TStringlist;
      if Assigned(Liste) then
        Memo1.Lines.Assign(Liste);
    end;
end;

punnzall 28. Feb 2010 16:40

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Danke
Ich hab es vorher auch mit einer Stringlist versucht, das klappte auch solang ich den Inhalt im Programm in die Stringlist eingetragen habe
und dann auch sofort ins memo übernehme, jedoch habe ich probleme diese stringlist korrekt abzuspeichern.
Muss ich auf was achten wenn ich eine Stringlist, die sich in einem Record befindet, abspeichere ?
Die Stringlist wird korrekt geschrieben und später auch ausgelesen, nur gespeichert wird sie falsch.

Paar Schnipsel zum erklären (Variablennamen ersetzt !):
Delphi-Quellcode:
tRecord = record
  name : string[30];
  text : tstringlist;
end;

var Record : tRecord;
Delphi-Quellcode:
// So setz ich das Memo in eine Stringliste
text := TStringlist.Create;
for I:=0 to zeilenanzahl do // Zeilenanzahl enthält die Anzahl der Zeilen im Memo
begin
  Record.text.add(frmMain.memMain.lines[I]);
end;
Delphi-Quellcode:
procedure SaveRecord;
var I:integer;
    Fle : file of tRecord;
begin
  assignfile(Fle,filename);
  rewrite(Fle);
  for I:=1 to N do // N = Recordanzahl
  begin
    write(Fle,Record[I]);
  end;
  closefile(Fle);
end;
Wie gesagt - Innerhalb des Prgramms funktioniert es super, nur wenn ich die vorher abgespeicherte Datei lade scheint die Stringlist leer zu sein.
Auch in der datei selber finde ich keinen Inhalt der Stringlist.
(Der Rest des Records wird richtig abgespeichert und auch gelesen)
Ich nehme an, dass ich die Stringliste anders abepseichern muss ?

DeddyH 28. Feb 2010 16:43

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Du darfst nicht die Stringliste an sich abspeichern (das ist nur ein Zeiger auf deren Instanz), sondern deren Inhalt. Das dürfte in einem Record aber schwierig werden.

punnzall 28. Feb 2010 16:44

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Und wie könnte ich das Problem lösen ? :/

Jens Hartmann 28. Feb 2010 16:45

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Hallo zusammen,

müsste das mit dem Speichern nicht so gehen...

Delphi-Quellcode:
Text := TStringList.Create;
...
Text.SaveToFile('.\MeinRecord');
Text.Free;
Gruss Jens

punnzall 28. Feb 2010 16:46

Re: Problem mit LixtBox, Stringlist und Memofeld
 
@Jens, ich möchte gerne den Record speichern, und nicht nur eine Stringlist :)
Die Stringlist befindet sich in diesem Record.
Mit dienem Code speichere ich nur die Stringliste.

DeddyH 28. Feb 2010 16:48

Re: Problem mit LixtBox, Stringlist und Memofeld
 
So in etwa. Du könntest dann noch den Namen (ist ja auch nur ein String) beim Speichern in die erste oder letzte Zeile der Stringlist schreiben, dann kannst Du sie nach dem Auslesen auch wieder zuordnen.

punnzall 28. Feb 2010 16:49

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Mein Record enthält im meinem Code viel mehr Inhalt, ich habe es nur im vorigen Code auf die beiden beschränkt, um den Fall etwas besser erkärne zu können. :)

DeddyH 28. Feb 2010 16:53

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Dann bliebe noch die Möglichkeit, die Stringliste wie von Jens gezeigt in einer Datei abzuspeichern und den Dateinamen als ShortString im Record abzulegen. Der Dateiname darf dann aber 255 Zeichen nicht überschreiten, zur Not müsstest Du ihn mit GetShortPathName in das alte DOS-Format bringen.

punnzall 28. Feb 2010 16:55

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Gegen die Lösung habe ich ncihts einzuwenden, aber das Problem könnte werden, dass später im Ordner zu viele Dateien sind :S
Es werden nähmlich recht viele Memo Felder gespeichert.
Sollte es keine andere Lösung geben, werd ich darauf zurückgreifen.
Wäre aber froh wenn es dennoch eine andere Möglichkeit gäbe :)

Jens Hartmann 28. Feb 2010 16:56

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Oder, je nach Art des Records, den Record durchlaufen und in eine eigene Stringliste schreiben und anschließend diese StringList z.B. speichern.

Oder, du musst den Record in einen DB schreiben.

Gruß Jens

DeddyH 28. Feb 2010 16:57

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Naja, eine Datenbank oder XML-Dateien wären evtl. noch eine Möglichkeit.

punnzall 28. Feb 2010 17:54

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Alles vom Record in eine Stringliste zu schreiben wär jetzt zu viel Arbeit, da ich mein komplettes Programm modifizieren müsste.
Und Datenbanken geht leider über meine Delphi Kenntnisse heraus.
Gibt es keine andere Möglichkeiten grosse Strings zeilenweise abzuspeichern ?

Jens Hartmann 28. Feb 2010 19:20

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Also, ich bin mir zwar nicht 100 % sicher, aber das sollte eigenlich nicht so ein Problem sein.

Delphi-Quellcode:
var
  Text : TStringList;
begin
  Text := TStringList.Create;
  for i := 0 to MeinRecord.Count - 1 do
    begin
      Text.Add(MeinRecord[i]);
    end;
  Text.SaveToFile('.\MeinRecord');
  Text.Free;
Also bitte verbessert mich, aber das habe ich gerade ohne Delphi geschrieben, da ich keins zur Hand habe. Aber so müsste das doch ohne großen aufwand gehen.

Gruß Jens

DeddyH 1. Mär 2010 08:17

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Ich habe es jetzt auch nicht ausprobiert, aber ich denke kaum, dass sich ein Record als solcher in einer TStringlist ablegen lässt. Was mir als Lösung noch einfiele: einen Stream erzeugen, 0 an den Anfang, dann den Record dahinter und zum Schluss den Text der Stringliste. Anschließend die 0 mit der aktuellen Streamposition überschreiben. Liest man diese Datei später wieder aus, kann man von Offset zu Offset springen (das steht ja jeweils am Anfang des Datensatzes).

Jens Hartmann 2. Mär 2010 07:46

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Sorry,

ja Du hast recht. Das geht so nicht. Allerdings müsste ich doch auf die einzelnen Werte des Records zugreifen können.

Ich habe mal dazu was gefunden. Vieleicht hilft Dir das ja...

Record in Datei schreiben

Gruß Jens

DeddyH 2. Mär 2010 07:59

Re: Problem mit LixtBox, Stringlist und Memofeld
 
Dann verbleibt aber immer noch das Problem mit der Stringliste.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:50 Uhr.

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