Einleitung
Um der FireDAC VCL Komponente von List & Label im Embarcadero RAD Studio eine Datenquelle zuzuweisen, verwendet man in der Regel den dafür integrierten Dialog für die Eigenschaft DataController > DetailSources der List & Label Komponente:
Entscheidend hierbei ist, dass die Datenquelle bereits zur Design-Zeit, also bereits beim Erstellen der Anwendung, bekannt und konfiguriert sein muss. Doch wie funktioniert das Ganze nun dynamisch zur Laufzeit, sodass man nicht zur Design-Zeit der Anwendung den Dialog verwenden muss, um so bspw. den späteren Anwendern der Anwendung ein Maß an Flexibilität zu ermöglichen? Genau diesen Aspekt zeigen wir im Folgenden in vereinfachter Form.
Datenquelle dynamisch im Laufzeit-Code
Hierzu verwenden wir zwei TDataSource-Objekte, die die beiden einfachen Tabellen Kunden (Customers) und Bestellungen (Orders) abbilden sollen. Zusätzlich wird später eine relationale Struktur zwischen diesen beiden Tabellen definiert, um eine Master-Detail-Beziehung abzubilden.
Kunden und Bestellungen definieren und mit Daten füllen
Mit Hilfe von TDataSource-Objekten wird die Datenstruktur definiert und gleichzeitig mit Daten gefüllt:
procedure GetDataSource(var DataSourceCustomers, DataSourceOrders: TDataSource);
var
DataSetCutomers: TClientDataSet;
DataSetOrders: TClientDataSet;
begin
{* Create DataSet/DataSource for "Customers" with Data *}
DataSetCutomers := TClientDataSet.Create(nil);
with DataSetCutomers do
begin
Name := 'Customers';
FieldDefs.Add('Id', ftInteger);
FieldDefs.Add('Name', ftString, 255);
CreateDataSet;
IndexDefs.Add('PK_Test', 'Id', [ixPrimary, ixUnique]);
Append;
FieldByName('Id').AsInteger := 1;
FieldByName('Name').AsString := 'Lars';
Append;
FieldByName('Id').AsInteger := 2;
FieldByName('Name').AsString := 'Dirk';
Append;
FieldByName('Id').AsInteger := 3;
FieldByName('Name').AsString := 'Torsten';
Post;
end;
DataSourceCustomers := TDataSource.Create(nil);
DataSourceCustomers.DataSet := DataSetCutomers;
{* Create DataSet/DataSource for "Orders" with Data and
define its relation to "Customers" *}
DataSetOrders := TClientDataSet.Create(nil);
with DataSetOrders do
begin
Name := 'Orders';
FieldDefs.Add('Id', ftInteger);
FieldDefs.Add('CustomerID', ftInteger);
FieldDefs.Add('Amount', ftFloat);
CreateDataSet;
IndexDefs.Add('PK_InnerTable', 'Id', [ixPrimary, ixUnique]);
IndexFieldNames := 'CustomerID';
Append;
FieldByName('Id').AsInteger := 1;
FieldByName('CustomerID').AsInteger := 1;
FieldByName('Amount').AsFloat := 99.25;
Append;
FieldByName('Id').AsInteger := 2;
FieldByName('CustomerID').AsInteger := 1;
FieldByName('Amount').AsFloat := 125.99;
Append;
FieldByName('Id').AsInteger := 3;
FieldByName('CustomerID').AsInteger := 2;
FieldByName('Amount').AsFloat := 12.98;
Post;
end;
DataSourceOrders := TDataSource.Create(nil);
DataSourceOrders.DataSet := DataSetOrders;
DataSetOrders.MasterSource := DataSourceCustomers;
DataSetOrders.MasterFields := 'Id';
end;
Erstellte Datenquelle dem List & Label Objekt zuweisen
Sobald die Strukur mit den Daten erstellt wurde, kann sie dem List & Label Objekt zugewiesen werden:
{* Create the List & Label object and assign the DataSource *}
LL := TListLabel25.Create(self);
GetDataSource(DataSourceCustomers, DataSourceOrders);
LL.DataController.DataSource := DataSourceCustomers;
Relation in der Datenquelle definieren
Anschließend muss die Relation im DataController definiert werden, die dann von List & Label im Designer und beim Druck verwendet werden soll:
{* Prepare the relational structure between the DataSources within
the List & Label DataController *}
with LL.DataController.DetailSources.Add do
begin
Name := 'Customers';
DataSource := DataSourceCustomers;
PrimaryKeyField := 'Id';
with TDetailSourceItem(AddChildNode) do
begin
Name := 'Orders';
DataSource := DataSourceOrders;
MasterKeyField := 'Id';
DetailKeyField := 'CustomerID';
end;
end;
Designer starten und Datenquellen überprüfen
Nun kann einfach die Design-Funktion aufgerufen werden, um das Ergebnis der bereitgestellten Datenquellen zu überprüfen und den Bericht zu erstellen:
// Start the Designer
LL.Design();
Fazit
Somit ist es schnell und einfach möglich dem späteren Anwender der Applikation einen recht flexiblen Ansatz der Datengestaltung beim Reporting zu ermöglichen.