Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   TClientDataSet aus Klassenstruktur (https://www.delphipraxis.net/200485-tclientdataset-aus-klassenstruktur.html)

hzzm 25. Apr 2019 08:48

Delphi-Version: 10 Seattle

TClientDataSet aus Klassenstruktur
 
Gibt es eine Moeglichkeit, ein
Delphi-Quellcode:
TClientDataSet
automatisch aus einer Objekt-Struktur zu bestuecken?
Ich will vermeiden, fuer eine Klasse
Delphi-Quellcode:
type
  TIngredient = class(TCollectionItem)
  private
    FName, // <<---
    FArticleNumber,
    FScaleUnit,
    FBarcode,
    FCategory: String;
  published
    property Name: String read FName write FName; // <<---
    property ArticleNumber: String read FArticleNumber write FArticleNumber;
    property ScaleUnit: String read FScaleUnit write FScaleUnit;
    property Barcode: String read FBarcode write FBarcode;
    property Category: String read FCategory write FCategory;
  end;

  TIngredients = class(TPersistent)
  private
    FIngredients: TCollection;
  public
    constructor Create;
    destructor Destroy;
    procedure Read;
    procedure Write;
    function GetIngredient(Index: Integer): TIngredient;
    procedure SetIngredient(Index: Integer; Value: TIngredient);
    property Item[Index: Integer]: TIngredient read GetIngredient write SetIngredient; default;
  published
    property Items: TCollection read FIngredients write FIngredients;
  end;
ein TClientDataSet ausfuehrlich mit
Delphi-Quellcode:
TClientDataSet.FieldDefs.Add('Name', ftString, 0, False); // <<---
etc. zu bestuecken.

Ich will die Klasse TIngredient angeben und die FieldDefs automatisch aus den published properties ableiten lassen.

peterbelow 25. Apr 2019 09:21

AW: TClientDataSet aus Klassenstruktur
 
Zitat:

Zitat von hzzm (Beitrag 1430926)
Gibt es eine Moeglichkeit, ein
Delphi-Quellcode:
TClientDataSet
automatisch aus einer Objekt-Struktur zu bestuecken?
Ich will vermeiden, fuer eine Klasse
Delphi-Quellcode:
type
  TIngredient = class(TCollectionItem)
  private
    FName, // <<---
    FArticleNumber,
    FScaleUnit,
    FBarcode,
    FCategory: String;
  published
    property Name: String read FName write FName; // <<---
    property ArticleNumber: String read FArticleNumber write FArticleNumber;
    property ScaleUnit: String read FScaleUnit write FScaleUnit;
    property Barcode: String read FBarcode write FBarcode;
    property Category: String read FCategory write FCategory;
  end;

  TIngredients = class(TPersistent)
  private
    FIngredients: TCollection;
  public
    constructor Create;
    destructor Destroy;
    procedure Read;
    procedure Write;
    function GetIngredient(Index: Integer): TIngredient;
    procedure SetIngredient(Index: Integer; Value: TIngredient);
    property Item[Index: Integer]: TIngredient read GetIngredient write SetIngredient; default;
  published
    property Items: TCollection read FIngredients write FIngredients;
  end;
ein TClientDataSet ausfuehrlich mit
Delphi-Quellcode:
TClientDataSet.FieldDefs.Add('Name', ftString, 0, False); // <<---
etc. zu bestuecken.

Ich will die Klasse TIngredient angeben und die FieldDefs automatisch aus den published properties ableiten lassen.

Eine fertige Lösung kenne ich nicht dafür, aber ein prinzipielles Problem ist das nicht. Für published properties wird seit Delphi 1 runtime type information erzeugt (siehe unit TypInfo), also ist es relative einfach, sich eine Klasse zu schreiben, die für beliebige Objekte einen passenden TClientDataset konfigurieren und die published properties darin speichern bzw. daraus lesen kann.

hzzm 25. Apr 2019 09:29

AW: TClientDataSet aus Klassenstruktur
 
Zitat:

Zitat von peterbelow (Beitrag 1430929)
Eine fertige Lösung kenne ich nicht dafür, aber ein prinzipielles Problem ist das nicht. Für published properties wird seit Delphi 1 runtime type information erzeugt (siehe unit TypInfo), also ist es relative einfach, sich eine Klasse zu schreiben, die für beliebige Objekte einen passenden TClientDataset konfigurieren und die published properties darin speichern bzw. daraus lesen kann.

Jo, ich dachte ich koennte kurzerhand vermeiden, das selbst auszucoden.
Kann aber echt nichts fertiges finden. Komisch, das Problem stellt sich sicher oefters...

Danke fuers Lesen

Uwe Raabe 25. Apr 2019 09:36

AW: TClientDataSet aus Klassenstruktur
 
In seinem Buch Mastering Delphi 7 beschreibt Marco Cantú im Kapitel A Dataset of Objects eine Methode dafür:


Delphi-Quellcode:
procedure TMdObjDataSet.InternalInitFieldDefs;
var
  i: Integer;
begin
  if FObjClass = nil then
    raise Exception.Create ('TMdObjDataSet: Unassigned class');
   
  // field definitions
  FieldDefs.Clear;
  nProps := GetTypeData(fObjClass.ClassInfo)^.PropCount;
  GetMem(PropList, nProps * SizeOf(Pointer));
  GetPropInfos (fObjClass.ClassInfo, PropList);
   
  for i := 0 to nProps - 1 do
    case PropList [i].PropType^.Kind of
      tkInteger, tkEnumeration, tkSet:
        FieldDefs.Add (PropList [i].Name, ftInteger, 0);
      tkChar: FieldDefs.Add (PropList [i].Name, ftFixedChar, 0);
      tkFloat: FieldDefs.Add (PropList [i].Name, ftFloat, 0);
      tkString, tkLString:
        FieldDefs.Add (PropList [i].Name, ftString, 50); // TODO: fix size
      tkWString: FieldDefs.Add (PropList [i].Name, ftWideString, 50);
        // TODO: fix size
    end;
end;

hzzm 25. Apr 2019 09:43

AW: TClientDataSet aus Klassenstruktur
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1430932)
In seinem Buch Mastering Delphi 7 beschreibt Marco Cantú im Kapitel A Dataset of Objects eine Methode dafür

Boah. Vielen, vielen Dank!


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:34 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