Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Klasse in einer TList wird immer überschrieben (https://www.delphipraxis.net/88486-klasse-einer-tlist-wird-immer-ueberschrieben.html)

fapsons 16. Mär 2007 08:32


Klasse in einer TList wird immer überschrieben
 
Hallo Leute,

ich weiß, mein Posting beinhaltet sehr viel Quellcode, aber das Problem ist, dass ich nicht genau weiß, an welcher Stelle ich einen Fehler gemacht habe.

Und zwar lese ich Kundendaten aus einer Datenbank aus. Diese sollen in die Klasse CustomerTerminal geschrieben werden. Alle einzelnen CustomerTerminals von allen Kunden sollen dann wiederum in die TList (LCustomerTerminal) geschrieben werden.

Beim Durchlauf der beiden Proceduren, die eigentlich genau das bezwecken sollten :gruebel: erhalten jedoch alle CustomerTerminals der TList die Werte des letzten CustomerTerminals aus der TList.

Führe wahrscheinlich den Add Befehl für die TList an der falschen Stelle aus oder so, jedenfalls komme ich selber nicht darauf, was ich genau falsch mache...
Ich hoffe, ihr könnt mir folgen :pale:.

Danke schon mal!

Gruß,
-fapsons--



Delphi-Quellcode:
Unit DBInterface;
...

procedure Get_Customer_Terminals;        // Kundenterminals von allen Kunden der DB werden ausgelesen
var TEID, TMID, VSID, Syst, Knot :Integer;
    Bez, Beschr, Typ, IP_A, Schnitts, Firmbez,FirmW, TermProg, KartTyp, Zubeh:String;
begin

 with D_DataModule.DataSet do
 begin
     SelectSQL.Clear;
     SelectSQL.Text := 'select * from V_CUSTOMER_TERMINALS v where v.vsid = ''' + (inttostr(reg.Versions_ID)) + '''';
     Open;
 end;

 while not D_DataModule.DataSet.Eof do
 begin
   TEID := D_DataModule.DataSet.FieldByName('TEID').AsInteger;
   TMID := D_DataModule.DataSet.FieldByName('TMID').AsInteger;
   ...
   Zubeh := D_DataModule.dataset.FieldByName('ZUBEH').value;

   reg.Add_Cust_Terminal(Bez + Beschr + Typ,TMID, VSID, Syst, Knot, Schnitts, IP_A, Firmbez, FirmW, TermProg,    KartTyp, Zubeh);
   D_DataModule.DataSet.Next;

 end;

 D_DataModule.DataSet.Close;
end;



Unit DeclareTypes;
...
procedure TSoftwarePaket.Add_Cust_Terminal(TMNA1: String; TMID, VSID, Syst, Knot: Integer; Schnittst, IP, Firmenbez, Firmware, TermProg, KartTyp, Zubehoer: String);

begin
with CustomerTerminal do
   begin
      TMNA := TMNA1;
      TEID := TEID;
      ...
      Zubehoer := Zubehoer;
   end;
   LCustomerTerminal.Add(CustomerTerminal);
   ...
End;

sirius 16. Mär 2007 08:50

Re: Klasse in einer TList wird immer überschrieben
 
Wenn dein LCustomerTerminal von TList ist, kannst du keinen einfachen record übergeben. Denn du übergibst nur den Pointer an die stelle, wo der Record gerade ist. Wenn der Record in einer Klasse existiert, dann steht er immer an derselben Stelle, weswegen du immer den selben Pointer übergibst. Und je nachdem, was du gerade als letztes in den Record eingetragen hast, steht dies auch an allen Stellen in der Liste.

Mir fehlen jetzt deine RecordDeklarationen, aber ich versuchs mal:
Delphi-Quellcode:
procedure TSoftwarePaket.Add_Cust_Terminal(TMNA1: String; TMID, VSID, Syst, Knot: Integer; Schnittst, IP, Firmenbez, Firmware, TermProg, KartTyp, Zubehoer: String);
var PcustomerTerminal:^TcustmerTerminal;
begin
 with CustomerTerminal do
   begin
      TMNA := TMNA1;
      TEID := TEID;
      ...
      Zubehoer := Zubehoer;
   end;
   new(PcustomerTerminal);
   PCustomerterminal^:=Customerterminal;
   LCustomerTerminal.Add(PCustomerTerminal);
   ...
End;
Und beim Löschen, das Dispose nicht vergessen.
(Du hast ja den ganzen QuellCode, da kannst du dies bisschen besser anpassen)

fapsons 16. Mär 2007 09:22

Re: Klasse in einer TList wird immer überschrieben
 
Puuh Sirius,

jetzt habe ich gehofft in meinem Praktikum, was ich momentan mache mich nicht mit Pointern beschäftigen zu müssen. Jetzt ist der letzte Tag des Praktikums und ich merke, dass ich wohl doch nicht drum herum komme...;)


Habe deinen Code mal so übernommen.
Da ich aber wie gesagt absolut keinen Plan von Pointern habe, bin ich leider nicht in der Lage, den neuen Fehler zu beheben. Fehler lautet, dass der maximale Listenindex (0) überschritten würde. Wie kann das sein? Wurden meine Daten doch nicht korrekt in die Liste hinzugefügt?




Delphi-Quellcode:

procedure TSoftwarePaket.Add_Cust_Terminal(TMNA1: String; TMID, VSID, Syst, Knot: Integer; Schnittst, IP, Firmenbez, Firmware, TermProg, KartTyp, Zubehoer: String);
var PCustomerTerminal :^TCustomerTerminal;
begin

  with CustomerTerminal do
   begin
      TMNA := TMNA1;
      TEID := TEID;
      TMID := TMID;
      VSID := VSID;
      Schnittst := Schnittst;
      Syst := Syst;
      Knot := Knot;
      IP := IP;
      Firmenbez := Firmenbez;
      Firmware := Firmware;
      TermProg := TermProg;
      KartTyp := KartTyp;
      Zubehoer := Zubehoer;
   end;

   new(PcustomerTerminal);
   PCustomerTerminal^:=CustomerTerminal;
   LCustomerTerminal.Add(PCustomerTerminal);

   showmessage(TCustomerTerminal(LCustomerTerminal.Items[0]).tmna);
End;

sirius 16. Mär 2007 09:34

Re: Klasse in einer TList wird immer überschrieben
 
Ich glaube, dazu brauche ich mal deine LCustomerTerminal - deklaration. Und ob das mit dem Typecasting im Showmessage so in Ordnung geht, weis ich jetzt nicht.


Alternativ zu deiner Struktur, kannst du aus dem Record auch eine eigene Klasse (von TObject) machen und dann statt TList TObjectList verwenden. sieht dann mehr nach OOP aus und die
Speicherverwaltung (besonders das Löschen) übernimmt dann die Liste.

Luckie 16. Mär 2007 09:37

Re: Klasse in einer TList wird immer überschrieben
 
Siehe zu sirius Vorschlag auch dies hier: http://www.delphipraxis.net/internal...t.php?t=105489

fapsons 16. Mär 2007 09:38

Re: Klasse in einer TList wird immer überschrieben
 
Du meinst wahrscheinlich TCustomerTerminal, und nicht LCustomerTerminal, oder? Weil sich es bei der LCustomerTerminal nur um die Liste handelt.
TCustomerTerminal ist übrigens gar kein Record, sondern bereits eine Klasse:


Delphi-Quellcode:
  TCustomerTerminal = class
      TMNA :String;
      TEID :Integer;
      TMID :Integer;
      VSID :Integer;
      Schnittst :String;
      Syst :Integer;
      Knot :Integer;
      IP :String;
      Firmenbez :String;
      Firmware :String;
      TermProg :String;
      KartTyp :String;
      Zubehoer :String;
  End;

sirius 16. Mär 2007 10:14

Re: Klasse in einer TList wird immer überschrieben
 
Na wenn du schon ne Klasse hast, wo ist dann dein Create?
Ich glaub, hier muss mal einbisschen aufgeräumt werden :zwinker:

fapsons 16. Mär 2007 10:18

Re: Klasse in einer TList wird immer überschrieben
 
Hier ist mein Create...;)
Habe nur gerade meine TList zur TObjectList gemacht.
Ist doch sinnvoller in diesem Fall, oder?



Delphi-Quellcode:
procedure TSoftwarePaket.Init;
begin

 LCustomerTerminal := TObjectList.Create;
 CustomerTerminal := TCustomerTerminal.Create;
...
End;

sirius 16. Mär 2007 10:28

Re: Klasse in einer TList wird immer überschrieben
 
Ach, jetzt kommen wir der Sache näher (Ich glaube Luckies TuT wärerecht hilfreich für dich). Ich versuch mal hier:
Vergess erstmal alles mit dem record (new, dispose und Pcustomer...)

Die objectliste ist in Ordnung (Du solltest noch die eigenschaft ownsobject auf true setzen.)

Das CustomerTerminal ist falsch. Du musst doch für jeden neuen Eintrag eine Instanz createn.
Delphi-Quellcode:
procedure TSoftwarePaket.Add_Cust_Terminal(TMNA1: String; TMID, VSID, Syst, Knot: Integer; Schnittst, IP, Firmenbez, Firmware, TermProg, KartTyp, Zubehoer: String);

begin
customerTerminal:=TcustomerTerminal.create; //hier jedes mal neu, du brauchst doch für jeden Kunden eine neue Instanz
                                            //Das Free wird automatisch durch die ObjectList aufgerufen wenn ownsobject auf true ist
with CustomerTerminal do
   begin
      TMNA := TMNA1;
      TEID := TEID;
      ...
      Zubehoer := Zubehoer;
   end;
   LCustomerTerminal.Add(CustomerTerminal);
   ...
End;

fapsons 16. Mär 2007 10:49

Re: Klasse in einer TList wird immer überschrieben
 
Habe deine Anregungen jetzt umgesetzt...;)
Die ShowMessage - Anweisung liefert mir allerdings jetzt die Werte von allen TCustomerTerminals, aus der ObjectList und nicht nur den ersten. Woran liegt das genaU?


Delphi-Quellcode:
procedure TSoftwarePaket.Add_Cust_Terminal(TMNA1: String; TMID, VSID, Syst, Knot: Integer; Schnittst, IP, Firmenbez, Firmware, TermProg, KartTyp, Zubehoer: String);
begin

  LCustomerTerminal := TObjectList.Create;
  LCustomerTerminal.OwnsObjects := True;

  with CustomerTerminal do
   begin
      TMNA := TMNA1;
      TEID := TEID;
      TMID := TMID;
      VSID := VSID;
      Schnittst := Schnittst;
      Syst := Syst;
      Knot := Knot;
      IP := IP;
      Firmenbez := Firmenbez;
      Firmware := Firmware;
      TermProg := TermProg;
      KartTyp := KartTyp;
      Zubehoer := Zubehoer;
   end;

   LCustomerTerminal.Add(CustomerTerminal);
   showmessage(TCustomerTerminal(LCustomerTerminal.Items[0]).tmna);
End;


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:13 Uhr.
Seite 1 von 2  1 2      

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 by Thomas Breitkreuz