Reference Guide For Report Scripts
Reference Guide For Report Scripts
0c Tools
Reference Guide for Report Scripts
The information in this document is subject to change without notice. No part of this document may be reproduced,
stored or transmitted in any form or by any means, electronic or mechanical, for any purpose, without the express
written permission of Baan Development B.V.
Baan Development B.V. assumes no liability for any damages incurred, directly or indirectly, from any errors, omissions
or discrepancies between the software and the information contained in this document.
Table of contents
1. Introduction 1-1
No detailed knowledge is required to use this guide, however, understanding the contents is
easier if you are familiar with the general sessions and modules of BaanERP 5.0c Tools. This
document consists of the following chapters:
Chapter 1, “Introduction,” provides a general introduction to this guide.
Chapter 2, “BaanERP 5.0c report scripts presentation,” provides an overview and figures to
expand upon BaanERP 5.0c Tools.
This document provides information about BaanERP 5.0c Tools. The figures and information
in this document enable you to carry out customization and testing in BaanERP Tools.
Design Environment
O ntw ikk elaar
DSGN_001
tdB40O_b_kl02 tpB40O_b_kl02
T TT
OPER_001
tdB40O_b_kl01 tpB40O_b_kl01
T TT
B40Sb
tdB40_b tpB40_b
To customize and test reports, a prerequisite is that you must use a design environment. A
special package ccombination (DSGN_001) must be present and linked with a developer and
test company. For each BaanERP package, this package combination contains a special design
VRC, for example, cl02, which is derived from the operational VRC, for example cl01.
Print
session
01011
10110
application
pakket dm
versie a
forms forms
module oes module oes
tools
ned eng
Report
layout
Compile 10101
00011 Report object
If … then
……
Report script else
(BAAN-C) …...
endif
Figure 2-3 Illustration between the report layout and the report script
The report object and report script are stored seperately in the Tools tables, which is the
application dictionary. However, during compilation, when a report object is created on
runtime level, both components are compiled to one report object. As a result, in the runtime
data dictionary, only one report object that contains information about the reports layout and
the report script can be found.
• Complex calculations
• Complex field expressions
You can use a report script to perform a complex calculation. The outcome will then be placed
in a variable. You can place this variable in the report layout as a report field, which is a field
expression, by means of the report editor.
If conditions, such as output expressions / print conditions, for printing a report layout, for
example, detail, or a certain field becomes complex, you can also use a report script. You can
program the conditions by means of a program structure, such as an if-then-else statement.
The same is true if an aggregate function, such as Total, can only be carried out under specific
conditions. You can use a alculation in the report script instead of the aggregate function and
the function’s related aggregate expression (condition). Another advantage of using a report
script for an aggregate function is that you can then use the outcome elsewhere in the report.
In some instances, printing particular fields from a reference table on the report can be useful.
To print fields from a reference table, you must place these fields in the report layouts.
However, you can only place the fields in the report layouts if the program object of the print
session will open the specified reference table. If this is not the case, the reference table still
can be opened by means of embedded SQL in the report script.
Subsection(s)
• before.report.<seq.nr.>
• header.<seq.nr.> before.layout
• before.<field name>.<seq.nr.> Actions before printing
• detail.<seq.nr.>
• after.<field name>.<seq.nr.> after.layout
• after.report.<seq. nr.>
The sections in the upper block of the slide, before.report to after.report, have a direct relation
with the report layouts.
Actions in relation to the detail layout with sequence number 10 will be programmed in the
section detail.10. If you are dealing with a before.field or after.field, you must also include the
sorting field in the section.
For example, suppose you have a before.field with a sequence number 10, and the sorting field
of the before.field is dmoes001.igpc. If a script must be programmed for this before.field, this
script must be carried out in the section before.dmoes001.igpc.10.
The following two possible subsections exist for the main sections mentioned in the first block
of the previous figure:
before.layout
Actions programmed in this subsection are carried out before the specified report layout is
printed. For example, suppose a calculation must be carried out in the detail layout with
sequence number 10. The result of this calculation must be printed in the detail line. In that
case, the calculation must take place before the detail line will be printed. As a result, the
calcutation must be programmed in the subsection before.layout of the main section detail.10.
after.layout
Actions programmed in this subsection are carried out after the specified report layout is
printed. A frequently used action in this subsection is resetting variables to the variables’initial
value.
For each main section, at least one subsection is mandatory. Both subsections are also allowed.
In other words, for each main section, one or both of before.layout or after.layout is
programmed.
The lower block in the previous figure deals with programming of text fields. For this section,
you must use the subsection before.print. For example, suppose you want to use a text that is
linked to the text field dmoes001.text. If certain actions must be programmed for this text field,
you can program these actions in the subsection before.print of the main section
field.dmoes001.text.
To obtain additional information, take the following steps:
1 On the menu browser, select BaanERP 5.0 Tools.
2 On the menu bar, click Help ¾ Contents.
3 Click Programmer Reference Information ¾ Report Scripts ¾ Relations (button) ¾
Report Sections.
Examples - Declaration
declaration:
string description(30) | Item description
long tot.number | Total number of items per warehouse
double tot.amount | Total amount per warehouse
By means of domains
declaration:
domain dmdscr description | Item description
domain dmquan tot.number | Total number of items per warehouse
domain dmpris tot.amount | Total amount per warehouse
The declaration of variables can take place in two ways: by means of data types or by means of
domains.
data types
In the section “declaration” the data type will be declared, followed by the name of the related
variable. If the data type is a string variable, the length of the string must also be declared, and
is placed behind the data type between brackets. If the length is omitted, the length will be set
to the default value, which is one character.
domains
Domains are defined in the Baan Tools, and specify the type of data. If you use domains in the
declaration section, you are not required to specify the data type, because that information is
already included in the domain. In other words, if, for example, you use the domain dmdscr,
the domain already contains the correct information:
Datatype: String.
Length: 30
Therefore, you can simply specify the domain to which you want to link the variable:
<domain code> <name of variable>
The last method is prefered to achieve a consistent layout of the reports.
before.program:
tot.number = 0
tot.amount = 0
detail.1:
after.layout:
tot.number = tot.number + dmoes020.quan
tot.amount = tot.amount + (dmoes020.quan * dmoes001.spri)
after.dmoes020.cwar.1:
after.layout:
tot.number = 0
tot.amount = 0
In the before.program section, two variables will be initialized. Next, these variables will be
calculated in the after.layout of the detail with sequence number 1. Finally, these variables will
be reset to zero in the after.field of the after.dmoes020.cwar.1 layout (cwar = warehouse code).
This process is necessary to calculate the next group / warehouse code.
Program structures
if....then....else.....endif
on.....case..:...case...:..default:...endcase
while......endwhile
repeat....until.......
for....=....to.....step....endfor
break/continue
<condition> ? <expression-1> : <expression-2>
If the stock on hand is zero, the stock on hand will not be printed. In all other cases, the stock it
will be printed.
The on-case construction is useful if a number of options exist that must be tested. This
construction is a type of multiple choice option. The following figure provides an example:
The constructions while, repeat-until, for and break / continue are used to create loops.
The last option of the slide is often refered to as the question mark expression. This option
works as follows:
If the condition before the question mark is true, expression 1 will be carried out.
If the condition is false, expression 2 will be carried out.
Example dmoes001.cvat = 001 ? lattr.print = true : lattr.print = false
As a result, the VAT code will be printed if the code equals 001. In all other cases, the VAT
code will not be printed.
To obtain additional information, take the following steps:
1 From the menu browser, select BaanERP 5.0 Tools.
2 From the menu bar, click Help ¾ Contents.
3 Click Programmer Reference Information ¾ 3GL Language Features ¾
¾ Transfer of Control, then choose one of the following:
Relations (button)¾
− The GOTO statement.
− The IF-THEN-ELSE statement.
− The ON-CASE statement.
4 Click Select Programmer Reference Information ¾ 3 GL Language Features ¾
Relations (button) ¾ Iterations, then choose one of the following:
− WHILE Statement.
− FOR Statement.
− REPEAT-UNTIL Statement.
− Using BREAK and CONTINUE.
on case dmoes001.igpc:
case “010”: newprice = 1.10 * dmoes001.spri
break
case “015”: newprice = 1.25 * dmoes001.spri
break
case “032”: newprice = 1.15 * dmoes001.spri
break
case “067”: newprice = 1.35 * dmoes001.spri
break
default: newprice = 1.05 * dmoes001.spri
break
endcase
This figure provides an example of an ON-CASE statement. The Item Group Code
(dmoes001.igpc) table field will be tested. If the value of this field equals 010, the newprice
variable will be 1.10 times the sales price (=dmoes001.spri). In other words, the sales price
will be increase by 10 percent. If the item belongs to one of the item group 015, 032, or 067,
the increase in sales price will be 25, 15, and 35 percent, respectively.
For all other item groups, by default, the sales prices will increase by five percent.
The ON-CASE statement must always end with endcase.
Operators
Mathematical operators
+ - * / \ &
Logical operators
AND OR NOT
Relational operators
= <> > < >= <=
EQ NE GT LT GE LE
Predefined variables
This figure provides a number of predefined variables that you can use in reports and forms.
The free$ variable has a maximum length of 50 characters, and can be used for extra selection
possibilities on a form of a print session. For example: suppose that a date selection must be
possible on the form of the Print Stock Transactions session. Therefore, you must place two
extra fields on the form: Date From and Date To. The first eight spaces of free$ will be used
for the Date From field, with start position 1 and an input length of 8. For the Date To field,
position 9 through 16 of free$ will be used with a start position 9 and also an input length of 8.
Both fields will be linked to the date domain.
Next, you must test both fields in the report script. You must define the following two
variables to test the fields: date.f and date.t. Both variables are from the data type long,
because the program handles dates as numbers. The variables will be initialized in the section
before.program as shown in the following text:
date.f = lval(free$(1;8)) and date.t = lval(free$(9;8))
Finally, you must test whether the transaction date of the stock maintenace falls within the
range of dates as provided in the Date From and Date To fields. You can perform this test in
the subsection before.layout of the main section detail.1:
if dmoes020.trdt >= date.f and dmoes020.trdt <= date.t then
lattr.print = true
else
lattr.print = false
To obtain additional information, take the following steps:
1 From the menu browser, select BaanERP 5.0 Tools.
2 From the menu bar, click Help ¾ Contents.
Predefined functions
lattr.print
lattr.textexpand
lattr.lineno
lattr.break
lattr.enddata
lattr.prline
spool.pg.length
spool.pg.width
spool.device
You can use several special report variables. Some of these variables have already been
mentioned in one of the previous examples. The lattr.print varaiable determines whether or not
a layout must be printed. The lattr.break variable determines under which condition(s) a page
break must occur. And , finally, the lattr.lineno variable returns the line number.
To obtain additional information, take the following steps:
1 From the menu browser, select BaanERP 5.0 Tools.
2 From the menu bar, click Help ¾ Contents.
3 Click Programmer Reference Information ¾ Report Scripts ¾ Relations (button) ¾
Predefined Variables.
page()
to.page()
skip()
skip.to()
layout.again()
reset.suppress()
need()
You can also make use of several special report functions. These functions will not be
discussed here. For more information, refer to the BaanERP help texts.
To obtain additional information, take the following steps:
1 In the menu browser, select BaanERP 5.0 Tools.
2 On the menu bar, click Help ¾ Contents.
3 Click Programmer Reference Information ¾ Reports Scripts ¾ Relations (button) ¾
Functions in Report Scripts.
Embedded SQL
Select <Fields>
From <Table(s)>
Where <Condition>
Selectdo
<Action(s) on each selected record>
Selecteos
<Action(s) after last selected record>
Selectempty
<Action(s) if no records are selected>
Selecterror
<Action(s) in case of an error>
Endselect
This figure provides the standard syntax of embedded SQL. You can use embedded SQL in a
report script to read data from reference tables. You do not have to use all parts of the syntax.
In many cases, using the statements SELECT – FROM – WHERE – SELECTDO is sufficient.
You can even omit the SELECTDO statement. However, you will receive a warning that this
is not a neat solution, but the program will accept the solution.
To obtain additional information, take the following steps:
1 On the menu browser, select BaanERP 5.0 Tools.
2 On the menu bar, click Help ¾ Contents.
3 Click Select Programmer Referenece Information ¾ Database Handling ¾
Relations (button) ¾ Baan SQL
Stock
dmoes001
maintenance item igpc
17 bmw 10 Item groups
Items
Figure 2-18 Illustration of the link between first and second degree reference tables
In this figure, you see an example of a direct reference between the Stock Transactions table
and the Items table. In the Stock Transactions table, each transaction is linked to an item
number (dmoes020.item). This field has a reference to the table field dmoes001.item in the
Item table. This reference is called a first degree reference.
A first degree reference also exists between the Item table and the Item Groups table.As a
result, a reference exists between the Stock Transactions table and the Item Groups table,
mediated by the Item table. In this case, the reference is referred to as a second degree
reference.
In addition to the main table, the first degree reference tables are usually opened in a print
session. As a result, you can easily read and print data from these tables. For example, the Print
Stock Transactions session can also print various types of item data, such as item description,
purchase price, sales price, and item group code.
Data from second degree reference tables is usually not directly available. For example, the
Print Stock Transactions session cannot print the item group description, because this data is
stored in a second degree reference table. If you want to read this data, you must make use of
embedded SQL in a report script, as shown in the following figure.
declaration:
table tdmoes010
Stock
maintenance
Item groups
detail.1:
before.layout:
select dmoes010.dscr Items
from dmoes010
where dmoes010.igpc=:dmoes001.igpc
selectdo
endselect
where dmoes010._index1={:dmoes001.igpc}
First, you must declare the second degree reference table in the declaration section of the
reports script.
Data will be read in the detail, for example detail.1:, where the item group description must be
printed. Of course, the data must be read before the data can be printed. In other words, you
must program this action in the before.layout subsection.
In the where-statement, the fields dmoes010.igpc and dmoes001.igpc will be linked to each
other. This link is necessary to ensure that the correct group is selected in the item groups
table. In other words, if the item group code of the item is 010, the item group description of
item group 010 must be selected. The colon (:) behind the equal sign (=) is mandatory because
the dmoes001 table is not declared in the from-statement.
The dmoes010.igpc field is an index field (primary index) of the dmoes010 table. In this case,
for best results you can use the following construction in the where-statement:
dmoes010._index1 = {:dmoes001.igpc}
The item group table will be read according the index (sequentially), which increases the
performance. This can be especially useful if you deal with very large tables.
Arrays
• Table/matrix
• Maximal 4 dimensions
• Data type: long, double, string
• Usage: collect + print subtotals
declaration:
tot.stock(2)
long tot.stock(5)
tot.StockValue(2)
double tot.StockValue(5)
30
string GroupDescription(30,5)
GroupDescription(1,2)
declaration: tot.stock(4,2)
long tot.stock(5,3)
tot.StockValue(4,2)
double tot.StockValue(5,3)
30
string GroupDescription(30,5,3)
GroupDescription(1,4,2)
For the declaration of a string array, you must use the first dimension for the field length. To
define a field of a string array, you first state the position in the field, followed by the field
location.
Arrays - Fill
before.program:
ap1 = 0
before.dmoes001.igpc.1:
before.layout: 30
ap1 = ap1 + 1
GroupDescription(1,ap1)=dmoes010.dscr
detail.1:
after.layout:
tot.stock(ap1) = tot.stock(ap1) + dmoes001.stck
tot.StockValue(ap1) = tot.StockValue(ap1) +
(dmoes001.stck*dmoes001.spri)
In this report script, the item group description, the total stock and the total stock value, all per
item, are stored in arrays. When you fill these arrays, the variable ap1 (array pointer 1) is used.
This pointer indicates which element (field) of the array must be filled.
In the before.program, the ap1 is set to zero (0). Subsequently, the pointer will shift one array
field for each item group to the right: ap1 = ap1 + 1 in the item group-before.field.
At the first group, ap1 is set to 1 (0 + 1). Subsequently, the item group description is placed
from the before.field into field 1 of the array item group description:
item group description(1,ap1)=dmoes010.dsr.
Next, the total stock amount and the total stock value are calculated in the array fields
tot.stock(1) and tot.stockvalue(1).
After all the records of the first item group have been processed, the next group is processed,
which means that .before.field is carried out again. The array pointer will shift one position to
the right: ap1 = ap1 + 1.
As a result, the data for this group will be written in field 2 of the arrays.
This proces is repeated for each item group.
Arrays - Printing
before.program:
ap2 = 1
after.report.2:
before.layout: 30
if ap2 <= ap1 then
lattr.print = true
else
lattr.print = false
endif
after.layout:
if ap2 < ap1 then
ap2 = ap2 + 1
layout.again()
endif
Suppose five item groups exist. Variable ap1 from the previous figure will have value 5 at the end.
For printing, a second variable, ap2 (array pointer 2) is used. This variable is set to 1 in the
before.program, which means that print output will start from array field 1.
Because the summary must be printed at the end of the report, an after.report is used. At Maintain
Layouts, two after.reports are added. The first, seq.no. 1, is empty and will only be used to force a
new page, Page = yes, so the summary will begin on a new page.
The second after.report, seq.no. 2, contains the three array field for the summary: item group
description (1,ap2), tot.stock(ap2) and tot.stock value(ap2).
Before the after.report (seq.no.2) is printed (before.layout), a check, ap2 <= ap1, is carried out. If
this check is not carried out, no printing takes place. Suppose no data is printed. In that case, the
summary in the after.report must not be printed. If no data has been printed, ap1 will still have
value 0. In this case, ap2 (=1) will not be less than or equal to ap1 (=0). As a result, this check
prevents the printing of an empty page.
In the example in the slide, five groups have been printed. (ap1=5), therefore the condition has
been complied with. In this case, the first fields of the three arrays are printed. Next, the
after.layout is checked to see whether ap2 (1) has not reached the value of ap1(5) yet. This is not
the case, and, therefore, ap2 is shifted one position to the right, after which layout.again is
executed. This procedure is carried out to print the after.report one more time: an after.report is
usually only printed once. Because ap2 is now 2, the second series of the arrays is printed. After
this, ap2 is set to 3, and so on. As soon as ap2 reaches the value 5, the fifth series of array fields is
printed. Subsequently, in the after.layout, ap2 (5) is not less than ap1 (5). As a result, no
layout.again is available, and the report will stop.
Macro’s
declaration:
#define MAX 5
long tot.stock(MAX)
double tot.StockValue(MAX)
30
string GroupDescription(30,MAX)
You can use a macro to store a text item (program code). You can use the macro several times
in the report script.
A macro must always be declared in the following way:
#define <macro name> <contents>
Example #define MAX 5
In the array declarations in the figure, MAX can now be used instead of 5. This can be useful if
the length of the three arrays must be changed afterwards. You can now implement the
necessary alteration at one time by adjusting the macro definition.
Instead of numbers, pieces of program syntax can also be stored in macros.
Own functions
• Type
• long, double, string, domain, void
• Prototype
• declaration
• Definition
• functions
• Call
• before.program, detail, et cetera
The function type depends on the data type of the return value. The default function type is
void (no return value). If no type is declared in the function prototype and the function
definition, the function type will be void.
In most cases, in the declaration of the report script, a function prototype, including function
header and possibly arguments, must be defined.
The following two situations are situations in which no function prototype is required:
If the function is of type Void and has no arguments.
If the function call happens after the function definition. As a result, the function call is also
somewhere in the functions section of the report script.
The function definition shows exactly which actions the function performs. The function
definition takes place in the functions section of the report script.
Function call means the use of the function. This can take place in various parts of the program
script, such as before.program, before.report, and detail. Obviously, the same function can be
called several times in the report script.
detail.1:
before.layout:
fill.arrays()
Call
functions:
function fill.arrays() Definition
{
tot.stock(ap1) = tot.stock(ap1) + dmoes001.stck
tot.StockValue(ap1) = tot.StockValue(ap1) +
(dmoes001.stck*dmoes001.spri)
}
The function prototype in the declaration is not mandatory in this case because the function is
of type void and has no arguments.
functions:
function double incl_vat(double spri, double perc) Definition
{
double i | local variable
i = spri + (spri * (perc / 100))
return i
}
In the header, the function prototype is found, which, in this case, is mandatory. The function
has the following two arguments: spri and perc.
Under functions, the function definition is found. The function calculates the price, which
includes the VAT percentage. The result is stored in local variable i. Next, the i variable is
returned.
In the detail, the function is called. Table fields dmoes001.spri and dmoes012 are declared as
argument. These fields are substituted for spri and perc, respectively. The result of the
calculation (i) is stored in variable price.incl.vat. This variable can be printed in the report.
Debugger - Use
• Track errors
• Run program step by step
• “Trace” variables
To activate the debugger, compile the report with the Debugger option. The next time the
report is started, the Debugger window automatically appears on screen.
To print the report in the normal way again, the report must be compiled again in the normal
fashion, without the debugger.
Debugger - Options
[s] Step
[b] “linenr” Break at “linenr.”
[t] “var” Trace “var”
[stop if] “expr” Stop in case “expr”
[stop in] “func” Stop in “function”
[g] “linenr” Go to “linenr”
[j] “func” Jump to “function”
[c] Continue
[q] Quit debugger
A very important feature is tracing a variable. With this feature, you can follow a variable. The
command t <variable name> starts the trace. If command c (continue) is given next, the
program will jump to the first location where this variable changes its value. After this, you
can enter c again, and so on.
Another important feature is setting breakpoints (b). This enables step-wise execution of the
program.
Several more options are available. For an elaborate description, refer to the Help screen of the
debugger.