Σχόλια 0

Το κείμενο του εγγράφου

File: C:\WINDOWS\TEMP\QuickReport 3.docBuild ReportsusingQuickReport 3for Borland DelphiDistributed Worldwide by QBS Software Ltd2 Bui l d Repor t s usi ng Qui ckRepor t 3ContentsWhat is QuickReport 3?..........................................................................................................3There’s more...........................................................................................................................3A first report...............................................................................................................................5The components........................................................................................................................9Band components.................................................................................................................10Printable components..........................................................................................................11Previews and composite reports........................................................................................13Filters......................................................................................................................................15Chart.......................................................................................................................................16Creating reports.....................................................................................................................17TQuickRep in detail.............................................................................................................17Working with bands............................................................................................................22Groups....................................................................................................................................27Master/detail reports............................................................................................................29More about printable components....................................................................................31Text components..................................................................................................................31Using expressions................................................................................................................33Creating a default custom preview...................................................................................36Further resources..................................................................................................................39Bui l d Repor t s usi ng Qui ckRepor t 3 3What is QuickReport 3?QuickReport 3 is a set of Delphi components designed to let youproduce database output quickly and easily. As well as allowing you tofling together printed reports, QuickReport lets you create printpreviews where the user can check the result of a printout withoutwasting paper, and export data to other file formats, such as plainASCII, comma separated values (CSV) and HTML.QuickReport is itself written in Delphi and knows all about the Delphimodel for handling databases. So you can use it to report on traditionalBDE-based databases such as Paradox and dBase, client datasets used inmulti-tier environments, the new Delphi 5 ADO and Interbase Expresscomponents and third party alternatives such as Apollo. You can evenuse QuickReport formatting facilities to print out non-database data, ifyou need to.This manual is designed to get you up to speed quickly withQuickReport, so that you can start to use it in your own applications atonce.There’s moreQuickReport is a fine product – but if you need even more versatility,you might consider upgrading to QuickReport Pro. Naturally, the Proversion is offers everything in the standard product plus: Three extra export filters:Excel XLS: The XLS filter is compatible with Excel 4 and later, andprovides a simple and robust mechanism for exporting unformatteddata into spreadsheets.Rich Text RTF: The RTF filter, based on Microsoft’s RTF version1.5 spec, supports more RTF features than TRichEdit itself.Windows Metafile WMF: The WMF filter lets you capture reportoutput in a convenient graphical format. Some powerful extra components. Let the user do the work:TQREditor is an end user report editor that you can ship royalty-freewith your app.4 Bui l d Repor t s usi ng Qui ckRepor t 3TQuickAbstractRep is a descendant of the TCustomQuickRep baseclass that does not use TDataset - use it to build your own reportsystems.TQRLoopBand prints the number of times set in its PrintCountproperty - great for creating blank forms.TQRListWizard will create an instant report based on the fields of atable. Expert technical support via email. Full source code. Use the source, Luke! The user can easily modifythe code to localise the language, adopt it to local interfacestandards, add new features and so on. More demos with more depth, including examples of how to makeuse of all the Pro edition features, and advanced techniques such aswriting custom functions for the expression evaluator.You can upgrade to QuickReport Professional by ordering from our website, that of our distributor QBS Software Ltd at http://www.qbss.com orfrom your local Delphi add-on reseller.Bui l d Repor t s usi ng Qui ckRepor t 3 5A first reportThe best way to get the hang of the QuickReport library is to see it inaction. So this section explains how to set up a very basic report. Withthe Delphi IDE running, follow these steps:1 Choose File | New Application.2 Drop a TTable component onto the main form.3 Use the Object Inspector to set its DatabaseName property to‘DBDemos’, TableName to ‘CUSTOMER.DB’ and Active to True.4 Drop a TQuickRep component on the main form. Its size andposition don’t matter.5 Set its DataSet property to ‘Table1’. This is a key step. The reportobject to iterates through all the records in it DataSet, in this caseTable1, whenever it is printed or previewed.6 If necessary, expand the Bands property in the Object Inspector byclicking on the + symbol to its left. Set the HasDetail item to True.You will see the detail band appear inside the report; changing theproperty actually creates the DetailBand1 object.7 Drop a TQRDBText component onto the newly created detail band.8 Set its DataSet to ‘Table1’ and DataField to ‘Company’.At this point your form should look something like Figure 1 below.Figure 1 – Setting up a basic reportTo check that you have set up the properties correctly, preview thereport by right-clicking somewhere on the TQuickRep component andselecting the Preview item from the popup menu. If you did everythingright you should now see a preview window containing your report, asshown in Figure 2.6 Bui l d Repor t s usi ng Qui ckRepor t 3Figure 2 – The preview windowIf all has gone well, you now have a report that works at design time. Ofcourse all may not have gone well. If you are now mournfully gazing atan entirely blank report, please check that you have completed all thesteps – a likely explanation is that you forgot to set TTable1’s Activeproperty to True. Similarly, if you are looking at a report with only oneline – ‘Kauai Dive Shoppe’ – the problem is probably that you failed toconnect QuickRep1’s Dataset property to TTable1.One other problem which may bite you is that the buttons on the toolbarabove the report preview area fail to appear. This is nobody’s fault: youhave become a victim of what the manufacturer of your PC’s operatingsystem is pleased to call, in its technical documents, ‘DLL Hell’.Specifically, your machine’s copy of the common control library(comctrl32.dll) is before 4.72, and needs updating.Bui l d Repor t s usi ng Qui ckRepor t 3 7You can download a later version of comctrl32.dll from the Microsoftwebsite at http://www.microsoft.com. But since this is one of those filesthat invariably turns up in new versions of Internet Explorer andWindows Service Packs, you may well find it on one of those CDs thatthey give away with PC magazines, and save a download. (In fact, it isunlikely that this bug will bite you the developer. We describe it here sothat you will recognise the problem if one of your users is caught by it.)Now lets make the report work as part of a compiled program. You needto write code to call TQuickRep.Preview:1 Drop a button to your form and set its Caption property to ‘Preview’2 Double click on the button to add an OnClick event. Add a line ofcode, so that it looks like this:procedure TForm1.Button1Click(Sender: TObject);beginQuickRep1.Preview;end;Now run your application and click the Preview button. As before, youshould see the preview window appear. If you want to try printing thereport directly to the default printer, simply change the call to thePreview method to a call to Print, ieprocedure TForm1.Button1Click(Sender: TObject);beginQuickRep1.Print;end;At this point I must admit to taking a slightly dirty shortcut. Our testapplication a TQuickRep component on its main form and, as you cansee, this looks pretty odd. In real applications you never display a formcontaining a TQuickRep component. Instead you use them from otherforms.So what we should really do to finish off, if this little example weregoing to be a real application, is:1 Create another form – it will be called Form22 Make the new form into the main form of the project by settingProject | Options | Main form to Form23 Drop a button on Form28 Bui l d Repor t s usi ng Qui ckRepor t 34 Write code like this in the button’s event handlerprocedure TForm2.Button1Click(Sender: TObject);beginForm1.QuickRep1.Preview;end;5 Compile the project. The compiler will complain that Unit1 is not inUnit2’s Uses list, and offer to fix the code. Accept the offer.The application should now compile and run, and looks prettier andmore ‘realistic’. The end user doesn’t get to see any bewilderingTQuickRep components.But doing this aesthetic polishing doesn’t get us any further withQuickReport. So I am going to leave out the need to have a second formfrom all the examples from this point onwards, and trust you willremember when making real applications.Bui l d Repor t s usi ng Qui ckRepor t 3 9The componentsThe QuickReport components are all contained in the QReport tab ofthe Delphi component palette. Here is a whistle stop tour of what theyare and what they do to help you get your bearings.Figure 3 - TQuickRep and band componentsTQuickRep. This is the most important component of them all, acontainer for all the other printing components. It represents the paperon which your report will be printed. Its Page property lets you set upthe dimensions of the paper you are going to print on, while the Datasetproperty specifies a source of data that the report will iterate through.Note that, instead of dropping a TQuickRep component onto an ordinaryform, you can instead add a TQuickReport module to your project:1 Choose File | New… to display the New Items dialog box.2 Choose the New tab3 Select the Report item (middle of the bottom row)A TQuickReport is a bit like a TDataModule – it is a specialist type ofform, which is never displayed to the user. If you wish you can useTQuickReport pseudo-forms instead of TQuickRep components onordinary forms – there is no difference in their methods, properties andevents. But we recommend, from experience, that you put a TQuickRepcomponent on a form: it’s the more versatile approach. For example,having the TQuickRep component on a form lets you use the form’sOnCreate event if you want to create additional objects to be used bythe report programmatically.10 Bui l d Repor t s usi ng Qui ckRepor t 3Band componentsThese are also container components, representing horizontal stripsacross report. Bands can be associated with a physical position on apage – for example the top – and also reflect the master/detailrelationships in the database that is being displayed. For example, in thesame way that there might be many sales records for a given customerrecord, so a band containing data about an individual sale might appearmany times for each occurrence of a band containing customer data.TQRSubDetail. This is the detail band in a master/detail relationship.You can also make it the master of another detail band, and so createmultiple levels of subdetails.TQRStringsBand. This band provides one mechanism to report on datawithout using a TDataSet. It encapsulates a TStrings container; insteadof retrieving a sequence of records from a database, it retrieves asequence of strings from its container.TQRBand. A generic band type, which can act in different rolesaccording to it BandType property. Usually there is no need to drag aTQRBand onto a report. Instead use the Bands property of TQuickRep,which creates TQRBand objects and sets their band type in one go.TQRChildBand. Use TQRChildBand objects when you need to extendan existing band. For example, suppose you have placed someTQRMemo components in a band, and wish to add, say, a TQRLabel,which should always appear below. Since TQRMemo objects canexpand themselves according to their contents, it is not sufficient toarrange the label within the band. Instead add in a TQRChildBandobject, and put your label on that. The easiest way to add a child band,by the way, is to double-click the HasChild property of its parent in theObject Inspector.TQRGroup. A band that prints whenever an expression changes, usuallya database field. This band is used to group like records together. Forexample, given a database table containing US addresses, one could sortthem by a State Code field and add a group band with it Expressionproperty set to the State Code field. When the report is printed, thecontents of the group band will be printed between records belonging toa given state.Bui l d Repor t s usi ng Qui ckRepor t 3 11Printable componentsFigure 4 - Printable componentsThe QuickReport printable components are mostly equivalents ofstandard controls that you use on forms. These are the controls, whichactually get printed on the paper. Position them within bands to definethe layout of your report.TQRLabel. Place some static text on the page.TQRDBText. Equivalent of a TDBText control – use it to display thecontents of a linked database field. Unlike ordinary data-aware controls,but in common with all QuickReport controls, TQRDBText uses aDataSet property to specify its source of data. Normal data-awarecontrols use a DataSource property, which requires you to supply anextra TDataSource component to ‘wire’ controls to a dataset.QuickReport controls have no such requirement.TQRExpr. Use this to display an ‘expression’. Typically you use one ofthese when you need to massage the appearance of your data beforeprinting it out. The best way to think of these is as ad hoc calculatedfields, used only in the report. For example, you might use it toconcatenate the parts of a customer name, held in a customer table asstring fields called “Title”, “Forename” and “Surname”. To do thissimply set the Expression property of TQRExpr toTitle + " " + Forename + " " + SurnameIn real life, you would probably use a more complex expression to copewith blank fields elegantly, but you get the idea.12 Bui l d Repor t s usi ng Qui ckRepor t 3TQRSysData. A control to display ‘system data’, by which we meanthings like the current page number within the report, and the currentdate and/or time.TQRMemo. Very much like its standard control cousin the TMemo; usethis to display multiple lines of text. As you would expect, the text to beprinted is held in a TStrings type property called Lines.TQRExprMemo. A composite of TQRExpr and TQRMemo. You can usethis to include {braced} expressions in multi-line blocks. This makes itan absolute natural for doing addresses, especially since it includes aboolean property RemoveBlankLines. For example:Company : {CompanyName}Address : {Address1}{Address2}Contact : {Contact + ' ' + Phone number}TQRRichText. Place some rich text (ie multi-line text with RTFformatting) on the page. One use of this component is to print thecontents of a TRichEdit control – simply assign it to TQRRichText’sParentRichEdit property.TQRDBRichText. As you’d expect, this is a data-aware version ofTQRRichText. Use it to print formatted memos stored in BLOB fields.TQRShape. A cousin of the little-used TShape control from Delphi’s‘Additional’ palette. Actually the QuickReport version is very useful forplacing ‘furniture’ into report layouts such as dividing lines above totalsand grouping rectangles.TQRImage. Display a picture or logo on a report using this control.Supports the same vector and bitmap image formats as TImage, and canbe loaded at design time using the Picture property.TQRDBImage. A data-aware image control for displaying images storedin BLOB fields in the database.Bui l d Repor t s usi ng Qui ckRepor t 3 13Previews and composite reportsFigure 5 - Filters and miscellaneous componentsTQRCompositeReport. Sometimes you need to group together separatereports into a single print run. For example, maybe you need to print outall the new customers obtained in the last week, together with asummary of all orders in the last week and also a list of stock that needsreordering. As far as your customer is concerned these things belongtogether and should be printed together. But from the database point ofview you will want to use three separate TQuickRep components to dothe job.The way to handle this situation is to use a TQRCompositeReportcomponent. Drop one on the form where you want to kick off theprinting. First you need to define a handler for its OnAddReports event,which calls the TQRCompositeReport.Add method to add all theTQuickRep components you need to print. Suppose the reports you wantto print are held on forms called RepNewCust, RepOrderSummary andRepStockReorder, and in each case the TQuickRep component on theform is called ‘Report’ (see the section ‘TQuickRep in detail’ below forwhy you might do this). Then your OnAddReports event handler shouldlook like this14 Bui l d Repor t s usi ng Qui ckRepor t 3procedure TForm1.QRCompositeReport1AddReports(Sender: TObject);beginQRCompositeReport1.Reports.Add(RepNewCust.Report);QRCompositeReport1.Reports.Add(RepOrderSummary.Report);QRCompositeReport1.Reports.Add(RepStockReorder.Report);end;(If you don’t mind using the with statement in your code, you can tidyup this fragment considerably by wrapping it up inwith QRCompositeReport1.Reports dobegin...end;and knocking out the ugly repetitive QRCompositeReport1.Reports fromthe middle three lines.)Now you can call QRCompositeReport1.Print to print out all threereports in a single batch, and QRCompositeReport1.Preview to previewthem together. There are also TQRCompositeReport componentproperties that let you set up paper sizes and set an overall title for thecomposite report – basically everything you need to handle the outputfrom the multiple reports in one place.TQRPreview. To preview a report before it is printed for real, all youneed do is call TQuickRep.Preview and a standard preview window willappear. There are times, however, when you want to have more controlover the exact appearance of the preview.The TQRPreview control lets you do this. Drop it on one of your ownforms and, after you have added a line of code to theTQuickRep.OnPreview event, the control will act as a frame for thepreviewed report. If you are more ambitious, or you want to change thepreview of a composite report, you can register your own preview formas the default. See the section ‘Error! Reference source not found.’later on for details.Bui l d Repor t s usi ng Qui ckRepor t 3 15FiltersSometimes, instead of printing or displaying it directly, you need toexport data from your database to another format. QuickReport comescomplete with three filter components that let you do this quickly andeasily for their respective formats. Simply drop the export filter onto thesame form as the report, and the file format appears in the drop-downlist of the Save To file dialog in the preview. Registration is automatic,and you don’t need to code a thing! (Don’t worry - you can export areport programmatically too if you wish – see below.)Note that not all printable components are exported by filters.Specifically, only the contents of the following text-producingcomponents appear in exported data: TQRLabel, TQRDBText,TQRExpr, TQRMemo, TQRSysdata and TQRExprMemo.TQRTextFilter. ‘Text’ format: exports the contents of the report in plainASCII, using spaces to separate fields.TQRCSVFilter. CSV format: exports the report as ‘Comma SeparatedVariables’. As well as using a comma to separate fields, this filter places“double quotes” around them, which allows you to have commas withinthe fields themselves. This format is easily imported into spreadsheetssuch as Microsoft Excel. By the way, the component has a Separatorproperty that specifies the character used to separate the fields. Bydefault this value is set to ‘,’ comma, but it can be changed to matchyour requirements.TQRHTMLFilter. HTML format: exports the report to a HyperTextMarkup Language file, as used in web browsers, some emailers, helpsystems and many other places.It is also possible to call filters explicitly from code. This fragment usesthe HTML filter.quickrep1.ExportToFilter(TQRHTMLDocumentFilter.Create('c:\report.txt'));To use the Text or CSV filters in this way, use the same ExportToFiltercall but instantiate a TQRAsciiExportFilter orTQRCommaSeparatedFilter object as appropriate.16 Bui l d Repor t s usi ng Qui ckRepor t 3ChartTQRChart is a version of TChart adapted to work with QuickReport.This allows you to add complex charts to your reports – the combinationis very powerful indeed. TQRChart is used in the same way as theordinary TChart control – double click it to bring up its extensiveproperty editor. For details of how to accomplish tasks such as settingup series and adjusting the look of a chart, please see the TeeChartdocumentation.Version incompatibilityBecause of dependency issues beyond our control, certain versions ofTeeChart are incompatible with newer versions of QuickReport, and theTQRChart control and the whole of TeeChart can be unloaded whenyou upgrade QuickReport. For example, at time of writing the Delphi 3version of QuickReport 3 (or higher) will not work with TeeChart,because the version of TeeChart that is shipped with Delphi 3 is codedto depend on the QuickReport 2 package. A workaround is to downloadthe (free) TeeChart 4 evaluation version from the TeeMach site athttp://www.teemach.com/.This issue extends to the Decision Cube components found inClient/Sever and Enterprise Editions of Delphi – these depend onTeeChart, and get unloaded when it does. At present, there is no way touse the Delphi 3 Decision Cube with both QuickReport 3 and TeeChart.We do apologise for this unsatisfactory situation. Since it is caused bydesign decisions made by other parties in code we cannot access, so thatwe are not able to fix matters autonomously. If you run into troublewhen upgrading QuickReport, please check our websitehttp://www.qusoft.no/ and TeeMach’s for the latest information.Bui l d Repor t s usi ng Qui ckRepor t 3 17Creating reportsThe first step when creating a QuickReport is to create a form to storeyour TQuickRep component. We refer to this form as a ‘report form’since it’s just a container for a report component and is not shown to theend user at runtime. It’s a good idea to adopt a naming convention forsuch reports so that they are easily identifiable in the project managerand in directory listings. For example, you could prefix all report formnames with ‘rep’ or ‘rp’ to make them stand out. You might want to usea similar scheme with form and data module unit names.TQuickRep in detailThe next step is to drop a TQuickRep component onto the form. Anotheruseful convention you may like to adopt: by naming all TQuickRepcomponents ‘Report’, you can reference them asrepCustomerListing.Report, repSalesListing.Report and so on.Units and Zoom propertiesWhen dropping the TQuickRep component on a form you will se a gridto act as a guide for positioning components. The grid is shown in thecurrent QuickReport units. Select the currently active unit by changingthe TQuickRep.Units property in the property inspector. The grid will beupdated when you change this property.Figure 6 - Adjusting the Units property to alter grid spacingWith Units set to ‘MM’, the grid displays at 10mm intervals; if it is setto ‘Inches’ then the grid displays at 1" intervals. Using the grid you canproduce very accurate report layouts, positioning and sizingQuickReport components to 0.01" or 0.01mm.18 Bui l d Repor t s usi ng Qui ckRepor t 3Usually your screen is too small to display an entire TQuickRepcomponent, since it sizes itself based on the actual paper size selected.To get a clearer picture of the whole report, change the Zoom propertyto 50% or less. Changing the zoom causes the TQuickRep componentand all the printable controls it contains to be redrawn at once to therequested scale. This feature can also be used to enlarge importantdetails for accurate positioning and sizing.Paper size and marginsYou can set up page layout accurately by expanding the Page propertyof the TQuickRep component. Double click on the + sign to the left of‘Page’ in the Object Inspector to expand the sub properties. You willnow see all the settings controlling the page layout.Figure 7 - Page sub propertiesThe values given are in the currently selected Units, in this case inches.The margin settings can be seen as blue dotted lines on the TQuickRepcomponent. All bands are sized to fit inside the margins.The sub properties are described in Table 1 below:Bui l d Repor t s usi ng Qui ckRepor t 3 19Table 1 - Sub properties of PagePropertyType/ValuesNotesBottomMargin Extended Units property determinesinterpretation.Columns Integer Number of columns whenprinting multi-column detailbands.ColumnSpace Extended Space inserted between eachcolumn in a multi columnreport. Units propertydetermines interpretation.LeftMargin Extended Units property determinesinterpretation.Length Extended Read-only, unless PaperSizeis set to Custom. Unitsproperty determinesinterpretation.Orientation TPrinterOrientation =(poPortrait, poLandscape)PaperSize TQRPaperSize =(Default, Letter, LetterSmall,Tabloid, Ledger, Legal,Statement, Executive, A3, A4,A4Small, A5, B4, B5, Folio,Quarto, qr10X14, qr11X17,Note, Env9, Env10, Env11,Env12, Env14, Sheet, DSheet,ESheet, Custom)These are all the default papersizes supported by Windows.To use another paper size, setthis property to Custom andset Length and Widthappropriately – but see alsonote below.RightMargin Extended Units property determinesinterpretation.Ruler Boolean Enables display of grid.TopMargin Extended Units property determinesinterpretation.Width Extended Units property determinesinterpretation.20 Bui l d Repor t s usi ng Qui ckRepor t 3Not all printer drivers support setting custom paper sizes through theCustom setting of Papersize. In these cases you must select ‘Custompaper size’ in the printer driver’s own dialog (accessed from theWindows Control Panel) and define the paper’s dimensions there. Setthis custom paper size to be the default paper size for that printer andfinally set the TQuickRep.Page.PaperSize property to Default. Yourcustom size will now be picked up at runtime.Alternatively, and perhaps more robustly, use the next largest standardpaper size, and set the margins to keep the printing within the customarea.Selecting a fontAs you would expect, you can set the default font for your report in theTQuickRep.Font property. Double click on the property to get thestandard Delphi font dialog.The fonts listed are the Windows system fonts, True Type fonts and anyPostScript fonts (if Adobe TypeManager is installed). You can use anycombination of fonts in your reports but we advise the use of TrueTypeor PostScript fonts if you intend to allow the user to preview the report.The system fonts do not scale very well in preview.Some dot matrix printers print much faster if you select a font alreadybuild into the printer hardware, called a ‘printer font’. Such fonts are notlisted by the font dialog, but can be set programmatically:repCustomerListing.Report.Font.Name := 'CG TIMES';The readability of your report depends very much on your fontselection. You should consider this carefully when selecting fonts.Using many different fonts, colours and styles in a report can easilymake it look cluttered and difficult to read.Bui l d Repor t s usi ng Qui ckRepor t 3 21Title and DescriptionThe TQuickRep component has Title and Description string propertiesto identify and describe the report. These are provided for yourconvenience, so you can make report selection a data-driven procedure.For example, you might have generate a menu that lists all your reportsby title and shows the description when the user selects a report. Anexample of this can be seen in the QuickReport example project.The Title property can be printed on the report itself using aTQRSysData component.FunctionsThe Functions property of a TQuickRep allows you to set up constantsand functions that can be used by QuickReport expressions contained inany TQRExpr, TQRExprMemo and TQRGroup components that youdrop on the report. Double-click the property the ‘…’ button in theobject inspector to bring up the special property editor:Figure 8 - Functions property editorUse this dialog, and the expression builder that underlies it, to defineconstants that you expect to require in multiple expressions. Forexample, you can see that in Figure 8 above I have defined, with aregrettable lack of originality, the constant PI as 3.14159265358979.The other functions you see, PAGENUMBER, COLUMNNUMBER andREPORTTITLE, are automatically predefined.22 Bui l d Repor t s usi ng Qui ckRepor t 3Working with bandsQuickReport is a banded report generator. If you are unfamiliar withbanded report generators you can think of them as small papertemplates, which are arranged horizontally on a page and filled withdata. Different templates are copied into different parts of thepage/report. The printable components, TQRLabel, TQRDBText and soon, are designed to be placed on these bands. Placing these componentsdirectly on the report is not supported.The easiest way to add bands is via the TQuickRep.Bands property inthe Property Inspector. Click the ‘+’ sign to the left of the word ‘Bands’to expand the list of common bands:Figure 9 - Bands sub propertiesThe Object Inspector shows if a given band type exists in the report ornot, and you can add or delete a band simply by changing the relevantproperty. Bands created this way get names that describe their function:DetailBand1, PageHeaderBand1 and so on. The BandType property ofeach band is also set automatically.Bui l d Repor t s usi ng Qui ckRepor t 3 23You can also add bands by selecting the TQRBand component on thecomponent palette and dropping it on the report. Note that if you do itthis way you must take care to set the BandType property to the desiredband type, and you should also give the band a descriptive name. TheBands property of the container TQuickRep will update itself to reflectbands added to the report this way.Here are the simple band types you can add to a report:Table 2 - Simple band typesBand typePurposePage Header The first band usually printed on all pages. Whetherit is printed on the first page printing is governed bythe report’s Options.FirstPageHeader property. Thedefault is to print the first page header.Title A title band is the first band printed to a report (afterthe very first page header, if any). It’s useful forprinting the report title, data selection criteria,creation date and time and so on.Column Header The column header band is printed on top of eachreport column. In a regular single column report, thisband is printed once per page, following the pageheader (and the title band for the first page). In amulti column report it’s printed once for eachcolumn. It’s most useful for printing field names.While it is possible to add a band manually and set its BandType torbSubDetail or rbGroupHeader, this is not recommended. These bandtypes are intended for use only with TQRSubDetail and TQRGroupcomponents. Using them elsewhere may cause unexpected andundesirable effects when the report is printed.24 Bui l d Repor t s usi ng Qui ckRepor t 3Detail One detail band is printed for each record (row) ofdata in your dataset. This is perhaps the mostimportant band in your report and is usually whattakes most of the space on the final output. Youwould typically put data-aware printable controlssuch as TQRDBText on this band.Summary After all detail bands has been printed you can print asummary band. This is often used for printing totalsof numeric fields.Page Footer The last band printed on all pages. Last page printingis governed by the report’s Options.LastPageFooterproperty. The default is to print the last page footer.As you add new bands to a report, you will notice that theyautomatically position themselves in the actual printing order. You willsee that the Page Header band is on top, followed by the Title band,column header band and so on, as shown in Figure 10 below.Figure 10 - Simple band typesBui l d Repor t s usi ng Qui ckRepor t 3 25Each band has its band type printed in small letters in its lower leftcorner. This allows you to identify the bands while designing the report.This text is not printed on the final report.Bands appear on the TQuickRep component in the order in which theyare printed. It is helpful to understand why the bands line up the waythey do. Generally bands will print in at the frequency shown in Figure10, although things become more complicated when you start to add subdetails and group bands.Sizing the bandsBands derive their horizontal size from the containing TQuickRepobject. Their Size.Width properties should be considered read only;values written to them are ignored. For a single column report, the widthof all bands is set to the page width minus the left and right margins. Inmulti-column reports, the width of certain band types (Column Header,Detail, Sub Detail, Group Header and Group Footer) is adjusted toreflect the width available for a single column.However you can adjust the vertical size of the bands. Select a band andresize it with the mouse in the usual way or, if you want more accuratecontrol, setting an exact value in the Size.Height property.Turning bands on and offYou might sometimes want to disable printing of a certain band. Thiscan be done, either at design time or at run time, by setting theTQRBand.Enabled property to False.During report generation you can also temporarily disable printing of aband by creating an event handler for the band’s BeforePrint event. Thisevent handler takes a boolean parameter PrintBand that can be set toFalse to disable band printing – but just for that single instance. Thisfeature can be used to perform simple filtering:procedure TrepCusList.RepDetailBeforePrint(Sender: TQRCustomBand;var PrintBand: Boolean);beginPrintBand := CustTableTotalSales > 3000000;end;26 Bui l d Repor t s usi ng Qui ckRepor t 3Note: When PrintBand is set to False for a detail band, the values forthat record are not included in any aggregate TQRExr function, forexample the SUM function. This is a behaviour change betweenQuickReport 2 and QuickReport 3.If you turn off a Page Footer band, it will have the effect of leaving ablank space at the bottom of each page – the Detail Bands will notexpand to fill the space. To optimise performance, QuickReport doesn’tcheck the length of the page footers all the time. So after you change theEnabled property of your Page Footer, call the report object’sResetPageFooterSize method to force QuickReport to update its pagefooter information.Bui l d Repor t s usi ng Qui ckRepor t 3 27GroupsGroups allow you to generate extra bands between groups of records.For example, if you were listing an address book, you might wish togroup all the contacts whose name began with the same capital letter,and to print that letter in large type above each group – in fact this iswhat we do in the example.To create a group:1 Create a simple report as described in ‘A first report’ above.2 Set the IndexName property of the TTable component to‘ByCompany’.3 Drop a TQRGroup component onto an existing TQuickRep object,where it appears as a new band. This band will be the group header.Every time the group ‘breaks’, this band will be printed.4 Set the Expression property toCOPY(Table1.Company, 1, 1)This extracts the first character from the ‘Company’ field.5 Drop a TQRExpr control onto the header band. Set its Expressionproperty to the same value:COPY(Table1.Company, 1, 1)In addition you can also add a group footer band. Although we don’treally need one here, we’ll make one for practice.6 Select the TQRBand component on the palette and drop it on thereport. Rename it to FooterBand1.7 Click on the group header band once more. Set theTQRGroup.FooterBand property to FooterBand1.8 Drop a TQRLabel onto the footer band. Set its Caption property to‘FOOTER’.If all has gone to plan, you should be looking at something like Figure11:28 Bui l d Repor t s usi ng Qui ckRepor t 3Figure 11 - Creating a groupNow preview the report, either by running the program, or simply right-clicking on the report object and choosing Preview:Figure 12 - Preview of a grouped reportAs expected, the resulting report shows a list of all the companiesgrouped in alphabetical order, with each group headed by a line showingthe current letter.Bui l d Repor t s usi ng Qui ckRepor t 3 29Master/detail reportsYou will very often wish to create a master/detail report – that is onewhere you are extracting data from two datasets connected by amaster/detail relationship. QuickReport allows you to include one ormore such relationships in a report using TQRSubDetail components.An obvious example of a master/detail report is to list out all the ordersassociated with each customer in a database. Here is a quick example:1 Start with the group report as created in the previous section.2 Drop a TDataSource component on the form, and make its DataSetproperty ‘Table1’.3 Drop a new TTable component on the form. Set its DatabaseNameproperty to ‘DBDemos’, TableName to ‘ORDERS.DB’, IndexNameto ‘CustNo’, MasterSource to ‘DataSource1’, MasterFields to‘CustNo’ and Active to True. The two TTable components are nowset up in a master/detail relationship.4 Drop a TQRSubDetail component onto the existing TQuickRepobject, where it appears as a new band. Notice that its Masterproperty is automatically set to QuickRep1. The master/detailrelationship between the two TTable objects is mirrored between thereport object and its sub detail band.5 Set the TQRSubDetail component DataSet property to ‘Table2’. TheTQRSubDetail component iterates all through its DataSet for eachchange in the Dataset of its Master.6 Drop three TQRDBText components on the sub detail band. Set theirDataSet properties to ‘Table2’, and set the DataField properties to‘OrderNo’, ‘SaleDate’ and ‘ItemsTotal’ respectively.If you have done all that correctly, you should now be looking atsomething like Figure 13 below.30 Bui l d Repor t s usi ng Qui ckRepor t 3Figure 13 - Creating a report with sub detailNow preview the report. The result will look like Figure 14, with eachcustomer’s orders listed below the customer name. Note that the formatof the date and currency fields depends on Windows’ internationalsettings. Mine are set to British, your mileage will obviously vary.Figure 14 - Preview of a master/detail reportBui l d Repor t s usi ng Qui ckRepor t 3 31More about printable componentsBy now, you will have a feel for QuickReport’s printable components –use them like ordinary controls to define you layout. However, there area few QuickReport-specific things to learn about them.Text componentsQuickReport’s printable text components – TQRLabel, TQRDBText,TQRExpr, TQRSysData, TQRMemo, TQRExprMemo, TQRRichText andTQRDBRichText – share some common properties, which they inheritfrom a parent, class:Table 3 - Text component propertiesPropertyPurposeAlignToBand By default components will print/align at the positionset in the designer. But sometimes it is more practicalto align components to the vertical edges of the bandthat it is placed on. When AlignToBand is True, atext components will align itself relative to its parentband instead of its own text rectangle.AutoSize Set this property to True and a component sizes itselfhorizontally to fit whatever text is put into it.AutoStretch If AutoStretch and WordWrap are both True, acomponent can expand vertically to accommodate itstext. When a component expands in this way it alsoexpands its parent band, provided that band’sCanExpand property is set to True. A band canexpand over multiple pages if necessary.Note that if a component expands it will not moveother components on the same band down. If youhave components whose desired position shoulddepend on the length of a stretching text, you shouldplace these in a child band.Note also that this property cannot be used forcomponents on any band that prints at the bottom ofthe page. This is typically the page footer, but alsoapplies to any band that has had its AlignToBottom32 Bui l d Repor t s usi ng Qui ckRepor t 3property set to True.Frame All text components can display a visible framearound them. This property controls the appearanceof the frame, which sides it is drawn on and so on.Size All printable components share the Size property. IfAutoSize is False you can use this property to set theexact size of the component. This property alsocontains the position of the component relative to itsparent band.WordWrap If WordWrap is set to True text can span multiplelines.Formatting fieldsTQRDBText components use any formatting options defined for thefield to which they are connected. Sometimes, however, you need tocustomise the display of a particular value; this can be achieved usingTQRDBText’s Mask property. This takes the same values as Delphi’sown FormatFloat function (for numeric fields) and FormatDateTimefunction (for date and time fields) – in fact, QuickReport itself callsthese functions to do the work. To give you an example, suppose youwished to print out a numeric value to two decimal places, with thethousands separated by a comma, and negative values shown (inparentheses) in the style favoured by accountants. Then you could use aMask like this#,##0.00;(#,##0.00)which would cause the values1234 and -1234.5to be printed as1,234.00 and (1,234.50)respectively.Check out the Delphi help for FormatFloat and FormatDateTime fordetails and more examples.To specifically set a formatting of a field use the Mask property. Themask works differently for different field types.Bui l d Repor t s usi ng Qui ckRepor t 3 33Using expressionsQuickReport includes an advanced expression evaluator, used by theTQRExpr, TQRExprMemo and TQRGroup components. Expressionscan be used to combine and manipulate database fields, and performadvance formatting. Their syntax is rather like that of Object Pascal: theexpressions can be of boolean, float, integer or string type. Note thatdate and time fields are converted into strings, and BLOB and memofields are not supported in expressions.The evaluator supports the usual set of operators:Table 4 - Operators supported by the expression evaluatorOperatorsFunction+ Addition, string concatenation- * /Subtraction, multiplication, division()ParenthesesAnd Or Not Logical operators= < ><= >= <>Comparison operatorsand a set of standard functions:Table 5 - Functions supported by the expression evaluatorFunctionDescriptionAVERAGE(EXPR)Aggregate function. Averages the EXPRCOPY(STR,S,L)Returns a sub string of STR starting atcharacter S length LCOUNT Aggregate function. Returns the number ofiterations of the Master band.DATEReturn current date as a stringDIV(X, Y)Integer division of X by YFALSE Logical value FalseFORMATNUMERIC(F, N)Format numeric N using string mask F. The34 Bui l d Repor t s usi ng Qui ckRepor t 3mask takes the values as Delphi’sFormatFloat function.FRAC(NUM)Returns the fractional part of a NUMIF(EXPR, R1, R2)Returns R1 or R2 depending on the booleanEXPRINT(NUM)Returns the integer part of NUMLOWER(STR)Returns STR in lowercaseMAX(EXPR) Aggregate function. Returns the highestvalue of EXPRMIN(EXPR) Aggregate function. Returns the lowestvalue of EXPRPRETTY(STR)Returns STR in ‘pretty’ case, ie first latterin uppercase, the remainder lowercaseSQRT(NUM)Returns the square root of NUMSTR(NUM)Converts NUM to a stringSUM(EXPR) Aggregate function. Returns the sum ofEXPRTIME Return current time as a stringTRUE Logical value TrueTYPEOF(EXPR)Returns the data type of EXPR as a string,eg ‘BOOLEAN’UPPER(STR)Returns STR in uppercaseIf your expression includes aggregate functions like SUM or COUNT youmust link the Master property to the component, TQuickRep orTQRSubDetail that will be used to update the expression. For a simplereport this is your TQuickRep component, but in a complicated reportwith many datasets you must take care to link to the correctTQRSubDetail. The expression is recalculated each time the recordpointer of the linked master is advanced.The ResetAfterPrint property is also useful when working withaggregation functions, and allows you to create, for example, grouptotals as well as running totals.Bui l d Repor t s usi ng Qui ckRepor t 3 35The expression builderTo make it easier to create expressions for your reports, QuickReportincludes a special property editor, which appears when you click the‘…’ button. This is shown in Figure 15.Figure 15 - Expression builder dialogThe expression builder lets you design your expression by selectingfunctions and field names from lists – so it makes it a lot easier to avoidtypos in identifier names. It also brings up special dialogs to prompt forfunction arguments.Figure 16 - Setting function arguments in the expression builder36 Bui l d Repor t s usi ng Qui ckRepor t 3Creating a default custom previewWe mentioned back in the ‘Previews and composite reports’ section thatit was possible to change the default preview mechanism. It is time tolook at how this is done.The first step when creating a custom default preview is to derive a newclass from TQRPreviewInterface, like this:// use QRPrntr to get TQRPreviewInterfaceTQRCustomPreviewInterface = class(TQRPreviewInterface)publicfunction Show(AQRPrinter : TQRPrinter): TWinControl; override;function ShowModal(AQRPrinter : TQRPrinter): TWinControl; override;end;Notice that this is an interface1class – it serves only to define a coupleof functions, and has no data of its own. These two functions areimplemented to construct and display your custom preview in non-modal and modal forms.Lets suppose that the preview form is going to be called TCustPreview.Then the implementation of the TQRCustomPreviewInterface methodsmight look like this:function TQRCustomPreviewInterface.Show(AQRPrinter: TQRPrinter): TWinControl;varfrm : TCustPreview;beginfrm := TCustPreview.Create(Application, AQRPrinter);frm.Show;Result := frm;end;

1We have not used Delphi’s interface keyword to define these classes because this is not currentlycommon practice, and many Delphi programmers are unfamiliar with the syntax. However, theconcepts are very similar.Bui l d Repor t s usi ng Qui ckRepor t 3 37function TQRCustomPreviewInterface.ShowModal(AQRPrinter: TQRPrinter): TWinControl;varfrm : TCustPreview;beginfrm := TCustPreview.Create(Application, AQRPrinter);frm.ShowModal;Result := frm;end;To register our alternative previewer, we need to call theRegisterPreviewClass function, which is in the QRPrntr unit. The calllooks like this:RegisterPreviewClass(TQRCustomPreviewInterface);Now we are done with the glue code, and can build the actual previewerform. Mine is minimal; just a single TQRPreview control stuck onto aform:Figure 17 - Simple preview formWhen you do real previews in your applications, you will probably wantto add buttons to call TQRPreview’s Zoom method and other facilities.To support the previewing mechanism, I had to write a little more code.Here is the declaration of TCustPreview. Notice I have added a newconstructor, which expects to receive the TQRPrinter argument passedin by the Show and ShowModal methods of the interface class. Delphigenerates a warning message that the new constructor hides the original.In this case it is deliberate, so I have wrapped the class in{$WARNINGS ON} ... {$WARNINGS OFF}38 Bui l d Repor t s usi ng Qui ckRepor t 3compiler directives to make it shut up.{$WARNINGS OFF}TCustPreview = class(TForm)QRPreview1: TQRPreview;procedure CustPreviewClose(Sender: TObject;var Action: TCloseAction);private{ Private declarations }fQRPrinter : TQRPrinter;public{ Public declarations }constructor Create(AOwner : TComponent;AQRPrinter : TQRPrinter); virtual;end;{$WARNINGS ON}Finally, here is the implementation of the class. Notice in particular thecleanup code held in the form’s OnClose event. If you don’t callClosePreview here, you will get a nasty memory leak. (QuickReport 2users should note that this is a new requirement. You must modify yourexisting preview forms when porting them to QuickReport 3 and later.)constructor TCustPreview.Create(AOwner: TComponent;AQRPrinter: TQRPrinter);begininherited Create(AOwner);fQRPrinter := AQRPrinter;QRPreview1.QRPrinter := AQRPrinter;end;procedure TCustPreview.CustPreviewClose(Sender: TObject;var Action: TCloseAction);beginfQRPrinter.ClosePreview(Self);Action := caFree;end;Bui l d Repor t s usi ng Qui ckRepor t 3 39Further resourcesThere are many other resources available to you, to help you make themost of QuickReport in your Delphi applications.Help files. The QuickReport help files are installed and integrated withDelphi’s own help. As well as context-sensitive Reference forcomponents and properties, there are also extensive User Guide andKnowledge Base sections. Since they don’t appear in the main Helpcontents, it’s easy to overlook these, so if you get stuck or need to knowmore, remember to fire up QuickReport help from its Start menushortcut.Demo applications. You’ll find these in theProgram Files\Borland\Delphi5\Demosdirectory. The project Quickrpt\Qr3\qr3demo.dpr contains lotsof examples of different kinds of report. Start here if you want to exploitQuickReport’s fancier features, like export filters. Also see the projectDb\Mastapp\mastapp.dpr contains a good example ofQuickReport being integrated into a larger application.Templates and wizards. Again often overlooked – the standard Delphirepository includes templates for Master/detail, Labels and List reports,plus a report building wizard. Take File | New in the Delphi IDE andhave a look at the Forms and Business tabs.Website. Our website is http://www.qusoft.com Please come and checkit out to find more examples, updates, tips and add-ons.