Printing records as they appear in a cxGrid fires exception
in RAP
I have a cxGrid where the user can add and sort records. I want to print only those records in the same sequence as they are displayed on screen. The report is very simple, no subreports etc. I am using a TppDBPipeline that is connected to a TDataset. The cxGrid shows the same data but uses a second dataset. I tried to set the recordcount to that of the grid :
nRecordsToPrint := tvJobMw.DataController.FilteredRecordCount;
RecordIndexToPrint := 0;
ppDBPipeline1.RangeEnd := reCount;
ppDBPipeline1.RangeEndCount := nRecordsToPrint;
In the OnTraversal event I look in the grids datacontroller for the unique ID value of the records, then position the pipelines datasource to the same record :
tvJobMw is the cxGrids tableview.
procedure TFormTestJobs.ppDBPipeline1Traversal(Sender: TObject);
var
ci, ri, id, n: integer;
ds: TDataset;
i: Integer;
begin
inherited;
ds := ppDBPipeline1.DataSource.DataSet;
ri := tvJobMw.DataController.FilteredRecordIndex[RecordIndexToPrint];
ci := tvJobMw.GetColumnByFieldName('ID').Index;
id := tvJobMw.DataController.Values[ri, ci];
if ds.Locate('ID', id, []) then begin
n := ds['ID'];
end;
if RecordIndexToPrint < nRecordsToPrint then
Inc(RecordIndexToPrint);
end;
After print I get an exception : List index outside of valid range (14).
Note: there are 14 records to print.
After closing the exception the report is displayed and shows the 14 reords.
So without exception everything seems ok.
I expected the pipeline to stop fetching data after the RangeEndCount has exceeded.
But obviously I am wrong.
Do you know why ?
Regards
Gerhard Sachs
nRecordsToPrint := tvJobMw.DataController.FilteredRecordCount;
RecordIndexToPrint := 0;
ppDBPipeline1.RangeEnd := reCount;
ppDBPipeline1.RangeEndCount := nRecordsToPrint;
In the OnTraversal event I look in the grids datacontroller for the unique ID value of the records, then position the pipelines datasource to the same record :
tvJobMw is the cxGrids tableview.
procedure TFormTestJobs.ppDBPipeline1Traversal(Sender: TObject);
var
ci, ri, id, n: integer;
ds: TDataset;
i: Integer;
begin
inherited;
ds := ppDBPipeline1.DataSource.DataSet;
ri := tvJobMw.DataController.FilteredRecordIndex[RecordIndexToPrint];
ci := tvJobMw.GetColumnByFieldName('ID').Index;
id := tvJobMw.DataController.Values[ri, ci];
if ds.Locate('ID', id, []) then begin
n := ds['ID'];
end;
if RecordIndexToPrint < nRecordsToPrint then
Inc(RecordIndexToPrint);
end;
After print I get an exception : List index outside of valid range (14).
Note: there are 14 records to print.
After closing the exception the report is displayed and shows the 14 reords.
So without exception everything seems ok.
I expected the pipeline to stop fetching data after the RangeEndCount has exceeded.
But obviously I am wrong.
Do you know why ?
Regards
Gerhard Sachs
Comments
In my quick testing, the RangeEnd and RangeEndCount features are functioning as designed. I believe the issue is that you are altering the current record each time the pipeline tries to traverse to a new record. The pipeline is not designed to "jump" around the dataset like that each time it moves to a new record.
My suggestion would be to manipulate the dataset (query) connected to the DBPipeline before printing the report to match the CXGrid or use a JITPipeline to pull data directly out of the CXGrid and remove the need for a second dataset.
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com