TMasterFieldLinks
What is the appropriate method for creating, setting the owner, and freeing
a TMasterFieldLink at runtime?
I need to setup the link between the two data pipelines at runtime. However
when I close the program I get an access violation. Since the
TMasterFieldLink has an owner, I thought the owner would handle destroying
the link am I wrong?
Bill
a TMasterFieldLink at runtime?
I need to setup the link between the two data pipelines at runtime. However
when I close the program I get an access violation. Since the
TMasterFieldLink has an owner, I thought the owner would handle destroying
the link am I wrong?
Bill
This discussion has been closed.
Comments
Try using the following example...
---------------------------------------------------------
Tech Tip: Define Master/Detail DataPipeline Links in Code
---------------------------------------------------------
Defining a Master/Detail relationship for a DataPipeline
requires that the detail pipeline have the
following properties defined:
1. MasterDataPipeline
2. MasterFieldLinks
At Delphi design-time you can use the object inspector
and the DataPipeline's FieldLinks editor to define
the master/detail relationship.
The following example illustrates how to define the
master/detail relationship dynamically at run-time.
var
lFieldLink: TppMasterFieldLink;
begin
{define the master/detail pipeline relationship}
plDetail.MasterDataPipeline := plMaster;
{create a new field link }
lFieldLink := TppMasterFieldLink.Create(nil);
lFieldLink.Parent := plDetail;
{assign the detail field name}
lFieldLink.DetailFieldName := 'CustNo';
{assign the master field name}
lFieldLink.MasterFieldName := 'CustNo';
end;
Note: The DataPipeline linking requires the records in the detail dataset to
be ordered by the linking fields. In the above example, the detail data must
be ordered by CustNo.
--
Tech Support mailto:support@digital-metaphors.com
Digital Metaphors http://www.digital-metaphors.com
Best regards,
Nard Moseley
Digital Metaphors
www.digital-metaphors.com
plDetail.AddChild(lFieldLink);
No, that will cause an AV on the destroy. Setting the FieldLink.Parent
property will cause it to be added to the pipeline. (Internally an
appropriate destroy notification relationship will established and AddChild
will be called).
lFieldLink.Parent := plDetail;
Best regards,
Nard Moseley
Digital Metaphors
www.digital-metaphors.com
Whenever I try to create a report and creating a master-child in code the
report comes up blank if I place any child pipeline fields in a subreport.
Here is the code I use to create the dataset, datasource and pipelines. It
works fine on basic pipeline reports. Even reports with multiple pipelines,
but once I try to do a master-child report (which I have added to the
method) it doesn't work.
procedure TfmDynReports.CreatePipe(PipeSQL: String; PipeID, MasterID:
Integer; MC_Mapping: String);
var
PipeQuery: TMSQuery;
PipeDataSource: TDataSource;
PipePipeline: TppDBPipeline;
m: TppMasterFieldLink;
i: Integer;
s: String;
begin
PipeQuery := TMSQuery.Create(Self);
PipeQuery.Name := Format('PipeQuery%d', [PipeID]);
PipeQuery.Connection := dmMain.dbInstitution;
PipeQuery.SQL.Text := PipeSQL;
PipeQuery.Active := True;
CreatedItems.Add(PipeQuery.Name);
PipeDataSource := TDataSource.Create(Self);
PipeDataSource.DataSet := PipeQuery;
PipeDataSource.Name := Format('PipeDataSource%d', [PipeID]);
CreatedItems.Add(PipeDataSource.Name);
PipePipeline := TppDBPipeline.Create(Self);
PipePipeline.DataSource := PipeDataSource;
PipePipeline.Name := Format('PipePipeline%d', [PipeID]);
CreatedItems.Add(PipePipeline.Name);
//setup master child if exists
{the master-child relationship is setup by doing the following
First - The master data pipeline is identified by identifying the
sql_order
value of the master pipeline. -1 in this value means there is no
master datasource
Second - The master - child field mappings are identified by the
following format: MASTER=CHILD
To add multiple master - child field mappings separate the
mappings with a semicolon like such:
MASTER=CHILD;MASTER=CHILD.
}
if MasterID <> -1 then
begin
PipePipeline.MasterDataPipeline :=
TppDBPipeline(FindComponent(Format('PipePipeline%d' , [MasterID])));
for i := 1 to ListLen(MC_Mapping, ';') do
begin
m := TppMasterFieldLink.Create(nil);
m.Name := Format('MasterFieldLink%d_%d', [PipeID, i]);
CreatedItems.Add(m.Name);
m.Parent := PipePipeline;
s := ListGetAt(MC_Mapping, i, ';');
m.MasterFieldName := ListGetAt(s, 1, '=');
m.DetailFieldName := ListGetAt(s, 2, '=');
end;
end;
end;
Bill
1. Make sure that the detail query data is ordered by the linking fields (in
the exact same order).
2. I cannot determine what is happening by looking at that code. I would
approach something like this incrementally. Create a simple master detail
report at Delphi design-time - for example Customer/Orders using DBDemos.
Link the pipelines using the field links editor. Once it is working
correctly, then incrementally start converting the data access pieces to
code. First implement the pipeline creation and linking. Then run and test
until it works. Next implement the DataSource creation. Run and test. Then
implement the Query creation in code. Once all that is working, then create
the more general purpose routines. If you use DBDemos as a starting point,
then if you get stuck you can zip it up and send to
support@digital-metaphors.com and we can run it here in the debugger.
Best regards,
Nard Moseley
Digital Metaphors
www.digital-metaphors.com