Professional Documents
Culture Documents
User Guide
Create reports to get relevant information out of your data
DataFlex Reports User Guide
Technical support:
Internet: http://www.dataaccess.com
Forums: http://support.dataaccess.com/forums
E-mail: support@dataaccess.eu
Please forward all your findings (suggestions, bugs in the documentation) to support@dataaccess.eu.
No part of this publication may be copied or distributed, transmitted, transcribed, stored in a retrieval system,
or translated into any human or computer language, in any form or by any means, electronic, mechanical,
magnetic, manual, or otherwise, or disclosed to third parties without the express written permission of Data
Access Corporation, Miami, Florida, USA.
DISCLAIMER
Data Access Corporation makes no representation or warranties express or implied, with respect to this
publication, or any Data Access Corporation product, including but not limited to warranties of merchantability
or fitness for any particular purpose.
Data Access Corporation reserves to itself the right to make changes, enhancements, revisions and alterations of
any kind to this publication or the product(s) it covers without obligation to notify any person, institution or
organization of such changes, enhancements, revisions and alterations.
TRADEMARKS
Windows Server 2008, Windows Server 2003, Windows 7, Windows Vista, Windows XP, Windows ME, Windows
2000 and Windows 98 are registered trademarks of Microsoft Corporation.
All other company, brand, and product names are registered trademarks or trademarks of their respective
holders.
Designed to be used by end-users, power-users and professional software developers alike, DataFlex Reports
works with a wide variety of ODBC datasources including – but not limited to – Microsoft SQL Server, IBM DB2,
Oracle, MySQL, Pervasive SQL, PostgreSQL, Microsoft Access, the DataFlex embedded database and more.
The use of ODBC as the datasource is strongly advised when reports are created for a DataFlex based
application that has its data stored in an SQL environment (such as in MS SQL Server) rather than using the INT
files found in the application’s data folder.
DataFlex Reports’ Report Creation Wizard steps users through the entire process of creating a report from
selecting datasources to grouping, filtering, summarizing and sorting information. The wizard displays the
completed report in a visual, drag & drop WYSIWYG interface. Ready to view the results on-screen, print or make
further formatting changes and enhancements. A full range of text formatting (fonts, bold, italics, justification,
etc.) is available in DataFlex Reports along with a rich library of string, logical and math functions.
DataFlex Reports is developed in DataFlex, the state-of-art software development tool from Data Access
Worldwide.
For DataFlex developers, DataFlex Reports offers both seamless integration with their DataFlex development
environment and seamless integration of reports in Windows and web applications. When the developer edition
of DataFlex Reports is installed you have the option to install a report integration wizard and library for
integration of reports with applications made in the DataFlex Studio. More information about this integration
can be found in the DataFlex Reports Developer Guide.
For deployment, reports integrated in DataFlex Windows and web applications require only the installation of a
single OCX. Distribution of integrated reports and the OCX is royalty-free with the Developer Edition of DataFlex
Reports.
Check the ‘Options’ from the ‘File’ menu and make sure that DataFlex Reports uses the defaults of your
preference. All possible options are covered in section 4.2 (Options). The second thing to do is to change the
language. For more information how to change the language read section 11 (The Language menu).
Before creating a new report it is important to decide what data needs to be shown and how the information
will be grouped.
Let’s suppose that the report needs to show order-information and that the orders must be presented in groups
of order-lines per order-number. The data needed for making this report would be:
Per order-line:
o product-number
o product-description
o quantity
o price
Per order:
o For the ‘order header’:
order-number
order-date
customer-name
customer-address
payment- and shipping-conditions
o For the ‘order footer’:
total order amount
Next, determine which tables are needed to show the necessary information. Typically for a report that needs to
show order-information, the order-header, order-details, products or inventory, and customer table are needed.
These tables need to be related to each other. The relationship looks like this:
Inventory
In which order must the data be presented? Will it be sorted by order-number? Or customer-number?
Must all orders be printed, or should it be possible to filter certain orders? What are the filtering criteria?
If a database field to be grouped on was already selected for the report, it can be found in both options. The
quickest way to select a field is to click on the ‘+’ symbol in front of the ‘Report Objects’ and click on the field.
When clicking the button with the ‘>‘ symbol in the center, the data will be grouped by that field.
The data in the report will be sorted in ascending order by default. In the bottom of the treeview on the right-
hand side, this can be changed. For each field that is grouped on, the sort order can be set to ascending or
descending.
The Group can easily be removed from the report by selecting it in the panel on the right-hand side and clicking
the button with the ‘<‘ symbol.
Select the field ‘OrderHea.Customer_Number’ and pick ‘is equal to’ from the operator dropdown box. Enter
‘1’ in the Value box. Click on ‘Next’ for the next wizard page.
The first combo box lets you select the page size
for the report. Selecting a correct size here helps
you in the further design of the report. The new
report wizard divides the selected fields over the
width of the paper, selecting the desired page size
will give a different reduction in width if more
fields are selected than can be presented on one
row.
Click the 'Next' button to go to the Finish page. Here you can close the wizard by clicking on the ‘Finish’
button.
Report Header
Page Header
Details
Report Footer
Page Footer
Group Header
Group Footer
A preview window can be opened to see what the result of the report will look like. Activating the preview
window can be done in several different ways:
Fields can be selected via a lasso. Hold the Shift key down
and drag with the mouse. Fields can also be moved by use
of the cursor keys on the keyboard. Resizing can be done
by keeping the Shift key pressed, while clicking a cursor
key. When multiple objects are selected with the lasso the order of selection depends on the order in the Report
Explorer.
The way the cursor keys react depends on the settings of the grid options. Read more about this in section 4.2
(Options).
Draw a ‘Text Object’ in the ‘Page Header’ section. Right click on the ‘Text Object’ and select ‘Edit text’ from
the popup menu. Type ‘Printed on’ into the box and click with the mouse outside the box. Move the Special
field ‘Print Date and Time’ from the ‘Report Header’ right after the text object.
In the ‘Group Header #2’ and ‘Group Footer #2’ separator lines are added. Select the line object in the
toolbar. The cursor changes into a pencil. Move the mouse to the position where the line should start and
drag the mouse, while pressing the left mouse button, to the position where the line should end.
If it is likely that multiple reports will be using the same tables, the use of the repository is recommended, see
the 6.3 (Repository explorer).
After clicking on ‘Next’ in the welcome page you can select the type of chart you want to
use in your report. The different chart types are explained in section 3.2 (Chart types).
3.1.1 Datasource
After selecting the chart type you must select
the datasource for the Category (X-axis) and
Value (Y-axis).
3.2.2 Bar
A bar chart displays data with rectangular "bars" with lengths relative to the data
they symbolize. Generally a bar chart is used to display discontinuous data (data
that has a discrete value); however it can also be used for continuous data.
Examples of discontinuous data would be "car color" or "tire size"; examples of
continuous data would be "population" or "age".
3.2.3 Line
A line chart is used to show a series of data points connected by straight line
segments. Charts of this type are generally used to illustrate trends in data over a
period of time.
At the left bottom corner you will find a button "Change datasource". This will start up the
chart wizard where you can change the chart type, datasource and the basic layout of the
chart.
3.3.1 Common
In this tab page you can change the chart type,
see section 3.2 for the different chart types
you can select.
To display a label displaying the value of each bar, point, etc. check the "Label visible" checkbox.
"Marker height" and "Marker width" define the size of the marker icon left of the legend text.
When the colors in this tab page are set to "Default", the colors defined in the Appearance scheme currently
selected are being used.
3.3.3 Titles
On the "Titles" tab page you can define some
extra text that will be displayed with the chart:
a title and a subtitle.
3.3.4 Category
The ‘Category’ tab defines options for the X-
Axis.
When the colors in this tab page are set to "Default", the colors defined in the Appearance scheme currently
selected are being used.
3.3.5 Value
The ‘Value’ tab defines options for the Y-Axis
and is similar to the Category tab above.
3.3.6 Lines
The ‘Lines’ tab contains options for the grid
lines in the chart area.
3.3.7 Scale
In the ‘Scale’ tab a number of options for the
display scale of the axes can be defined.
Use the option ‘Open…’ to open a report. The option opens a Windows
common file dialog from which you can select a DataFlex Reports
report file. The file extension is .dr for reports and .dpl for page
layers.
To close the active report or all reports, the options ‘Close’ and ‘Close
All’ are available.
The option ‘Lock report design’ requires the entry of a password. This
password must be entered every time the report is opened in DataFlex
Reports. Users can use such reports by integration with your DataFlex
application without the password.
Besides printing reports, it is possible to export report data to different file-formats such as PDF, RTF, CSV, Excel
and HTML or to an image file (JPG, GIF, TIF or PNG). This option is discussed in paragraph 4.1 below.
The ‘Options’ for DataFlex Reports are explained in section 4.2 below.
The 10 most recently used reports are shown in the menu above the ‘Exit’ option. Simply select one of the listed
reports to open it.
Exiting DataFlex Reports while one or more unsaved reports are still open will display a request to save all
changes.
4.1 Export
Reports can be exported to various formats.
This includes several formats aimed at human
reading (HTML, image, PDF, and RTF) and
some aimed at machine reading (CSV and
Excel).
1
Most image formats allow only a single page. TIFF has built-in support for multiple pages and DataFlex Reports
can use this.
A PDF document has limited control of how a PDF reading program will display the document by default. The
‘Page display’ options are:
Full screen
Display with outline
Display with thumbnails
Display without outline or thumbnails
PDF documents can also be secured using passwords. Setting an ‘Owner password’ makes sure that the
document cannot be manipulated without entering that password. Setting a ‘User password’ as well will require
readers to enter that password.
Many documents include images, which increases the file size a lot. In order to assure that PDF files are portable
images are compressed using an algorithm that drastically reduces the file’s size, but also reduces image quality.
You have a choice to increase the ‘Image quality’ setting from ‘Low’ to ‘High’, which results in better image
quality at the cost of a larger file size.
The ‘Field separator’ in most CSV files is the comma, but implementations using semicolons or pipe characters
are also commonplace. In addition, because this character can occur in character values, a ‘character delimiter’
is needed. Usually this is a double quote.
CSV files often represent a single grid of rows and columns. The special sections in a report (report, page, and
group headers and footers) cannot easily be identified, so software programs (as well as people) reading the file
will have difficulty parsing the data. By default these sections are not exported to a CSV format file, but you can
choose to export them anyway using the three checkboxes ‘Export report sections’, ‘Export page sections’, and
‘Export group sections’.
You can choose to put all data on a single worksheet, or to create one sheet for each page. Note that Excel
versions before 2010 have a maximum of 65,536 rows per worksheet.
By default the program attempts to export the file into a format that visually corresponds to the original report
(more or less). It uses the rows and columns of Excel as a drawing grid, which you can manipulate by changing
the ‘Column width’ setting. If you wish to export the report without any alignments and markup, the checkbox
‘Export data only’ allows you to do that.
In contrast to the CSV format Excel files have a lot of styling options, which makes report sections identifiable.
Therefore by default they are included in the export. If you do not want that, you can disable them.
4.2 Options
The window containing the default settings for DataFlex Reports consists of three tab pages: ‘Options’, ‘Fonts’
and 'Formatting'.
In the group "Datasource options" the setting of the ‘Show tables’, ‘Show views’ and ‘Show stored procedures’
decides whether to list SQL Tables, SQL Views and SQL stored procedures in the Database Expert and New
Report Wizard.
When the option "Show information messages" is ticked, the product will show you informational messages
from the ODBC backend or messages like "Cannot open file".
The option ‘Always Sort Locally’ applies to reports with ODBC as a datasource. For the DataFlex database records
are always sorted locally. To sort records from an ODBC datasource using the selected collation instead of the
collation used in the ODBC backend you can check this option.
5.4 Find
In large reports it can happen that an object becomes more
difficult to find. Use the ‘Find’ option to find an object. The
name attribute of the object is used for the search. If the
object is found, it will be selected and easily visually
identifiable as such.
5.5 Go to page
In the preview window, a quick way to go to a certain
page is by using the ‘Go to Page’ option.
5.6 Object
The last item on the menu shows "Object" or "Edit Text",
"Edit Function" or "Edit Parameter". When it shows
"Object" the menu item is unavailable and cannot be chosen. For "Edit Text", click on a text object (such as a
column label). For "Edit Function" click on a function object in the report and the function editor dialog will be
presented. This is documented in chapter 12. For "Edit Parameter" click on a parameter object in the report and
the parameter dialog will be presented. This is documented in chapter 14.
The ’Design’ and ‘Preview Report’ options switch between the design window and
the preview window.
If a window is opened, the active window can be closed using the ‘Close Current
View’ option. You can achieve the same result by clicking the 'X' in the report design
or preview tab-page.
The options for ‘Field Explorer’, ‘Report Explorer’, ‘Repository Explorer’ and ‘Arrange Objects’ are explained in
paragraphs below.
Clicking the option for the ‘Status Bar’ switches the status bar in
the bottom of the window to show, or not. The check-mark in
front of the option indicates that the status bar is activated.
Clicking the ‘+’ symbol for ‘Database Fields’ will expand the tree and
show the tables that are available for the report. Clicking on the ‘+’
symbol for a table will show the fields of that table. You can drag a field from the tree to the report.
Clicking the ‘+’ symbol for ‘Function Fields’ will expand the tree, and
show all the function fields for the report. After selecting ‘Function
Fields’ in the tree view, the button ‘Create new’ in the button bar at the
top of the panel is enabled. The ‘Delete’, ‘Edit’ and ‘Rename’ buttons are
enabled when a function field is selected. The same options are available
in the context menu, which can be activated by clicking the right mouse
button while a function field is selected. See more about function fields
in section 7.4 (Function field) and chapter 12 (Functions).
In the section named ‘Group Name Fields’, a field is listed for each group
in the report. See more about groups in section 10.6.
The section ‘Special Fields’ pertains to fields like report title, page number and print-date and -time. An
explanation of the special fields is listed in chapter 15 (Special Fields).
Add a field to a report as follows: activate the design window of the report and select the field to add. Drag the
field from the Field Explorer above the design window where the field needs to be placed, to drop it.
Remove a field from a report by selecting the field in the design window and pressing the Del key, or use the
context menu activated by a right mouse click, followed by choosing ‘Delete’.
The floating menus for 'Report Header', 'Page Header', 'Details', 'Report
Footer' and 'Page Footer' offer the same options. The floating menus for
'Group Header' and 'Group Footer' also contain the same options.
The following table explains all the options of the floating menu for the
report node.
Function Description
Refresh Report Data The datasource behind the report is requested to deliver the data again. You
need to confirm the action.
Performance Information Opens the report performance dialog, see 10.10 (Performance information).
Report Options Opens the report options dialog, see 10.12 (Report options).
Report Document Properties Opens the report document properties dialog, see 10.11 (Report document
properties).
The following table explains all the options of the floating menu for the
details section.
Function Description
Group Expert Opens the group expert dialog, see 10.6 (Group expert).
Delete Group Delete this group from the report.
Hide Section Toggling the option to hide or show a section.
Section Expert Start the Section Expert, see 10.4 (Section expert).
Fit Section Changing the size of a section, automatically removing white-space in the
bottom of a section.
Insert Section Below Insert a new section and place it below an existing section.
Select All Section Objects Select all objects in a section. (For example to move, or Delete all at once).
The following table explains all the options of the floating menu for the
details section.
Function Description
Hide Section Toggling the option to hide or show a section.
Section Expert Start the Section Expert, see 10.4 (Section expert).
Fit Section Changing the size of a section, automatically removing white-space in the
bottom of a section.
Insert Section Below Insert a new section and place it below an existing section.
Select All Section Objects Select all objects in a section. (For example to move, or Delete all at once).
The available options of the menu are explained in the following table.
The screenshot below shows the information you get when you click the
properties button in the Repository Explorer’s toolbar. You can see the name
of the repository, the tables used, the database name, connection string, if applicable the schema name and
number of relationships.
Note when you use the lasso to select multiple objects, the base object is the first selected object in the report
explorer.
Except for the first option each choice is also available via a comparable button that can be
chosen from the insert button bar.
See paragraph 4.2.1 for the default setting to automatically place a text object with caption in the 'Page Header'
section when a database field is added to the report.
7.2 Summary
First select a field that needs to be summarized. Then choose ‘Sum’
from the ‘Insert’ menu. If we choose this for the field ‘qty_ordered’
from the orderdtl table we will see the dialog on the right.
Function Description
Sum Sums the values of the field (only works on numeric fields).
Average Show the average value of the field (only works on numeric fields).
Maximum Show the maximum value of the field (only works on numeric fields).
Minimum Show the minimum value of the field (only works on numeric fields).
Count Count the number of times that a certain value occurs.
Distinct Count Count the distinct number of times a value occurs (only works on numeric
fields).
You can select where the 'Sum' field is placed. This is normally either a 'Group Footer' or a 'Report Footer'. All
possible locations are shown.
If your report does not contain a group – see next paragraph – and you would like to place the summary in a
group you can immediately create the group by clicking the 'Insert Group' button.
The First combo box is used to select the field on which the grouping
takes place. The second combo box defines the sorting-order (ascending
or descending).
The ‘Group Name Field’ has per default the same value as the field upon
which the grouping takes place. Suppose that the Group is defined as on
customer number, but the ‘Group Name Field’ needs to be the customer
name this can be changed by checking the checkbox ‘Customize Group
Name Field’ to change it to the appropriate field.
Select ‘Function Field’ from the ‘Insert' menu and move the mouse cursor to the place in the report where the
function field needs to be placed. Press the left mouse button down while dragging, to resize the object as
appropriate.
There is a tree view for selecting available fields (from report or database), one for selecting a specific type of
manipulation (expression or statement) and one for selecting functions.
If a function does not return a value (the 'return' statement is not present), the value returned from the function
is undetermined.
Example: If we want a function that returns the first 10 characters from the name of a customer we have to do
the following:
Double-click the ‘Return’ expression in the middle tree view. While not shown here the editor part
will contain "return" after this.
Check the function by clicking the function-check button in the tool-bar of the function editor
window. If no error occurs, the syntax of the function is correct and you can click the OK button to
store the function in the report.
For adding a picture in a report, first select the picture, then move it to the place in the report and release it in
the report by clicking the left mouse button. By default the picture will have the same aspect ratio as the
original, and it can now be resized using the mouse.
Images which are stored in a database can also be added. For this, the field which contains the images has to be
added to the report.
A sub-report can either be linked, or not be linked to the main report. If the reports are not linked, the
information is not related, data from one report is not filtered by reference to the data presented in the other
report.
It is possible to link reports by using global variables in the filter functions and function fields. The following
example shows a main report with order-header information, linked to a sub-report showing order-details.
Create a new report based on the table with order-header data and Group the data on order-number.
Create a second Detail section, the report now shows ‘Details-A’ and ‘Details-B’
Add a ‘Function field’ to the ‘Details - A’ section. The function will define a global variable named
“iOrder” that gets the value of the current order-number:
Open the sub-report by double clicking it. Add the following 'Filter Function':
Defining the global variable iOrder in the filter function is optional here, because it is already defined in the
main report, but it is good practice to leave it in for documentation purposes. The filter process will now
only use those order-detail records that belong to the current order record that was set in the main report.
8.1 Font
The menu option 'Font' contains a sub-menu in which you can choose to make the field's
font bold, italic or underlined or to increase or decrease the font size. All five options also
have a button in the tool-bar to accomplish the same goal.
8.4.1 Common
The first input field allows the name of
the object to be changed. The name of
the object does not need to be unique.
If the object refers to a function the
name of the function and the name of
the object might be different and it is
up to you to decide whether you want
to keep them in sync or not.
By checking the checkbox ‘Suppress’, the object can be hidden in the report. Suppression can be conditionally
realized by using a function. Click the button on the right-side and enter a function. An example of a function on
how to suppress a field:
if ({OrderDtl.Qty_Ordered} = 0) then
return true
else
return false
end
Checking the ‘Lock Position and Size’ option locks the object so that size and location cannot be changed until
the object is unlocked again.
8.4.2 HTML
The ‘HTML’ tab page contains options that are specific for HTML output of reports.
‘Hyperlink id’ is meant for integration. Setting this value will create a DIV element when HTML output is chosen.
For further information on integration refer to the ‘DataFlex Reports Developer Guide’.
8.4.3 Border
On the ‘Border’ tab page the settings of
the object border can be changed. This
tab page is not available for all objects.
None (drBorderNone)
Single (drBorderSingle)
Double (drBorderDouble)
Dashed (drBorderDashed)
Dotted (drBorderDotted)
Pick one of the predefined colors from the drop-down or select a custom color from the RGB color range to set
the color of the borders.
Setting the color can also be done by using a function. Click the button to add a function.
Solid (drSolidGradient)
Horizontal (drHorizontalGradient)
Vertical (drVerticalGradient)
Setting the gradient style can also be done by using a function. Click the button to add a function.
Pick one of the predefined colors from the drop-down or select a custom color from the RGB color range to set
the color of the background. When the background-style is set to ‘Solid’ only the primary color is used. When a
gradient is selected the ‘End color’ defines the color on the right or bottom of the gradient. Setting the colors
can also be done by using a function. See the example above.
The font, the size and the color of the font can
be defined conditionally by using a function.
Note: make sure the named font is available on your development and/or the deployment machine.
For the styles, checkboxes can be used to display the font as ‘Bold’, ‘Italic’, ‘Underline’, and/or ‘Strikethrough’.
These setting can be conditionally defined by using a function as well.
return 90
Checking the checkbox ‘Variable Height’ will allow the field to automatically grow in height, if the content of the
field in the report will be larger than the original size of the object. This setting can be conditionally defined by
using a function. Such a function should return false or true.
Checking the checkbox 'Rich Text Format (RTF)' tells the system that the data contains RTF instructions that need
to be converted from RTF to formatting. This setting can be conditionally defined by using a function. Such a
function should return false or true.
Checking the checkbox 'RTL (right-to-left) Text' is meant for languages where writing starts at the right hand side
and continues to the left (reversed writing when compared to Western languages). Do not turn on this checkbox
if your data and fonts are not ready for it.
The ‘Custom’ option allows for several date settings. Depending on the settings, a ‘Date Mask’ of the object can
be set. The Date Mask determines how the date will be represented and can be designed manually or
conditionally by using a function.
The next table explains which codes can be used in a Date Mask.:
Code Representation
d The number of the day: 1 – 31
dd The number of the day, 2-digits: 01-31
ddd Abbreviated name of the day: Sat - Sun
dddd The full name of the day: Saturday - Sunday
M The number of the month: 1-12
MM The number of the month, 2-digits : 01-12
MMM Abbreviated name of the month: Dec – Jan
MMMM The full name of the month: December – January
yy The year, 2-digits: 00-99
yyyy The year, 4-digits: 0000-9999
g Period/era string, usually A.D.
For example, to get the date string "Wed, Aug 31 94", a "ddd',' MMM dd yy" mask should be used. Be aware that
the string values, like ‘ddd’, are returned in the user’s locale.
Return ({User.TimeFormat})
The ‘Custom’ option allows for several date settings. Depending on the settings, a ‘Time Mask’ of the object can
be set. The Time Mask determines how the date will be represented and can be designed manually or
conditionally by using a function.
The next table explains which codes can be used in a Time Mask.:
The mask can also be set using a function. An example of such a function is:
If ‘Suppress if Zero’ is checked DataFlex Reports will not print the number when the number equals zero, this can
also be set using a function.
Solid (drLineSolid)
Dash (drLineDash)
Dot (drLineDot)
Dash Dot (drLineDashDot)
Dash Dot Dot (drLineDashDotDot)
None (drLineNone)
if (gbImportant) then
return 1
else
return 4
end
You can select the line width from the second combo-form that shows a range from 1 to 3.5 points. The values
returned by a function are in twips, 15 twips equals 1 point, so a 1 point line requires a return value of 15.
In the color combo-form you can select a color for the line. The color can also be set from a function returning a
constant, a color number or the result of an RGB(R,G,B) function call.
Finally you can set the variable height of a line to true via the checkbox. This is active for vertical lines and made
effective if the section containing this line grows in height because of a variable height text field.
Solid (drSolidGradient)
Horizontal
(drHorizontalGradient)
Vertical (drVerticalGradient)
Setting the gradient style can also be done by using a function. Click the button to add a function.
Pick one of the predefined colors from the drop-down or select a custom color from the RGB color range to set
the color of the background. When the background-style is set to a gradient using the combo box or by a
function the ‘End color’ will be enabled. Setting the colors can also be done by using a function. See the example
above.
The ‘height’ and ‘width’ input boxes can be used to specify the exact dimensions of the image in pixels. The
‘horizontal scale’ and ‘vertical scale’ fields are useful for resizing an image by specific percentages.
8.5 Move
The ‘Move ‘ option supports ‘Forward’, ‘To Front’, ‘Backward’ and ‘To Back’. It is meant for arranging objects,
deciding which one is on top, or in the background (i.e. behind others).
Suppose that there are three objects in a report that are overlapping: A
text object, a box and a picture. If the picture is the last object that was
added to the report, it will end up on top, covering the other objects.
This is probably an unwanted situation.
In this situation the image object would cover the text and box objects.
To let the picture object to go to the back, first click on the picture
object and then choose the ‘To Back’ option in the ‘Move’ menu. The
report explorer’s tree view will then look as follows:
Next, the box needs to go behind the text object. Select the box object
and click ‘Backward’ in the ‘Move’ menu. The tree view will now appear
as shown on the right.
As a result, the picture will be placed, then the box on top of it, and finally the text.
To move objects in the other direction (to the top) the options ‘Forward’ and ‘To Front’ are available.
8.6 Align
Aligning multiple objects can be done thru the Align pulldown menu. The starting point of
the alignment is the first selected object.
Tops, Middles Bottoms, Left, Centers and Rights will align the selected objects at the same
corresponding value of the first selected object.
Baseline aligns the baselines of the objects at the baseline of the first selected object. A
baseline is the imaginary line under the text.
'Top to Bottom' spreads the selected objects over the height of the section, 'Left to Right'
will spread the objects over the width of the section.
Note when you use the lasso to select multiple objects the starting point is the first selected object in the report
explorer.
8.7 Size
When one or more fields are selected there are several options to manipulate the size. ‘Size to font’ changes the
size of each selected field to match the height of the font and the expected width of the field. ‘Size to section
height’ adjusts the position and height, so that each field covers the entire height of the section.
When multiple fields are selected they can easily be made the ‘same width’, ‘same height’, or both (using ‘same
size’).
Note that these options are unavailable when one of the selected objects has a locked position and size.
If you click the Find button ( )the name of a table can be entered and DataFlex Reports will try to find that
table in the tree with available datasources. The Find Next button ( ) can be used to find the next table with
the entered name. You can enter a full or a partial name (like ‘inv’ for ‘inventory’).
The tree view for the datasources consists of five elements: Current, DataFlex, ODBC, Runtime Datasource and
Repository.
DataFlex
Select ‘DataFlex’ in the left tree
view and click the ‘Open database’
button, or double-click the
‘DataFlex’ text to add a DataFlex
table as a datasource.
Another option to using the filelist.cfg for opening tables is by opening a table directly or using a VDF
workspace. When using a VDF workspace (either a .sws or .ws file), the filelist accociated with the workspace is
automatically opened and DataFlex Reports uses the same search path as specified in the workspace file. When
opening tables directly both .dat and .int type files can be used.
ODBC
All databases, for which an ODBC driver is
available, can be used as a datasource for
DataFlex Reports. ODBC is short for Open
DataBase Connectivity and it’s a universal
way to access all sorts of databases. In order
to access a database via ODBC, the
appropriate driver needs to be installed.
Type Description
User The user DSN is stored in the Windows registry and is only accessible for a specific user.
System The system DSN is stored in the Windows registry and is available for all users on the
computer.
If, for some reason, a DSN is not used, a Connection String can be used to connect to a datasource. An example
of a connection string: SERVER=(local);DRIVER=SQL Server;DATABASE=001;UID=sa. The connection string may be
different for each database driver. Refer to the documentation for your environment or attempt to find out the
right syntax via the ODBC Datasource manager.
Parameters can also be set and retrieved from functions – like the filter
function – using the ‘{?ParamName}’ format where ‘ParamName’ is the
name of a input Parameter. For example, to set the value of a parameter in a filter function, use the following
code.
After selecting the database (root) item, all tables can be removed at once by clicking the button with the double
arrows pointing left.
When you remove table(s) from the report you will get a question whether you really want to do this when the
report uses fields from the table. If you confirm the question the objects using the fields will be removed. The
designer will not enumerate all your functions and remove the database references. This means you must check
the functions in the report and change the references to the table(s) removed from the report.
9.1.3 Relationships
To use multiple tables in a report,
relationships must be defined between
those tables. In most cases the relationship
between two tables is based on two
common fields pointing from the field in
one table to the field in the other table.
Sometimes a relationship between tables
requires multiple fields, which is supported
by DataFlex Reports. The example on the
right shows the relationship from the
‘Customer’ table to the ‘Orderhea’ table.
A relationship is created by selecting the common field in the main file, and dragging the mouse while keeping
the left mouse button suppressed, towards the common field in the other, related table.
Relationships can only be made between two tables if the common fields are of the same type and length.
Clicking with the right mouse button on a field, offers the ‘Show Field Types’ option, showing the data-type and
field length.
For DataFlex tables the link to field needs to have a unique index.
The following table offers the options for the ‘Table Links’ buttons at the right hand side of the dialog.
Function Description
Auto Link Automatically create relationships
Auto Size Automatically create the size of table panel
Auto Arrange Automatically arrange tables
Minimize Tables Minimize the table panel
Delete All Links Remove all the table links
Delete Selected Link Remove the selected link
Edit Link Properties Edit the properties of the selected link
By clicking on the line between two tables (the relationship) with the right mouse button shows the context
menu. Selecting the ‘Link Options’ choice or the button for the ‘Edit the link properties’ shows the panel for
changing the specific properties of the relationship.
Join type
The table below explains what the results are when the
different ‘Join Types’ of the relationships are used for the example of the customer and orders table. Fields from
the customer table as well as the orders table are used in the report, which is relevant because a relationship to
or from a table is ignored if no fields from that table are used in the report.
Enforce join
For reports that use an ODBC datasource, a SQL statement is prepared for fetching the data set. The table below
explains the influence of ‘Enforce Join’ on the SQL query.
Link type
The table below explains each ‘Link Type’.
When you change the structure of one or more tables after the report creation you should use the option Check
database to get the report lined up with the table structure again. If you do not do this errors can be reported or
wrong information can be printed.
This option also needs to be chosen if you want to change the definition (number of columns, column names,
column types) of an RDS datasource.
The length of the field "SalesPerson_ID" has been changed from 4 to 5 characters.
The field "Order_Total" does not exist anymore.
A new field named "Processed" has been added with a length of 1 character.
When the database is the DataFlex database but individual tables are selected the location of each of the tables
and/or the connection string can be changed.
When the database is an ODBC datasource you can change the datasource to be used and/or the connection
string used. If the current tree view item points at a table you can view the information but not alter it.
If this option is selected, a check-mark shows in the appropriate item of the ‘Database’ menu.
For more complex filters, filter functions can be defined manually. See paragraph 10.2 below.
Adding a filter starts with selecting a database field in the available fields tree view. The tree view shows two
top-levels: ‘Report fields’ showing the fields that are used in the report and ‘Database fields’ showing all tables
and fields.
Click on the ‘Browse Data’ button in the button bar at the top of the tree view, to inspect the content of a
selected field.
By clicking the ‘Find Field’ button a fieldname can be found. This is particularly useful if the tree view contains
many entries.
After selecting a database field a filter can be added, by clicking the button with the single arrow, pointing to the
right.
Removing a filter is done in a similar fashion. Select the filter and click the button with the single arrow pointing
to the left to remove the filter.
A filter can be added by selecting the type from the combo box, for instance: ‘is greater than’. Next, the value
can be entered in the entry form, for example ‘1000’, or by selecting a value from a selection list, by clicking the
prompt button.
Note: for DataFlex datasources, only filters on the left-most table can be optimized.
Example of a filter
function:
In this example, only records are selected that contain item ID’s starting with ‘ACE’.
Note: filters defined using the ‘Filter-Expert’ and ‘Filter-Function’ are both used when selecting records.
Section Description
Report Header The part of the report that is printed as the very first element
Page Header Printed at the beginning of each page
Group Header Printed at the beginning of each group
Details Printed for each record
Group Footer Printed at the end of each group
Report Footer Printed at the very end of the report
Page Footer Printed at the end of each page
The Section Expert is for changing settings, as well as adding new sections. The original sections cannot be
removed, though they can be hidden.
The sections of a report are shown in the available sections tree view. The button bar at the top of the panel is
for adding, merging or removing sections. At the right-hand side of the panel, options available for the selected
section are shown. For each option that supports conditionally switching the option on or off a button is
available.
Most options are self-explanatory. The 'Filler section' is available only for detail sections and can be used to fill
up the space between the last printed detail line and the group or page footer for example to draw vertical lines.
10.4.2 Sections
In some cases it makes sense to split up one section into multiple sections.
The image below shows a report with customer details split in ‘Details A’ showing data unconditionally, and
‘Details B’ showing details conditionally. The option ‘Hide this section' for the ‘Details B’ section is set by a
function to suppress that section in case the field is empty.
Another practical use of splitting sections is for supporting language dependencies. An extra section for each
language can be added. A section can then be suppressed or shown depending on a variable that indicates which
language should be used. Here is an example of a function for hiding a section based on a language code:
10.4.3 Options
The several settings of each section can be toggled by selecting the appropriate checkbox. It can be toggled
conditionally, based on a function as well. Check the appropriate checkbox and click the ‘Function’ button,
followed by entering the function.
The background color of a section can be set by choosing the preferred color in the combo box.
As mentioned before, functions are powerful. For example we can color each other row in the report output
through the results of a function. Use the following steps to create a report with output like:
Select the details section in the available sections tree view and click on function button of the background color.
Enter the following function, close the dialog and – if needed – refresh the report.
With the Function Explorer users can navigate easily through all the
functions in a report. The functions are displayed per report section.
Both user defined as well as built-in functions are displayed.
The filter button can be used to hide sections without functions.
Adding a group starts with selecting a database or function field in the available fields tree view. The tree view
shows three top-levels: ‘Report fields’ showing the database fields that are used in the report, ‘Function Fields’
showing the function fields defined in the report and ‘Database fields’ showing all tables and fields.
Click on the ‘Browse Data’ button in the button bar at the top of the tree view, to inspect the content of a
selected field.
By clicking the ‘Find Field’ button a fieldname can be found. This is particularly useful if the tree view contains
many entries.
After selecting a database or function field a Group can be added to the report by clicking the button with the
single arrow pointing to the right.
Removing a group works in a similar fashion; select the Group and then click the button with the single arrow
pointing to the left. Note that fields placed in the group header or footer will be removed from the report.
An additional group is placed under the already existing groups. The order in which the groups appear can be
changed by selecting a group and then clicking the ‘Up’ or ’Down’ button.
If a group is selected, clicking the ‘Properties’ button shows the panel for the settings for that Group:
The combo box ‘Sort order’ is for setting the sort order to ascending or descending.
The default value of the ‘Group Name field’ is the same as the value of the field on which grouping takes
place; it can be set to any other field by selecting that field in the corresponding combo box.
By checking the checkbox ‘Repeat Group Header On Each Page’ the ‘Group Header’ section is repeated on
each page of the report.
Click on the ‘Browse Data’ button in the button bar at the top of the tree view, to inspect the content of a
selected field.
By clicking the ‘Find Field’ button a fieldname can be found. This is particularly useful if the tree view contains
many entries.
After selecting a database or function field, a new sort order can be added by clicking the button with the single
arrow pointing to the right.
Remove a sort order by selecting it and clicking on the button with the single arrow pointing left.
A new sort order is placed under already existing sort orders. The order of each can be changed by selecting it
and clicking the ‘Up’ or ‘Down’ button.
The combo box in the button bar at the top of the right-panel is for setting the sort order of each sorting field (to
ascending or descending).
Note that a group sort executes before a record sort which means that the record sort is always within a group
(if present).
The combo box ‘Group sort type’ is for setting the sorting type to: ‘None’, ‘All’, ‘Top N’, ‘Bottom N’, ‘Top N
percent’ or ‘Bottom N percent’. For the last four types the entry form ‘Where N is’ is enabled for entering the
value of ‘N’. For sorting type ‘All’ the combo box ‘Group sort order’ is enabled for selecting an ascending or
descending ordering.
The combo box ‘Sum to sort on’ is for selecting the sum field to sort on.
Check the option ‘Include ties’ to accommodate groups whose summarized values are equal. The example below
explains what the results are when the ‘Include ties’ option is checked for sort type ‘Top N’ and N = 3.
Sum value Option ‘Include ties’ not selected Option ‘Include ties’ selected
1000 √ √
750 √ √
500 √ √
500 - √
500 - √
250 - -
By checking the option ‘Include ties’, not three but five groups are selected.
To print pages from different trays, such as printing the Report header and footer on a different paper type or
color, use a result from a function.
It is possible to include a custom ANSI collation sequence in the report. This is loaded from a file and saved
within the report file. The custom collation sequence allows sorting based on character weight and includes the
code page for which the collation was created. See chapter 17 (ANSI collation sequences) for more information.
‘Always Sort Locally’ is only for reports using an ODBC datasource and is set to its default values as defined in the
global settings of DataFlex Reports, see paragraph 4.2.1.
Checking the checkbox ‘Suppress Printing If No Records’ avoids an empty page, showing just a header and footer
when no records were selected for the report.
The checkbox ‘Select Distinct Records’ is only for reports using an ODBC datasource. It forces a repeating
combination of certain values to be only shown once in a report. This setting can also be defined directly from
the ‘Database’ menu, see paragraph 9.7.
When the option ‘Add Ellipsis’ is set, DataFlex Reports will add ‘…’ before the last number in a numeric object
when the number exceeds the width of the object.
The name of these options may differ in various versions of Windows. After changing the Windows Regional
Options you can change the language in DataFlex Reports by choosing a language from the ‘Language’ menu.
Note: if a function does not return a value (the 'return' statement is not present), the value returned from the
function is undetermined.
12.1 Syntax
When writing functions you need to comply with the syntax rules in this section.
Rule Example
Text must be between single or double quotation-
"Ok"
marks. //or
'Ok'
Expressions
Statements
Constants
return (-{OrderHea.Order_Total})
Let iNum = 10
12.2.2 Statements
The function language has the following statements defined.
Let
For assigning a value to a variable, where the value can be a constant, a database field or an expression.
It is not necessary to declare the variable first, the type of variable is automatically determined based on the
content. The variable name must start with a letter, followed by a number of alpha-numeric characters
(including an underscore ‘_’).
let x = {OrderHea.Order_Total}
let y = 0.75
let z = (y * x)
In the above example, variable ‘x’ gets the value of the order amount (database field). The variable ‘y’ is a
constant (value 0.75) and variable ‘z’ is the outcome of the multiplication of 0.75 times the order amount
(expression).
If then end
For conditional execution of statements.
The result in this example is 300 if the Total order amount is higher than the order limit of the customer.
The result in this example is an exclamation point (‘!’) if the Total order amount is higher than the order limit of
the customer. Otherwise the result is a check-mark (‘v’).
The above example illustrates that it is possible to nest statements. The result is green for an amount higher
than 0, red for an amount less than 0 and black for equal to 0.
Note: for rgb color-codes, constants drRed, drGreen and drBlack can be used.
Return
Ends the function and sets the result for the function.
In the above example the result is the differential between the total amount of purchases of the customer and
the balance.
While do end
This command group can be used to execute a loop.
The example below tests if a variable consists only of numbers. The characters are tested one by one. If a
character is found that is not a number, the loop is exited.
Note: The while loop automatically terminates when it iterates for more than 1000 times in order to avoid
infinite recursion, which causes the program to become unresponsive.
if (stop = 0) then
return "variable consists only of numbers"
else
return "variable does not only consist of numbers"
end
Dim
This command declares a variable. The variable only exists inside the function. Declaring a variable is optional.
The ‘Let’ statement automatically declares a variable before assigning a value to it. The variable name must start
with a letter, followed by any number of alphanumeric characters, including the underscore (‘_’).
dim nAmt
let nAmt = ({OrderDtl.Extended_Price} * 0.75)
return nAmt
Dim as global
This command declares a global variable. Global variables are persistent throughout the report. The name of the
variable must start with a letter, followed by any number of alpha-numeric characters, including an underscore.
12.2.3 Constants
This part of the language elements shows which constants are defined and accepted in functions.
Category Values
Boolean True
False
String functions
Conversion functions
Date and Time functions
Arithmetic functions
Miscellaneous functions
Database functions
Trim
Returns a string with leading and trailing spaces removed.
Syntax:
trim(str)
Argument Description
str Required. Any valid string expression from which the spaces will be
removed.
Returns: String
Notes: When str cannot be converted to a string, a runtime error is generated.
Sample:
let sTest = " Hello World "
Syntax:
ltrim(str)
Argument Description
str Required. Any valid string expression from which the leading spaces
will be removed.
Returns: String
Notes: When str cannot be converted to a string, a runtime error is generated.
Sample:
let sTest = " Hello World "
Syntax:
rtrim(str)
Argument Description
str Required. Any valid string expression from which the trailing spaces
will be removed.
Returns: String
Notes: When str cannot be converted to a string, a runtime error is generated.
Sample:
let sTest = " Hello World "
Syntax:
left(str, int)
Argument Description
str Required. Any valid string expression from which the specified
number of characters are returned.
int Required. Any valid integer expression. The number of characters
returned.
Returns: String
Notes: When str or int cannot be converted to the specified type a runtime error is generated.
If int is 0, an empty string ("") is returned. If greater than or equal to the number of
characters in str, the entire string is returned.
Sample:
let sTest = "Hello World"
return left(sTest,5) // returns "Hello"
Syntax:
right(str, int)
Argument Description
str Required. Any valid string expression from which the specified
number of characters are returned.
int Required. Any valid integer expression. The number of characters
returned.
Returns: String
Notes: When str or int cannot be converted to the specified type a runtime error is generated.
If int is 0, an empty string ("") is returned. If greater than or equal to the number of
characters in str, the entire string is returned.
Sample:
let sTest = "Hello World"
return right(sTest,5) // returns "World"
Syntax:
mid(str, int1 [, int2])
Argument Description
str Required. Any valid string expression from which the specified
number of characters are returned.
int1 Required. Any valid integer expression. Starting position of the
characters in str to return. int1 is one based.
int2 Optional. Any valid integer expression. Number of characters to
return.
Returns: String
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
If int1 is greater than the number of characters in str, the function returns an empty
string ("").
If int2 is omitted or if greater than or equal to the number of characters in str from
int1, the entire string from the start position is returned.
Sample:
let sTest = "Mid Function Demo"
let sRet1 = mid(sTest, 1, 3) // = "Mid"
let sRet2 = mid(sTest, 14) // = "Demo"
let sRet3 = mid(sTest, 5, 8) // = "Function"
Syntax:
ucase(str)
Argument Description
str Required. Any valid string expression which will be converted to
uppercase.
Returns: String
Notes: When str cannot be converted to a string, a runtime error is generated.
Sample:
let sTest = "Hello World"
Syntax:
lcase(str)
Argument Description
str Required. Any valid string expression which will be converted to
lowercase.
Returns: String
Notes: When str cannot be converted to a string, a runtime error is generated.
Sample:
let sTest = "Hello World"
Syntax:
len(str)
Argument Description
str Required. Any valid string expression.
Returns: Integer
Notes: When str cannot be converted to a string, a runtime error is generated.
Sample:
let sTest = "Hello World"
Syntax:
instr(str1, str2 [,int [,bool]])
Argument Description
str1 Required. Any valid string expression. The string being searched.
str2 Required. Any valid string expression containing the search string.
int Optional. Any valid integer expression containing the starting position
of the search.
bool Optional. Any valid Boolean expression indicating if the search is case
insensitive.
Returns: Integer
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
If int is omitted the search will begin with the first character.
If bool is omitted the search will be case-sensitive.
If str2 is not found the function returns 0.
Sample:
let iPos = instr("AbraCadaBra", "b")
return iPos // returns 2
Syntax:
instrrev(str1, str2 [,int [,bool]])
Argument Description
str1 Required. Any valid string expression. The string being searched.
str2 Required. Any valid string expression containing the search string.
int Optional. Any valid integer expression containing the starting position
of the search.
bool Optional. Any valid Boolean expression indicating if the search is case
insensitive.
Returns: Integer
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
If int is omitted the search will begin with the first character.
If bool is omitted the search will be case-sensitive.
If str2 is not found the function returns 0.
Sample:
//Example case sensitive search:
let iPos = instrrev("AbraCadaBra","A",5)
return iPos // returns 1
Syntax:
replace(str1, str2, str3 [,bool])
Argument Description
str1 Required. Any valid string expression. The string in which the string
will be replaced.
str2 Required. Any valid string expression containing the search string.
str3 Optional. Any valid string expression containing the string which will
replace all occurrences of str2 in str1.
bool Optional. Any valid Boolean expression indicating if the search is case
insensitive.
Returns: String
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
If bool is omitted the search will be case-sensitive.
Sample:
//Example case sensitive replace:
let sTest = replace("ABC123abc", "abc", "def" )
return sTest // returns "ABC123def"
Syntax:
asc(str)
Argument Description
str Required. Any valid string expression.
Returns: Integer
Notes: When str cannot be converted to a string, a runtime error is generated.
Sample:
return asc("a") // returns 97
Syntax:
chr(int)
Argument Description
int Required. Any valid integer expression containing the ANSI character
code.
Returns: String
Notes: When int cannot be converted to an integer, a runtime error is generated.
The range of int is between 0 and 255. Control characters (< 32) are allowed.
Sample:
return Chr(97) // returns "a"
Syntax:
strcomp(str1, str2 [,bool])
Argument Description
str1 Required. Any valid string expression.
str2 Required. Any valid string expression.
bool Optional. Any valid Boolean expression indicating if the compare is
case insensitive.
Returns: Integer
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
If bool is omitted the search will be case-sensitive.
Sample:
//Example case sensitive compare:
let sStr1 = "ABCD"
let sStr2 = "abcd"
Syntax:
strreverse(str)
Argument Description
str Required. Any valid string expression.
Returns: String
Notes: When str cannot be converted to a string, a runtime error is generated.
Sample:
let sTest = "Hello World"
return strreverse({customer.name})
// when in above the customer name is "True Value & Tool Comp"
// the result is: "pmoC looT & eulaV eurT"
Syntax:
string(int, str)
Argument Description
int Required. Any valid integer expression. The number of characters
returned.
str Required. Any valid string expression. You can use a number that
corresponds with an ASCII character.
Returns: String
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
Sample:
return string(5, 42) // returns "*****"
return string(4, "a") // returns "aaaa"
return string(3, " sample ") // returns " sample sample sample "
Syntax:
space(int)
Argument Description
int Required. Any valid integer expression. The number of spaces
returned.
Returns: String
Notes: When int cannot be converted to the specified type a runtime error is generated.
The value of int needs to be between 1 and 256. Above or below you will get a runtime
error.
Sample:
return ("Hello" + Space(3) + "World") // returns "Hello World"
Syntax:
propercase(str1 [,str2])
Argument Description
str1 Required. Any valid integer expression.
str2 Optional. Overrides the default behavior of capitalizing the first alpha
character after each space.
The first alpha character in string is capitalized when a non-alpha
character is found that matches a non-alpha character in override
string.
When the override string contains an upper case alpha character all
corresponding characters in string will be upper cased.
If in override string a lower case alpha character is used all
corresponding characters in string will be lower cased.
Returns: String
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
Sample:
return ProperCase("JOHN DOE") // returns "John Doe"
Syntax:
numbertoroman(int)
Argument Description
int Required. Any integer expression. The value to be converted to a
Roman presentation.
Returns: String
Notes: Roman numbers have a range from 1 to 3999, when passing a number greater than
3999 a runtime error is generated.
Sample:
return NumberToRoman(459) // returns CDLIX
CInt
Returns an expression converted to an integer.
Syntax:
cint(exp)
Argument Description
exp Required. Any valid expression.
Returns: Integer
Notes: CInt rounds expressions. When the fractional part is exactly 0.5, CInt always rounds to
the nearest even number.
CInt uses the locale settings to convert expression to integer.
When exp cannot be converted to an integer, a runtime error is generated.
Sample:
let nTest = 2345.6789
Syntax:
cbool(exp)
Argument Description
exp Required. Any valid expression.
Returns: Boolean
Notes: If exp evaluates to zero, CBool returns false (0); otherwise CBool returns true (-1).
When exp cannot be converted to a Boolean, a runtime error is generated.
Sample:
let A = 4
let B = 5
return cbool(A = B)
Syntax:
cbyte(exp)
Argument Description
exp Required. Any valid expression.
Returns: Byte
Notes: CByte rounds expressions. When the fractional part is exactly 0.5, CByte always rounds
to the nearest even number.
CByte uses the locale settings to convert exp to byte.
When exp cannot be converted to a byte (0-255), a runtime error is generated.
Sample:
let nTest = 125.5678
Syntax:
ccur(exp)
Argument Description
exp Required. Any valid expression.
Returns: Currency
Notes: CCur rounds expressions to four decimals and uses the locale setting for decimal and
thousand separators.
When exp cannot be converted to a Currency, a runtime error is generated.
Sample:
let nTest = 125.5678
Syntax:
cdate(exp)
Argument Description
exp Required. Any valid expression.
Returns: DateTime
Notes: CDate uses the locale settings to convert expression to date.
When exp cannot be converted to a date, a runtime error is generated.
Sample:
let sTest = "February 10 2010"
return cdate(sTest)
Syntax:
cdbl(exp)
Argument Description
exp Required. Any valid expression.
Returns: Double
Notes: CDbl uses the locale settings to convert expression to double.
When exp cannot be converted to a double, a runtime error is generated.
Sample:
let nTest = ccur(234.456784)
let nCurr = (nTest * 8.2 * 0.01)
Syntax:
clng(exp)
Argument Description
exp Required. Any valid expression.
Syntax:
csgn(exp)
Argument Description
exp Required. Any valid expression.
Syntax:
cstr(exp)
Argument Description
exp Required. Any valid expression.
Returns: String
Notes: When exp cannot be converted to a string, a runtime error is generated.
Sample:
let nTest = 123.456
Now
Returns the current date and time.
Syntax:
now()
Returns: DateTime
Notes:
Sample:
let dtSys = now()
Syntax:
date()
Returns: DateTime
Notes:
Sample:
let dSys = date()
Syntax:
time()
Returns: DateTime
Notes: Time returns a DateTime variable with the date portion set to December 30, 1899.
Sample:
let iTime = time()
Syntax:
year(date)
Argument Description
date Required. Any valid datetime expression from which the year will be
returned.
Returns: Integer
Notes: When date cannot be converted to a datetime, a runtime error is generated.
Sample:
// the following returns the current year
let dtSys = now()
return year(dtSys)
Syntax:
month(date)
Argument Description
date Required. Any valid datetime expression from which the month will
be returned.
Returns: Integer
Notes: When date cannot be converted to a datetime, a runtime error is generated.
When date is passed as string, your PC’s regional settings are used for the conversion to
datetime. If that fails you get a runtime error.
Sample:
// returns the month (2) of the year
return month("3 february 2010")
Syntax:
day(date)
Argument Description
date Required. Any valid datetime expression from which the day will be
returned.
Returns: Integer
Notes: When date cannot be converted to a datetime, a runtime error is generated.
Sample:
// returns the day of the month of the orderdate
return day({OrderHea.Order_Date})
Syntax:
hour(date)
Argument Description
date Required. Any valid datetime expression from which the hour will be
returned.
Returns: Integer
Notes: When date cannot be converted to a datetime, a runtime error is generated.
Sample:
let dtSys = now()
Syntax:
minute(date)
Argument Description
date Required. Any valid datetime expression from which the minute will
be returned.
Returns: Integer
Notes: When date cannot be converted to a datetime, a runtime error is generated.
Sample:
let dtSys = now()
Syntax:
second(date)
Argument Description
date Required. Any valid datetime expression from which the second will
be returned.
Returns: Integer
Notes: When date cannot be converted to a datetime, a runtime error is generated.
Sample:
let dtSys = now()
Syntax:
weekday(date)
Argument Description
date Required. Any valid datetime expression from which the weekday will
be returned.
Returns: Integer
Notes: When date cannot be converted to a datetime, a runtime error is generated.
WeekDay does not use the locale settings to calculate the weekday – it always returns
the same value for a specific day of the week.
Sample:
// returns 1 (Sunday = 1 , Monday = 2 ...)
return weekday(dateserial(2014,5,30))
Syntax:
weekdayname(date [,bool])
Argument Description
date Required. Any valid datetime expression from which the weekday will
be returned.
bool Optional. When a true value is passed the abbreviated name of the
weekday is returned (e.g. "mo" instead of "Monday").
Returns: String
Notes: When date cannot be converted to a datetime, a runtime error is generated.
WeekDayName uses the locale settings to determine the name of the weekday.
Sample:
// returns "Friday" when PC’s regional settings are set to English
return weekdayname(dateserial(2014,5,30))
Syntax:
monthname(date [,bool])
Argument Description
date Required. Any valid datetime expression from which the month will
be returned.
bool Optional. When true, the returned name is the abbreviated name of
the month (e.g. Sep vs September).
Returns: String
Notes: When date cannot be converted to a datetime, a runtime error is generated.
MonthName uses the locale settings to determine the name of the month.
Sample:
// returns "May" when PC’s regional settings are set to English
return weekdayname(dateserial(2014,5,30))
Syntax:
datediff(str, date1, date2)
Argument Description
str Required. One of the following letters, static or as result of an valid
expression:
D (day)
H (hour)
N (minute)
S (second)
date1 Required. Any valid datetime expression.
date2 Required. Any valid datetime expression.
Returns: Integer
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
Sample:
// returns the number days between current date and time and the
// stored order date and time
return datediff('D', now(), {OrderHea.Order_Date})
Syntax:
dateadd(str, int, date)
Argument Description
str Required. Any valid string expression containing the interval:
D (day)
H (hour)
N (minute)
S (second)
int Required. Any valid integer expression holding the amount to add.
date Required. Any valid datetime expression to which the interval is
added.
Returns: DateTime
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
Sample:
// Adds 2 days to the order date
return dateadd ('D', 2, {OrderHea.Order_Date})
Syntax:
datepart(str, date)
Argument Description
str Required. Any valid string expression containing the interval:
D (day)
H (hour)
N (minute)
S (second)
Yyyy (year)
M (month)
Y (day of year)
W (weekday)
date Required. Any valid datetime expression to which the interval is
added.
Returns: Integer
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
Sample:
// Returns the day number of the order date
return datepart("D", {OrderHea.Order_Date})
// returns the difference between now and the order date in years,
// months and days. Days can be negative, no correction made on that.
let iYears = datepart("Yyyy", now())
- datepart("Yyyy", {OrderHea.Order_Date})
let iMonths = datepart('M', now())
- datepart('M', {OrderHea.Order_Date})
let iDays = datepart('D', now())
- datepart('D', {OrderHea.Order_Date})
Syntax:
dateserial(int1, int2, int3)
Argument Description
int1 Required. Any valid integer expression containing the year.
int2 Required. Any valid integer expression containing the month.
int3 Required. Any valid integer expression containing the day.
Returns: DateTime
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
DateSerial returns a datetime with the time portion set to midnight.
For int1 (the year), values between 0 and 99 are interpreted as the years 1900-1999.
Sample:
// Constructs a new date by subtracting 10 years from the static year
1990
let dVar = dateserial(1990 - 10, 5, 31)
Syntax:
timeserial(int1, int2, int3)
Argument Description
int1 Required. Any valid integer expression containing the hour.
int2 Required. Any valid integer expression containing the minute.
int3 Required. Any valid integer expression containing the second.
Returns: DateTime
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
DateSerial returns a datetime with the time portion set to midnight.
TimeSerial returns a datetime variable with the date portion set to December 30, 1899.
Sample:
// returns Saturday, december 30, 1899 6:15:00 AM
let dtTime = timeserial((12 - 6), 15, 0)
return dtTime
Syntax:
datevalue(str)
Argument Description
str Required. Any valid string expression containing the date.
Returns: DateTime
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
DateValue uses the locale settings to determine the date.
DateValue returns a date with the time portion set to midnight.
Sample:
// returns a fixed date; Saturday, June 05, 2010, 12:00:00 AM
return datevalue("06/05/2010")
Syntax:
timevalue(str)
Argument Description
str Required. Any valid string expression containing the time.
Returns: DateTime
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
TimeValue uses the locale settings to determine the date.
TimeValue returns a datetime variable with the date portion set to December 30, 1899.
Sample:
// returns Saturday, december 30, 1899 12:34:00 PM
return timevalue("12:34")
Syntax:
inleapyear(date)
Argument Description
date Required. Any valid date expression.
Returns: Boolean
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
Sample:
// Are we in a LeapYear?
if InLeapYear(now()) then
return "We are in a leap year"
else
return "We are not in a leap year"
end
Syntax:
weekago(datetime)
Argument Description
datetime Required. Any valid date expression containing a date.
Returns: DateTime
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
WeekAgo returns a datetime variable with the time portion set to 0:00:00 if no time
value is given.
Sample:
// returns Monday, march 25, 2013 00:00:00 PM
return WeekAgo("01-04-2013")
// returns the time of now minus 7 days with the current time.
return WeekAgo(now())
Syntax:
inlast7days(date)
Argument Description
date Required. Any valid date expression.
Returns: Boolean
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
Sample:
// Placed in a Font Color function
if InLast7Days({OrderHea.Order_Date}) then
return drBlack
else
return drRed
end
Syntax:
inlastfullmonth(date)
Argument Description
date Required. Any valid date expression.
Returns: Boolean
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
Sample:
// Placed in a Font Color function
if InLastFullMonth({OrderHea.Order_Date}) then
return drBlack
else
return drRed
end
Syntax:
inlastfullweek(date)
Argument Description
date Required. Any valid date expression.
Returns: Boolean
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
Sample:
// Placed in a Font Color function
if InLastFullWeek({OrderHea.Order_Date}) then
return drBlack
else
return drRed
end
Syntax:
inlastyearmtd(date)
Argument Description
date Required. Any valid date expression.
Returns: Boolean
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
Sample:
// Placed in a Font Color function
if InLastYearMTD({OrderHea.Order_Date}) then
return drBlack
else
return drRed
end
Syntax:
inlastyearytd(date)
Argument Description
date Required. Any valid date expression.
Returns: Boolean
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
Sample:
// Placed in a Font Color function
if InLastYearYTD({OrderHea.Order_Date}) then
return drBlack
else
return drRed
end
Syntax:
inlast4weekstosunday(date)
Argument Description
date Required. Any valid date expression.
Returns: Boolean
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
Sample:
// Placed in a Font Color function
if InLast4WeeksToSunday({OrderHea.Order_Date}) then
return drBlack
else
return drRed
end
Syntax:
inagedtodays(date, num1 [,num2])
Argument Description
date Required. Any valid date expression.
num1 Required. The maximum days ago.
num2 Optional. The minimum number of days ago. Default = 0.
Returns: Boolean
Notes: When the arguments cannot be converted to the specified type a runtime error is
generated.
Sample:
// Placed in a Font Color function
if InAgedToDays({OrderHea.Order_Date}, 30) then
return drBlack
else if InAgedToDays({OrderHea.Order_Date}}, 60, 31) then
return drYellow
else if InAgedToDays({OrderHea.Order_Date}, 90, 61) then
return rgb(205,140,0) // Orange
else // Date is > 90 days ago
return drRed
end
Abs
Returns the absolute value of a number.
Syntax:
abs(num)
Argument Description
num Required. Any numeric expression.
Returns: Number
Notes: When num cannot be converted to a number, a runtime error is generated.
Sample:
let nVar = -50.3
Syntax:
atn(num)
Argument Description
num Required. Any numeric expression.
Returns: Number
Notes: When num cannot be converted to a number, a runtime error is generated.
Sample:
return (4 * Atn(1))
// returns 3.14 (when the field has a 2 decimal format)
Syntax:
cos(num)
Argument Description
num Required. Any numeric expression. Represents the angle in radians.
Returns: Number
Notes: When num cannot be converted to a number, a runtime error is generated.
To convert degrees to radians, multiply degrees by pi/180.
Sample:
return cos(1.047)
// returns 0.50 (when the field has a 2 decimal format)
Syntax:
sin(num)
Argument Description
num Required. Any numeric expression. Represents the angle in radians.
Returns: Number
Notes: When num cannot be converted to a number, a runtime error is generated.
To convert degrees to radians, multiply degrees by pi/180.
Sample:
return sin(0.5235988)
// returns 0.50 (when the field has a 2 decimal format)
Syntax:
tan(num)
Argument Description
num Required. Any numeric expression. Represents the angle in radians.
Returns: Number
Notes: When num cannot be converted to a number, a runtime error is generated.
To convert degrees to radians, multiply degrees by pi/180.
Sample:
return tan(0.593412)
// returns 0.67 (when the field has a 2 decimal format)
Syntax:
log(num)
Argument Description
num Required. Any numeric expression greater than 0.
Returns: Number
Notes: When num cannot be converted to a number, a runtime error is generated.
Sample:
return log(86)
// returns 4.45 (when the field has a 2 decimal format)
Syntax:
sqr(num)
Argument Description
num Required. Any numeric expression greater than 0.
Returns: Number
Notes: When num cannot be converted to a number, a runtime error is generated.
Sample:
return sqr(23)
// returns 4.78 (when the field has a 2 decimal format)
Syntax:
exp(num)
Argument Description
num Required. Any numeric expression. If num exceeds 709.782712893 an
error is generated.
Returns: Number
Notes: When num cannot be converted to a number, a runtime error is generated.
Sample:
return exp(5)
// returns 148.41 (when the field has a 2 decimal format)
Syntax:
fix(num)
Argument Description
num Required. Any numeric expression.
Returns: Integer
Notes: When num cannot be converted to an integer, a runtime error is generated.
Sample:
return fix(-99.8)
// returns -99
Syntax:
sgn(num)
Argument Description
num Required. Any numeric expression.
Syntax:
mod(num1, num2)
Argument Description
num1 Required. Any numeric expression. Specifies the value to divide.
num2 Required. Any numeric expression greater than 0. Specifies the
number to divide by.
Returns: Number
Notes: When num cannot be converted to a number, a runtime error is generated.
Sample:
let nTest = mod(47.9, 9.35)
Syntax:
round(num [,exp [,type]])
Argument Description
num Required. Any numeric expression. The number to be rounded.
exp Optional. Any numeric expression. The number of decimals included
in the rounding or when type is drRoundUpToExp or
drRoundDownToExp the number to round to.
type Optional. One of the following constants defining a method of
rounding:
drRoundHalfToEven (default) rounds to the nearest even
number.
As default "Gaussian" rounding will be used. This method uses
the Gauss rule, also known as the "Banker's rounding", that if you
are in a perfect half case, you must round to the nearest digit
that can be divided by 2 (0, 2, 4, 6, and 8). This rule is important
to obtain more accurate results with rounded numbers after
multiple mathematical operations.
drRoundHalfUp rounds half towards positive infinity.
That is, half-way numbers are always rounded up. If the fraction
of num is exactly 0.5, then the result is num + 0.5. For example,
by this rule the value 23.5 gets rounded to 24, but −23.5 gets
rounded to −23.
drRoundHalfDown rounds half towards negative infinity.
As opposed from drRoundHalfUp, drRoundHalfDown will round
num down. For example 23.5 is rounded to 23 and -23.5 will be
rounded to -24.
drRoundHalfToZero rounds half away from infinity.
That is, half-way numbers are always rounded towards zero. If
the fraction of num is exactly 0.5, then the result is num - 0.5.
For example, by this rule the value 23.5 gets rounded to 23, but
−23.5 becomes −23.
drRoundHalfFromZero rounds half towards infinity.
That is, half-way numbers are always rounded away from zero. If
the fraction of num is exactly 0.5, then the result is num + 0.5.
For example, by this rule the value 23.5 gets rounded to 24, but
−23.5 gets rounded to −24.
drRoundFromZero rounds towards infinity.
The function returns the smallest number which is not less than
the input. For example, 12.2 gets rounded to 13 and -12.2 gets
rounded to -13.
drRoundToZero rounds away from infinity.
The function returns the smallest number which does not exceed
the input. For example, 12.2 gets rounded to 12 and -12.2 gets
rounded to -12.
drRoundUp rounds towards positive infinity.
Aka take the ceiling, the function returns the smallest integer
that is not less than num. For example, 12.2 gets rounded to 13,
but -12.2 gets rounded to -12.
Returns: Number
Notes: When num cannot be converted to a number, a runtime error is generated.
Sample:
return round(32.445, 2) // returns 32.44
return round(32.445, 2, drRoundHalfUp) // returns 32.45
return round(32.445, 2, drRoundHalfDown) // returns 32.44
return round(32.445, 2, drRoundHalfToZero) // returns 32.44
return round(32.445, 2, drRoundHalfFromZero) // returns 32.45
RGB
Returns a color constant.
Syntax:
rgb(int1, int2, int3)
Argument Description
int1 Required. Any integer expression. The Red component of the color
ranging from 0 to 255.
int2 Required. Any integer expression. The Green component of the color
ranging from 0 to 255.
int3 Required. Any integer expression. The Blue component of the color
ranging from 0 to 255.
Returns: Integer
Notes: If any color component exceeds 255, the value 255 is used.
Sample:
let red = rgb(255,0,0)
let green = rgb(0,255,0)
let black = rgb(0,0,0)
Syntax:
typename(exp)
Argument Description
exp Required. Any valid expression.
Returns: String
Notes: The following values can be returned:
exp Returns
Empty, only defined variable Empty
Cint(123.4) Integer
1234.5 Double
Ccur(12.78) Currency
Now() Date
‘abc’ String
1<2 Boolean
To use the returned value in a comparison, use a case insensitive compare.
Sample:
let iTest = cint(123.456)
Syntax:
vartype(exp)
Argument Description
exp Required. Any valid expression.
Returns: Integer
Notes: The following values can be returned. The value is equal to the standards for variant data
types.
exp Returns
Empty, only defined variable 0
Cint(123.4) 3
1234.5 5
Ccur(12.78) 6
Now() 7
‘abc’ 8
1<2 11
Sample:
let iTest = cint(123.456)
Syntax:
isdate(exp)
Argument Description
exp Required. Any valid expression.
Returns: Boolean
Notes:
Sample:
let dTest = cdate("30/05/2010")
return isdate(dTest)
Syntax:
isempty(exp)
Argument Description
exp Required. Any valid expression.
Returns: Boolean
Notes: Empty is different than a string without contents or numeric zero value.
Sample:
// the following variable is declared but not assigned a value
// and thus empty
dim sTest
return isempty(sTest)
Syntax:
isnull(exp)
Argument Description
exp Required. Any valid expression.
Returns: Boolean
Notes:
Sample:
let sTest = "Test"
return isnull(sTest)
Syntax:
isnumeric(exp)
Argument Description
exp Required. Any valid expression.
Returns: Boolean
Notes:
Sample:
let sTest = 459.5
return isnumeric(sTest)
Syntax:
hex(int)
Argument Description
int Required. Any integer expression. The value to be converted to a
hexadecimal presentation.
Returns: String
Notes:
Sample:
return hex(459) // returns 1CB
Syntax:
celsiustofahrenheit(num)
Argument Description
num Required. Any numeric expression.
Returns: Number
Notes: When num cannot be converted to a number, a runtime error is generated.
Sample:
return CelciusToFahrenheit(20) + " ºF"
// returns "68 ºF"
Syntax:
fahrenheittocelsius(num)
Argument Description
num Required. Any numeric expression.
Returns: Number
Notes: When num cannot be converted to a number, a runtime error is generated.
Sample:
return FahrenheitToCelcius(77) + " ºC"
// returns "25 ºC"
Previous
Returns the column value of the previous database row.
Syntax:
previous(column [,records])
Argument Description
column Required. Column name where the value should be retrieved from.
records Optional. The amount of previous rows where the value should be
retrieved from.
dim counter
dim State
let records = 1
let State = ""
return State
Syntax:
next(column [,records])
Argument Description
column Required. Column name where the value should be retrieved from.
records Optional. The amount of following rows where the value should be
retrieved from.
let records = 0
Syntax:
sum(type, start, field)
Argument Description
sum Summation type (see paragraph 12.2.3 for valid constants).
start Starting point of the summation (see paragraph 12.2.3 for valid
constants).
field Field to summarize.
Returns: Number
Notes:
Sample:
// Avarage Purchases of all customers
return sum(drAverage, drReport, {Customer.Purchases})
12.4.1 String
Operator Description
+ Concatenate
- Trim and concatenate
* Trim and concatenate with space
> Greater than compare
< Less than compare
>= Greater than or equal compare
<= Less than or equal compare
= Equal compare
<> Not equal compare
12.4.2 Boolean
Operator Description
Or Logical or
And Logical and
Xor Logical exclusive or
12.4.3 DateTime
Operator Description
> Greater than compare
< Less than compare
>= Greater than or equal compare
<= Less than or equal compare
= Equal compare
<> Not equal compare
12.4.4 Integer
Operator Description
+ Add
- Subtract
/ Divide
* Multiply
> Greater than compare
< Less than compare
>= Greater than or equal compare
<= Less than or equal compare
= Equal compare
<> Not equal compare
12.4.5 Number
Operator Description
+ Add
- Subtract
/ Divide
* Multiply
> Greater than compare
< Less than compare
>= Greater than or equal compare
<= Less than or equal compare
13.2 Reference
They need to be registered in the repository database DR.DB. Reference is
done via the 'Function editor' dialog.
If the current tree item points to the 'External library functions' node or a
present ELF function you can add a new function via the "Add" button.
The following dialog pops up.
CodeDescription
Syntax:
codedescription(location, type, code)
Argument Description
location Location and name of the DataFlex codemast table.
type Codetype (e.g. SHIPPING, REASONS, etc.)
code Code to be looked up (e.g. FEDEX, LUNCH, etc.)
Returns: String
Notes: The definition of the ELF is present in the also installed DR.DB file so that you can
immediately use the function.
Sample:
return CodeDescription("Codemast.dat","SHIPPING",{OrderHea.Ship_Via})
NumberToWords
Returns a word presentation of a number or currency.
Syntax:
numbertowords(num [,currency [,subcurrency]])
Argument Description
num Required. Any numeric expression.
currency Optional. A string representing the currency. This string is placed
between the integral and fractional part.
subcurrency Optional. A string representing the subcurrency. This string is placed
after the fractional part.
Returns: String
Notes: See paragraphs 13.1 and 13.2 for information how to add this function.
The source code of this function is published on our blog at:
http://support.dataaccess.com/Forums/entry.php?163-How-to-make-your-own-ELF
Sample:
return NumberToWords(123.61)
// returns "one hundered twenty three and sixty one"
return NumberToWords(12,"dollar")
// returns "twelve dollar"
Syntax:
fileexists(str)
Argument Description
str Required. The full path of the object to verify.
Returns: Boolean
Notes: See paragraphs 13.1 and 13.2 for information how to add this function.
The source code of this function is published on our blog at:
http://support.dataaccess.com/Forums/entry.php?164-How-to-use-Windows-API-
functions-in-Visual-Report-Writer
Sample:
// check if there is a logo of the customer
if (FileExists("C:\logos\" + {Customer.Name} + ".jpg")) then
return "C:\logos\" + {Customer.Name} + ".jpg"
else
return ""
end
DataFlex Reports uses the standard calling convention (_stdcall). Make sure that you use this convention. ELF
functions must use parameters to be passed as type VARIANT.
After selecting "Create new" from the floating menu while the
current tree-view item is on 'Parameter Fields' or on an existing parameter the following dialog will be opened
for the parameter definition.
To calculate the amount of time between the creation of the report and the latest save:
return DateDiff("H", {&Modification Date and Time}, {&File Creation Date and Time})
Filter Function
Returns the contents of the record filter if one is defined for the report. This is not the same as filter expert.
Record Number
Returns the number of the record from the data-set. This is not the same as "recnum" which is a normal field in
recnum tables.
If the following code is used for the background color of the details section, you give a different color to the even
and uneven output lines in the report.
Page Number
Returns the current page number.
If the following example is used for the details background color you will get a gray color on each uneven page.
Page N of M
Returns the page number relevant to the total number of pages.
At preview time the total number of pages might not be known yet and thus the special field returns "1 of 1". As
soon as the next page (or the last page) has been printed the number reflects the current location. The number
is always correct when printing.
return {&Page N of M}
At preview time the total number of pages might not be known yet and thus the special field returns "1". As
soon as the next page (or the last page) has been printed the number reflects the current location. The number
is always correct when printing.
Report Title
Returns the report title value. You can enter this value via Report | Report document properties.
Report Subject
Returns the report subject value. You can enter this value via Report | Report document properties.
Report Author
Returns the report author value. You can enter this value via Report | Report document properties.
Report Category
Returns the report category value. You can enter this value via Report | Report document properties.
Report Keywords
Returns the report keywords value. You can enter this value via Report | Report document properties.
Report Comments
Returns the report comments. You can enter this value via Report | Report document properties.
Report Revision
Returns the report revision value. You can enter this value via Report | Report document properties. The default
value of this property is zero.
Group Number
Returns the number of the group. Each time a group is used (printed) in the report the group number increases.
Creating a new page layer based on an existing one is done the same way as with a report. See section 2.3.
You must save the page layer file before it can be used in a report.
DataFlex Reports supports the usage of advanced custom collation sequence files. These files allow the choice of
a specific ANSI code page (for exotic characters) and fine-grained control of the sort order.
When using a custom collation sequence DataFlex Reports performs the actual sorting, which is otherwise
performed by the database. If the database can support the desired collation sequence and has the proper
index, it can return the data sorted as required which has better performance.
It is important to note that DataFlex Reports only accepts collation sequences that match the current Windows
code page. If the code page of the collation file is different DataFlex Reports will notify you with an error
message.
Collation files support a number of different statements that define one or more characters. The general sort
order will be from the top of the file down.
17.3 Example
The following listing shows an incomplete example of a collation file, which reflects a normal English case-
sensitive collation sequence.
* Codepage
CP 1252
* Control characters
RANGE 0 31
SINGLE 127 * DEL
SINGLE 160 * NBSP
SINGLE 173 * SHY
* Unused
SINGLE 129
SINGLE 141
SINGLE 143
SINGLE 144
SINGLE 157
* Punctuation
RANGE 32 47
RANGE 58 64
RANGE 91 96
RANGE 123 126
SINGLE 130
RANGE 132 137
SINGLE 139
RANGE 145 153
SINGLE 155
SINGLE 161
RANGE 166 169
RANGE 171 172
RANGE 174 177
RANGE 180 184
SINGLE 187
SINGLE 191
SINGLE 215
SINGLE 247
* Currency signs
TEXT "€£¥¤¢"
* Numbers
TEXT "0¼½¾1¹2²3³456789"
* Alpha characters
TEXT_EQ "AÀÁÂÄÃÅÆ"
TEXT_EQ "aàáâäãåæª"
TEXT_EQ "B"
TEXT_EQ "b"
TEXT_EQ "CÇ"
TEXT_EQ "cç"
.
.
.
Option Description
-autoclose Close DataFlex Reports once the preceding command(s) are completed.
-cmdfile Read the command line options from file. Useful for multiple commands.
-csvexport Export the specified report to a CSV file.
-htmlexport Export the specified report to an HTML file.
-imageexport Export the specified report to an image file (GIF, JPG, or TIFF).
-pdfexport Export the specified report to a PDF file.
-print Print the specified report.
-report Open the specified report
-rtfexport Export the specified report to a RTF file.
-run Open the specified report and its preview.
-x Start DataFlex Reports with the specified workspace.
-xlsexport Export the specified report to an Excel XLS file.
It is possible to open multiple reports and page layers by adding additional -report statements, like this
example:
The following example opens DataFlex Reports with the Order Entry example workspace.
This option cannot be repeated – only one workspace file can be opened per session.
Each of the available export formats has its own set of options. Partially they overlap but they will be described
separately in each of the following paragraphs. The only option that is required for all exports is -exportfile.
This options is used to specify the output file path.
Option Description
Multipage This boolean option, which is true by default, specifies that the entire report
will be exported. When false, only a single page is exported.
Page If the multipage option is false, this option specifies which page is exported. By
default this is set to page 1.
Option Description
Allpages This boolean option, which is true by default, specifies that the entire report
will be exported. When false, only a single page is exported.
Page If the allpages option is false, this option specifies which page is exported. By
default this is set to page 1.
Option Description
Allpages This boolean option, which is true by default, specifies that the entire report
will be exported. When false, only a single page is exported.
Image Default is OLEdrLow (0).
Ownerpwd Specifies a password that must be entered to open the PDF for editing. Default
is no password.
Page If the allpages option is false, this option specifies which page is exported. By
default this is set to page 1.
Pagemode Default is OLEdrNormal (0).
Userpwd Specifies a password that must be entered to open the PDF for reading. Default
is no password.
Support for DataFlex Reports can be reached via the following ways:
If the registration was successful DataFlex Reports will ask if you want to activate the product now. You need to
have an internet connection for this.
The Visual Report designer will default to the built in English text strings when the database cannot be found or
cannot be opened. No message is given but you will find that all languages of the language pull-down are grayed
out.
If the OCX needs to find a text for translation and the language.db cannot be opened you will get a message to
this effect and then the OCX defaults to the built in English text strings. The language database is used for text
strings such as "Page N of M", for errors generated by the database driver, or errors generated internally in the
OCX. If a translation cannot be found the system defaults to the built in English text string.
The language.db should be present in the same folder as where the DataFlex Reports Workstation Runtime is
installed.