发信人: wpf (Itouchthebluesky), 信区: BorlandDev
标 题: quickreport q/a 1
发信站: 哈工大紫丁香 (2001年06月09日20:06:18 星期六), 站内信件
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 cur
rent 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 contro
ls 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 e
asily 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, 9
9);
(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 ha
ve already formatted the report with a title, pageheader, pagefooter, etc, a
nd 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 f
or some reason?
A. You can only call AddPrintable or otherwise add a control to a report ba
nd before you start the report. QuickReport needs to know about all printab
le 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 f
ollowing 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 wil
l need to add the quickrpt and qrctrls units to the use list in the unit tha
t has this code.
You can reference each band type that can be set through the HasXXXXX proper
ties 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 ty
pe of control. You can then change the top and left properties by referenci
ng 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 manua
l.
A. You must make sure to set the aReport variable to nil before calling the
QRCreateList method. This was omitted from the documentation. The followi
ng 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 datab
ase }
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 QR
CreateList?
A. The width of the fields is calculated by setting the caption of each hea
der to the character 'X', with count coming from the field's DisplayWidth pr
operty. The spacing between each field is set to 10. If you change the dis
playwidth 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 s
pacing 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 intege
r)
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 o
f that QRlabel with all of the other QRLabels on the next page. Is there an
y 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 co
mponent 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 alrea
dy 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 buil
d the text line by line. I would use a subdetail band with 3 single compone
nts. 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 o
ne 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 Ri
chEdit component and separate the data by tabs. That would print as a singl
e component.
------------------
Q. My report goes out of control when I have child bands attached to the pa
ge header.
A. You can not have a page header where the height (including all child ban
ds ) is greater than a page. This is not supported. When the page header p
rints, the child bands that belong to the page header will be printed. If o
ne of the child bands doesn't fit on the page, it will cause a page break an
d the page header print code will be called again. This will put the page h
eader 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 b
e placed at the bottom of the report. If the subdetail band "belongs" to th
e 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 s
ubdetail 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 sam
e value for the master property, the safest way to do this is to view the fo
rm as text and cut and the paste the band to the location that you want. Th
e 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 befor
e 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 BeforePrin
t, it checks to see if the band will fit on the page. f it doesn't fit, a n
ew page is generated and the PageHeader BeforePrint event is called. You ca
n 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 Ch
ildBand's BeforePrint event, set the PrintBand variable that is passed in th
e 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 heig
ht 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 y
ou have extra space below a control, then that space is there for a reason a
nd 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 th
at space is used up.
------------------
Q. I have a childband and I set it's PrintBand to false based on certain co
nditions. When the band doesn't print, QuickReport doesn't check this and w
ill 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 Befor
ePrint 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 cou
ld 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 t
o 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 Head
er band?
A. The print order of the bands is fixed, you can not print a title band ab
ove 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 th
e 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 pr
operty 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 ba
nds). There are a couple of ways of doing what you are looking for. You co
uld either put the column labels on the group band or on a child band attach
ed to the group band.
------------------
Q. Is there a way to print a band as footer only on the last page of a repo
rt.
A. Instead of using a footer band, use a summary band and set it's AlignToB
ottom property to true.
------------------
Q. When my band is split on two pages, how can I keep the non-stretching te
xt controls on the first page?
A. If you have both stretching and non-stretching components on the same ba
nd make sure the non-stretching are printed first (right click and select 's
end to back')
------------------
Q. How do I disable the detail band so that I can calculate in the detail s
ection without printing it? I just want the summary band to print.
A. Set PrintBand to false in the band's BeforePrint event. That will suppr
ess 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 pa
rent to true. The following code creates a child band and then adds a QRLab
el 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 ba
nd during run-time?
A. The bands are descended from TCustomPanel and you can use the ControlCou
nt 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);
------------------
--
据说呆娃儿不笨
※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 202.118.245.166]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:209.112毫秒