<< Click to display table of contents >>


Occurs while processing a data query.


  TRVReportProgressStep = 

    (rvrpsExecutingQuery, rvrpsApplying, rvrpsFinished);


  TRVDataQueryProgressEvent = procedure (

    Sender: TCustomRVReportGenerator;

    Rule: TRVRowGenerationCustomRule

    Cell: TRVReportTableCellData;

    Step: TRVReportProgressStep; Level, Percent: Integer;

    var Proceed: Boolean) of object;


property OnDataQueryProgress: TRVDataQueryProgressEvent;

This event can be used to display a progress of processing a data query and to abort a report generation.

By default, this event is called in the context of the main process (even if reports are generated in a background thread), to allow interacting with user interface controls. If you want to call it in a thread context, exclude rvrgeOnDataQueryProgress from SynchronizedEvents.


Rule – a row generation rule of a report table. This parameter is assigned if the component currently processes a data query belonging to this rule, otherwise it is nil.

Cell – a cell of a report table.This parameter is assigned if the component currently processes a data query belonging to this cell, otherwise it is nil.

Level – a level of nesting of this data query. 1 for first level queries, 2 for queries nested in them, and so on. If you want to display a progress bar to show a progress, it makes sense to show it only for queries having Level = 1.

Step and Percent define a stage of progress.

You can assign False to Proceed to abort the report generation.


For each query: first, the event occurs before processing a data query (for example, before processing SQL SELECT statement) with Step = rvrpsExecutingQuery.,  the event occurs multiple times while applying query results to table rows/a cell, with Step = rvrpsApplying, and Percent growing from 0 to 100. If the report generator cannot calculate percentage (it happens when the total number of records is unknown), it calls the event with Percent = -1.

3.finally, the event occurs with Step = rvrpsFinished.

Aborting the report generation

A report generation is performed in the context of the main process. It means that an application is frozen until a report generation is finished.

You can unfreeze it by calling Application.ProcessMessages in this event, but be careful: this procedure is dangerous when used incorrectly!

You must:

hide the TRichView control processed by this report generator; there must not be attempts to redraw it while the report is not finished and this TRichView is formatted;

prevent the TRichView, TRVReportGenerator components (and all other components necessary for report generation) from destroying in this event; usually, it can be done by disallowing closing the form containing these components (by processing its OnCloseQuery event)

prevent the report generation to start again while the current report generation is finished; usually, it can be done by disabling all controls on the form, may be except for an "Abort" button.

You can implement an "Abort" button. When the user clicks it, assign some form's boolean variable. In OnDataQueryProgress, check this variable and assign Proceed = False if necessary.


Showing progress in ProgressBar1 and Label1.

procedure TForm1.RVReportGenerator1DataQueryProgress(

  Sender: TCustomRVReportGenerator;

  Rule: TRVRowGenerationRule; Cell: TRVReportTableCellData;

  Step: TRVReportProgressStep; Level, Percent: Integer;

  var Proceed: Boolean);


  function GetRuleName: String;


    Result := '';

    if Rule<>nil then

      Result := Rule.Name;

    if Result='' then

      Result := '<untitled>';




  if Level<>1 then


  case Step of



        ProgressBar1.State := pbsPaused;

        ProgressBar1.Visible := True;

        Label1.Visible := True;

        Label1.Caption := 'Executing query '+GetRuleName;






        if ProgressBar1.State <> pbsNormal then


          Label1.Caption := 'Applying query '+GetRuleName;

          ProgressBar1.State := pbsNormal;




        ProgressBar1.Position := Percent;




        ProgressBar1.Visible := False;

        Label1.Visible := False;