Currently, among software development tools, Delphi has become a globally recognized fast development tool due to its many controls, strong object-oriented programming functions, fast code execution speed and simplicity and ease of use, combined with a visual development environment and the fastest compiler technology. Application development tools are being used by more and more programmers. You can use Delphi to write various Windows applications, especially the development of database information management systems, which has its unique advantages. In the development process of database information management system, we often need to print out many reports. Using Delphi to design complex reports is a cumbersome event. It is not as simple as Visual FoxPRo. However, since controls are also used to design reports in Delphi, we can directly create the required report controls during program execution to generate reports in real time, and the generated report sample can be determined by program control. For example, when we query database information, the structure of the result information is generally not fixed. If we want to print out the query results, it is not enough to design only one report format. We must design one for all possible result information. Report formatting is not a good solution either. In order to solve such a problem, we can use real-time report generation technology. The purpose of this article is to introduce in detail how to generate reports in real time through an example.
This example will design a print dialog box, which includes the TQickRep control and some report style control controls. The appearance of other forms is as shown below:
1. Control function description
QuickRep:TQuickRep It includes column header (HB:TQRBand), details (DB:TQRBand), footer (FB:TQRBand), summary (SB:TQRBand) bands, and does not include a TQRLabel in the details, footer, or summary , TQRExpr or TDBText control, which are mainly created when the program is executed. The column header zone includes Title (TQRLabel) for the report title; QRSQL: TQRLabel is used for query conditions. The Caption properties of these two controls can be changed arbitrarily during program execution. In order to prevent QuickRep from being displayed, place it behind Panel1 (Tpanel) and expand Panel1 to the entire form;
Query: TQuery SQL statement control, the program will generate reports based on the results returned by Query. Therefore, when creating this form, you must specify a SQL statement for the Query.SQL property;
In the above form, the controls included in the "Paper" and "Page Setup" columns control the QuickRep.Page properties. Changing them when the program is executed will directly change the corresponding property values of the QuickRep control. This can be done through the OnChange or OnExit event. code completed;
The title in the "Print Content Settings" column is the title of the specified report (TT:TEdit). Its value is consistent with QuickRep.ReportTitle and Title.Caption and can be changed arbitrarily; the "Print Query Conditions" check box specifies whether to print the query conditions. Whether this check box is selected directly controls whether QRSQL.Caption is empty; "Table column alignment" consists of a set of option buttons. It is mainly used for the alignment of detailed content when generating reports. Its change control variable RD1 (Byte) value (0 automatic alignment, 1 center alignment, 2 left alignment); "Table column printing width" consists of a set of option buttons, mainly used for the width of column values when generating report formats, and its change control variables The value of RD2 (Byte) (0 automatic width, 1 Same Width, 2 Limit Maximum Width), when selecting 1 Same Width, 2 Limit Maximum Width, you are required to enter the width in pixels; "Statistical Method" indicates whether the report includes footer (FB: TQRBAND) and sum (SB: TQRBAND ) zone.
2. Program description
The program defines the following types:
TQRLabelName=array of TQRLabel;
TQRDBTextName=array of TQRDBText;
TQRShapeName=array of TQRShape;
TQRExpName=array of TQRExpr;
The above type is a dynamic array type, and each element of the data is a class. When creating report controls in real time, the number of controls to be created is uncertain and the control names cannot be determined. Using dynamic arrays is a better solution, that is, you can arbitrarily specify the dimensions of the data without having to manage memory allocation yourself. This problem also facilitates the release and processing of controls contained in reports. The program also declares variables of the above types as follows:
CHBName:TQRLabelName;
DBName:TQRDBTextName;
CHBShape,DBShape,FBShape,SumShape:TQRShapeName;
FBName,SumName:TQRExpName;
These array variables will allocate memory based on the field results returned by Query when the form is created. Each field corresponds to an element of the array.
Program execution process: When the form is created and displayed, the initialization operation is established for this form. Display the corresponding value of the QuickRep.Page property in the OnCreate event, perform the Query.Open operation in the OnShow event, and allocate the control array variable space according to the return result. After the form is created, click the "Generate" button to generate the report (ignoring the memo field and photo field), and then click "Print" and "Preview" to print or preview the report. When the settings are changed after the report is generated, the report must be regenerated. If the result set returned by Query has too many fields, the paper size may not be enough to generate all the reports when generating the report. You can adjust the report paper size and then generate the report. When the form is closed, the created controls are released.
3. Source program list and comments
unit PrintDlg;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons, ExtCtrls, Spin, QuickRpt,QRPrntr,printers, Qrctrls,
Db,DBTables,ComCtrls,SysIni;
type
TQRLabelName=array of TQRLabel;//Dynamic array of column title control classes in the column header strip
TQRDBTextName=array of TQRDBText; //Dynamic array of column title controls in the detail band
TQRShapeName=array of TQRShape; //Dynamic array of line control parts
TQRExpName=array of TQRExpr; //Statistical control class dynamic array
TPrintForm = class(TForm)
GroupBox1: TGroupBox;
Label5: TLabel;
BtnSet: TbitBtn;//"Settings" button control
BtnCancel: TBitBtn; // "Close" button control
Panel1: TPanel;
BtnPrint: TBitBtn; // "Print" button control
BtnPrview: TBitBtn; // "Preview" button
QuickRep: TQuickRep; // Quick report control
HB: TQRBand; // "Column header" band control
Title: TQRLabel;//Report title control
QRE1: TQRExpr;//"Page number" control in the column header band
QRE2: TQRExpr;//"Date" control in the column header band
Panel2: TPanel;
Label1: TLabel;
R1: TRadioButton;//"Portrait Print" control
R2: TRadioButton;//"horizontal printing" control
GroupBox4: TGroupBox;
TT: TEdit;//Title input box control
Label2: TLabel;
SR: TCheckBox; // "Print query conditions" control
Label3: TLabel;
Image1: TImage;//Display vertical printing image
Image2: TImage;//Display horizontal printing image
QRSQL: TQRLabel; // Used to display the "Query Condition" control in the column header band
GroupBox2: TGroupBox;
Label7: TLabel;
Label8: TLabel;
Label9: TLabel;
Label10: TLabel;
Label11: TLabel;
Label12: TLabel;
Label13: TLabel;
PageSpace: TEdit; // Column spacing input box control
PageTop: TEdit; // Input box control on page margin
PageBottom: TEdit; //Input box control under page margin
PageLeft: TEdit; // Page margin left input box control
PageRight: TEdit; // Page margin right input box control
PageDlux: TCheckBox; // "Double-sided printing" control
PageCol: TEdit; // Column input box control
Pages: TEdit; // Print number input box control
PaperH: TEdit; // Paper length input box control
PaperW: TEdit;//Paper width input box control
Label4: TLabel;
Label6: TLabel;
Ps: TComboBox;//Paper model list box control
Query: TQuery;//SQL query control
DB: TQRBand; // "Details" band control
CrtRep: TBitBtn; // "Generate" button control
Label14: TLabel;
Label15: TLabel;
Panel3: TPanel;
Wdauto: TRadioButton; // "Autowidth" control
Wdall: TRadioButton; // "Same width" control
Wdmax: TRadioButton; // "Limit to width" control
Label16: TLabel;
ColWd: TEdit; // Column width input box control
Panel4: TPanel;
DJAUTO: TRadioButton; // "Auto-align" control
DJCENTER: TRadioButton; // "Center" control
DJLEFT: TRadioButton; // "Align left" control
FB: TQRBand; // Footer band control
Label17: TLabel;
Panel5: TPanel;
TJ1: TCheckBox; // "Statistics per page" control
TJ2: TCheckBox; // "Statistical sum" control
SB: TQRBand; // Sum band control
procedure FormCreate(Sender: TObject);
procedure RadioButtonClick(Sender: TObject);
procedure PageDluxClick(Sender: TObject);
procedure PageColChange(Sender: TObject);
procedure PageSpaceExit(Sender: TObject);
procedure PagesChange(Sender: TObject);
procedure PageTopExit(Sender: TObject);
procedure PageBottomExit(Sender: TObject);
procedure PageLeftExit(Sender: TObject);
procedure PageRightExit(Sender: TObject);
procedure TTExit(Sender: TObject);
procedure DTClick(Sender: TObject);
procedure BtnPrviewClick(Sender: TObject);
procedure BtnSetClick(Sender: TObject);
procedure PsChange(Sender: TObject);
procedure PaperChange(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormDestroy(Sender: TObject);
procedure CreateReport(Sender: TObject);
procedure SRClick(Sender: TObject);
procedure ClearRep();
procedure FormShow(Sender: TObject);
procedure PaperSizeChg(Sender: TObject);
procedure DJChage(Sender: TObject);
procedure WdChage(Sender: TObject);
procedure QuickRepStartPage(Sender: TCustomQuickRep);
procedure BtnPrintClick(Sender: TObject);
private
{Private declarations}
CHBName:TQRLabelName;//Define column header strip control name dynamic array name
DBName:TQRDBTextName; //Define the dynamic array name of the detail band control name
CHBShape,DBShape,FBShape,SumShape:TQRShapeName; //Define the dynamic array name of the line control
FBName,SumName:TQRExpName; //Define the dynamic array name of the footer (FBNAME) and sum band (SUMNAME) control names
DJ:TAlignment;//Column alignment (taLeftJustify, taRightJustify, taCenter)
Rd1, Rd2:Byte; //Used to save table column alignment (RD1) and printing width (RD2) status variable names
public
{Public declarations}
CXTJ,BT:String;//CXTJ stores query conditions, BT stores report titles
//Specified by the upper level form
end;
const
PaperSize:array[0..26] of TQRPaperSize=(A3, A4, A4Small, A5, B4, B5, Letter,
LetterSmall, Tabloid, Ledger, Legal,Statement, Executive, Folio,
Quarto, qr10X14, qr11X17, Note, Env9, Env10, Env11, Env12,
Env14, CSheet, DSheet, ESheet, Custom);
//Paper types listed by QuickRep
var
PrintForm: TPrintForm;
implementation
{$R *.DFM}
procedure TPrintForm.FormCreate(Sender: TObject);
//Display the QuickRep.Page property and other property values
var
I:Byte;
begin
PageCol.Text:=IntToStr(QuickRep.Page.Columns);
PageSpace.Text:=FormatFloat('0.00',QuickRep.Page.ColumnSpace);
PageTop.Text:=FormatFloat('0.00',QuickRep.Page.TopMargin);
PageBottom.Text:=FormatFloat('0.00',QuickRep.Page.BottomMargin);
PageLeft.Text:=FormatFloat('0.00',QuickRep.Page.LeftMargin);
PageRight.Text:=FormatFloat('0.00',QuickRep.Page.RightMargin);
PageSpace.Text:=FormatFloat('0.00',QuickRep.page.ColumnSpace);
R1.Checked:=QuickRep.Page.Orientation=poPortrait;
Image1.Visible:=R1.Checked;
R2.Checked:=QuickRep.Page.Orientation=poLandscape;
Image2.Visible:=R2.Checked;
PageDlux.Checked:=QuickRep.PrinterSettings.Duplex;
Pages.Text:=IntToStr(QuickRep.PrinterSettings.Copies);
PaperH.Text:=FormatFloat('0.00',QuickRep.Page.Length);
PaperW.Text:=FormatFloat('0.00',QuickRep.Page.Width);
For I:=0 to 26 do //PS list box displays paper type
if QuickRep.Page.PaperSize=PaperSize[I] then begin
PS.ItemIndex:=I;
Break;
end;
//Determine whether the paper width can be changed. It can only be changed if the paper type is customized (Ps.ItemIndex=26)
PaperH.Enabled:=Ps.ItemIndex=26;
PaperW.Enabled:=Ps.ItemIndex=26;
end;
procedure TPrintForm.RadioButtonClick(Sender: TObject);
//Paper orientation change event handling
var
S:String;
begin
Image1.Visible:=R1.Checked;
Image2.Visible:=R2.Checked;
if R1.Checked then
QuickRep.Page.Orientation:=poPortrait
else
QuickRep.Page.Orientation:=poLandscape;
//Swap the values of paper width and length
S:=PaperH.Text;
PaperH.Text:=PaperW.Text;
PaperW.Text:=S;
if (Ps.ItemIndex=26) or (Ps.ItemIndex=0) then begin
QuickRep.Page.Width:=StrToFloat(PaperW.Text);
QuickRep.Page.Length:=StrToFloat(PaperH.Text);
end;
end;
procedure TPrintForm.PageDluxClick(Sender: TObject);
begin
QuickRep.PrinterSettings.Duplex:=PageDlux.Checked;
end;
procedure TPrintForm.PageColChange(Sender: TObject);
begin
if StrToInt(PageCol.Text)<1 then PageCol.Text:='1';
QuickRep.Page.Columns:=StrToInt(PageCol.Text);
end;
procedure TPrintForm.PageSpaceExit(Sender: TObject);
begin
QuickRep.Page.ColumnSpace:=StrToFloat(PageSpace.Text);
end;
procedure TPrintForm.PagesChange(Sender: TObject);
begin
if StrToInt(Pages.Text)<1 then Pages.Text:='1';
QuickRep.PrinterSettings.Copies:=StrToInt(Pages.Text);
end;
procedure TPrintForm.PageTopExit(Sender: TObject);
begin
QuickRep.Page.TopMargin:=StrToFloat(PageTop.Text);
end;
procedure TPrintForm.PageBottomExit(Sender: TObject);
begin
QuickRep.Page.BottomMargin:=StrToFloat(PageBottom.Text);
end;
procedure TPrintForm.PageLeftExit(Sender: TObject);
begin
QuickRep.Page.LeftMargin:=StrToFloat(PageLeft.Text);
end;
procedure TPrintForm.PageRightExit(Sender: TObject);
begin
QuickRep.Page.RightMargin:=StrToFloat(PageRight.Text);
end;
procedure TPrintForm.TTExit(Sender: TObject);//Title change event handling
begin
QuickRep.ReportTitle:=TT.Text;
Title.Caption:=TT.Text;
Bt:=TT.Text;
end;
procedure TPrintForm.DTClick(Sender: TObject);//Print query condition check box event
begin
QRSQL.Enabled:=SR.Checked;
end;
procedure TPrintForm.BtnPrviewClick(Sender: TObject); //Preview button click event
begin
QuickRep.Preview;
end;
procedure TPrintForm.BtnSetClick(Sender: TObject); //Set button click event
begin
QuickRep.PrinterSetup;
end;
procedure TPrintForm.PsChange(Sender: TObject);//Paper type change event
begin
QuickREp.Page.PaperSize:=PaperSize[Ps.ItemIndex];
PaperH.Text:=FormatFloat('0.00',QuickRep.Page.Length);
PaperW.Text:=FormatFloat('0.00',QuickRep.Page.Width);
PaperH.Enabled:=Ps.ItemIndex=26;
PaperW.Enabled:=Ps.ItemIndex=26;
CrtRep.Enabled:=True;
BtnPrint.Enabled:=not CrtRep.Enabled;
BtnPrview.Enabled:=BtnPrint.Enabled;
end;
procedure TPrintForm.PaperChange(Sender: TObject);//Paper width and length change events
begin
QuickRep.Page.Width:=StrToFloat(PaperW.Text);
QuickRep.Page.Length:=StrToFloat(PaperH.Text);
end;
procedure TPrintForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caFree;
end;
procedure TPrintForm.FormDestroy(Sender: TObject);
begin
ClearRep;
PrintForm:=nil;
end;
procedure TPrintForm.CreateReport(Sender: TObject);//Generate button click event
Var
I,L:Byte;
CHBtp,CHBlf,Cd,ObWidth:Word;
begin
Screen.Cursor:=crHourGlass;
Title.Caption:=Bt;//Set the title
ClearRep(); //Clear the created object;
if Sr.Checked then QrSQL.Caption:=CXTJ else QRSQL.Caption:=';//Whether to print the query conditions?
CHBtp:=HB.Height-17;//The top position of the created control in the band
CHBlf:=0; //The created control is at the left position in the band
ObWidth:=0; //The width of the created control
for I := 0 to Query.FieldCount-1 do //Create a control based on the number of fields returned by Query
begin
if (Query.Fields[I].DataType<>ftBlob) And (Query.Fields[I].DataType<>ftMemo) then
begin //Ignore the note field and photo field
L:=Query.Fields[I].DataSize-1;//L=field width (bytes)-1
case Rd1 of //Set the alignment of the control according to the selected alignment
0: if L<=10 then Dj:=taCenter else DJ:=taLeftJustify;
//Automatic alignment: Fields less than or equal to 10 are aligned in the center, otherwise aligned to the left
1: Dj:=taCenter;//center alignment
2: DJ:=taLeftJustify;//Left alignment
end;
case Rd2 of //Set the report column width according to the selected list width
0: begin
//Automatic width: if L>14 then width ObWidth=14+(L-14)/2; if ObWidth
//The width cannot display column titles, then ObWidth=column title width; if the field type
//For date type, currency type and floating point number type, ObWidth=65
if L>14 then L:=14+(L-14) div 2;
ObWidth:=L*6;
L:=Length(Query.Fields[I].DisplayName);
if ObWidth<L*6 then ObWidth:=L*6;
ObWidth:=ObWidth+2;
if (Query.Fields[I].DataType=ftDateTime) or
(Query.Fields[I].DataType=ftFloat) or
(Query.Fields[I].DataType=ftCurrency) then ObWidth:=65;
end;
1: if ColWd.Text<>' then ObWidth:=StrToInt(ColWd.Text)
else ObWidth:=100;//Same width:ObWidth=input width value
2: begin //Limit the maximum width: first calculate the automatic width and then determine whether the width exceeds the maximum value.
//If it exceeds ObWidth=maximum width input value
if ColWd.Text<>' then Cd:=StrToInt(ColWd.Text)
else Cd:=200;
ObWidth:=L*6;
if ObWidth>Cd then ObWidth:=Cd;
ObWidth:=ObWidth+2;
if (Query.Fields[I].DataType=ftDateTime) or
(Query.Fields[I].DataType=ftFloat) or
(Query.Fields[I].DataType=ftCurrency) then ObWidth:=65;
end;
end;
if CHBlf+ObWidth>=HB.Width then begin //Create control>paper width?
DlgMes:='The paper width is not enough, please change the paper size. ';
MessageBox(Handle,DlgMes,Cap_Inf,Ico_Inf);
break;
end
else begin
CHBShape[I]:=TQRShape.Create(HB);//Create column header strip line control
CHBShape[I].Parent:=HB;
CHBShape[I].Top:=CHBtp;
CHBShape[I].Left:=CHBlf;
CHBShape[I].Width:=ObWidth+1;
CHBShape[I].Height:=17;
CHBNAME[I]:=TQRLabel.Create(HB); //Create column title control
CHBNAME[I].Parent:=HB;
CHBNAME[I].Top:=CHBtp+2;
CHBNAME[I].Left:=CHBlf+1;
CHBNAME[I].AutoSize:=False;
CHBNAME[I].Width:=ObWidth-1;
CHBNAME[I].Alignment:=taCenter;
CHBNAME[I].Caption:=Query.Fields[I].DisplayName;//Get the field as the column name
CHBNAME[I].BringToFront;
DBShape[I]:=TQRShape.Create(DB); //Create detail strip line control
DBShape[I].Parent:=DB;
DBShape[I].Top:=-1;
DBShape[I].Left:=CHBlf;
DBShape[I].Width:=ObWidth+1;
DBShape[I].Height:=17;
DBNAME[I]:=TQRDBText.Create(DB); //Create detail band control
DBNAME[I].Parent:=DB;
DBNAME[I].ParentReport:=QuickRep;
DBNAME[I].Top:=2;
DBNAME[I].Left:=CHBlf+2;
DBNAME[I].AutoSize:=False;
DBNAME[I].Width:=ObWidth-3;
DBNAME[I].Height:=13;
DBNAME[I].Alignment:=Dj;
DBNAME[I].DataSet:=Query;
DBNAME[I].DataField:=Query.Fields[I].FieldName;
DBNAME[I].BringToFront;
if Tj1.Checked then begin //Do you want to create a footer band?
FBShape[I]:=TQRShape.Create(FB); //Create footer band line control
FBShape[I].Parent:=FB;
FBShape[I].Top:=0;
FBShape[I].Left:=CHBlf;
FBShape[I].Width:=ObWidth+1;
FBShape[I].Height:=17;
if (Query.Fields[I].DataType=ftFloat) or
(Query.Fields[I].DataType=ftCurrency) or (I<2) then
begin //If the field type is a numeric type, create it
FBNAME[I]:=TQRExpr.Create(FB); //Create footer band control
FBNAME[I].Parent:=FB;
FBNAME[I].ParentReport:=QuickRep;
FBNAME[I].Top:=3;
FBNAME[I].Left:=CHBlf+2;
FBNAME[I].AutoSize:=False;
FBNAME[I].Width:=ObWidth-3;
FBNAME[I].Height:=13;
FBNAME[I].Alignment:=taCenter;
FBNAME[I].Expression:='SUM(QUERY.'+Query.Fields[I].FieldName+')';
FBNAME[I].BringToFront;
end;
end;
if Tj2.Checked then begin //Should we establish the sum band?
SumShape[I]:=TQRShape.Create(SB); //Create a sum strip line control
SumShape[I].Parent:=SB;
SumShape[I].Top:=0;
SumShape[I].Left:=CHBlf;
SumShape[I].Width:=ObWidth+1;
SumShape[I].Height:=17;
if (Query.Fields[I].DataType=ftFloat) or
(Query.Fields[I].DataType=ftCurrency) or (I<2) then
begin //If the field type is a numeric type, create it
SumNAME[I]:=TQRExpr.Create(SB); //Create sum band control
SumNAME[I].Parent:=SB;
SumNAME[I].ParentReport:=QuickRep;
SumNAME[I].Top:=3;
SumNAME[I].Left:=CHBlf+2;
SumNAME[I].AutoSize:=False;
SumNAME[I].Width:=ObWidth-3;
SumNAME[I].Height:=13;
SumNAME[I].Alignment:=taCenter;
SumNAME[I].Expression:='SUM(QUERY.'+Query.Fields[I].FieldName+')';
SumNAME[I].BringToFront;
end;
end;
CHBlf:=CHBlf+ObWidth;//The current field processing is completed, one field width to the right
end;
end;
end;
CrtRep.Enabled:=False;//Disable the generation button
BtnPrint.Enabled:=not CrtRep.Enabled;Allow printing of ammonium buttons
BtnPrview.Enabled:=BtnPrint.Enabled;Allow preview button
if Tj1.Checked then begin //If a footer band is created, change the first two columns in the footer band
FBNAME[0].Expression:=''Total pages'';
FBNAME[1].Expression:='COUNT+'row'';
end;
if Tj1.Checked then begin //If the sum band is established, change the first two columns in the sum band
SumNAME[0].Expression:=''Total'';
SumNAME[1].Expression:='COUNT+'row'';
end;
//Adjust the date and page number printing position in the column header zone
QRE2.Left:=HB.Width-Qre2.Width;
QRSQL.Left:=QRE1.Width+10;
QRSQL.Width:= QRE2.Left-10-QRSQL.Left;
QuickRep.DataSet:=Query; //Specify the data set for QuickRep, this sentence must not be missing
Screen.Cursor:=crDefault;
end;
procedure TPrintForm.ClearRep();//Clear the control created when generating the report format
Var
I:Byte;
begin
For I:=0 to Query.FieldCount-1 do begin
if Assigned(CHBShape[I]) then begin CHBShape[I].Free;CHBShape[I]:=nil;end;
if Assigned(CHBNAME[I]) then begin CHBNAME[I].Free;CHBNAME[I]:=nil;end;
if Assigned(DBShape[I]) then begin DBShape[I].Free;DBShape[I]:=nil;end;
if Assigned(DBNAME[I]) then begin DBNAME[I].Free;DBNAME[I]:=nil;end;
if Assigned(FBShape[I]) then begin FBShape[I].Free;FBShape[I]:=nil;end;
if Assigned(FBNAME[I]) then begin FBNAME[I].Free;FBNAME[I]:=nil;end;
if Assigned(SumShape[I]) then begin SumShape[I].Free;SumShape[I]:=nil;end;
if Assigned(SumNAME[I]) then begin SumNAME[I].Free;SumNAME[I]:=nil;end;
end;
end;
procedure TPrintForm.SRClick(Sender: TObject);
begin
if Sr.Checked then QrSQL.Caption:=CXTJ else QRSQL.Caption:=';
end;
procedure TPrintForm.FormShow(Sender: TObject); //Form display event
begin
Query.Active:=True;//Print SQL
TT.Text:=Bt;
QuickRep.ReportTitle:=Bt;//Set the title
//Control name array allocates space
SetLength(CHBNAME,Query.FieldCount);
SetLength(CHBShape,Query.FieldCount);
SetLength(DBNAME,Query.FieldCount);
SetLength(DBShape,Query.FieldCount);
SetLength(FBNAME,Query.FieldCount);
SetLength(FBShape,Query.FieldCount);
SetLength(SumNAME,Query.FieldCount);
SetLength(SumShape,Query.FieldCount);
end;
procedure TPrintForm.PaperSizeChg(Sender: TObject);
begin
CrtRep.Enabled:=True;
BtnPrint.Enabled:=not CrtRep.Enabled;
BtnPrview.Enabled:=BtnPrint.Enabled;
end;
procedure TPrintForm.DJChage(Sender: TObject);//Alignment change event handling
var
Chg:Byte;
begin
if Djauto.Checked then Chg:=0
else if DjCenter.Checked then Chg:=1
else Chg:=2;
if Chg<>Rd1 then begin PaperSizeChg(nil);Rd1:=Chg;end;
end;
procedure TPrintForm.WdChage(Sender: TObject);//Width change event handling
var
Chg:Byte;
begin
if Wdauto.Checked then Chg:=0
else if Wdall.Checked then begin
Chg:=1;
if ColWd.Text=' then ColWd.Text:='100';
end
else begin
Chg:=2;
if ColWd.Text=' then ColWd.Text:='200';
end;
if Chg<>Rd2 then begin PaperSizeChg(nil);Rd2:=Chg;end;
ColWd.Enabled:=Chg<>0;
end;
procedure TPrintForm.QuickRepStartPage(Sender: TCustomQuickRep);
//Report printing starts new page event processing, and the statistical values in the footer band are cleared.
Var
I:Byte;
begin
if Tj1.Checked then
For I:=0 to Query.FieldCount-1 do
if Assigned(FBNAME[I]) then FBNAME[I].Reset;
end;
procedure TPrintForm.BtnPrintClick(Sender: TObject);
begin
QuickRep.Print;
end;
end.
4. Example of calling dialog box:
First, include the PrintDlg unit in the USES statement in the form to be called, and then call it with the following code:
if not assigned(PrintForm) then PrintForm:=TPrintForm.Create(application);
PrintForm.Query.SQL.Assign(Query.SQL);
//If the calling form does not contain a Query control, you can directly set the value of the SQL statement
PrintForm.Bt:=Report title;
PrintForm.Caption:=Form title;
PrintForm.CXTJ:=query conditions;
PrintForm.ShowModal;
5. Conclusion
The key to this program is the CreateReport event process and the processing of dynamic control names. Due to limited space, some contents are not explained and I hope readers can understand them by themselves. For general report generation, this program can meet the requirements.
I have the latest version, which has stronger functions. Friends who need it can send me an email and I will definitely send it.