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

Using ReportBuilder with DB transactions

edited April 2002 in General
I have a program which has a couple of transaction controlled routines that
update figures and status fields on the database server. During these
routines there are also reports that need to be printed, and in the case of
a rollback on the database server, the reports are useless and needs to be
thrown away. Are there any easy ways of holding these reports and realease
them on commit?

I'm using ReportBuilder Enterprise Edition v 6.03.

Comments

  • edited April 2002
    Where are these reports being printed to: archives, dbarchives, printer? If
    the report is printed to an archive it is trivial to simply remove the
    archive. Such a solution would be sufficient under a light load of
    transactions. A heavy transaction load would, however, create a lot of IO
    traffic on the server. Another possibility, which can also be used if the
    report goes directly into the printer queue is to print the report to a
    device and cache the pages in the publisher. In the case of a rollback,
    simply reset the publisher to release the report. In the case of a commit,
    loop through the cached pages of the publisher and send them to the
    appropriate destination device. For example:

    When the transaction occurs, print the report:

    ...
    ppReport1.CachePages := True;
    ppReport1.PrintToDevices;
    ...

    When the transaction is commited, send it to the printer:

    ...
    lPDevice := TppPrinterDevice.Create(nil);
    lPDevice.StartJob;

    for liIndex := 0 to ppReport1.Publisher.PageCount - 1 do
    begin
    lPDevice.Printer.PrinterSetup :=
    ppReport1.Publisher.Pages[liIndex].PrinterSetup;
    lPDevice.ReceivePage(ppReport1.Publisher.Pages[liIndex]);
    end;

    lPDevice.EndJob;
    ...

    You can also substitute TppArchiveDevice for TppPrinerDevice.

    --
    Cheers,

    Alexander Kramnik
    Digital Metaphors

  • edited April 2002
    Thanks for responding so quickly.
    Alle reports are being printed BOTH to an archive AND to a printer. I also
    need to generate up to 200 individual reports before the DataBase.Commit is
    called. So maybe the best solution is to store all reports through a
    dbarchive and loop the dbarchive after commit? I tried the CachePages
    aproach that you suggested, and it seemed to work ok if one report at a time
    is being generated and sent. If, however, the same TppReport is being used
    to generate several reports before sending the cached pages to the printer,
    it seems like only the last report is being printed. Is this correct or
    have I done something wrong?
    I do not have much experience with using dbarchives. Are there any
    resources where I can learn how to use them?

    Yours,
    Trond Leikvoll

    "Alexander Kramnik (Digital Metaphors)" wrote
  • edited April 2002
    That is the correct behavior since printing a new report will overwrite the
    pages cached by the last report. One approach is to grab the page objects
    and store them in your own TList, and maybe keep another list around so you
    can bookmark where in the page list each report begins. After calling
    PrintToDevices on the report you would loop through the pages in the
    publisher and store them, i.e.

    var
    lPage: TppPage;
    liIndex: Integer;
    begin
    ...
    for liIndex := 0 to ppReport1.Publisher.PageCount - 1 do
    begin
    lPage := TppPage.Create(nil);
    lPage.Assign(ppReport1.Publisher.Pages[liIndex];
    FPages.Add(lPage);
    end;
    ...

    Then at a later time you can loop through the pages in that list and send
    them to a PrinterDevice and the ArchiveDevice as desired. Follow the link
    below for an example of using DBArchive which will hopefully help you get
    you on the right track.

    http://www.digital-metaphors.com/tips/DBArchiveReader.zip

    --
    Cheers,

    Alexander Kramnik
    Digital Metaphors

  • edited April 2002
    This works perfect. However; I would like to create all the reports as
    DBArchive records directly (not files or printers), and then loop the
    DBArchive after commit to perform the actual print. Is there an easy way of
    doing this directly (i.e. stream the report directly to a TMemoryStream or
    something) instead of TFileStream ?

    "Alexander Kramnik (Digital Metaphors)" wrote
  • edited May 2002
    There is no DBArchiveDevice, we will look into creating this device in a
    future release so that you can directly stream a report archive to the
    database without having an intermediate file. You can stream a report
    archive to a BLOB field with this technique:
    http://www.digital-metaphors.com/tips/ArchiveToStream.zip


    Cheers,

    Jim Bennett
    Digital Metaphors

This discussion has been closed.