Interesting and useful Delphi components - TRTFReport
Reporting is very important feature of almost every application which works with data (saved in database tables, as a result of query or view). Particular editions of Delphi brought some reporting systems in the past, we can mention QuickReport, ReportSmith or very popular and useful FastReport.
We often come across the requests from users who want to edit default reports, creating new ones or customize existing reports according to their needs. In such cases is the most significant moment to provide userf-friendly, simple and elegant way how to manage those tasks.
Overview
TRTFReport, one of the most efficient solutions which should be taken into account for reporting comes from Czech developer Rosinsky Software. It allows to create various types of reports - documents, lists, tables, labels etc.; stencils for reports are created in RTF format and can be created, edited and customized in any RTF editor - Microsoft Word will be probably the most frequented tool for this. In addition, stencil as a report definiton can contain not only references for table columns but calculations, expressions, special tags for handling pictures, barcodes and many more as well. System is capable to handle basic database operations from the report definition - like filtering via IF and CASE commands, moving among particular records, skip records and so on.
Let's have a look at basic element of every stencil (template), the tag. Tag is reference for field value or other information placed at desired position in the template. We distinguish among several types of tags: field tags, parameters, variables and function tags, calculation tags, scan tags and IF/CASE tags but syntax of each type of tag is almost the same:
\DATASET_SEQUENCE.FIELD_NAME:FORMAT_STRING\
For instance, if we have in the first table used for creating report field called DATE_OF_ISSUE (its type is TDateTime) and want to display it as MM/DD/YYYY, we can use following tag definition:
\A.DATE_OF_ISSUE:mm/dd/yyyy\
We should keep on mind four handy features of tags:
- tags can be placed wherever inside the template - not only at the page but in header/footer section or table cell
- particular tag can be used repeatedly without restriction in one template
- value in destination report will inherits tag formatting - for example, if tag is formatted as bold and red font, corresponding value placed in the report will be displayed in the same way
- all the features of RTF format can be used for creating templatest - we can use header and footers, tables, textfields, numbering, bullets, pictures and drawings
Selection of scenarios for using RTFReport tags
Inserting picture into report and handling it (rotate, resize, quality)
Placing pictures is very easy and RTFReport can customize given picture in some ways. Picture can be picked-up from the field value or loaded from external file. However, field tag may be extended by adding some parameters:
Wcm=number - define max width of picture in centimeters
Hcm=number - define max height of picture in centimeters
Rotate=number - define angle of rotation
Enlarge - define that smaller pictures than defined W or H will be enlarged
InsertInRTF - picture will be inserted directly to RTF report in binary format (windows metafile is used), if this tag is missing, in rtf report will be only link to external file with picture
Quality - define quality of inserted picture (10..100, 100=full quality; Auto=automatic resize)
So if we need to display content of field PICTURE in the first table at the best possible quality, its size shall be 8 x 5 cm and want to flip it horizontally, we can create this tag:
\A.PICTURE:Wcm=8;Hcm=5;Rotate=180;Quality=100\
Displaying formatted text (RTF BLOB field content)
Technically, this approach inserts RTF fragment into another RTF file and we must be very careful towards formatting. Nevertheless, RTFReport offers three ways for handling fields with formatting which are available through tag options:
TEXT - blob is handled as text
RTF - blob is handled as RTF text
PLAIN - blob is converted from rtf to plaintext
Especially last option (PLAIN) is very helpful if we aren't sure how complicated BLOB content is, PLAIN option ensures proper displazing it in the report.
Using calculations
Calculations are a strong part of TRTFReport and using them can improve resulted report with almost no additional work. Calculation tags start with = sign and tag consists of main expression and optional Format part. As main expression we can use:
- signs: + - * /
- any number of brackets: ( )
- number constant
- field value: X.Field (value of the field must have number format)
- user defined variables (value of the variable must have number format)
- result of aggregation function
Should we calculate VAT and price with VAT from price without VAT, following tag can be used:
Total price is \A.TOTALPRICE\ CZK. VAT is \=A.TOTALPRICE*1.21\ CZK
and total price including VAT is \=A.TOTALPRICE*1.21+A.TOTALPRICE\ CZK.
Searching datasets
Next to working with single-record based templates, RTFReport can create lists-styled reports with summary. For this purposes, couple of tags SCAN and ENDSCAN is available. These tags can contain - as usual - options part for skipping records or setting condition for filtering:
- defines first point and conditions of scan function
- scan loop is finished when While condition come false
- scan loop skip record if SkipIf condition is true
- MinRows define minimum number of printed rows (if dataset has less records empty records are printed)
- MaxRows define maximum number of printed rows (scan loop is finished after defined number of records)
- NewLine insert new line after each record
- NewCol insert new column after each record
- NewPage insert new page after each record
- Sep(string) insert defined string as separator after each record
- scan loop do not move to first record if NoFirst is used
Tag definition for searching payments table and displaying values for quantity and price greater than 100 CZK can look like this:
\SCAN(B);SKIPIF(B.PRICE>100)\
Quantity: \B.QUANTITY\ Price: \B.PRICE:0.00\
\ENDSCAN(B)
Conditions tags
In certain situations we need to evaluate if given condition is valid or invalid because according to the result we place appropriate data and/or text into report. IF tag offers enough flexibility for every case.
Syntax of IF tag is
\IF(CONDITION)\ block if TRUE \ELSEIF\ block if FALSE \ENDIF\
Let's have a request for displaying VAT percentage in our report. There are two VAT rates in Czech republic, 15 (decreased) and 21% (common).
Tag \IF(A.VATPERCENTAGE=21)\ This item has common VAT rate. \ELSEIF\ This item has decreased VAT rate. \ENDIF\
Conditions are widely used in SCAN, IF and CASE tags and RTFReport works with following ones:
signs (equal, not equal, less than, greater than)
boolean field: A.ADULT
text field: X.LOCATION
text constant: "Price"
datetime constant: #YYYYHHMM# or #YYYYHHMMhhmmss#
any expression (see above)
any number of brackets: ()
logical operations: and or not
test if dataset is empty: A.0
test if dataset is eof : A.@
Practical stencils examples
At the end of our article we'd like to demnostrate some practical templates supplied for our customers and using widely in our applications. Let's take a look at three of them:
- printed parking card for residents
- license for the gamekeepers
- hunting statistics summary form
URL for download the samples is here.
Vendor's page can be found here.
About the Author
Ing. Karel Janeček, MBA, MSc.Torry.net