Quick Report FAQ [ 1 ]
猛料论坛欢迎大家贴出超级猛料没有包含的新资料,谢谢!
 
 
 

QuickReport Knowledge Base (kb.txt)

Frequently asked Questions (and Answers) and other tips

Copyright 2000 Qusoft AS

Visit our web site at http://www.qusoft.com

You will want to turn word wrapping on when viewing this file.

Revision 2.64

Last updated on January 4, 2000

QuickReport 3 specific items will start with the text "(QR3)" or will appear in their own section. Delphi 4 items will start with "(D4)"

We have added a QuickReport 3 Release Notes web page at http://www.qusoft.com/relnotesqr3.htm which will contain the latest news on QR3.

The PDF versions of this file were created automatically using code provided by TK Cham. He has a web site at http://members.xoom.com/tkcham/pdfindex.html

[Adding reports and/or controls at runtime]

==================

Q. How do I create a group band at runtime?

A. You can call the band's create constructor and set it's properties.

with TQRGroup.Create(Self) do

begin

Parent := QuickRep1;

Master := Parent;

Expression := 'CustNo';

end;

with TQRDBText.Create(Self) do

begin

Parent := QRGroup1;

Dataset := QuickRep1.Dataset;

DataField := 'CustNo';

end

------------------

Q. When I use QRCreateList() it looks like it's finding fields from the current record in another dataset. The other dataset has the same field names as the one that I am passing to QRCreateList().

A. The problem is in the field names. The QRCreateList adds TQRExpr controls to the report and sets the expression to the field name without the table name. When the report runs, QuickReport searches until it finds the first matching field name. Without the table name, it will use the first dataset that has a matching a field name. This is a known bug and will be addressed in a future release. That's the bad news. The good news is that you can easily alter the report after calling QRCreatelist and add the table name to the expression.

Example:

QRCreateList(aReport, Self, MyTable, 'Customer Listing', SomeFields);

{ Search the detail band for any TQRExpr controls and insert }

{ the table name after the left bracket in the expression }

for nIdx := 0 to aReport.Bands.DetailBand.ControlCount -1 do

if aReport.Bands.DetailBand.Controls[nIdx] is TQRExpr then

with TQRExpr(aReport.Bands.DetailBand.Controls[nIdx]) do

Expression := '[' + aReport.DataSet.Name + '.' + copy(Expression, 2, 99);

(QR3) This has been fixed for QuickReport 3. Also with QR3, areport must be of type TCustomQuickRep

------------------

Q. When I create a report at runtime and pass it to QRCreateList(), it does not use my title.

A. This is happening because you have created the report before the call to QRCreateList. If the report that is passed to QRCreateList is nil, then it is assumed that you want QuickReport to create the entire report for you. If you pass in a report that has already been created, we assume that you have already formatted the report with a title, pageheader, pagefooter, etc, and that you only want QuickReport to create the detail band for you.

------------------

Q. Using QR2 (or later) and trying to call addprintable in the beforeprint event of a band causes a GPF (or an Access Violation). Is this not allowed for some reason?

A. You can only call AddPrintable or otherwise add a control to a report band before you start the report. QuickReport needs to know about all printable controls before it starts the report.

------------------

Q. I am generating report at run time and I have a question: If for example I set QuickReport.HasTitle as true it automatically creates the title band. The problem is that I won't be able to know the name of title variable that was created.

A. You can reference it through the report's bands property like with the following example:

with QuickRep1 do

begin

ReportTitle := 'Sample Report';

Bands.HasTitle := true;

with TQRSysData(Bands.TitleBand.AddPrintable(TQRSysData)) do

begin

Data := qrsReportTitle;

AlignToBand := true;

Alignment := taCenter;

end;

Preview;

end;

This adds a titleband with the report's title centered on the band. You will need to add the quickrpt and qrctrls units to the use list in the unit that has this code.

You can reference each band type that can be set through the HasXXXXX properties from the following list:

TitleBand

PageHeaderBand

ColumnHeaderBand

DetailBand

PageFooterBand

SummaryBand

------------------

Q. If you use the method AddPrintable, how can you access the control that was created?

A. Just assign the control created by AddPrintable to a variable of that type of control. You can then change the top and left properties by referencing that variable.

Example:

var

MyCtrl : TQRSysdata;

.....

MyCtrl := TQRSysData(Bands.TitleBand.AddPrintable(TQRSysData));

with MyCtrl do

begin

Data := qrsReportTitle;

AlignToBand := true;

Alignment := taCenter;

end;

------------------

Q. I get an error when I try to use the QRCreateList example from the manual.

A. You must make sure to set the aReport variable to nil before calling the QRCreateList method. This was omitted from the documentation. The following example shows how to call this method:

procedure TFormMain1.btnCreateListClick(Sender: TObject);

var

aReport : TQuickRep;

SomeFields: TStringList;

MyTable: TTable;

nIdx: integer;

begin

{ Create a table on the fly, this example uses a table from the demo database }

MyTable := TTable.Create(self);

{ create the list of fields to output from the table }

SomeFields := TStringList.Create;

with MyTable do

begin

DatabaseName := 'DBDEMOS';

TableName := 'COUNTRY.DB';

ReadOnly := True;

Active := True;

{ For this example, we will pull the field names from the table }

for nIdx := 0 to FieldCount - 1 do

SomeFields.Add(Fields[nIdx].FieldName);

end;

{ You must set the report object to nil before calling QRCreateList}

areport := nil;

{ Build the report }

QRCreateList(aReport, Self, MyTable, 'Test Listing', SomeFields);

{ You can change the report objects before calling the report }

areport.page.orientation := poLandscape;

{preview or print the report}

aReport.Preview;

{ all done, free the objects }

aReport.Free;

MyTable.Free;

SomeFields.Free;

end;

------------------

Q. How can I change the field width and spacing in a report created with QRCreateList?

A. The width of the fields is calculated by setting the caption of each header to the character 'X', with count coming from the field's DisplayWidth property. The spacing between each field is set to 10. If you change the displaywidth property of a field, it will be reflected in the report.

To change the spacing, you can either modify the source code or change the spacing in the report after you call QRCreateList.

Example:

QRCreateList(aReport, Self, tbCountry, 'Test Listing', SomeFields);

// Now reduce the spacing between each field by 5 (nIdx declared as integer)

for nIdx := 0 to aReport.Bands.ColumnHeaderBand.ControlCount -1 do

if aReport.Bands.ColumnHeaderBand.Controls[nIdx] is TQRPrintable then

with TQRPrintable(aReport.Bands.ColumnHeaderBand.Controls[nIdx]) do

Left := Left - (5 * nIdx);

for nIdx := 0 to aReport.Bands.DetailBand.ControlCount -1 do

if aReport.Bands.DetailBand.Controls[nIdx] is TQRPrintable then

with TQRPrintable(aReport.Bands.DetailBand.Controls[nIdx]) do

Left := Left - (5 * nIdx);

------------------

[Bands]

==================

Q. I have a detail band with 3 stretching QRLabels on them, When the band breaks over a page, I get some of the 1st QRLabel on one page and the rest of that QRlabel with all of the other QRLabels on the next page. Is there any way to get to split all three components over the page?

A. No, this is a limitation of QuickReport. When a band prints, it starts out at it's design time size and prints each component, one by one. If a component can stretch, the band stretches in increments until all of the text has printed. If this happens over a page break, it will print what is already on the band. With three stretching controls, we are not going to be able to print them all at the same time when the band goes over a page break.

You have several options depending on where the data comes. If you can build the text line by line. I would use a subdetail band with 3 single components. You could use the OnNeedData event to loop the subdetail band to print each line. If the band is less than the height of the page, you could run the report in 2 passes and record the stretched length of the band in pass one and use that value to manually size the band on the 2nd pass. There is a Delphi example on our download page named QR3LSD4.ZIP that has most of the code for doing this. Another option would be to put the data in a single RichEdit component and separate the data by tabs. That would print as a single component.

------------------

Q. My report goes out of control when I have child bands attached to the page header.

A. You can not have a page header where the height (including all child bands ) is greater than a page. This is not supported. When the page header prints, the child bands that belong to the page header will be printed. If one of the child bands doesn't fit on the page, it will cause a page break and the page header print code will be called again. This will put the page header code in a recursive loop until the computer runs out of disk space or memory.

------------------

Q. I just added a new subdetail band and it's at the bottom of the report. How do I put it in the correct location?

A. The band order is determined by the band type, it's master property, and it's creation order. If the master property is blank, then the band will be placed at the bottom of the report. If the subdetail band "belongs" to the detail band, then the master property should be set to the report. If it belongs to another subdetail band, set the master property to that band

------------------

Q. I just added a subdetail band to a report that already has a couple of subdetail bands. How can I put the new band above the other ones?

A. If you are trying the subdetail band before another one that has the same value for the master property, the safest way to do this is to view the form as text and cut and the paste the band to the location that you want. The band order is determined by the band type, it's master property, and it's creation order.

------------------

Q. Why does GroupHeader (or Detail) band's BeforePrint event executes before than PageHeader band's BeforePrint event?

A. When the GroupHeader (or Detail) band's BeforePrint event has executed, the report is still on the previous page. After it processes the BeforePrint, it checks to see if the band will fit on the page. f it doesn't fit, a new page is generated and the PageHeader BeforePrint event is called. You can suppress the band from printing with the BeforePrint event, that is why it doesn't do a new page until after the BeforePrint event has run.

------------------

Q. I would like to have a blank row every fifth line. Is there an example on how to do this?

A. A simple way to this is to add a childband to the detailband. In the ChildBand's BeforePrint event, set the PrintBand variable that is passed in the event to true every 5th band and false the rest of the time.

Example:

procedure TfrmBands.ChildBand1BeforePrint(Sender: TQRCustomBand;

var PrintBand: Boolean);

begin

PrintBand := (TQuickRep(Sender.Parent).RecordNumber mod 5) = 0;

end;

------------------

Q. My ColumnHeader bands are not printing when there isn't any data for the report

A. You must have at least one detail band printed to print a column header band.

------------------

Q. I found this Bug in one of my reports, where the Detailband has the height of two lines and the AutoStretch Label is on the first of this lines. So the Band was expanded, still if there was enough room for a second line.

A. This is not a bug, it is designed this way. Our assumption is that if you have extra space below a control, then that space is there for a reason and we expand the band to keep that space. You could increase the height of the control to cover that space and then the band will not increase until that space is used up.

------------------

Q. I have a childband and I set it's PrintBand to false based on certain conditions. When the band doesn't print, QuickReport doesn't check this and will generate a new page is this band would have been the last band on page.

A. QuickReport checks the space required for the next band before the BeforePrint event of that band is processed. There is a simple work around that will resolve this issue. In the BeforePrint event of the previous band (in this case, the detail band), set the height of the child band to 0. You could store the height of the child band in it's Tag property at the same time. In the BeforePrint event of the ChildBand, you would set the height back to original height when you have set PrintBand to True.

------------------

Q. How can I create a report with a Title band to print ABOVE the Page Header band?

A. The print order of the bands is fixed, you can not print a title band above the page header. One work around would be to use a child band with the page header. Put the page header information on the child band and place the title information on the actual page header band. In the Page Header band's BeforePrint event, set PrintBand to false when the report's PageNumber property is greater than 1.

------------------

Q. How do I get the column header for to print right above the detail band when I also have a group band?

A. ColumnBands always printed at the top (after the title and pageheader bands). There are a couple of ways of doing what you are looking for. You could either put the column labels on the group band or on a child band attached to the group band.

------------------

Q. Is there a way to print a band as footer only on the last page of a report.

A. Instead of using a footer band, use a summary band and set it's AlignToBottom property to true.

------------------

Q. When my band is split on two pages, how can I keep the non-stretching text controls on the first page?

A. If you have both stretching and non-stretching components on the same band make sure the non-stretching are printed first (right click and select 'send to back')

------------------

Q. How do I disable the detail band so that I can calculate in the detail section without printing it? I just want the summary band to print.

A. Set PrintBand to false in the band's BeforePrint event. That will suppress the output of the band, but the expressions will still be calculated.

(QR3) NOTE: This behavior changed with QuickReport 3. To emulate the Quick Report 2 code, instead of setting PrintBand to false, set the height of the band to 0 when you want to suppress it and still use it for functions. Just remember to set the height back to the design time height when you do want to print the band.

------------------

Q. How can I add a child band at runtime and fields to it?

A. The way to create a child band is to set the HasChild property of the parent to true. The following code creates a child band and then adds a QRLabel control to the child band

QRGroup1.HasChild := true;

with TQRLabel(QRGRoup1.ChildBand.AddPrintable(TQRLabel)) do

begin

Left := 0;

Top := 0;

Caption := 'Hello there';

end;

------------------

Q. Is there any possibility to extract the fields embedded in a specific band during run-time?

A. The bands are descended from TCustomPanel and you can use the ControlCount property to loop through all of the controls on the band.

For example:

with PageHeaderBand1 do

for nIdx := 0 to ControlCount -1 do

if Controls[nIdx] is TQRLabel then

TQRLabel(Controls[nIdx]).Caption := IntToStr(nIdx);

------------------

Q. We trying to use a QRBand in order to create a 'ColumnFooter' but w/o success. Do you have some tip ?

A. Quickreport does not have a column footer band. One way to get a band to print at the bottom of each page would be to use a page footer band and place QRLabels underneath where each column would be.

------------------

Q. How do I reference the name of a childband created at runtime by setting a band's HasChild property to true?

A. You must create the Childbands before the report starts. All QuickReport bands and controls must exist before the report starts. The easiest way to create a childband is the set the HasChild Property of the parent band to true. You can reference the child band through the Parent band's ChildBand property. The childband will have a blank name property, but you can set that at runtime. The following example shows how to create a childband, add a label to it, and then get the name of that band:

procedure TfrmReport.FormCreate(Sender: TObject);

var

MyChild: TQRChildBand;

begin

QRGroup1.HasChild := true;

with TQRLabel(QRGRoup1.ChildBand.AddPrintable(TQRLabel)) do

begin

Left := 0;

Top := 0;

Caption := 'Hello there';

end;

MyChild := QRGRoup1.ChildBand.Name;

end;

------------------

Q. How do I check the height of a band with stretching controls at runtime?

A. This can not be done with QuickReport 2.0. The ability to retrieve the height of stretching controls will in the 3.0 release (due out later this year).

------------------

Q. Is it possible to have 2 or more PageHeader Bands in same Report ?

A. You can not have multiple PageHeader bands on a report, but there are ways to resolve this. The simplest way would be to add a child band to the page header and put the fields on the child band that would be used for the 2nd page header. You would then use the BeforePrint event of the page header and of it's child to decide at run time which band to print.

------------------

Q. I have a detail band with a child band. I want to change the number and layout of the controls on the child band at runtime, but I get an exception error when I add new controls while the report is running.

A. All bands and the controls on the bands must be created before the report starts, otherwise you will get the exception that you reported.

There are a couple of ways of doing this. One way is to have multiple child bands, each one with a different layout to fit your needs. At run-time, you control which child bands can be output. Just use the BeforePrint event and set the PrintBand variable to false for the ones that you do not want to print.

If you only want one band, put all of the controls on it. and at run time hide the ones that you do not need by setting their Enabled property to false. To have the controls use the enabled property, you must be using version 2.0j or newer.

------------------

Q. I have a report that has about 10 child bands that may or may not get printed depending on run time criteria. This report always prints two pages, even if it only needs one to accommodate the Childbands allowed at run time. Is there a workaround for this?

A. In the report's form create event, set each childband's tag property to it's height value and then set the height to 0. Whenever you set printband to true in the BeforePrint event of a band, set the band's height to the it's tag value. In the AfterPrint event, set the height back to zero again.

------------------

[Barcodes]

==================

Q. Where can I get a barcode component to use with QuickReport?

A. We do not provide a barcode control, but on our download page, there are some links to companies who do barcode controls for QuickReport.

------------------

Q. Where can I find a barcode font that I can use with QuickReport?

A. There are many companies that have barcode fonts, here are a few of them:

CIA (Bar Codes), Wythenshawe, Manchester, UK http://ourworld.compuserve.com/homepages/CIA_UK

Rivers Edge, Cedar Park, TX, USA http://www.riversedge.com

Azalea, Seattle, WA, USA http://www.azalea.com

------------------

[C++Builder]

==================

Q. I can not find any of the C++ source code files to QuickReport.

A. QuickReport is written entirely in Delphi, there are no C++ files in the package. C++Builder has the ability to compile Delphi files directly to .obj and .hpp files.

------------------

Q. I tried to build one the demo projects, only to get errors indicating that the files VCLMID40.bpi and DSS40.bpi could not be found.

A. You will have to remove those references from the project or makefiles (the file with the .BPR extension). C++Builder includes package references from the C++Builder C/S version even though those packages were never referenced by the demo. If that does not work, delete the project file and create a new one using the units from this project.

------------------

Q. I mix Delphi code with C++ code in 3.0.5 and C++Builder 4 and I get an error about qrlabled not being compiled with the quickrpt unit.

A. The 3.0.5 installer copied the qrlabled.* files to the lib directory and they should be in lib. If you manually copy the files in, that will fix the error.

------------------

Q. I just installed QR 3 into C++Builder 4 and I can't link the project that I created with BCB3.

A. Make sure that the project is using qrpt40 as the runtime package instead of the qrpt43c file from BCB3. The QR3 installer will not modify your project files, you may have to manually edit the .bpr files.

------------------

Q. I just installed QR 3 into C++Builder 3 and I can't link the project.

A. Make sure that the project is using qrpt43c as the runtime package instead of the qrtp35 file from QR2. The QR3 installer will not modify your project files, you may have to manually edit the package list and header files used by the project. For C++Builder 4, the package name is qrpt40.bpl.

------------------

Q. I just installed 3.0.5 into C++Builder 4 and the preview's print and print setup buttons are disabled.

A. We have had isolated reports of this and it appears to be related to the precompiled headers feature of C++Builder. Try deleting the vcl40.csm file (or the filename listed under the compiler project options for precompiled headers) from the cbuilder4directory.

Select 'Build with runtime packages' in the program options, and verify that qrpt40.bpl (C++Builder 4) or qrpt43c.bpl (C++Builder 3) is in the corresponding package list. The QR3 installer will not modify your project files, you may have to manually edit the package list and header files used by the project.

------------------

Q. I get an access violation if set the detail band's ForceNewPage property to true at runtime.

A. This can happen if you smart linking enabled. You can either turn off the smart linking or set the property at design time.

------------------

Q. I am trying to write my own Quick Report control using C++Builder 3.0, but I am getting an incorrect value when I try reading the TQRPrinter's FXFactor property? It evaluates as 1.68100026993337964E-4932 when it should be 1.

A. A user did some research on this and discovered BCB 3 thinks that variables of the type extended are 12 bytes (instead of 10 bytes) and is shifting the data by two bytes when an extended variable is used in a class. If you need to use extended variables in Quick Report classes, it may be easier to do that code in Delphi Pascal and just let BCB compile it in.

------------------

Q. I have a project in which I'm using QR2.0i (standard CB3 package). I installed Quick Report 3 and recompiled. The program won't run because of the exception "objectname->Functions.Strings: Property does not exist." I have not changed the code in any way.

A. You will need to check your project make files to make sure that you are not pulling in any QR2 header or object files. The functions property is a property of the TCustomQuickRep class and does not exist in QR2. You would get this message if you tried to compile a form with a QR3 object but used Qr2 header files. You will need to replace any reference to the QR2 package file QRPT35.bpi with qrptc43.bpi.

------------------

Q. Will my Quick Report professional 2.0i work with new C++Builder 3.0 or I should wait for an upgrade from you?

A. The current release will not work with it, but C++Builder 3.0 will come with a version of QuickReport 2 that we have compiled for it. We will post new releases for it after Borland releases 3.0.

------------------

Q. I am trying to use QuickReport with C++Builder, but your documentation and examples are all Delphi based.

A. QuickReport is primarily a Delphi product, we do not have the resources to provide the same level of support to the C++Builder users as we can for Delphi users.

------------------

[Composite Reports and multiple dataset reporting]

==================

Q. How do I make a MDI custom preview that supports the CompositeReport?

A. Custom Previews for CompositeReports can be done in the Delphi version of QuickReport 3. There is a QR3 MDI demo project on our download page. Due to language differences, this fucntionality is not available for C++Builder.

------------------

Q. I have an application that saves a series of reports to the QRP format. I would like to print them all at once as a single print job, is that posible?

A. In the QR3RNGD4.ZIP project on our download page, we have a function named CombineQRP() in the qrqrp.pas unit. The function takes a stringlist of QRP filenames and combines them into a single QRP file. You can then load that file into a preview or the TQRPHandler class for viewing or printing. This can be used as an alternative to the CompositeReport.

------------------

Q. The save button does not work for the export filters in the preview for the composite report.

A. The export filters are not supported by the TQRCompositeReport component. The only work around is to export each report individually.

------------------

Q. What are the steps to load reports and preview composite reports. I add reports to the TList property of QRComposite and then call preview and the preview is empty.

A. You must add the reports in the TQRCompositeReport's OnAddReports event or they will not be picked up.

Example:

procedure TMainForm.QRCompositeReport1AddReports(Sender: TObject);

begin

with QRCompositeReport1 do

begin

Reports.Add(ListForm.QuickRep);

Reports.Add(GrpListForm.QuickRep);

Reports.Add(MDForm.QuickRep);

Reports.Add(ManyGrpForm.QuickRep);

end;

end;

------------------

Q. How can we save a composite report to a file (*.QRP) from source code? (We can not access a QRPrinter object for Composite Report (seems to be declared 'private')).

A. You should be able access the qrprinter by referencing the qrprinter of one of the individual reports in the composite report after you call Prepare.

------------------

Q. Is there a way to set it up so that each individual report making up the composite starts on a new page when that portion goes to print?

A. To get the second (or 3rd...) report to start on a new page, make sure that 2nd report has a title band and in the title band's BeforePrint event, call the NewPage method of the second report. If this report is used outside of the composite report, you will need to disable that code.

------------------

Q. Why wasn't the Composite Report fixed in 2.0 or 3.0?

A. There are problems with TQRCompositeReport that are related to printer settings, header/footer bands, exporting, and a few other issues. If this isn't important to you please use the component as much as you like. The reason for not publishing the fixes is that they require changes to the interface sections of the units/packages and this breaks package dependencies with Delphi and 3rd party packages that use QuickReport.

You can build a single report that would behave like multiple reports. The way you would lay it out would be to leave the detail band empty and set PrintIfEmpty to true. Then add subdetail bands to handle each report. The master property of each band would be set to the report and they would run one after the other. You would use each subdetail band as if it was the detail band for the individual report.

An alternative way would be to use the report's Prepare method and save the report to a .QRP files (example code can be found in our Knowledge Base on our download page.) We have a demo project on our download page named qr3rngd4.zip that has a unit named qrqrp.pas. This unit has a function called CombineQRP() that can take a list of QRP files and generate a single QRP file from them. You can then preview and or print that file with the TQRPHandler class.

------------------

Q. I wish to create a report which lists the contents of two unrelated tables. How do I do this if you can only have one detail band per report?

A. Use multiple subdetail bands, one for each table. Set their Master property to the report. You don't need a detail band, but you will need to set the PrintIfEmpty property of the report to true. Each subdetail band can have nested subdetail bands and group header and footer bands.

------------------

Q. One of the reports in my Composite Report has Landscape Orientation, and the others are Portrait. The report prints everything in Portrait

A. You can not mix landscape and portrait oriented reports with the composite report.

------------------

Q. I'm currently using QuickReports for printing static forms without any report functionality. This works fine for me. Then I try to print multiple forms (multiple TQuickReps) as one print job. Therefore I磎 using the TQRCompositeReport component but if there are no report components on the TQuickReps nothings happens if you try to print or preview. Is there a way to print different static forms as one print job ?

A. The CompositeReport control requires that the reports have their controls on report bands. I was able to print two static reports in a composite report by using a detail band size to fit the page and with the report's PrintIfEmpty set to true.

------------------

Q. In a report I need just to apply a new filter to the qreport dataset and then continue the report. It's like running several reports but "bundled" all together in one preview / report.

A. You can not change the filter on an open dataset, that's a BDE limitation. One way to do this would be to use multiple subdetail bands for each band. Each band could use the same dataset. You would add a group footer band to each dataset. You would close it, change the filter, and the reopen it in the group footer band of the PREVIOUS dataset.

------------------

[Datasets]

==================

Q. Is it possible to exclude the BDE in any of the 2.x versions of QuickReport as one can do with QR1.1a using the line: {$define XBDE}? If so, which 2.x version?

A. QuickReport 2 does not have the XBDE compiler directive that was in QuickReport 1. If you are using Delphi 2 or later, this should not be a problem, as the BDE does not get initialized until the first time that it's called. If you are using Delphi 1, the only alternatives are to either include the BDE or to use QuickReport 1.

------------------

Q. I am getting the error "Unable to locate source file "quickrpt.pas" and after that EBDEngineError "Table does not support this operator"

A. There appears to be a bug in the BDE that allows datasets to make a call to the RecordCount property when that value is not supported by all databases. We have yet to find a satisfactory work around that works for all databases. You can manually edit the quickrpt unit and comment out the call that causes this exception.

Copy the quickrpt.pas to your project directory.

Look for the line that contains "RecCount := ParentReport.RecordCount;" in the quickrpt unit (the location of the line in the unit will vary depending on which release of QR2 you are using) and comment it out.

Recompile your report (you don't need to add the quickrpt unit to your project, Delphi will find it).

Even though there is a try..except block in our code, Delphi is still throwing an exception. If you modify this code in the quickrpt unit and comment out the code in the if DataSetOK block, you will no longer get that error.

------------------

[DLLs and ActiveX]

==================

Q. I'm passing a dataset to a report in a DLL and none of the TQRExpr controls are displaying data.

A. The TQRExpr control checks the type of the dataset field. When you pass a dataset to a report in a dll, the runtime type information (RTTI) is not available and the TQRExpr control can't check the data type.

------------------

Q. Is there any known problems using Quick Report in a Delphi 2 (or 3) DLL??Each time I am finished and make a call to FreeLibrary() from my calling application, the calling application freezes.

A. There is a known problem unloading a Quick Report dll, something is not being freed and that's why your call to FreeLibrary hangs.

The simplest solution is to add QuickRpt and QRprntr (and possibly QRextra) units to the uses clause of the calling app's project source unit. This way the QR dll's are already loaded and the dll will simply increase/decrease the reference count as it is loaded/freed.

------------------

Q. Where is the ActiveX component that is mentioned on your web page?

A. We still have some remaining issues to fix with the ActiveX component before we can release it.

------------------

Q. I think I have installed version QuickReport 3 correctly with Delphi 3, and it prints short reports if I call the PRINT command. If I use preview however, I receive a "Control has no parent window error" when I press the print button. I didn't have this problem with Version 2.0K.

A. The DLL needs a reference to the calling application so that the DLL's forms are children of the application. Please see the Delphi help page for TApplication.Handle.

------------------

[Documentation and help files]

==================

Q. I like to have the manual loaded, but Word takes up a lot of resources

A. We have an Adobe Acrobat version of the QuickReport 2 manual available via FTP from ftp://ftp.qusoft.no/pub/quickrep/qr2acro.zip

------------------

Q. I don't find information on TQRCompositeReport.

A. Documentation for the TQRCompositeReport will be included in a later release. There are a few programming issues that still need to be fixed for the Composite Reports and we will release the documentation after they have been resolved. The example demo program included with QuickReport 2 does use the CompositeReport so you can follow that if you wish to work with the CompositeReports before we release the update.

-----------

Q. I cannot find information about Options Property for TQuickRep

A. The first options (FirstPageHeader, LastPageFooter) are self describing. If the FirstPageHeader is set to false, then the page header will not be printed on the first page. LastPageFooter works in a similar manner If the Compression property is set to true, then a simple compression routine is used on the internal metafile storage of a rendered report.

Please note that a bug was introduced in Delphi 3.02 that prevents compressed QRP files from being loaded.

------------------

Q. How does the OnPrint event work?

A. The OnPrint event is called just before the control is printed. The string to be outputted is in the Value property and can be changed. This property is also useful to suppress printing of repeated values. This event only gets called at runtime, the design time preview will not call any of the event handlers.

------------------

Q. How do I install the help files into Delphi 3's integrated help?

A. 1. Copy the file QUICKRPT.HLP into the HELP directory under the Delphi 3 main directory.

2. Add the line

:Link quickrpt.hlp

to the "Third-Party Help" section at the bottom of the DELPHI3.CFG file located in the Delphi HELP directory.

3. Delete the hidden file Delphi3.GID in the HELP directory.

The next time you launch the Delphi 3 help, it will rebuild the delphi3.gid file and the QuickReport help file will be in the integrated help. Please note that this help file is not complete and will not have support for all controls. This will addressed in the 3.0 release.

------------------

[Exporting reports]

==================

Q. What is the best way to import pages from a report into a PowerPoint slide show?

A. Is you use the WMF export filter, PowerPoint can import the files with all of the formatting intact.

------------------

Q. Could you please tell me how to save a report with a qrp extension instead of printing or previewing it

A. You would call the report's prepare method to create the report. Then use the report's qrprinter.save method to save the file, and finally free the qrprinter object of the report.

Example:

quickrep1.Prepare;

quickrep1.qrprinter.Save('c:.qrp');

quickrep1.qrprinter.Free;

quickrep1.qrprinter := nil;

------------------

Q. I am writing a printable component for QuickReport 3 (using C++ Builder3) to display a schedule. I was wondering what needs to be done to make the printable component have the ability to export to the various export filters. Currently when I try to export to any filter other than wmf it exports to a blank file.

A. You would need to add code in your component's Print method that checks the report's Exporting property and call the report's ExportFilter->TextOut() function with the text to be printed. All of our code is in Delphi, but you should be able to do this with BCB3. In the source code for the qrctrls.pas unit, look at the PrintLine procedure, it show how we pass the text to the export filter for our standard text components.

------------------

Q. (QR3) When I add QR Filters to existing reports, I get duplicates in the file type drop down in the Save As ... dialog. How do I avoid/eliminate this?

A. How are you adding the filters? This can happen if you have multiple copies of a filter component, either on one form or multiple forms. If you place the filter components only on the main form, that makes it easier to prevent duplicates.

------------------

Q. How do I save a report to a QRP file in code?

A. You would use the report's QRPrinter.Save method to save a file in the QRP format. Save can be called after a report have been generated by Preview or Prepare.

------------------

Q. Is there any way to combine QRP files into a single QRP?

A. There is a demo project on our download page named QR3RNGD4.ZIP and it has a unit named qrqrp.pas. That unit contains a function named CombineQRP() for combining multiple QRP files ((as long as they all use the same page size and orientation)) to a single QRP file. You just pass in the new file name and a stringlist of existing QRP files, and it combines them.

------------------

Q. How do I call the Quick Report 3 export filters outside of the preview?

A. To call a filter explicitly you would use syntax like:

quickrep1.ExportToFilter(TQRXLSFilter.Create('c:.xls'));

Other filters:

HTML: TQRHTMLDocumentFilter

ASCII: TQRAsciiExportFilter

CSV: TQRCommaSeparatedFilter

RTF: TQRRTFExportFilter

WMF: TQRWMFExportFilter

------------------

Q. The output from RTF export filter looks odd when loaded into a TRichEdit control. If I load it into Word 97, it looks more like the report.

A. The RTF export filter was written to the MS RTF specification, version 1.5. I am not familiar with a control named TRichTextBox, but the files generated by this filter can be read by TRichEdit. TRichEdit does not fully support the RTF command sequence and it will not display RTF files with same accuracy as MS Word. For example, TRichEdit does not support right alignment.

------------------

Q. The output from the export filters does not match the preview's layout.

A. The export filter layout is a best fit approximation. You are taking controls that can be arranged anywhere on a band and sending them to a format that is not as flexible. You can get better results for the filters by changing the layout of the fields and/or their font property. The report has a boolean property, Exporting, that will be set to true when an export filter is running. You can add code in the BeforePrint event of the report to check this property if you want to make changes that would only take affect when exporting a report. If you are using proportional spaced fonts, the layout from the ASCII export filter is going to be a poor match. You will want to use a mono spaced font like Courier New instead of Arial for the controls. You could also set the font's Pitch to fpFixed and let Windows substitute the font for you.

------------------

Q. How do I use the WMF export filter outside of the preview?

A. The WMF export filter works differently than the other filters. The other export filters render the report using the filter. The WMF filter takes the pages rendered to the preview and saves each page as a metafile. To use this filter outside of the preview, you have to render the report first using Prepare.

Example:

quickrep1.Prepare;

quickrep1.qrprinter.ExportToFilter(TQRWMFExportFilter.Create('c:'));

quickrep1.qrprinter.Free;

quickrep1.qrprinter := nil;

Please note that the file named extension is picked by the Enhanced property to the export filter. EMF if it's True, WMF if it's false.

------------------

Q. When I export my report to the TXT export filter, I lose the TQRRichText fields

A. The TQRRichText, TQRDBRichText, TQRShape, TQRImage, TQRDBImage controls are not supported for the export filters (except for the WMF filter). One workaround would be to use a TQRDBText control for the RTF data and enable it (and disable the RTF control) when the report's Exporting property is set to true.

------------------

Q. I want to change the layout of the report when it is being saved with export filter, is there a way to determine when a report is being exported?

A. When an export filter is being used, the report's Exporting property will be set to true. Some of the current export filters have problems lining up columns when the column header's controls have a different alignment than the controls on the detail band. You can check the Exported property in the report's BeforePrint event and change the appearance of the controls based on that value.

------------------

Q. PrintPreview & Print work OK until I use ExportToFilter after which PrintPreview & Print do not produce output.

A. This was a known bug and was address in the 2.0j release

------------------

Q. When I try to export a previously saved report (a .QRP file), nothing happens.

A. Quickreport can only export reports when they are being generated. The .QRP saved file consists of a list of metafiles, one for each page. There is no way to take the data out of the metafile and export to another format.

------------------

Q. How do I get all of the export filters to show in the save dialog in my preview?

A. (QR2 only) Add the qrextra and qrhtml units to your report's uses clause and the filters in those units will show up at runtime.

(QR3) Just drop the export filter components on the main form of your application.

------------------

Q. How do I use the HTML export filter?

A. The export filter topics start at page 98 in the manual, under the topic "ExportFilter". The HTML filter is an add-on and you will need to add qrextra and qrhtml to your uses clause (and the QuickRep source directory will need to be on your library search path. You would call the HTML filter like this:

QuickRep1.ExportToFilter(TQRHTMLExportFilter.Create('file.htm'));

------------------

[Expressions and user functions]

==================

Q. I have been trying to use a summed expression in the summary band to calculate percentages in the detail band without success. I am trying to calculate and print each customer sales as a percentage of the the total sales for the report

A. You will not be able to do that unless you have the total first. The detail band prints as it reaches each record in the dataset, the total is not known until you have reached all of the records. You could do this by using a TQuery that just returned the total and use that field in your expression.

------------------

Q. How do you use Date and Time fields with the TQRExpr component? The IF() function has the wrong result when I compare date fields.

A. Date and Time fields are handled by QuickReport as strings, the IF() function can only handle strings or numbers. There are a few ways of around this. One way would be to add a calculated field to the dataset. That field would just be the date field's AsFloat property. You could then use IF() and compare it to the double value of the date that wish to compare it to. A variation would be to use a calculated string field that would return the data as a string in the format 'YYYY-MM-DD' using the FormatDateTime function. You could then use IF() to do a string compare of the dates. You could also bypass the TQRExpr component altogether and use a TQRLabel and set it's value with it's OnPrint event.

------------------

Q. Fields that have a period in the fieldname that are placed on a report via the QuickReport Wizard results in "Unknown function".

A. This is an open issue and the workaround is: Via the Object Inspector, go into the Expression Wizard and select the field so you have "Table1.F_ADT1.F_CHARL1" instead of "[F_ADT1.F_CHARL1] ".

------------------

Q. I tried changing the expression property of a TQRExpr component in the BeforePrint event of the detail band but it did not work.

A. The Expression property of the TQRExpr and TQRGroup components is read only the beginning of the report and can not be changed while the report is running. You can use the OnPrint event to override the output of the TQRExpr component.

------------------

Q. How can we Round Off a number, like to 2 decimal places?

A. We do not have a rounding function, but this is easy to emulate. Add 0.05 to the value, then multiply the value by 100, use the INT() function to truncate the decimal point, then divide by 100.0

------------------

Q. Can I test for multiple conditions with the SUM() function?

A. You would need to wrap the expressions in parenthesis like: SUM(IF(((PayType1='C') And (PayType2='N')), tPayments.PayValue,0.0))

------------------

Q. How can I do an IF() function for a field that has single quotes around it?

A. At design time you would enter into the Object inspector something like: IF(MyField=''SomeValueInSINGLEQuotes'', 1, 0)

In code you would syntax like QRExpr.Expression := 'IF(MyField='#39#39'SomeValueInSINGLEQuotes'#39#39', 1, 0)';

------------------

Q. I have a report with a TQRGroup,a DetailBand and a GroupFooter band. I want to sum certain values in the GroupFooter for each Group. The problem is that it doesn't sum within the group. It just keeps increasing the values until the end of the report. I don't get the sum for each group.

A. You will need to set the ResetAfterPrint property to true for the TQRExpr control that you are using on the GroupFooter.

------------------

Q. I am trying use the SUM() function inside the IF() function to do a conditional sum, but the control just prints the expression text. My expression is IF(Table1.PUR_PRICE>40, SUM(Table1.PUR_PRICE), '').

A. IOU are missing the 3rd parameter to the IF function and all three parameters are required. Try using an blank string ('') as the 3rd parameter.

Example: SUM(IF(COPY(Table1.pos,1,1)='M',table1.Price,0.0))

This would sum the table1.Price field for the current record if the Table1.pos starts with the letter "M". If the Table1.pos field did not start with "M", that record would not be included in the SUM() function.

------------------

Q. I would like to summarize the number of times a non numeric value repeats in a table (without making a new sqlquery like "select count(xxx) where xxx = 'yyy')

A. You can embed functions in other functions. You can use the IF() function in the SUM() function to sum the number of times a value appears in the dataset. The following expression will return the number of records where the state = 'HI', SUM(IF(Customers.State='HI', 1, 0))

------------------

Q. With the TQRExpr control, the expression -3*4 evaluates to 12 instead of -12

A. This is bug in QuickReport 2 (fixed in QuickReport 3) and the work around would be to use the expression (0-3)*4, which will give the correct value.

------------------

Q. When I create a report from the Delphi menu (File/New/Report), the QRExpr control does not find all of the datasets on that report.

A. When the report is not on a form, QRExpr controls will not pick datasets that are connected to the report unless you manually add them at runtime using AllDataSets. When the report is on a form, QRExpr will find the datasets on that form automatic.

------------------

Q. I am using a TQRExpr to print the SUM of a field of a Query. But I have a problem. If the Query has no result (zero records) then instead of printing the number 0, It is printing SUM(qry.Total).

A. This is a known problem with QR2 and the work around is to use the OnPrint event of the TQRExpr control to blank out or zero out the value when the value is equal to the expression like the following example:

procedure TfrmReport.QRExpr1Print(sender: TObject; var Value: String);

begin

if sender is TQRExpr then

if Value = TQRExpr(sender).Expression then

Value := '0.0';

end;

(QR3) This has been fixed with QuickReport 3

------------------

Q. When I add lines to a QRExprMemo control at runtime, the control does not filter out any blank lines that may have added.

A. This control filters out blank lines when the lines are defined before the report starts. When you add blank lines in the BeforePrint event, we assume that you actually want them in the memo. The work around is to add code to the BeforePrint event so that you are not adding blank lines at runtime.

------------------

Q. How do you use the FORMATNUMERIC function, I can't find a help files to help me?

A. This function is a wrapper for Delphi's FormatFloat() function.

------------------

Q. Is there an expression that will permit grouping by month? The underlying database has a date field.

A. You have to pass in an expression that would be the month, the easiest way is to use a calculated database field that would be the year and the month (unless you want the same month from multiple years grouped together.

------------------

Q. I want to have a database field as the expression, but the table is not available to me at design time and adding <tablename>.<fieldname> to the expression string at run time doesn't work.

A. To define an expression at runtime, you must define it before the report starts. Group bands initialize their expression at the start of the report and you can not change the expression while the report is running. This limitation will be removed in a future release.

------------------

Q. I couldn't find any information for the meaning of the "arguments" parameter in the RegisterQRFunction

A. The last parameter is used for the expression builder to know what

group to put the function in and what parameters to accept.

First is the group (1-6), followed by one character for each

parameter.

1NN would be in the first group (don't remember which one), with two

numeric arguments.

2SNB would be in the second group, three parameters (text, numeric

and boolean

------------------

Q. Expression wont work if the field name has a space or a hyphen in it

A. The expression parser will not work with field names with spaces or hyphens in it. This is a limitation that we try to fix in a future release. There are a few simple workarounds for this. One way is to use a TQuery control and rename the field name in the SQL statement. If you have to use a TTable, create a calculated field based that equals the original.

(QR3) With Quick Report 3, you can use fields with spaces in TQRExpr expressions if the field is enclosed in square brackets like '[Table1.Field 1]'.

------------------

Q. My function doesn't work I want to use:

if (table1.field1 = '', 'Blank', table1.field1)

to output the text "blank" when the field is blank or null

A. Change "if (" to "if(" and the function will work.

------------------

Q. I can't sum TTimeFields?

A. TTimefields get converted to strings by the expression evaluator which prevents the report from doing

math operations on it. A future release will have a a function to 'convert back' to a float.

------------------

Q. Expressions are being evaluated from right to left

A. This will be addressed in a later release. The work around is to use parentheses

------------------

Q. The following expression always returns 0: SUM(IF(Query1.CartonID='SI', Query1.Caliper, 0))

A. Change the 0 to 0.0 and the SUM() function will work correctly.

------------------

Q. Why doesn't the expression Count(Table1.Field1) return the right value?

A. The Count function in the expression builder returns a number that increments by 1 with every call to Count. It does not behave like the SQL Count() function that counts the variable passed to the function. If you click on Count in the expression builder you should see "Increments for each iteration" appear under the Count label as the function's description.

-----------

Q. How do I check the value of QRExpr control at runtime?

A. The "Value" property of a TQRExpr component is of type TQREvResult, which is defined in qrprntr.pas. You can check "Value.Kind" to see what the datatype is. The following table shows how to retrieve the results of the expression based on the value of "Value.Kind"

If Value.Kind = resInt then the results of the expression are in Value.IntResult

If Value.Kind = resDouble then the results of the expression are in Value.DblResult

If Value.Kind = resString then the results of the expression are in Value.StrResult (defined as string[255])

If Value.Kind = resBool then the results of the expression are in Value.BooResult

If Value.Kind = resError then the expression had an error

------------------

Q. I use QRExpr to calculate the Average of a currency field but it shows as numerical, not currency.

A. This is a known limitation of the QRExpr control. You can have the control display the currency character by using the mark property and set the mask to something like '$,###.00'. The QRExpr control's mask is the format string used by FormatFloat() and FormatDateTime functions. Please refer to their documentation for allowable values.

------------------

Q. Why does my report crash when I use TQRExpr controls under Delphi 1? The same report runs fine when I compile it with Delphi 2.

A. Delphi 1 uses a lot of stack space when you use nested expressions with the TQRExpr control. This is why we suggest that you raise the stack size as high as Delphi 1 will let you go for your project. We allocate all of our expression variables from the heap. but Delphi 1 still uses stack space to handle the multiple function calls required to evaluate the expressions. With Delphi 1, some expressions are bettered handled by adding code to calculate the results instead of using the TQRExp control.

------------------

Q. I have a simple query that uses the SQL COUNT(*) and I am?trying to display it in a QRExpr component but it is not displaying that field.

A. The SQL COUNT(*) is conflicting with the QR COUNT function. You will have to alias the column or use a QRDBText to output the field.

------------------

Q. I can't get the QRExprMemo to display more than 255 characters when I use Delphi 1.

A. The number of characters in a QRExprMemo is limited to the maximum string size. In Delphi 1, the maximum string length is 255 characters.

------------------

Q. How can I count frequencies of the values in a dataset field?

A. You can do this with expressions like:

SUM(IF(Table1.GENDER = 'M', 1, 0)) and SUM(IF(Table1.GENDER = 'F', 1, 0))

------------------

Q. How can I get the dataset of the report to display in the QRExpression if the dataset is on a separate form?

A. You will need to add the dataset to the report, using the report's AllDataSets property. The expression will not work at design time, but it will work at runtime.

Example:

 

Form1 has a dataset named tbCountry with the field 'Capital' in the table.

Form2 has a report named QuickRep1 with a qrexpr control on the summary band.

You want qrexpr to read the capital field of the tbCountry dataset.

You would have form2 use form1 and in the report's BeforePrint event you would add the tbcountry table to the report with the following syntax:

procedure TForm2.QuickRep1BeforePrint(Sender: TQuickRep;

var PrintReport: Boolean);

begin

with quickrep1.AllDataSets do

if IndexOf(Form1.tbCountry) = -1 then

Add(Form1.tbCountry);

end;

The QRExpr.Expression property would be set to tbcountry.capital

------------------

Q. I want to sum a field, but I need to ignore the highest and lowest value, can this be done?

A. You can do this by using the expression 'SUM(Field)-MIN(Field)-MAX(Field'. Please note that if you only have two records, the sum will be zero.

------------------

Q. What are the allowable datatypes that can be used in a TQRExpr control?

A. The allowable Delphi datatypes that can used in a TQRExpr control (or Group expression) are longint, double, string[255], and boolean. Currency fields are stored as double. Date and time fields are stored as string.

------------------

[Frames]

==================

Q. How can I separate the letters from the top of the frames with a QRDBText control?

A. The current release provides no control over the relative positioning of the frame in regards to the text. You can get finer control by using a QRShape control and place it underneath the text control.

------------------

Q. Setting DrawBottom to true of the report's Frame property of works on preview, not when printed.

A. The default bottom margin of a report goes beyond the printable area of many printers. If you set the bottom margin to a greater value (try 1.0 in as an example), you should see the bottom frame.

------------------

Q. Some lines do not appear in the preview, but they appear in the printout.

A. The report is rendered to a TMetafile object when it is sent to the preview. Depending on the zoom value of the preview, the scaling of the TMetafile may crop out some of the lines. If you zoom in (you may need to use a custom preview to zoom in close enough), the lines will reappear.

------------------

[Groups]

==================

Q. How do I print a group footer band?

A. Add a TQRBand, set it's type to groupfooter and link to rbGroupFooter. You would then link it to TQRGroup band by the footerband property. The new band will print at the end of the group of detail band.

------------------

Q. Is there an expression that will permit grouping by month? The underlying database has a date field.

A. You have to pass in an expression that would be the month, the easiest way is to use a calculated database field that would be the year and the month (unless you want the same month from multiple years grouped together.

------------------

Q. I have a billing report. In the group-footer I take the sum of the amounts. I print it at the summary . Now I would like to print the intermediate-results of the amounts at the end of each page (except at the end of the last page). How can I do it?

A. You would put the TQRExpr component to handle the amounts on a page footer band. Set the QRExpr's ResetAfterPrint to true so that the total will get reset after each page. To suppress the final page footer, set the report's Options.LastPageFooter to true.

If you want to have a page footer on the last page, but want to suppress the output of the last page's total, one easy way to tell that you are on the last page is to use a summary band. It will be called before the last page footer and you can use it's BeforePrint event to set a flag to prevent the output of the final QRExpr total. If you don't need a summary band, set it's height to 0.

------------------

Q. When I have a group header for a sub-detail band, the header gets printed twice for the first record and only once for every record thereafter.

A. If you just want a group header band to print for each set of subdetails, do not use a TQRGroupband, that band is for when you want to break up the data in groups. Just set the subdetail band's Bands.HasHeader to true. This will add a band of type TQRBand and it will only print at the start of each set of subdetails. This is documented on page 5-73 of the manual under the topic "BANDS PROPERTY FOR TQRSUBDETAIL".

------------------

Q. TQRGroup does not work with an expression on a queryfield if the query component is not on the report form.

A. The dataset must be either on the form or on the report's datamodule.

------------------

Q. A new page is not generated on the GROUPHEADER if the current page number is 1 (one) and the Property NewPage is TRUE. It will work fine if this occurs on page number 2 or higher.

A. QuickReport was designed to ignore the first ForceNewPage band if that band is on the first page. To get around this, set ForceNewPage back to false and call the report's NewPage method from the BeforePrint event of that band like the following:

procedure TfrmGroupTest.QRGroup1BeforePrint(Sender: TQRCustomBand;

var PrintBand: Boolean);

begin

Quickrep1.NewPage;

end;