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

Access Violations still happening...

edited September 2001 in General
I have a form where I'm using a TppViewer component. All of my reports
are contained in TForms. On the main form (where the TppViewer is), the
user selects reports from the menu bar.

The problem I'm having is when the application is closed while a report
is busy, or the user selects a new report from the menu bar while the
current report is busy. When this happens, the application crashes
(Access violation).

When a menu item is selected, or the application closes, I execute the
following code:

{currentReport is a public var, holding a reference to the TForm with
the TppReport}

If Assigned(currentReport) then
begin
currentReport.ppReport1.Cancel;
ppViewer1.Report := nil;
FreeAndNil(currentReport);
end;

This code executes OK, but crashes afterwards in the
TppPublisher.Publish method.

Note that this problem is most evident when using a large, remote
datasource (so the query takes a while....you need to be able to cancel
in the middle of a query to see this problem.) Can anyone help? (using
RB 5.5, but tried 6.01, too.)

Thanks.

Comments

  • edited September 2001
    When you set the report on the viewer to nil, the publisher for the screen
    device is set to nil in the set method for that property. That may be where
    your problems begin. Take a look at our main reports demo project as we
    have a viewer on a form and call PrintToDevices on the report object. What
    code are you executing after the report is freed, which is causing the
    viewer to AV.

    Cheers,

    Jim Bennett
    Digital Metaphors


  • edited September 2001
    There is nothing else done after this code....For example, I created a
    new toolbar button to cancel the current report, with the following
    code:

    ppViewer1.Cancel;
    ppViewer1.Report := nil;
    If Assigned(currentReport) then
    begin
    ppViewer1.Reset;
    FreeAndNil(currentReport);
    end;


    At runtime, when I click the cancel button while the report is
    executing, the report crashes. This can be easily seen using a remote
    dataset (I'm using SQL server w/ an ODBC connection.) The report takes
    ~5-10 seconds to display. Clicking the cancel button at this time
    causes the crash.

    I looked at the demo project, but a couple of differences:
    - The demo project is using the local DBDEMOS database, so the data
    access is very fast (the problem I'm encountering wouldn't be noticable
    on a local DB)
    - The data in the DBDEMOS database is minimal, so the queries don't
    take long to return.

    My DB is MS SQL Server 7.0, the DB contains only 2 tables. Table 1 has
    ~1000 records in it that reference detailed records in Table 2, which
    has ~55000 records in it.

    I don't mind that the reports are a bit slow in generating, but I need
    to give users a way to quit without crashing....Even if the application
    is closed while a report is generating, the application crashes. I need
    a way to solve this.
  • edited September 2001
    Another difference with the demo project is that when one report is
    generating (ppViewer.Busy), and a user tries to open a new report (in
    the Grid's OnDoubleClick event) the method is exited. This really isn't
    a problem for the demo project, since the DB is local and the report
    only takes ~1 second to display. But in my report, the DB is remote and
    the DB is large, which makes the report take ~5-10 seconds to generate.
    I would really like a way to terminate the current report.
  • edited September 2001
    The problem most likely is that you call Report.PrintToDevices and free the
    report before it finishes execution. While the report is generating, you
    call cancel and try to free the report. However, there is still unexecuted
    code from the PrintToDevices call, however, you've just freed the report and
    when it references the report object to finisht the current page, then it
    will AV. You need to check to cancel the report only after calling
    PrintToDevices.

    begin
    ppReport1.PrintToDevices;

    {detect if the report is cancelled}
    if ppReport1.Engine.StopPrinting then
    ppReport1.Free;
    end;

    Since you have a report on a form, you will have to put a Cancelled property
    on the form so you can check if the report on the form you've just printed
    has been cancelled.


    Cheers,

    Jim Bennett
    Digital Metaphors


This discussion has been closed.