Unit 'msereport' Package
[Overview][Constants][Types][Classes][Procedures and functions][Index] [#msegui]

Reference for unit 'msereport'

Reports with treport

uses

  System,

  classes,

  mclasses,

  

Copy of the Free Pascal Classes unit, modified for MSEgui

  mseapplication,

  msegui,

  msegraphics,

  msetypes,

  msewidgets,

  

msewidgets is the base unit of every visual component

  msegraphutils,

  mseclasses,

  mseinterfaces,

  mseificomp,

  msetabs,

  mseprinter,

  msestream,

  msearrayprops,

  mseguiglob,

  msesimplewidgets,

  msedrawtext,

  msestrings,

  mserichstring,

  msedb,

  mdb,

  msethread,

  mseobjectpicker,

  msepointer,

  mseevent,

  msesplitter,

  msestatfile,

  mselookupbuffer,

  mseformatstr,

  msegdiprint,

  msemenus,

  mseglob;

Overview

About this guide

This guide explains how to build printed reports with the report generator of unit msereport. It is based on the explanations given by Martin Schreiber when the report generator was written (2007), checked against the current source code.

The report generator works differently from most reporting tools: there are no predefined header, footer, group or summary bands. A report is built from a few primitives (pages, band areas, bands, tabulators) whose visibility depends on the data, and from event handlers. Any widget can be placed on a report, not only the components of the 'Rep' tab of the component palette.

Structure of a report

A report is created in MSEide by 'File'-'New'-'Form'-'Report'. It is a treport containing one or more treportpages (popup menu item 'Add report page'); widgets can not be placed directly on the report, only on its pages.

All sizes and positions are in millimetres, except the line distances (dist), which are in pixels; tcustomreport.ppmm is the number of pixels per millimetre.

Data and record navigation

There are two basic layouts:

A report can be fed by datasets, by code, or both. In the onbeforerender event of a band (or of a page), set the values to display and the empty parameter: rendering stops when no band and no page has data any more, that is when all connected datasets are at eof and all onbeforerender events return empty = true.

A page without data is not printed. Set rpo_once in treportpage.options to print a page once without data, for example a front page. In the same way, a band with bo_once in its options is printed once, for example a title or a column header.

To print the current record only (instead of all records), use a page with rpo_once, leave the datasource of the bands empty, and set the datasource of the tabulator items instead.

The onbeforerender event of a band can be called more than once for the same record, because a band which does not fit on the current page is rendered again on the next page. Code which must run once per record belongs in onafterrender.

Rendering

A report is printed by one of the render methods of tcustomreport: to a canvas, to a tstreamprinter (e.g. tpostscriptprinter) with a print command or a stream, or to a tgdiprinter.

Rendering runs in a separate thread. Consequences:

With reo_autorelease, the report frees itself after rendering, which allows to create and print it in one statement:

procedure tmainfo.printexe(const sender: tobject);
begin
 tmyreport.create(nil).render(printer);
end;

A report without reo_autorelease can be rendered several times, for example with different query parameters, as long as each rendering is finished (waitfor) before the next one starts.

Page numbers: "Page N of M"

The number of pages is only known after the report has been rendered. Set reo_prepass in treport.options: the report is then rendered twice, the first pass (tcustomreport.prepass = True) producing no output and only counting the pages.

In a treppagenumdisp, the characters 0 and 1 of format are replaced by the page number and by the page count: for example 'Page 0 of 1'. Text between quotes is not replaced.

Both passes are identical, so values accumulated in event handlers (totals...) must be reset before each pass, in treport.onbeforerender. In the same way, to show something on the last page only, test pagenum = lastpagecount - 1 (page numbers are zero-based); this only works with reo_prepass, because lastpagecount is 0 during the first pass.

Tables: tabulators and lines

The columns of a record band are defined by its tabs property (treptabulators), one item (treptabulatoritem) per column: position (pos), alignment on the position (kind: tak_left, tak_right, tak_centered, tak_decimal), textflags, font, and the value: a constant value, the field datafield of datasource, a lookup (lookupbuffer), or the result of the ongetvalue event.

Frame lines are set per band (lileft, litop, liright, libottom, livert of tabs) and per tabulator item (litop, livert, libottom):

Groups and totals

Example (from Martin Schreiber): a table with a header and a footer on every page.

  1. Place a tbandarea on the page, and a tbandgroup into it.
  2. Place the header band into the band group, and set in its optionsshow: bos_showfirstofpage, bos_hidenormalofpage, bos_hidelastofpage.
  3. Place the data band below the header band, into the band group.
  4. Place the footer band below the data band, into the band group, and set in its optionsshow: bos_hidefirstofpage, bos_hidenormalofpage, bos_showlastofpage, bos_showlastrecord.
  5. Set the datasource of the band group, and osc_expandy, osc_shrinky in its optionsscale.

Several reports in one print job

To print the same report several times on continuous output (e.g. once per selected customer), call restart of the band area from the onbeforerender event of its last band, when it has no more data:

procedure tmyreport.lastbandbeforerender(const sender: tcustomrecordband;
               var empty: boolean);
begin
 if empty and morereports then begin
  setupnextreport; //change the query parameters, call first...
  bandarea1.restart;
 end;
end;

With several band areas, call restart of the report page.

Printing tips


Documentation generated on: 2026-10-03