Understanding the ReportWriter processing flow
Because ReportWriter presents a user interface for creating reports, in most circumstances you will not need to know its internal processing sequence. However, when designing complex reports, the order of of events may play an important role in getting the desired output.
Build phase
When you elect to run a report, ReportWriter must first build an executable code structure from the report definition. During this phase, the following occurs:
1. | The RW_INITBLD_METHOD routine is called. |
This “user hook” routine enables you to initialize any global data or perform any other one-time initial processing required by the other “user hook” routines.
2. | The files for the report are opened. |
For each filename to open, ReportWriter calls the RPS_FILNAM_METHOD routine to perform any runtime mapping of the filename before attempting the open. At this point, if the file type is user-defined, the RPS_OPEN_METHOD routine is called.
3. | ReportWriter determines whether sorting is necessary and what access key and initial find values are optimal. |
4. | The report definition structures are translated into executable code. |
Generation phase
After building the report, ReportWriter generates the report from the files to read and the code that was created during the build phase. During the generation phase, the following occurs:
1. | Environment variables are loaded. |
The RW_ENV_METHOD routine is called once for each environment field to load its contents.
2. | Question fields are processed. |
ReportWriter builds input windows from the question field parameters and accepts input.
3. | Any sorting is performed. |
If sorting is necessary, each set of records is read from the related files (see Reading sets of records from related files), and an intermediate file is created from all fields being accessed. This file is then sorted and becomes the new (and only) input file for the report. Also included in this file are the results of any calculation fields that are not dependent on subtotal access fields and that were not explicitly specified to occur after sorting. If any of the file types are user-defined, the routine RPS_READS_METHOD is used to retrieve the data.
4. | The report’s output file is opened. |
If the report is being displayed, the screen is accessed. If a report file is being printed or generated, the routine RW_PRTOPEN_METHOD is called.
5. | The first record set is read. |
If a sort was performed, this is the first record from the sorted intermediate file. If no sort was performed, the first set of records from the related files are read in. (See Reading sets of records from related files.) Any calculation fields that depend on subtotal access fields, or that were specified to occur after sorting, are calculated. If no record set is available, skip to step 12 below.
6. | The report header is printed. |
If visible, the report header lines are passed individually to the RW_HEADER_METHOD routine for any runtime changes and are then printed.
7. | Paging is performed. |
If a new page is needed (and this is always true at the beginning of the report), a page break occurs. If there was a previous page, any visible page footer is first printed. Each line of the footer is passed to the RW_FOOTER_METHOD routine for any runtime modifications and is then printed. A new page is ejected, and any visible page header is printed. Each line of the page header is passed to the RW_HEADER_METHOD routine for any runtime modifications and is then printed.
8. | A pre-break is processed. |
If necessary, subsequent record sets are processed to accumulate any subtotal access fields that are “Complete” subtotals, and the position in the file(s) is reset. Any subtotal-dependent calculation fields are recalculated. All appropriate pre-break print lines are printed (which is all of them the first time).
9. | The record set is processed. |
If a new page is needed, paging is performed as described in step 7. “Fields to print” lines are printed. If any of the printed fields are defined as type user-defined, the RPS_DATA_METHOD routine is called to format the output. The contents of all fields accessed in post-break print lines are copied off.
10. | The next record set is read. |
As described in step 5 above, the next record from the intermediate file, or the next appropriate set of records from the files, is returned. Subtotal-dependent or post-sort calculations are performed. If no next record set is available, skip to step 12 below.
11. | Breaks are checked. |
If a break field has changed, any appropriate counts, subtotals, or post-break print lines are printed and subtotal accumulators are cleared. If the break elicits a new page, return to step 7 above. If the break does not require a page break, return to step 8 above. If no break has occurred, return to step 9 above.
12. | End processing is performed. |
A post-break for the report is processed as described in step 11 above, using grand totals. Any page footer is printed as described in step 7. If a report footer is visible, each line of the footer is passed to RW_FOOTER_METHOD for any runtime modifications and then printed. The output file is closed by calling RW_PRTCLOSE_METHOD. The input file(s) are also closed, calling RPS_CLOSE_METHOD if necessary.
Reading sets of records from related files
If the report data must be sorted, record sets are read from the input files before the sort occurs. If no sorting is required, the record sets are read in as the report output records are processed.
Reading the first record set
1. | A record is read from the primary file. If no more records exist, return immediately, indicating “no more records” to ReportWriter. |
2. | Any selection criteria that are dependent only on the primary file are evaluated. If the results (combined with other selection criteria whose results are unknown) allow ReportWriter to exclude this record, return to step 1. |
3. | For the next related file, read any related record in the order in which the records are related. If no related record is found, or if we are currently processing multiple projections separately for another parallel file, the record will be set to blanks, and %GOTREC for the file will return 0. Any selection criteria that are dependent only on this file (or on this file and a prior file) are evaluated. If the results, combined with previously evaluated selection criteria and the unknown results of other selection criteria, allow ReportWriter to exclude this record set, return to step 1. Otherwise, repeat this step until all related files have been processed. |
4. | After all related files have been processed, any calculation fields that are not dependent on subtotal access fields and that have not been explicitly specified to occur after sorting are computed. Any remaining unevaluated selection criteria are evaluated. If the results, combined with previously evaluated selection criteria, logically exclude this record set, return to step 1. Otherwise, the record set is complete. |
Reading subsequent record sets
These steps occur when reading subsequent record sets, starting with the last file relation level.
1. | Get the next related record(s) at this level. |
- If we’re processing multiple projections separately, read the next related record from the current file in this relation level. If no next related record exists, set the record to blanks, set the return value of %GOTREC for this file to 0, and repeat this step for the next file at this relation level. If no more files exist at this level, repeat step 1 for the parent file. If there is no parent file, indicate “no more records” to ReportWriter.
- If we’re not processing multiple projections separately, read the next related records from all files in this relation level. If no next related record exists in a file, set its record to blanks and its return value for %GOTREC to 0. If no related records exist for any of the files at this relation level, repeat step 1 for the parent file. If there is no parent file, return a “no more records” message to ReportWriter.
2. | Any selection criteria that are dependent only on this file relation level (or on this level and a prior level) are evaluated. If ReportWriter can exclude the record set based on these criteria, return to step 1. |
3. | Follow steps 3 and 4 as described for the first record set above. |