Expressions may reference query column names, environment variables, internal variables and user defined Report variables. These references are called identifiers. Their values are evaluated during the report execution.
Identifiers are in the format domain.identifier
where the domain name or the dot are optional.
OpenCReports uses UTF-8 encoding even in identifier names. National or accented characters are accepted in identifiers.
Valid names for domain
and
identifier
may start with an underscore
or UTF-8 letters and may contain underscore, UTF-8 letters
and numbers in subsequent characters.
Any valid identifier is by default a query column reference, with or without the domain name. Examples:
field_name field_name5 myquery1.field_name oszlop_név lekérdezés.oszlop_név
In the above example,
oszlop_név
means
field_name
, and
lekérdezés.oszlop_név
means
query.field_name
in Hungarian.
The accented characters are a courtesy of UTF-8.
Query field identifiers in expressions are resolved by matching them against query names (used as the domain) and their field names.
If the domain name is specified, a query matching the domain name name must be declared for the report, either as the primary query, a follower query, or an independent query. That query must have a column name that matches the identifier name.
If the domain name is not specified, the field name references are matched against all the queries of the report in the order of their declaration. The first query with a matching column name will be used for that reference.
For exceptions (and exceptions from under the exceptions!), see below.
Domain v
signifies user defined
report variables, which can be used to shortcut expressions.
Example:
v.my_variable
For details, see Report variables and Variable node.
Some domain names carry special meaning for the report.
Domain m
indicates the domain
of environment variables.
The nature of environment variables depends on the languange binding. For example in C, it's the environment variables in the operating system. In PHP, the identifier name is first matched against global PHP variables, and if not found, against the operating system environment variables. Example:
m.current_date
Since such a setting is controlled outside the report, and for the duration of running the report, its value cannot (or shouldn't) change, environment variable references are optimized into constants at the beginning of the report execution.
Environment variables can't change during report execution in single threaded applications, but they can in multi-threaded ones. By optimizing environment variables into constants in expressions instead of querying the environment every time the same expression is evaluated, potential data races (that may result in inconsistent results) are eliminated.
Domain r
indicates the domain
of internal report variables.
r.pageno
The current page of the report is maintained by the report layout during the report run. For example, if an expression is evaluated on page 4 of the report, and happens to reference the current page number variable, then this variable will have the value 4 in the result.
PDF output supports pagination. Other output formats do not. For them the value of this variable is 1.
r.totpages
This variable carries the total number of pages in the report. Its value is maintained by the report.
Only the PDF output format supports pagination. For output formats not supporting pagination, the value of this variable is 1 throughout the report.
This variable is inherently precalculated. Expressions like this will intuitively produce the expected result:
printf("Page: %d / %d", r.pageno, r.totpages)
For example, on the 3rd page of a 5-page report, the value would be:
Page: 3 / 5
r.lineno
This variable gives the current row (line) number in the data set.
It can be thought as an alias to the Query row number function function which does the same by default. But functions may be overridden by user defined functions, while this variable will always work as described.
r.detailcnt
This variable works similarly to the Line number variable and Query row number function, except it restarts from 1 when a field header is emitted on the report. See Detail node.
With the default behaviour of the field header
regarding breaks (see
Report field header priority attribute),
i.e. when field header is printed on the top of every page,
r.detailcnt
works as a per page
line count value.
When the report field header priority is set to low, the effect may be more emphasized because the value of this variable is reset more often.
r.value
Data on the report is represented by field description. Along with the data expression, supplementary expressions are used for metadata that make up the displaying of the value. Such supplementary expression exist for the foreground and background colors, the formatting of the value, and others.
The supplementary expressions may reference the field value, without having to type out the field expression multiple times.
Using r.value
also helps reducing
the report runtime because the value expression is not
computed multiple times. This is a manual
optimization.
Referencing r.value
is only possible
for supplementary expressions in the same field
description. This variable cannot cross-reference other
field descriptions, or anything not in the same scope.
For this purpose, there are user
Report variables.
r.format
This variable returns the current output format
name as a string. For example: PDF
,
HTML
, etc.
r.self
This variable references the previous result of the expression. It is used in iterative expressions, like in user-defined Report variables. It can also be used in any user defined expression.
r.baseexpr r.ignoreexpr r.intermedexpr r.intermed2expr
These variables are references for the four subexpressions that potentially make up a user-defined custom variable. The expressions in order are: base expression, the row ignoring expression and two intermediary expressions.
Actually, there's a fifth subexpression that exists in every user defined variable, namely the result expression. It's reference is simply the user variable reference, see User defined variables and Custom variable attributes.
They are evaluated in this order:
r.baseexpr
The base expression must not reference
any of the others of
r.ignoreexpr
,
r.intermedexpr
,
and r.intermed2expr
.
r.ignoreexpr
The data row ignoring expression must not reference
r.intermedexpr
and
r.intermed2expr
,
but it can reference
r.baseexpr
.
r.intermedexpr
The first intermediary expression can
reference r.baseexpr
and r.ignoreexpr
,
but it must not reference r.intermed2expr
.
r.intermed2expr
The second intermediary expression can
reference any of
r.baseexpr
,
r.ignoreexpr
,
and r.intermedexpr
.
The result expression, which has no internal
variable name. It can reference all of
r.baseexpr
,
r.ignoreexpr
,
r.intermedexpr
and
r.intermed2expr
.
For example, a running average over a data series needs two intermediary expressions: one for the sum of the values, the other for the number of values in the series. The result is the sum of values divided by the number of values.
Their usage is only valid when declaring a custom user defined variable.
Both domain
and identifier
names may be quoted or unquoted. Quoting names allow using
semi-reserved and reserved words as identifiers and also
allow special characters in identifier names. Examples:
query.field_name1 query."field_name2" query."field with space in the name" "query2".field_name3 "query2"."and"
A dot-prefixed identifier is one where the domain name is not specified, but the identifier name is prefixed with a dot. Examples:
.field_name ."field_name"
The boolean constants are semi-reserved words. They can be used as identifiers with dot-prefixed identifier names without a domain name and without quoting:
.yes .no .true .false yes.no
The above unquoted identifiers are equivalent with these quoted ones below:
."yes" ."no" ."true" ."false" "yes"."no"
Operator names are reserved words, e.g. and
and or
. They cannot be used with dot-prefixed
operator names without quoting, as it would cause an
expression syntax error. But they can be used as quoted
identifiers, in case you would want to use such a query name
and column name:
."and" ."or" "and"."or"
When identifier domains are quoted, they lose their special meaning and the identifiers become query field identifiers. Of course, in this case, such a query name must exist and the query must have a field name specified in the identifier. Examples:
"m".current_date "r".totpages "v".my_variable