Composite Report built from Multiple Existing Reports
Polomint
Australia
OK, I know this is something I should be able to resolve from the documentation or source code, but...
We have an application that produces a number of reports at end of Financial Year. We've been asked if we can simplify the task of running the reports, by "batching them up". The obvious answer was to create a Composite Report.
Each Report is set up in separate Delphi Units, with their own frxReport component and FR3 definition file. The consolidated report is also in its own Unit with a frxReport / FR3 that creates a cover-page, and then pulls in the constituent parts. One of the key design requirements was to make only minimal changes to the original reports, and to have most of the unique work done in the consolidating report's Unit.
This is working reasonably well except for a few issues.
#1 - the total page count is right, but each constituent report starts counting pages from 1.
Rather than dump the whole application here, I've created a test program and reports that reproduce the problem.
Attached is the PDF export of the report produced from three basic reports (also attached). The code that generates the report is:
The containing program includes the PDF Export component, which was used to generate the file from the Preview Form.
#2 - the user wants to have blank pages between the constituent reports to ensure each "sub-report" starts on an odd-numbered page.
We've tried using frxReportComposite1.PreviewPages.AddEmptyPage to do this, but cannot work out how
- to test the report for number of pages "so far"
- how to set the value of the single parameter (seems to only accept zero!)
#3 - can we get rid of the "cover page"?
The equivalent of the Test Example's frxReportComposite1 in the User Application is currently producing a simple cover sheet page, with no data. The user doesn't want it! We've tried starting with an empty report, but just got a lot of AVEs and Memory Leaks.
====
I've tried searching in these Fora for an answer, but there seems to be very little on the subject...
Cheers, Paul
We have an application that produces a number of reports at end of Financial Year. We've been asked if we can simplify the task of running the reports, by "batching them up". The obvious answer was to create a Composite Report.
Each Report is set up in separate Delphi Units, with their own frxReport component and FR3 definition file. The consolidated report is also in its own Unit with a frxReport / FR3 that creates a cover-page, and then pulls in the constituent parts. One of the key design requirements was to make only minimal changes to the original reports, and to have most of the unique work done in the consolidating report's Unit.
This is working reasonably well except for a few issues.
#1 - the total page count is right, but each constituent report starts counting pages from 1.
Rather than dump the whole application here, I've created a test program and reports that reproduce the problem.
Attached is the PDF export of the report produced from three basic reports (also attached). The code that generates the report is:
procedure TFormTestFastReports.ActionReportsCompositeExecute (Sender : TObject);
begin
  frxReportComposite1.PrepareReport ();
  frxReportComposite2.PrepareReport ();
  frxReportComposite1.PreviewPages.AddFrom (frxReportComposite2);
  frxReportComposite3.PrepareReport ();
  frxReportComposite1.PreviewPages.AddFrom (frxReportComposite3);
  frxReportComposite1.ShowPreparedReport;
end; {TFormTestFastReports.ActionReportsCompositeExecute}
Each of the frxReportComposite* objects has EngineOptions.DoublePass set TRUE.The containing program includes the PDF Export component, which was used to generate the file from the Preview Form.
#2 - the user wants to have blank pages between the constituent reports to ensure each "sub-report" starts on an odd-numbered page.
We've tried using frxReportComposite1.PreviewPages.AddEmptyPage to do this, but cannot work out how
- to test the report for number of pages "so far"
- how to set the value of the single parameter (seems to only accept zero!)
#3 - can we get rid of the "cover page"?
The equivalent of the Test Example's frxReportComposite1 in the User Application is currently producing a simple cover sheet page, with no data. The user doesn't want it! We've tried starting with an empty report, but just got a lot of AVEs and Memory Leaks.
====
I've tried searching in these Fora for an answer, but there seems to be very little on the subject...
Cheers, Paul
Comments
Answer to part (a) of #2 may be to use frxReport.PreviewPages.Count, which seems to return the expected value...
3. Use TfrxReport.PreviewPages.DeletePage
However,
- As explained in the original post, we cannot use "one TrfxReport" as the > 20 reports are built using "stand alone" Units, and because they are complex (some include charts, all have many report-specific BeforePrint events for Header / Detail / Footer Bands etc.) - refactoring the Application Reporting into a monolith would be time-consuming, risky, and (to be frank) create a maintenance nightmare. We may have to hack the FastReport code, or see if we can do something with the underlying templates, common code, and "user variables".
- We've discovered that there is no need to introduce an empty TfrxReportPage. - Using AddEmptyPage(0) we can prefix the second and subsequent "sub-reports" with a blank page (when needed) before adding to the Composite
- How exactly should we use DeletePage? - A trial run (code below) has had no effect on the Cover Page ("Report1"). See the PDF file attached.
Tantalisingly close but not there yet!
Most of what we want of the Composite of existing stand-alone reports is now fully addressed by a couple of "tricks".
- DeletePage (0) after all "sub-reports" added but before the call to ShowPreparedReport
- Prefixing the second and subsequent reports with a blank page (AddEmptyPage) only if there is currently an even number of pages in the Composite
I've also checked our Application, in the Test Environment, using this technique. Seems to work well...
Now we just need to work out how to number the pages correctly in the footers.
Turns out that correctly numbering the pages in the Composite (with blank pages "for formatting purposes") didn't require anything more exotic than a user-defined variable containing the "base page number", and a small change in the footer of our inherited report "template" (to replace [Page#] with [<Page>+<BasePageNo>]. The actual application and 20+ reports make use of a lot of shared code, so we leveraged that to avoid too many changes and future maintenance headaches.
The "Test Application" shows simply how this was done, using "in line" code rather than objects / shared-functions, and the attached PDF confirms that it works!
Hope you find it useful.
Cheers, Paul
See also: https://www.fast-report.com/documentation/P..._a_variable.htm