Sign in Join
Wiki copytemporary

LazReport Tutorial: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11## Overview
22
33This page started as a translation of the Portuguese language [[LazReport Tutorial/pt|Tutorial de LazReport]] (which itself appears to be a translation from a French document). It was updated for LazReport (instead of FastReport) on Lazarus (instead of Delphi), using T*Connection instead of a DBase table.
44
55## Starting with LazReport
66
77We're going to use a demo database which is provided by Delphi (DBDEMOS). You'll need to create a new application with a main form *Form1*.
88
99We're assuming you already have your database set up as specified in [[SQLdb Tutorial0]]. If not, please do so.
1010
1111### Setting up your form
1212
1313Place the following components on the form:
1414
1515- A T*Connection, e.g. TIBConnection:
1616 - DatabaseName := your database, e.g. C:\Program Files\Firebird\Firebird_2_5\examples\empbuild\EMPLOYEE.FDB
1717 - UserName, Password, HostName: as appropriatie (e.g. SYSDBA,password,\<none\> for Firebird embedded)
1818 - Transaction: TSQLTransaction1
1919- TSQLTransaction
2020- TSQLQuery:
2121 - Database := IBConnection1
2222 - Active: true
2323 - SQL: select * from employee
2424- TDataSource
2525 - DataSource1.DataSet := SQLQuery1
2626- TfrDBDataSet
2727 - frDbDataSet.DataSource := DataSource1
2828- TfrReport
2929- TfrDesigner
3030- 2 TButton
3131- Button1.Caption := 'Editing'
3232- Button2.Caption := 'Preview'
3333
3434This results in:
3535
36-<figure>
37-<img src="lazreptut01.png" title="lazreptut01.png" />
38-<figcaption>lazreptut01.png</figcaption>
39-</figure>
36+![](/wiki-images/4/4f/Lazreptut01.png)
4037
4138Double-click on the **TfrReport** icon (or right-click, Design Report) to bring up the report designer:
4239
43-<figure>
44-<img src="lazreptut01b.png" title="lazreptut01b.png" />
45-<figcaption>lazreptut01b.png</figcaption>
46-</figure>
40+![](/wiki-images/6/6a/Lazreptut01b.png)
4741
4842### Setting up variables
4943
5044LazReport lets you link variable names to database fields or system values, in order to spare your end users from having to decipher cryptic field names. In our example, we're going to create a variable for our database fields FIRST_NAME, LAST_NAME etc.
5145
5246In the File menu, click **Variables list**. Now you get an overview of the defined variables:
5347
54-<figure>
55-<img src="lazreptutvariableseditor.png" title="lazreptutvariableseditor.png" />
56-<figcaption>lazreptutvariableseditor.png</figcaption>
57-</figure>
48+![](/wiki-images/d/d9/Lazreptutvariableseditor.png)
5849
5950Click on the button **Variables** in order to define some variables. Write the contents according ot the following image. "Demo Variables" represents a category and the other entries (xxx field) represent variables. To differentiate the two, the variables start with a space.
6051
6152**Note**. The distinction between variables and variables categories by starting variables with a space is needed unique and exclusively in this dialog (**Variables List**). Anywhere else (Report Designer, main source code and scripts) a variable should be invoked without spaces.
6253
63-<figure>
64-<img src="lazreptutdefinevariables.png" title="lazreptutdefinevariables.png" />
65-<figcaption>lazreptutdefinevariables.png</figcaption>
66-</figure>
54+![](/wiki-images/8/86/Lazreptutdefinevariables.png)
6755
6856Finally click on OK to confirm your entries, and you'll see this:
6957
70-<figure>
71-<img src="lazreptutvariablesdefined.png" title="lazreptutvariablesdefined.png" />
72-<figcaption>lazreptutvariablesdefined.png</figcaption>
73-</figure>
58+![](/wiki-images/f/ff/Lazreptutvariablesdefined.png)
7459
7560As you can see, the category we defined is shown in the ComboBox above the variables. Each variable must be linked with a field. To do this, select the variable and then the field. Do this for all variables; the screenshot shows the link for Hire date:
7661
77-<figure>
78-<img src="lazreptutvarhiredatetofield.png" title="lazreptutvarhiredatetofield.png" />
79-<figcaption>lazreptutvarhiredatetofield.png</figcaption>
80-</figure>
62+![](/wiki-images/b/b6/Lazreptutvarhiredatetofield.png)
8163
8264### Objects and bands
8365
8466After closing the variables editor, we're back in our report designer. You may have noticed a small number of objects in the object bar to the left of the report surface. These are:
8567
8668- the mouse icon pointer
8769- rectangle object
8870- band
8971- picture object
9072- subreport
9173- draw lines
9274- insert barcode object
9375
94-<figure>
95-<img src="lazreptut01b.png" title="lazreptut01b.png" />
96-<figcaption>lazreptut01b.png</figcaption>
97-</figure>
76+![](/wiki-images/6/6a/Lazreptut01b.png)
9877
9978Click the band icon, go to the report surface, and click on it to drop a band object.
10079
101-<figure>
102-<img src="lazreptutinsertnewband.png" title="lazreptutinsertnewband.png" />
103-<figcaption>lazreptutinsertnewband.png</figcaption>
104-</figure>
80+![](/wiki-images/2/29/Lazreptutinsertnewband.png)
10581
10682You must click on the type of band you want to create. Select **Report title** and click OK.
10783
10884| Band type | Use |
10985|----|----|
11086| Report title | Shown only on the first page |
11187| Report summary | Shown only on the last page |
11288| Page header | Shown at the top of each page |
11389| Page footer | Shown at the bottomof each page |
11490| Master header | Shown at the beginning of the first detail band/level |
11591| Master data | First detail level data; repeated for each record in dataset |
11692| Master footer | Shown at the end of the first detail band/level |
11793| Detail header | Shown at the beginning of the second detail band/level |
11894| Detail data | Second detail level data |
11995| Detail footer | Shown at the end of the second detail band/level |
12096| Subdetail header | Shown at the beginning of the third detail band/level |
12197| Subdetail data | Third detail level data |
12298| Subdetail footer | Shown at the end of the third detail band/level |
12399| Overlay | Shown once on each page lower layer |
124100| Column header | Shown at the top of every column |
125101| Column footer | Shown at the bottom of every column |
126102| Group header | Shown at the top of every group |
127103| Group footer | Shown at the bottom of every group |
128104| Cross header | Shown at the top of cross tables/pivot tables |
129105| Cross data | Shows cross tables/pivot table data |
130106| Cross footer | Shown at the bottom of cross tables/pivot tables |
131107
132108### Report title
133109
134110In the Report title band, add a rectangle. The text editor will show up. In the first line the title of the report should be indicated. On the the second, system date and time need to be added. They are obtained by clicking **Variable** and then Category **Other**, then double-click on the desired variable (once you are familiar with the variables, you can also just type them). Now we have:
135111
136-<figure>
137-<img src="lazreptutreporttitle.png" title="lazreptutreporttitle.png" />
138-<figcaption>lazreptutreporttitle.png</figcaption>
139-</figure>
112+![](/wiki-images/a/ad/Lazreptutreporttitle.png)
140113
141114Click OK to exit the editor, then adjust the title rectangle to the desired size. Choose a color for the background with the Bucket Fill button on the toolbar.
142115
143116### The main event: showing data in the master data band
144117
145118Let's insert a master data band. LazReport prompts you for a data source; choose **frDBDataSet1**, the main data source for our example. The master band will be repeated for each record in the data source. You can double-click later on the band if you want to change the data source.
146119
147-<figure>
148-<img src="lazreptutbanddatasource.png" title="lazreptutbanddatasource.png" />
149-<figcaption>lazreptutbanddatasource.png</figcaption>
150-</figure>
120+![](/wiki-images/b/b7/Lazreptutbanddatasource.png)
151121
152122In the left half of the band we insert a rectangle and double click. The familiar text editor appears.
153123
154124Now we will add several fields in the one rectangle. If needed though, you can use one rectangle per field if you want to apply different formatting etc.
155125
156126The first line **Name** \[Full name field\] is obtained by writing Name and then, with the **Variable** button, entering the variable \[Field Name\]. Alternatively, as indicated before, you can write the resulting text directly.
157127
158128The next line **Salary** \[Salary field\] is written similarly.
159129
160130The third line - Salary divided by job grade \[\[Salary field\]/\[Job grade field\]\] - is done likewise. This shows you can perform calculations with fields coming from the data source. Note the extra set of square brackets around the calculation. As you may guess, you can not only use the variables listed via the **Variable** button, but also database fields via **DB Field**.
161131
162-<figure>
163-<img src="lazreptutmasterdata.png" title="lazreptutmasterdata.png" />
164-<figcaption>lazreptutmasterdata.png</figcaption>
165-</figure>
132+![](/wiki-images/6/6a/Lazreptutmasterdata.png)
166133
167134You can use all kinds of operators and functions in your calculations; see [[LazReport Documentation|LazReport Documentation#Documentation]] for an overview.
168135
169136#### Formatting output
170137
171138You can control how the text in the rectangles is displayed.
172139
173140Let's first add a new rectangle with the *Hire date field* variable.
174141
175142In the variable editor, let's set a format. A format is valid for all variables of a rectangle/object. To show the format editor, double click on a rectangle to get the Text Editor, then click the *Format* button.
176143
177144Let's set the date format you want here:
178145
179-<figure>
180-<img src="lazreptutformattingdate.png" title="lazreptutformattingdate.png" />
181-<figcaption>lazreptutformattingdate.png</figcaption>
182-</figure>
146+![](/wiki-images/1/12/Lazreptutformattingdate.png)
183147
184148The first ComboBox indicates the type of data (text, numeric, date, time, logical/boolean). The second lets you select a preset format.... with some obvious restrictions:
185149
186150- The Text type does not allow any Number type formatting.
187151- The Number type requires a number of any type (Integer, Double, Currency...).
188152- The Date type: you can choose a pre-defined format or write a custom format like MM/DD/YY for example.
189153
190154Except for Text and Logic types, you can use the formatting strings you also use in Lazarus.
191155
192156Other formatting options are present on the button bar below the menu (e.g. bold, italic, highlighting).
193157
194158Highlighting is very useful for emphasizing data. You can specify a condition that determines when highlighting is applied.
195159
196160For that, use the keyword Value to indicate the value of the variable. Here is the highlighting for all hire dates later than 1989. Because Hire date is a TDateTime field (which internally is a float), I cheated by just using the float value of January 1st, 1990 which is 32874. By default highlighter is a simple bold on white background. You can set these parameters to an area by clicking the Highlight button.
197161
198-<figure>
199-<img src="lazreptutconditionalhighlight.png" title="lazreptutconditionalhighlight.png" />
200-<figcaption>lazreptutconditionalhighlight.png</figcaption>
201-</figure>
162+![](/wiki-images/d/df/Lazreptutconditionalhighlight.png)
202163
203164#### A picture is worth...
204165
205166If you haven't already, we'll need to add a PHOTO field to our test database; using an SQL statement like this (note: unfortunately different databases use different syntax; BLOB can be CLOB,IMAGE,OLE...):
206167
207168`ALTER TABLE EMPLOYEE ADD PHOTO BLOB;`
208169
209170Now add some test data - the example here uses jpg files - into the PHOTO field with your favourite database tool. Note: this is the way Delphi DBImage works: just binary blobs with image data. By default, Lazarus DBImage is more flexible and stores the file extension before the image data, allowing different file formats to be used. For simplicity's sake, we'll use the Delphi approach.
210171
211172> **Note:** For this "DBImage BLOB without file extension info" to work, you'll need the patch from issue 25453/at least revision ... of LazReport
212173
213174Now we have to tell the report you need to treat all data as binary jpg image files. Click on frReport1, go to Object Inspector, events and initiates a procedure OnDBImageReader:
214175
215176```delphi
216177procedure TForm1.frReport1DBImageRead(Sender: TObject; S: TStream;
217178 var GraphExt: string);
218179begin
219180 // Force TDBImage to Delphi compatible behaviour: únicamente acepta un formato de fichero, e.g. jpg
220181 // esto significa que los BLOBs de la base de datos deben ser justamente ficheros jpg binarios sin más datos.
221182 GraphExt:='jpg';
222183end;
223184```
224185
225186In File\>Variables List, add the SQLQuery1.PHOTO field as variable Photo field, similarly to how you did this before. If you don't see the field, you may need to set the form's SQLQuery to inactive and active again to refresh the list of columns.
226187
227188Click on the Insert image... icon on the left of the window; now click on the right side of the band to drop the image control. A Picture editor shows up:
228189
229-<figure>
230-<img src="lazreptutpictureeditor.png" title="lazreptutpictureeditor.png" />
231-<figcaption>lazreptutpictureeditor.png</figcaption>
232-</figure>
190+![](/wiki-images/4/48/Lazreptutpictureeditor.png)
233191
234192If you wanted to always show the same picture, you'd just need to click Load ... (or double click on the picture control) and choose your image.
235193
236194However, let's press the Memo button and insert your Photo variable:
237195
238-<figure>
239-<img src="lazreptutphotofield.png" title="lazreptutphotofield.png" />
240-<figcaption>lazreptutphotofield.png</figcaption>
241-</figure>
196+![](/wiki-images/5/56/Lazreptutphotofield.png)
242197
243198This turns the picture into an object associated with the data field. Press OK as needed to get back to the report designer.
244199
245200Adjust height and width as needed.
246201
247202You can also press F11 to show the Object Inspector which allows you to edit more if needed:
248203
249-<figure>
250-<img src="lazreptutobjectinspector.png" title="lazreptutobjectinspector.png" />
251-<figcaption>lazreptutobjectinspector.png</figcaption>
252-</figure>
204+![](/wiki-images/b/b1/Lazreptutobjectinspector.png)
253205
254206Close the report editor and save the report definition (with the same name, **lazreporttutorial.lrf**).
255207
256208If you go to File\>Preview, you'll see your report includes the images.
257209
258210Close the report editor and save the report definition as **lazreporttutorial.lrf**.
259211
260212### Detail data
261213
262214To do: show how to use the detail part of master/detail. see e.g. sample in components/lazreport/samples/editor directory; see the button title "Master-Detail" **Please write me.**
263215
264216### Loading the report from the form
265217
266218Now let's write the code required to load and view or edit our report. To this add the following code to the project:
267219
268220```delphi
269221TForm1.Button2Click(Sender procedure: TObject);
270222begin
271223 frReport1.LoadFromFile('lazreporttutorial.lrf');
272224 frReport1.ShowReport;
273225end;
274226TForm1.ButtonClick(Sender procedure: TObject);
275227begin
276228 frReport1.LoadFromFile('lazreporttutorial.lrf');
277229 frReport1.DesignReport;
278230end;
279231```
280232
281233You have a preview option that gives end users a way to modify the report without changing the basic application.
282234
283235### Printing
284236
285237Now we're going to add features to our basic example.
286238
287239Add a TButton component with Caption := 'Print...', and a TPrintDialog. Behind the scenes, a project dependency on the **Printer4Lazarus** packages will be added by the IDE, so make sure that package is installed.
288240
289241We end up with this:
290242
291-<figure>
292-<img src="lazreptutformwithprintbutton.png" title="lazreptutformwithprintbutton.png" />
293-<figcaption>lazreptutformwithprintbutton.png</figcaption>
294-</figure>
243+![](/wiki-images/e/e3/Lazreptutformwithprintbutton.png)
295244
296245Now add the **printers** unit to your form's uses clauses.
297246
298247Put the following code in the OnClick event of the **Print** button:
299248
300249```delphi
301250procedure TForm1.Button3Click(Sender: TObject);
302251var
303252 FromPage, ToPage, NumberCopies: Integer;
304253 ind: Integer;
305254 Collap: Boolean;
306255begin
307256 // Load report definition from application directory
308257 AppDirectory:=ExtractFilePath(ParamStr(0));
309258 frReport1.LoadFromFile('lazreporttutorial.lrf');
310259 // Need to keep track of which printer was originally selected to check for user changes
311260 ind:= Printer.PrinterIndex;
312261 // Prepare the report and just stop if we hit an error as continuing makes no sense
313262 if not frReport1.PrepareReport then Exit;
314263 // Set up dialog with some sensible defaults which user can change
315264 with PrintDialog1 do
316265 begin
317266 Options:=[poPageNums ]; // allows selecting pages/page numbers
318267 Copies:=1;
319268 Collate:=true; // ordened copies
320269 FromPage:=1; // start page
321270 ToPage:=frReport1.EMFPages.Count; // last page
322271 MaxPage:=frReport1.EMFPages.Count; // maximum allowed number of pages
323272 if Execute then // show dialog; if succesful, process user feedback
324273 begin
325274 if (Printer.PrinterIndex <> ind ) // verify if selected printer has changed
326275 or frReport1.CanRebuild // ... only makes sense if we can reformat the report
327276 or frReport1.ChangePrinter(ind, Printer.PrinterIndex) //... then change printer
328277 then
329278 frReport1.PrepareReport //... and reformat for new printer
330279 else
331280 exit; // we couldn't honour the printer change
332281
333282 if PrintDialog1.PrintRange = prPageNums then // user made page range selection
334283 begin
335284 FromPage:=PrintDialog1.FromPage; // first page
336285 ToPage:=PrintDialog1.ToPage; // last page
337286 end;
338287 NumberCopies:=PrintDialog1.Copies; // number of copies
339288 // Print the report using the supplied pages & copies
340289 frReport1.PrintPreparedReport(inttostr(FromPage)+'-'+inttostr(ToPage), NumberCopies);
341290 end;
342291 end;
343292end;
344293```
345294
346295It's a bit long, but if needed, you can create a descendant of TfrReport with an easier printing method or class , create a PrintReport (Report: string) procedure to load the report and print.
347296
348297When double clicking on **frReport1**, in the report designer File\>Page Options menu you get this:
349298
350299Select paper size:
351300
352-<figure>
353-<img src="lazreptutpapersize.png" title="lazreptutpapersize.png" />
354-<figcaption>lazreptutpapersize.png</figcaption>
355-</figure>
301+![](/wiki-images/9/90/Lazreptutpapersize.png)
356302
357303Choose desired margins, number of columns, and the space between them, layout order etc. ![](/wiki-images/4/4a/Lazreptutprintoptions.png)
358304
359305### Report options
360306
361307Via File\>Report Options you can set a default printer that will be used for the report (using the "Select when report loaded" checkbox).
362308
363309If you want to include the total number of pages with the page number on each page, you need to select **Two-pass report** (which tells Lazreport to build the report twice, inserting total number of pages on the second run).
364310
365-<figure>
366-<img src="lazreptutreportoptions.png" title="lazreptutreportoptions.png" />
367-<figcaption>lazreptutreportoptions.png</figcaption>
368-</figure>
311+![](/wiki-images/2/2e/Lazreptutreportoptions.png)
369312
370313On the **Other** tab, you can fill out some report metadata, as is done on the screenshot below: ![](/wiki-images/f/f6/Lazreptutreportoptionsother.png)
371314
372315### General purpose variables
373316
374317Now we'll add some report variables unrelated to the database data in our example. They let you e.g. show different names according to the context.
375318
376319To do this, open the report editor and select the File menu and the Variable List. Add a Test category, and a test1 variable the same way we did earlier (with a space before the variable name):
377320
378-<figure>
379-<img src="lazreptutvariableseditortestvar.png" title="lazreptutvariableseditortestvar.png" />
380-<figcaption>lazreptutvariableseditortestvar.png</figcaption>
381-</figure>
321+![](/wiki-images/8/8d/Lazreptutvariableseditortestvar.png)
382322
383323The only difference is that you will not select a value field, but leave None (the default value): ![](/wiki-images/2/20/Lazreptutvariabletest.png)
384324
385325Return to Lazarus (do not forget to save your report, if necessary) and set up the **OnGetValue'' event of the**frReport1''' component by adding the following code:
386326
387327```delphi
388328procedure TForm1.frReport1GetValue(const ParName: String; var ParValue: Variant
389329 );
390330begin
391331 // Conditionally assign value:
392332 if ParName='test1' then
393333 ParValue:='Answer: Variable "test1"'; //perhaps replace with a call to a random function or something?
394334end;
395335```
396336
397337Alternatively, you can also pass the value directly to the variable using the following code:
398338
399339```delphi
400340procedure TForm1.Button1Click(Sender:TObject);
401341begin
402342 frReport1.Values.FindVariable('test').Field := QuotedStr('test1');
403343 frReport1.ShowReport;
404344end;
405345```
406346
407347## See also
408348
409349- [[LazReport Tutorial/pt|Tutorial de LazReport]] Version used as a basis for this translation.
410350- [[LazReport Documentation]]
411351
412352---
413353*From the Free Pascal wiki, page "LazReport Tutorial", as it stood on 2020-04-02 after a change by Volkir, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
414354Category: LazReport
415355Category: Lazarus
416356Category: Tutorials

Back to history