Question
“How can I can collate the pages of my subreport?”
I have two subreports and would like for the pages to alternate subreport1 page 1, subreport2 page 1, subreport1 page 2, subreport2 page 2,..
Solution
This example generate the pages to cache, then re-orders the page cache, prior to preview.
Download: CollateSubReportPages.zip
Sample Delphi code:
uses
ppDevice,
ppTypes;
procedure TForm1.PreviewClick(Sender: TObject);
begin
// initialize
FFirstReportPageCount := 0;
FSecondReportPageCount := 0;
// generate pages to cache
PrintToCache;
// collate pages
CollatePages;
// preview
ppReport1.DeviceType := dtScreen;
ppReport1.Print;
end;
procedure TForm1.ppEmpSalesEndFirstPass(Sender: TObject);
begin
// save first child report page count
FFirstReportPageCount := ppSubReport1.Report.AbsolutePageCount;
end;
procedure TForm1.ppCustListEndFirstPass(Sender: TObject);
begin
// save sedcond child report page count
FSecondReportPageCount := ppSubReport2.Report.AbsolutePageCount;
end;
procedure TForm1.PrintToCache;
var
lDevice: TppDevice;
begin
// create a dummy device
lDevice := TppDevice.Create(Self);
lDevice.PageSetting := psLastPage;
lDevice.Publisher := ppReport1.Publisher;
// generate the pages to cache
ppReport1.CachePages := True;
ppReport1.PrintToDevices;
lDevice.Free;
end;
procedure TForm1.CollatePages;
var
liIndex: Integer;
lPages: TList;
lPublisher: TppPublisher;
lFirstReportPage: TppPage;
lSecondReportPage: TppPage;
liCollatedPages: Integer;
lPage: TppPage;
begin
lPages := TList.Create;
lPublisher := ppReport1.Publisher;
liIndex := 0;
// build list of collated pages
while (liIndex < FFirstReportPageCount) and (FSecondReportPageCount > 0) do
begin
// add page from first report
lFirstReportPage := lPublisher.Pages[liIndex];
lFirstReportPage.AbsolutePageNo := lPages.Count + 1;
lFirstReportPage.PageNo := lPages.Count + 1;
lPage := TppPage.Create(nil);
lPage.Assign(lFirstReportPage);
lPages.Add(lPage);
// add page from second report
lSecondReportPage := lPublisher.Pages[FFirstReportPageCount + liIndex];
lSecondReportPage.AbsolutePageNo := lPages.Count + 1;
lSecondReportPage.PageNo := lPages.Count + 1;
lPage := TppPage.Create(nil);
lPage.Assign(lSecondReportPage);
lPages.Add(lPage);
Inc(liIndex);
Dec(FSecondReportPageCount);
end;
{add remaining pages to list}
liCollatedPages := liIndex;
if (FSecondReportPageCount > 0) then
for liIndex := 0 to FSecondReportPageCount - 1 do
begin
lSecondReportPage := lPublisher.Pages[FFirstReportPageCount + liCollatedPages + liIndex];
lSecondReportPage.AbsolutePageNo := lPages.Count + 1;
lSecondReportPage.PageNo := lPages.Count + 1;
lPage := TppPage.Create(nil);
lPage.Assign(lSecondReportPage);
lPages.Add(lPage);
end
else if (liCollatedPages < FFirstReportPageCount) then
begin
if (liCollatedPages > 0) then
TppPage(lPages[lPages.Count - 1]).LastPage := False;
for liIndex := liCollatedPages to FFirstReportPageCount - 1 do
begin
lFirstReportPage := lPublisher.Pages[liIndex];
lFirstReportPage.AbsolutePageNo := lPages.Count + 1;
lFirstReportPage.PageNo := lPages.Count + 1;
if (liIndex = FFirstReportPageCount - 1) then
lFirstReportPage.LastPage := True;
lPage := TppPage.Create(nil);
lPage.Assign(lFirstReportPage);
lPages.Add(lPage);
end;
end;
{update page cache}
for liIndex := 0 to lPages.Count - 1 do
begin
lPage := TppPage(lPages[liIndex]);
lPublisher.ReceivePage(lPage);
end;
{free old pages}
for liIndex := 0 to lPages.Count - 1 do
TppPage(lPages[liIndex]).Free;
lPages.Free;
{update page number of new pages}
for liIndex := 0 to lPublisher.PageCount - 1 do
lPublisher.Pages[liIndex].Update(nil);
end;