Dynamic subreport loading...take it to the limit!
I'd like to invite to a general discussion on an issue I think has a great
potential.
It seems dynamic subreport loading (DSL), as explained in the
"RBuilder\Demos\3. EndUser\5. Dynamic Subreport Loading" directory, is
becoming increasingly popular. With good reason, because I have found it to
be a great help in building complex reports. I use the technique very
extensively in my apps - I have created about 60 "report components" that I
load dynamically into 140 different main reports, achieving effects that I
could never dream of without DSL.
Anyway, it seems DSL has changed a bit from RB6 to RB7. After I upgraded, my
reports started crashing with AV errors, until I found it is now required to
include the following lines after loading the template:
Subreport.Report.Engine.State := Report.Engine.State - [esInitialized];
Subreport.Init;
So I have these questions:
- Are there other changes to DSL from RB6 to RB7 that we should be aware of,
than the new need for the above Init operation?
potential.
It seems dynamic subreport loading (DSL), as explained in the
"RBuilder\Demos\3. EndUser\5. Dynamic Subreport Loading" directory, is
becoming increasingly popular. With good reason, because I have found it to
be a great help in building complex reports. I use the technique very
extensively in my apps - I have created about 60 "report components" that I
load dynamically into 140 different main reports, achieving effects that I
could never dream of without DSL.
Anyway, it seems DSL has changed a bit from RB6 to RB7. After I upgraded, my
reports started crashing with AV errors, until I found it is now required to
include the following lines after loading the template:
Subreport.Report.Engine.State := Report.Engine.State - [esInitialized];
Subreport.Init;
So I have these questions:
- Are there other changes to DSL from RB6 to RB7 that we should be aware of,
than the new need for the above Init operation?
This discussion has been closed.
Comments
The two lines of code change was all that is needed to convert the
subreports to work in RB 7 from RB 6. The conversion code stems from the
changes we made while we were fixing bugs and making the report engine
threadsafe.
Cheers,
Jim Bennett
Digital Metaphors
http://www.digital-metaphors.com
info@digital-metaphors.com
footers on our reports, being maintained separately and loaded at runtime.
Below there is the component which does this. Just drop the
supreport-component on the report and assign the name of the report you want
to have loaded at runtime to the edit field where you usually enter the
caption text.
Works like a charm :-)
Bernd
unit SubreportSOF;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
IniFiles, ppClass, ppBands, ppSubRpt,
ppTypes, ppVar, ppCtrls;
type
TBafSubReport = class(TppSubReport)
private
FAutomatedLoad : Boolean;
FTemplateName : String;
procedure LoadSubreport;
protected
function GetTemplateName : string;
procedure SetTemplateName(Value: string);
function GetCaption : string; override;
public
constructor Create(aOwner: TComponent); override;
destructor Destroy; override;
procedure Generate; override;
procedure StartOfMainReport; override;
published
property AutomatedLoad : Boolean read FAutomatedLoad write
FAutomatedLoad default True;
property TemplateName : string read GetTemplateName write
SetTemplateName;
end;
implementation
{$R SubreportSOF.res}
// -- Create
constructor TBafSubReport.Create(aOwner: TComponent);
begin
inherited Create(aOwner);
FAutomatedLoad:=True;
DefaultPropName:='TemplateName';
DefaultPropEditType:=etEdit;
end;
// -- Destroy
destructor TBafSubReport.Destroy;
begin
inherited Destroy;
end;
// -- Generate
procedure TBafSubReport.Generate;
begin
Report.AutoStop:=True;
inherited Generate;
end;
// -- LoadSubreport
procedure TBafSubReport.LoadSubreport;
begin
Report.Template.FileName:=ExtractFileDir(Report.MainReport.Template.FileName
)+'\'+FTemplateName;
Report.Template.LoadFromFile;
Report.PrinterSetup.DocumentName:=Band.Report.MainReport.PrinterSetup.Docume
ntName;
Report.Engine.State := Report.Engine.State - [esInitialized];
Init;
end;
// -- StartOfMainReport
procedure TBafSubReport.StartOfMainReport;
begin
inherited StartOfMainReport;
if (AutomatedLoad) and not (Overflow) then begin
LoadSubreport
end;
end;
// -- SetTemplateName
procedure TBafSubReport.SetTemplateName(Value: string);
begin
if FTemplateName<>Value then begin
FTemplateName:=Value
end;
end;
// -- GetTemplateName
function TBafSubReport.GetTemplateName : string;
begin
Result:=FTemplateName;
end;
// -- GetCaption
function TBafSubReport.GetCaption : string;
begin
Result:='Runtime template';
end;
initialization
ppRegisterComponent(TBafSubReport, 'Demo Components', 0, 0, 'Runtime
template', 0);
finalization
ppUnRegisterComponent(TBafSubReport);
end.