Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Die Sache mit dem Listenproperty (https://www.delphipraxis.net/191901-die-sache-mit-dem-listenproperty.html)

Delbor 1. Mär 2017 20:28

Delphi-Version: 5

Die Sache mit dem Listenproperty
 
Hi zusammen

Da man Pferde ja bekanntlich vom Kopf her aufzäumt, fang ich gleich mal damit an. Meinem Datenmodul habe ich ein Feld mit zugehörigem Setter, Getter und Property verpasst. In private:
Delphi-Quellcode:
FContentmastertables: TStringlist;
und
Delphi-Quellcode:
function GetContentmasterTables: TStringlist;
sowie schliesslich public:
Delphi-Quellcode:
property Contentmastertables: TStringlist read GetContentmasterTables;
Bei Programmstart greife ich ein erstes mal darauf zu:
Delphi-Quellcode:
procedure TServerInfoFrame.CatalogInformation;
  var i, j: Integer; Catalog: string;
      LIndent : String; CatNames: TStringlist;
begin
  CatNames := TStringList.Create;
  try
  ...
  finally
    CatNames.Free;
  end;
  LIndent := '   -  ';
  for i := 0 to LBxCatalogNames.Items.Count - 1 do
  begin
...
    Catalog := LBxCatalogNames.Items[i];
//    CM_First.ProcedureReport.Add(LIndent + 'Catalog := '+ Catalog);
    if Catalog = 'contentmasterdata' then
    begin
      Memo1.Lines.Add('*************');
      Memo1.Lines.Add(Catalog);
      Memo1.Lines.Add('------------');
      Memo1.Lines.AddStrings(FDMySQLDml.Contentmastertables); // Löst offenbar die AV aus. Der GRund: Keine Rückgabe
      ...
Dies löst den Getter aus:

Delphi-Quellcode:
function TFDMySQLDml.GetContentmasterTables: TStringlist;
  var SqlString : String; I: integer;
begin
  SqlString := 'SHOW TABLES';
  FDQueryMain.Open(SqlString);
  FDQueryMain.First;
  while not FDQueryMain.Eof do
  begin
    FContentmastertables.Add(FDQueryMain.Fields.Fields[0].AsString);
    FDQueryMain.Next;
  end;
  Result.Clear;
  Result := (FContentmastertables);
 end;
Spätestens bei der Übrgabe an Result krachts...

Ich habe jetzt mindestens einen Tag hinter mir. Dabei habe ich mir unter anderem dies und das.

Ich habe auch schon versucht, mit TStrings zu arbeiten. Aber irgendwie komm ich da nicht ganz klar. So, wie ich das verstanden habe, kann ich zwar eine Variable als TStrings deklarieren, muss dieser dann aber einen TStrings-Nachkommen "mit Hand und Fuss" zuweisen, bevor ich irgendwas befüllen kann.

Da es sich bei der Funktion um einen Getter handelt, kann ich die Methode nicht einfach in eine Prozedur umwandeln.
Was mache ich falsch??

Gruss
Delbor

Lemmy 1. Mär 2017 20:36

AW: Die Sache mit dem Listenproperty
 
Was genau soll das Result.Clear; bewirken? An der Stelle ist doch Result noch gar nicht definiert...

Delbor 1. Mär 2017 21:22

AW: Die Sache mit dem Listenproperty
 
Hi Lemmy
Stimmt. Ich hab das aus einem Beispiel - ziemlich gedankenlos - übernommen. Andrerseits sollte es keinen Schaden anrichten.

Gruss
Delbor

Uwe Raabe 1. Mär 2017 21:35

AW: Die Sache mit dem Listenproperty
 
Wo wird die Instanz von
Delphi-Quellcode:
FContentmastertables
erzeugt?

Delbor 1. Mär 2017 21:43

AW: Die Sache mit dem Listenproperty
 
Hi Uwe Raabe

Erzeugt wird das Feld im Daamodul.Create und im DataModuleDestroy wieder freigegeben. Das Feld selbst ist nicht das Problem, auch die Daten vom Query werden korrekt übergeben.

Gruss
Delbor

Uwe Raabe 1. Mär 2017 21:56

AW: Die Sache mit dem Listenproperty
 
Zitat:

Zitat von Delbor (Beitrag 1362979)
Andrerseits sollte es keinen Schaden anrichten.

Ähm - doch! Da Result an der Stelle nicht definiert ist, kann alles Mögliche drin stehen (auch nil). In jedem Fall ist der Aufruf Result.Clear zu entfernen. Schau mal, ob es dann funktioniert.

Delbor 1. Mär 2017 22:28

AW: Die Sache mit dem Listenproperty
 
Hi Uwe Raabe

Ups!! Genau das wars! Vielen Dank!

Gruss
Delbor

p80286 2. Mär 2017 13:36

AW: Die Sache mit dem Listenproperty
 
Da würde ich gleich Nägel mit Köpfen machen:
Delphi-Quellcode:
procedure TFDMySQLDml.GetContentmasterTables(var Liste:TStringlist);
   var SqlString : String; I: integer;
begin
   SqlString := 'SHOW TABLES';
   FDQueryMain.Open(SqlString);
   //FDQueryMain.First;   {---- ist nicht notwendig}
   while not FDQueryMain.Eof do
   begin
     FContentmastertables.Add(FDQueryMain.Fields.Fields[0].AsString);
     FDQueryMain.Next;
   end;
   Liste.Clear;
   Liste:= (FContentmastertables); {---- was ist FContentmastertables ????} 
  end;
eine Stringliste als Ergebnis einer Funktion ist nicht so der Bringer.

Gruß
K-H

sakura 2. Mär 2017 13:47

AW: Die Sache mit dem Listenproperty
 
Mal grundsätzlich ist das so kein guter Ansatz:
  • Wenn mehrere Threads gleichzeitig auf die Eigenschaft zugreifen, wirst Du sehr seltsame Ergebnisse bekommen
  • Ändert sich das Ergebnis so rasant, dass es Sinn mach mit jedem Zugriff alles neu zu ermitteln
  • Macht evtl. eine lokale StringListe mehr Sinn/bzw als Rückgabetyp ein Array?
  • ...
...:cat:...

DeddyH 2. Mär 2017 14:59

AW: Die Sache mit dem Listenproperty
 
Ich würde vermutlich Lazy Initialization benutzen: ein privates Feld vom Typ TStrings oder gleich TStringList. Stellt der Getter nun beim ersten Aufruf fest, dass das Feld noch nil ist, erzeugt er die Liste und befüllt sie. Zum Schluss gibt er dann einfach das Feld zurück, was dann in jedem Fall eine gültige Instanz enthalten sollte. Jeder weitere Getter-Aufruf geht dann schneller, weil die Instanz ja schon vorhanden ist.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:44 Uhr.
Seite 1 von 3  1 23      

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