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

What is wrong with this code

Attached is short example project. It behaves weird.
Scenario and reproduction steps inside the main form.
I can't find out what is wrong with the code or what am I missing.
Any sugestions are very welcome.

Best regards
Tom Urlep

Comments

  • edited December 2020
    Hi Tom,

    Thanks for the example.

    Starting with RB 14, the screen device (preview) generates all pages in a background thread. In your code when you preview and export to XLS, these actions can be occurring simultaneously causing the engine to fail.

    There are two options:

    1. Turn off the threaded preview (and multi-page view) by setting the Report.PreviewFormSettings.SinglePageOnly to True.

    2. Wait until the screen device has finished generating pages before exporting to XLS. Do this by using the TppViewer.OnEndGenerate event. Once the event fires, it is okay to export.

    procedure TForm1.ppReport1PreviewFormCreate(Sender: TObject);
    begin
    TppViewer(ppReport1.PreviewForm.Viewer).OnEndGenerate := ehViewer_EndGenerate;

    end;

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • Thanks for your answer but

    Option 1: Doesn't change the behaviour
    Option 2: I added ppViewr to the USES clause but it doesn't compile
    ( Undeclared identifier: 'ehViewer_EndGenerate' )
  • edited December 2020
    Hi Tom,

    Sorry for the confusion, I apparently misread your instructions.

    You need to set the Report.DefaultFileDeviceType to 'PDF' before calling print the first time. This will ensure the default file device used from the preview is PDF. Otherwise, it remains XLSData after you set the DeviceType at the end of the first run.

    procedure TForm1.btnPrintClick(Sender: TObject);
    begin
    ppReport1.AllowPrintToFile := True;
    ppReport1.ShowPrintDialog := False;
    ppReport1.PDFSettings.OpenPDFFile := cbOpenPDF.Checked;
    ppReport1.TextFileName := TPath.GetDocumentsPath + '\Test\Test.pdf';

    ppReport1.DefaultFileDeviceType := 'PDF'; //Add this

    if FileExists( ppReport1.TextFileName ) then
    DeleteFile( PChar( ppReport1.TextFileName ) );

    if rgDestination.ItemIndex = 0 then
    // ------------------------------------------------------ print with preview
    ppReport1.DeviceType := 'Screen'
    else
    // --------------------------------------------------------- or print to pdf
    ppReport1.DeviceType := 'PDF';

    ppReport1.Print;

    //...


    This worked the first time because PDF is the default value for DefaultFileDeviceType.

    I still suggest implementing one of the suggestions in my first response. While a simple report may work correctly, a more complex one could cause issues.

    The ehViewer_EndGenerate is an event you need to implement, the event name is made up :).

    procedure TForm1.ppReport1PreviewFormCreate(Sender: TObject);
    begin
    TppViewer(ppReport1.PreviewForm.Viewer).OnEndGenerate := ehViewer_EndGenerate;

    end;

    procedure TForm1.ehViewer_EndGenerate(Sender: TObject);
    begin
    //Notify application generation is complete
    end;
    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • Excellent!

    I implemented both your suggestions and it works.

    Thanks for quick reply.
Sign In or Register to comment.