The ReportScript language
1. General
The ReportScript language is used to write report scripts. Scripts are interpreted at run time by TScriptReport VCL component and used to preview and print reports. Although the language is developed to write database reports it can be used unrelated to databases. This paper defines semantics and syntax of the ReportScript language.
Report script consists of lines of plain text and ReportScript language operators. Operators are preceded by '\' sign. If a token is preceded by '\' it is considered as operator otherwise it is considered as text. Backslash '\' escapes '\'. Hash '#' sign is used to comment the text until end of line. The text formatted by operators is then splitted into lines, all spaces (spaces, tabs, newness) being considered to be a single space although some operators such as \EOL, \SPACE and others can override this.
The operator has the following syntax:
\ <name> [ <parameters> ] [ { <body> } ]
body is a operator body - a block of text and operators this operator is applied to.
The body if any is enclosed in curly brackets. Example of operator FONT: \FONT NAME='Arial Cyr' SIZE=10 { This font is Arial Cyr, size 10 }. Operator and parameter names are not case-sensitive. Blanks are ignored.
There are 3 types of operators: text formatting, definition/evaluation and flow control. They are described below.
Script report can contain variables. Besides of using variable substitutions in the text, variables are used in arithmetic operations and as \FOR parameters. There are three types of variables: QUERY-variables, local variables and extern variables, each type having its own namespace. QUERY-variables specified in INTO clause get values by executing select SQL queries and are defined within \FOR corresponding to particular \QUERY only. They are undefined out of appropriate \FOR operator scope and can not be used as left part of \SET operator. Local variables are those defined by \SET operators. Once defined by \SET local variable can be used anywhere below this point in the report script. Extern variables are interfaces to your application. Any time TScriptReport encounteres extern variable it calls the function specified by ExtFunction event. Extern variables can be used anywhere in report script except in a left part of \SET operator.
To simplify all types and procedure calls are given in Pascal notation.
For detailed examples and sample database refer to EXAMPLES directory.
2. Operators summary
# | REM { block }3. Operators description
3.1. Text formatting
Operator: Comment until EOL or comment blockAll text from '#' (including it) until the end of line is ignored, like in UNIX shell scripts. All text within curly brackets of \REM is ignored.
Operator: Escape single characterPlaces any single character into report. The character is placed as it is. This is the only way to place '\' and '#' into report (otherwise '\' is considered to be operator sign and '#' is considered to be comment sign).
Operator: Single spacePlaces a single space into report (using current font) which is not ignored by ReportWriter. Use of \SKIP is recommended instead of \SPACE.
Operator: Relative horizontal skipSkips N mm from current position to the right.
Operator: Absolute horizontal skipSkips N mm from the edge of page to the right.
Operator: Relative vertical skipSkips N mm down from the current position.
Operator: Line breakBreaks current line. The text after \EOL would be placed at the beginning of next line.
Operator: Page breakBreaks current page. The text after \NEWPAGE would be placed at the beginning of next page.
Operator: Font definitionSets default font to the font specified. Example: \FONT FACE = 'Arial Cyr' SIZE=10.
Operator: Italic fontMakes current font italic.
Operator: Bold fontMakes current font bold.
Operator: Normal fontClears all styles (i.e. italic and bold) from current font.
Operator: Font size definitionSets the size of current font to N (pixels).
Operator: Center alignmentCenters the block within current scope.
Operator: Right alignmentRight-justifies the block within current scope.
Operator: Left alignmentLeft-justifies the block within current scope.
Operator: Text boxPlaces the block within a box. If BORDER is not specified the box is not bordered. Otherwise if border width is not specified the default one of 1 pixel is used. Continuos boxes are drawn one after another, internal borders being drawn once.
Operator: Table
Syntax: \TABLE [COLS[=]] W1[[,] W2 ...] [BORDER[[=]N]] { block }
Parameters: W1, W2 - column widths in mm; N - border width in pixels
Scope: Anywhere
Places the block within a table. If BORDER is not specified cells within table are not bordered. Otherwise if border width is not specified the default one of 1 pixel is used. The block can contain as \TR as other operators. For instance sometimes it is useful to place \FOR operators and do calculations before \TR.
See also: \TH, \TR, \TD.
Defines table header. The header is placed before the table. If the table does not fit in current page the header is placed on the beginning of every page the table fits in. The header and the table are separated by empty line.
See also: \TABLE, \TR, \TD.
Defines table record (table row). The table is a set of records (rows) each consisting of a set of cells (columns). At present only tables MxN are supported. Incorrect number of columns specified by \TD are ignored when possible. The block can contain as \TD as other operators.
See also: \TABLE, \TH, \TD.
Defines table data (table cell).
See also: \TABLE, \TR
Defines and starts a new page.
Operator: Papre size definitionDefines page paper size. If \PSIZE is not specified the default size of 210x297 (A4) is used.
Operator: Page orientation definitionDefines page paper orientation. Default is PORTRAIT. Sets Printer page orientation. Does not affect anything else. Should be preceded by PSIZE. Note that if \PSIZE is not specified the page is built as if it is A4 which is much like PORTRAIT ;) rather than LANDSCAPE.
Operator: Top marginDefines page top margin. The default is 20mm.
Operator: Bottom marginDefines page bottom margin. The default is 20mm.
Operator: Left marginDefines page left margin. The default is 20mm.
Operator: Right marginDefines page right margin. The default is 20mm.
Operator: Page header definitionDefines page header.
See also: \PAGENUM, \DATE.
Defines page footer.
See also: \PAGENUM, \DATE.
Places all the text produced by the block on a single page if possible. If the block does not fit in the current page it is placed from the beginning of the next page.
3.2. Definition and evaluation operators
3.2.1. ExpressionsExpressions referred to in Section 3.2 are defined by the following grammar:
Term = Number | QueryVar | LocalVar | Ext | Eval | "'" Text "'"Text case is not supported by \EVAL and \SET operators.
3.2.2. Operators Operator: Query definitionDefines a query to use with \FOR operators. The body is a select-sql query followed by INTO clause. The number of variables should be the same as number of columns to select in sql query. At present variables are position-based, each of them corresponding to sql query column having the same position within sql query. If sql query has parameters they must be specified in \FOR. They are not checked during parsing \QUERY.
See also: \FOR, Section 1.
Example:
\QUERY QEmployees { SELECT FirstName, SecondName FROM Depts WHERE RowID = :Param0 INTO :FirstName, LastName }
Sets local variable LocalVarName value to Expr. If it is the first \SET for variable LocalVarName in the report script it is considered as variable declaration as well.
See also: \EVAL, \%, \$, Section 1.
Example: \SET x=1
Substitutes the value for QUERY variable.
See also: \QUERY, \FOR, \EVAL, \$, Section 1.
Substitutes the value for local variable.
See also: \SET, \EVAL, \%, Section 1.
Substitutes the value for extern variable.. This is the way to exchange data with application C/C++/Pascal functions. If ExtFunction event (design time published property) of TScriptReport instance is assigned, each time ReportWriter encounters \EXT it calls the function specified by ExtFunction property. The ExtFunction is defined by:
TExtfunction = function(ExtName: string; var Data: string; var MoreValues: boolean): boolean of object;
ExtFunction: TExtfunction;
ExtFunction is called with the following parameters: ExtName is filled by VarName, Data is filled by \EVAL { Expr }. Having executed ExtFunction \EXT returns one's Data to the report. MoreValues specifies if extern variable considered has more values. This case is considered in Section 3.2.3 in description of \FOR. At present ExtFunction return value (boolean) is ignored.
Example:
Consider TForm1.ScpiptReport1.ExtFunction = TForm1.ExtFunc and TForm1.ExtFunc is:
function TForm1.ExtFunc(ExtName: string; var Data: string; var MoreValues: boolean): boolean;
begin
if LowerCase(ExtName) = 'hello' then begin { we were asked extern variable hello }
Data := 'Hello, ' + Data + '!' { a new value of variable hello is defined }
MoreValues := false;
end;
end; { TForm1.ExtFunc }
Then consider we place the following in the report script:
\EXT hello, 'World' # so the report script would contain 'Hello, World!'.
See also: \SET, \EVAL, \%, Section 1, \FOR.
Evaluates expression Expr and return data evaluated to the report.
See also: \SET, \EVAL, \%, \EXT, Section 1, Section 3.2.1.
\PAGENUM is substituted by current page number. Can be used in arithmetic expressions.
Operator: Current date substitution\DATE is substituted by current date according to ShortDateFormat global variable. Cannot be used in arithmetic expressions.
3.3. Flow control operators
Fills QUERY parameters in positional order, opens the QUERY and executes the block for each resulting record.
If there is no resulting record the block is not executed. Term1, Term2 ... are evaluated, resulting values being used as sql query parameters.
When using \EXT as Expr, each parameter in PARAMS clause is considered to be a multi-value extern variable. In this case MoreValues parameter of ExtFunction is used. \FOR opens the sql query and execute the block for each value of multi-value extern variable by calling ExtFunction appropriate number of times to obtain all values of variable, until MoreValues is set to false. If you use several multi-value extern variables \FOR will execute the block for each combination of their values, i.e. if Expr1 has N values and Expr2 has M values \FOR will execute the block N*M times.
Example:
It is a very common case when user is to choose a series of objects to build a report for these objects only. Using \FOR with multi-value extern variables is a good possibility to do that. Consider user chooses several employees into ListBox, database application filling ListBox by their RowIDs as Items.Objects[i] and names as Items.Strings[i]. To build a database report on chosen employees write TForm1.ExtFunction as following:
function TForm1.ExtFunc(ExtName: string; var Data: string; var MoreValues: boolean): boolean;
const i: integer = 0;
begin
MoreValues := false;
if LowerCase() = 'emplist' then begin { we were asked extern variable EmpList }
if (i < 0) or (i >= ListBox1.Count) then Data := '0'
else with ListBox1 do begin
Data := IntToStr(integer(Items.Objects[i]));
inc(i);
MoreValues := i < Count; { i = 0 .. Count - 1 }
end;
end else if LowerCase(ExtName) = 'seti' then begin { we were asked extern variable SetI }
i := StrToInt(Data);
Data := ''; { not to place anything into report }
end;
end; { TForm1.ExtFunc }
Then place into report script the following:
\QUERY QEmployees { SELECT FirstName, LastName FROM Employees WHERE RowID = :v0 INTO FirstName, LastName }
\EXT SetI, 0
\FOR QEmployees PARAMS=\EXT EmpList {\%FirstName, \%LastName\EOL} # would place into report employees names chosen in TForm1.ListBox1.
See also: \QUERY, \%, \$, \EXT, \SET, Section 1, Section 3.2.1.
Executes block1 if BoolExpr is true, executes block2 otherwise.
Example: \IF (\%XCount > 1) {\EVAL{\%XETC / \%XCount} / \%XETC} ELSE {\%XETC}
If XCount = 2 and XETC = 10, it would place into report the following string:
5/2
See also: Section 3.2.1.