Home End User
New Blog Posts: Merging Reports - Part 1 and Part 2

Migrate Existing Standard Report to End-User Report

edited August 2003 in End User
Hi All,

Delphi Version: 5.01
R.Builder: 7.02 Professional

I am migrate the existing standard report to end-User Report. So that All
the current Printout can
be changed by the end user. But I hit the following problem, Please advise:

1. Since currently I've a datamodule containing all the data For Printing
the report. From your demos( end -user report and Custom Data View), Should
I recreate the data logic again to support end-user design? Since I've many
cacluated field in it, Can I simply use the current DataSet to Support the
End-User Design without recreate it Again.

From My Testing, I have create a custom dataView which is inherited from
TdaBDEQueryTemplateDataView( the sample of MydataVw). I can use all the
field and see the current row data at design tabset. But When I click
Preview, It show the Error "No Sql Statement is avaliable".

Can you explain it? Can I use existing Data such as offline
TclientDataSet( load it from a file without connecting to any database or
datasetprovider ) to use end-User Report?

In the Following, I attached my Class which try to use existing dataset
without executing any sql statement: Please Comment What's wrong with the
Code:

It works as expected except when click preview, it show "No Sql Statement is
avaliable".

TdvOrder = class(TdvCustomTemplateDataView)
private
FMasterTable: TClientDataSet;
FMasterDataSource: TDataSource;
FMasterDataPipeline: TppBDEPipeline;

FDetailTable: TClientDataSet;
FDetailDataSource: TDataSource;
FDetailDataPipeline: TppBDEPipeline;

FChrgTable: TClientDataSet;
FChrgDataSource: TDataSource;
FChrgDataPipeline: TppBDEPipeline;

protected

public
constructor Create(aOwner: TComponent); override;
destructor Destroy; override;

procedure DefineDataSelection; override;

class function ClassDescription: String; override;

procedure DefineSelectedFields; override;
procedure CreateDataPipelines; override;
procedure CreatePipelineFields(aDataPipeline: TppDataPipeline);
override;

procedure ConnectPipelinesToData; override;
procedure ConnectReportToPipelines;override;

published
{publish DataPipelines - must be read/write}
property MasterDataPipeline: TppBDEPipeline read FMasterDataPipeline
write FMasterDataPipeline;
property DetailDataPipeline: TppBDEPipeline read FDetailDataPipeline
write FDetailDataPipeline;
property ChrgDataPipeline: TppBDEPipeline read FChrgDataPipeline write
FChrgDataPipeline;

{publish DataSources - must be read only (i.e. do NOT declare "write
FDataSource")}
property MasterDataSource: TDataSource read FMasterDataSource;
property DetailDataSource: TDataSource read FDetailDataSource;
property ChrgDataSource: TDataSource read FChrgDataSource;


end; {class, TdvOrder}


class function TdvOrder.ClassDescription: String;
begin
Result := 'New Quotation';
end;

procedure TdvOrder.ConnectPipelinesToData;
begin
inherited;
FMasterDataPipeline.DataSource := MasterDataSource;
FMasterDataPipeline.RangeBegin := rbCurrentRecord;
FMasterDataPipeline.RangeEnd := reCurrentRecord;
FDetailDataPipeline.DataSource := DetailDataSource;
FChrgDataPipeline.DataSource := ChrgDataSource;
FMasterDataPipeline.MasterDataPipeline := DataPipeline;
end;

procedure TdvOrder.ConnectReportToPipelines;
begin
Report.DataPipeline := MasterDataPipeline;
end;

constructor TdvOrder.Create(aOwner: TComponent);
begin
inherited Create(aOwner);

DatabaseName := '_DB';

FMasterTable := Tform1(aOwner).Dm.cdsMaster;
FDetailTable := Tform1(aOwner).Dm.cdsDetail;
FChrgTable := Tform1(aOwner).Dm.cdsChrg;



FMasterDataSource := CreateDataSource;
FDetailDataSource := CreateDataSource;
FChrgDataSource := CreateDataSource;

FMasterDataSource.DataSet := FMasterTable ;
FDetailDataSource.DataSet := FDetailTable ;
FChrgDataSource.DataSet := FChrgTable ;


end;

procedure TdvOrder.CreateDataPipelines;
begin

inherited CreateDataPipelines;

FMasterDataPipeline := CreateDataPipeline;
FMasterDataPipeline.UserName := 'plMaster';

FDetailDataPipeline := CreateDataPipeline;
FDetailDataPipeline.UserName := 'plDetail';

FChrgDataPipeline := CreateDataPipeline;
FChrgDataPipeline.UserName := 'plChrg';

end;

procedure TdvOrder.CreatePipelineFields(aDataPipeline: TppDataPipeline);
var i:Integer;
begin

inherited CreatePipelineFields(aDataPipeline);

{create detail pipeline fields}
if aDataPipeline = FMasterDataPipeline then
begin
For i:= 0 to Pred(FMasterTable.FieldCount) Do
CreatePipelineField('QT_MTR',
FMasterTable.Fields[i].FieldName,
FMasterTable.Fields[i].DisplayName,
aDataPipeline, False, False);
end
else if aDataPipeline = FDetailDataPipeline then
begin
For i:= 0 to Pred(FDetailTable.FieldCount) Do
CreatePipelineField('QT_DET',
FDetailTable.Fields[i].FieldName,
FDetailTable.Fields[i].DisplayName,
aDataPipeline, False, False);
end
else if aDataPipeline = FChrgDataPipeline then
begin
For i:= 0 to Pred(FChrgTable.FieldCount) Do
CreatePipelineField('QT_CHRG_TBL',
FChrgTable.Fields[i].FieldName,
FChrgTable.Fields[i].DisplayName,
aDataPipeline, False, False);
end

end;

procedure TdvOrder.DefineDataSelection;
begin
// inherited;

end;

procedure TdvOrder.DefineSelectedFields;
var
lMasterTable: TdaTable;
lDetailTable: TdaTable;
lChrgTable: TdaTable;
i:Integer;
begin

inherited DefineSelectedFields;
{
lMasterTable := AddSelectTable('QT_MTR');
For i:= 0 to Pred(FMasterTable.FieldCount) Do
AddSelectField(lMasterTable,FMasterTable.Fields[i].FieldName,
FMasterTable.Fields[i].DisplayName,True,True);

lDetailTable := AddSelectTable('QT_DET');
For i:= 0 to Pred(FDetailTable.FieldCount) Do
AddSelectField(lDetailTable,FDetailTable.Fields[i].FieldName,
FDetailTable.Fields[i].DisplayName,True,True);

lChrgTable := AddSelectTable('QT_CHRG_TBL');
For i:= 0 to Pred(FChrgTable.FieldCount) Do
AddSelectField(lChrgTable,FChrgTable.Fields[i].FieldName,
FChrgTable.Fields[i].DisplayName,True,True);
}
end;

destructor TdvOrder.Destroy;
begin

inherited Destroy;

end;

Comments

  • edited August 2003

    The class hierarchy looks like this:

    TdaQueryDataView
    TdaBDEQueryDataView
    TdaBDETemplateDataView
    TdaBDEQueryTemplateDataView

    All of the dataviews descend from TdaQueryDataView which requires a SQL
    statement.

    The ancestor class for the custom DataViews that you are creating,
    TdaBDEQueryTemplateDataView defined a TQuery and DataSource and BDEPipeline
    that are to be used for the master. If you want to add linked datasets then
    you define additional TTables and TQueries.

    Try to work towards a solution incrementally. First get a custom dataview
    working that has just a single query. Once you get that working, add a
    single linked detail table/query, etc.



    --
    Nard Moseley
    Digital Metaphors
    http://www.digital-metaphors.com

    Best regards,

    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com
  • edited August 2003
    Thank Your for Information.

    If I've exisitng DataModule with the following setting:

    ClientDataSet A Link To ClientDataSet B

    Since I've many Calculated Field In it. I f I want to use current
    ClientDataSet.

    Please Indicate which Class I Should inherit or any way to do it


  • edited August 2003

    Perhaps try overriding the SQLChanged method so that it does nothing. Do not
    call inherited. Connect the DataSource and DataPipeline desclared in the
    ancestor to your client dataset. You do not need to use the methods such as
    DefineSelectedFields that are used to build a SQL statement.



    --
    Nard Moseley
    Digital Metaphors
    http://www.digital-metaphors.com

    Best regards,

    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com
This discussion has been closed.