Pismatically generate QuickReport report in Delphi

zhaozj2021-02-16  53

---- The author uses the Delphi development database in the previous paragraph, the user puts forward such a requirement: to dynamically generate reports based on their own query results and then print. After several exploits, the author uses the dynamically generated QuickReport control to meet the needs of users. This method will now be described below, I hope to provide a good choice for friends who have similar work to be made.

First, basic ideas

---- Some parameters (such as SQL commands, field names, field widths, etc.) are first written in a temporary file in a certain format. When generating a report, dynamically generate a variety of QuickReport controls according to the parameters recorded in the temporary file.

Second, the program is realized

2.1 Temporary File Format

---- The format of the temporary file can be customized as needed, and the author uses INI's file format. Delphi provides a TiniFile class that makes an Ini format file in Delphi, which is very convenient. There are many articles about the format of the INI file and specific operations. I will not go here. The temporary file format is as follows:

Report.ini

: Report Details

[rep_detail]

Title = xxxxx table

: Playing paper setting, 1 is A4 paper, 2 is B5 paper, 3 is 16K

Page = 1

: Printing method, 1 is horing, 0 is vertical

Orientation = 1

: The number of fields containing the fields

Column = 8

: TQurey component information

[QureyData]

: The content of the SQL command of the tQurey component in the QuickReport component

SQL_COMMAND = SELECT V_XM, V_JGZW, V_BMMC, V_DWMC, V_DWZW, V_ZY, V_ZC, V_BGDH from HVZZJG WHERE V_XM LIKE 'Lee%'

[col_0]

CAPTION = last name

DataFiled = v_xm

Width = 60

......

......

2.2 Dynamic Generation QuickReport Report

--- The main control of the report and its main attribute settings are as follows

Name of the control class name attribute property value Form_rep TForm caption dynamic reports QuickRep TQuickRep DataSet REP_QUERY DetailBand1 TQRBand BandType rbDetail ColumnHeaderBand1 TQRBand BandType rbColumnHeader REP_DataSource TDataSource DataSet Rep_Query Rep_Query TQuery DatabaseName REPDATABASE Rep_Database

TDATABASE

Connected true params.strings' server name = xxx 'user mame = xxx' 'password = xxx' databasename repdatabase

The control shown above is manually created in the program. Other controls are dynamically created in the program.

2.2.2 Main procedures

Unit f_rep;

Interface

Uses

Windows, Messages, Sysutils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, Extctrls, Quickrpt, Qrctrls, DB, DBTABLES, Printers, qrprntr, inifiles,

TeeProcs, Tengine, Dbchart, QRTEE

Type

TFORM_REP = Class (TFORM)

QuickRep: tquickrep;

Detailband1: tQRBAND;

ColumnHeaderband1: tqrband; rep_datasource: tdataserce;

REP_QUERY: TQUERY;

Rep_DATABASE: TDATABASE;

Procedure TFORM_REP.QUICKREPAFTERPREVIEW (Sender: TOBJECT); // Browse, release all created components

Private

{Private Declarations}

public

{Public declarations}

END;

Var form_rep: tform_rep;

Summary information of Type // Report

C_rep_summary = record

Title: String; // Report title

Page: TQRPAPERSIZE; / / Report page settings, use the model of paper

Orientation: tprinterorientation; // The page settings of the report are hosted or vertical

Columns: integer; // The number of columns included

END;

Type

C_REP_COL_SUMMARY = Record // Summary information of the report column

CAPTION: STRING; // Report column name

DataFiled: String; // The list of fields in the list of reports corresponding to the list of fields

Width: integer; // Reporting column width

END;

Type

C_rep_col_sum_store = record // Store summary information of the report

CAPTION_ARRY: Array of string;

DataFiled_Array: array of string;

Width_Array: array of integer;

END;

VAR

Rep_summary: c_rep_summary;

REP_COL_SUMMARY: C_REP_COL_SUMMARY;

REP_COL_SUM_STORE: C_REP_COL_SUM_STORE;

COLUM_NAME: Array of TqrrichText;

Colum_Data: Array of TqrdbrichtexT;

C_Query: tQuery;

Procedure form_rep_init ();

Procedure DyncReat_tqrdbtext (colum_num: integer; color; dataset_name: tquery); // Dynamically create TQRDBText control

Procedure Dyncreat_tqrrichtext (colum_num: integer); // Dynamically create TQRRICHText control

Procedure Dyncreat_tquery (Inifile_name: tinifile); // Dynamically create the SQL statement for the TQUERY control

Procedure get_pagecount (); // Get the total number of prints

Function open_inifile (): tinifile; // Open temporary file

Procedure read_col_summary (inIfile_name: tinifile); // Read the summary information of the report column

Procedure read_rep_summary (inIfile_name: tinifile); // Read the summary information of the report

Function rep_chanslateorientation (var rep_orientation: integer): tprinterorientation; // Convert the print mode setting

Function rep_chanslatepage (var rep_page: integer): tqrpapersize; // Transfer page size settings

IMPLEMENTATION

{$ R * .dfm}

Function rep_chanslate (var rep_page: integer): tqrpapersize; // Convert the Print Page Type Settings

BEGINCASE rep_page of

1: Begin

Result: = a4;

Form_rep.quickrep.printersettings.papersize: = a4;

END;

2: Begin

Result: = b5;

Form_rep.quickrep.printersettings.papersize: = B5

END;

3: Begin

Result: = Executive;

Form_rep.quickrep.printersettings.papersize: = Executive;

END;

END;

END;

Function rep_chanslateorientation (var rep_orientation: integer): tprinterorientation; // Convert the print mode setting

Begin

Case rep_orientation of

0: Begin

Result: = poporTrait; // 0 is vertical

Form_rep.quickrep.printersettings.orient: = poporTrait;

END;

1: Begin

Result: = polandscape; // 1 is level

Form_rep.quickrep.printersettings.orientation: = polandscape;

END;

END;

END;

Function open_inifile (): tinifile; // Open temporary file

Var filename: String;

INI_FILENAME: STRING;

Begin

FileName: = 'Report.ini';

INI_FILENAME: = File_Path FileName;

Result: = TiniFile.create (INI_FILENAME);

END;

Procedure read_rep_summary (inIfile_name: tinifile); // Read the summary information of the report

Var rep_page, rep_orientation: integer;

Begin

REP_PAGE: = INIFILE_NAME.Readinteger ('rep_detail', 'page', 1);

Rep_ORIENTATION: = INIFILE_NAME.Readinteger ('rep_detail', 'orientation ", 0);

With rep_summary do

Begin

Columns: = INIFILE_NAME.Readinteger ('rep_detail', 'colorns', 0);

Title: = INIFILE_NAME.Readstring ('rep_detail', 'title', 'unnamed report');

Page: = rep_chanslatepage (rep_page); // Convert the print page size

Orientation: = rep_chanslateorientation (rep_orientation); // Convert the print mode setting

END;

END;

Procedure read_col_summary (inIfile_name: tinifile); // Read the summary information of the report column

Var i_count: integer;

Begin

// Save the column information in the array

with rep_col_sum_store do

Begin

SETLENGTH (CAPTION_ARRAY, Rep_SUMMARY.COLUMNS);

SETLENGTH (DataFiled_Array, Rep_SUMMARY.COLUMNS);

SetLength (width_array, rep_summary.columns);

END;

For i_count: = 0 to rep_summary.columns-1 do

Begin

With rep_col_summary do

Begin

CAPTION: = INIFILE_NAME.Readstring ('COL _' INTOSTR (i_count), 'caption', 'unnamed');

DataFile: = INIFILE_NAME.Readstring ('COL _' INTOSTR (i_count), 'DataFiled', '');

Width: = INIFILE_NAME.Readinteger ('COL _' INTOSTR (i_count), 'width', 0);

END;

with rep_col_sum_store do

Begin

CAPTION_ARRAY [i_count]: = rep_col_summary.caption;

DataFiled_Array [i_count]: = rep_col_summary.datafiled;

Width_Array [i_count]: = rep_col_summary.width;

END;

END;

END;

Procedure Dyncreat_tqrrichtext (color_num: integer); // Dynamically create TQRRICHTEXT controls, this control is used to display the Chinese name of each column of reports

Var colum_name_list: tstrings;

Begin

Colum_name [colum_num]: = tqrichtext.create (Application); // Create a TQRRICHTEXT control

Colum_name [colum_num] .parent: = form_rep.columnheaderband1;

COLUM_NAME [colum_num] .frame.drawtop: = TRUE;

Colum_name [colum_num] .frame.drawbottom: = true;

Form_rep.columnheaderband1.height: = 40;

COLUM_NAME [colum_num] .height: = 40;

COLUM_NAME [colum_num] .font.height: = - 14;

Colum_name [colum_num] .font.name: = 'black body';

Colum_name [color_num] .top: = 0;

Colum_name [colum_num] .alignment: = Tacenter;

COLUM_NAME [colum_num] .autostradch: = FALSE

// Painted Table Line

Colum_name [colum_num] .frame.style: = pssolid;

Colum_name [color_num] .frame.width: = 1;

Colum_name [colum_num] .frame.drawright: = true;

Colum_name [colum_num] .frame.drawbottom: = true;

IF color_num = 0 THEN

Begin

Colum_name [colum_num] .frame.drawleft: = true;

END;

// Put the information in the RREP_COL_SUM_STORE to colum_name

COLUM_NAME_LIST: = TStringList.create;

Colum_name_list.add (rep_col_sum_store.caption_Array [color_num]); colum_name [color_num] .line: = colum_name_list;

Colum_name [colum_num] .width: = rep_col_sum_store.width_Array [color_num];

Colum_name [color_num] .visible: = true;

// calculate the left boundary

IF colum_num> 0 THEN

Colum_name [colum_num] .left: = colum_name [color_num-1] .left color_name [colum_num-1] .width

Else

COLUM_NAME [Colum_Num] .left: = 0;

END;

Description: This TQRRICHTEXT control is used here because the TQRRICHText control can be automatically wrap when the name is too long.

Procedure Dyncreat_tqrdbtext (colum_num: integer; color; dataset_name: tQuery); // Dynamically create TQRDBText control, this control is used to display the value of each column

Begin

Colum_data [color_num]: = tqrdbtext.create (application);

Colum_data [color_num] .parent: = form_rep.detailband1;

// Set the data set

Colum_data [colum_num] .dataset: = dataset_name

// Set the array colum_data.datefield property to the field name in c_rep_col_sum_store

Colum_data [colum_num] .Datafield: = rep_col_sum_store.datafiled_Array [colum_num];

Colum_data [colum_num] .width: = rep_col_sum_store.width_Array [colum_num];

Colum_data [color_num] .height: = colum_height;

Form_rep.detailband1.height: = colum_height;

Colum_data [color_num] .top: = 0;

Colum_data [colum_num] .autosize: = false;

Colum_data [colum_num] .autostradch: = false;

Colum_data [colum_num] .WordWrap: = false;

Colum_data [colum_num] .visible: = true;

// Painted Table Line

Colum_data [colum_num] .frame.style: = pssolid;

Colum_data [color_num] .frame.drawright: = true;

Colum_data [colum_num] .frame.drawbottom: = true;

IF color_num = 0 THEN

Colum_data [colum_num] .frame.drawleft: = true;

// calculate the left boundary

IF colum_num> 0 THEN

Colum_data [colum_num] .left: = colum_data [color_num-1] .left color_data [colum_num-1] .width

Else

Colum_data [color_num] .left: = 0;

END;

Procedure Dyncreat_tquery (InIfile_name: tinifile); // Dynamically set the SQL statement VAR of the TQUERY control

SQL_COMMAND: STRING;

Begin

FLAG_CREATQUERY: = FALSE;

SQL_COMMAND: = INIFILE_NAME.ReadString ('QureyData', 'SQL_COMMAND', '');

Form_rep.rep_query.close;

Form_rep.rep_query.sql.clear;

Form_rep.rep_query.sql.Append (SQL_COMMAND);

IF not form_rep.rep_query.prepared then

Form_rep.rep_query.prepare;

Try

Form_rep.rep_query.execsql;

Form_rep.rep_query.active: = true;

Form_rep.rep_query.autocalcfields: = true;

Flag_creatquery: = true;

Except

Application.MessageBox ('sql statement error!', 'System prompt', MB_ICONWARNING);

FLAG_CREATQUERY: = FALSE;

END;

END;

Procedure form_rep_init ();

Var i_count: integer;

Rep_INIFILE: TINIFILE; / / Open INI file name

COL_HEIGHT: INTEGER;

Flag_sum: boolean;

Begin

Rep_INIFILE: = Open_INIFILE); // Open a temporary file file

Read_rep_summary (rep_inifile); // Read Summary Information for Reports

Read_col_summary (rep_inifile); // Read summary information of the report column

/ / Dynamically create a report control based on the parameters of the report read

WITH FORM_REP DO

Begin

Flag_creattqrexpr: = false; // Indicates that there is no TQREXPR control yet

Dyncreat_tquery (rep_inifile);

IF flag_creatquery then

Begin

QRLABEL_TITLE.CAPTION: = rep_summary.title;

QRLABEL_HEADER.CAPTION: = rep_summary.title;

// Set page information

Quickrep.page.orientation: = rep_summary.orientation;

Quickrep.page.papersize: = rep_summary.page;

SetLength (Colum_Data, Rep_SUMMARY.COLUMNS);

SetLength (colum_name, rep_summary.columns);

For i_count: = 0 to rep_summary.columns-1 do

Begin

DyncReat_tqrrichtext (i_count); // Dynamically create TQRRICHText control

DyncReat_tqrdbrichtext (i_count, col_height, form_rep.rep_query) // Dynamically create TQRDBText control

END;

// Turn the rep_x.ini file

Rep_inifile.destroy ();

end

Else

Form_rep.close;

END;

END;

Procedure tform_rep.quickRepAfterPreview (sender: TOBJECT); // Browse, release all created components VAR i_count: integer;

Begin

For i_count: = 0 to rep_summary.columns-1 do

BEGIN

COLUM_NAME [i_count] .free;

Colum_data [i_count] .free;

END;

END;

End.

Third, the problem that needs attention

---- Drawing the table line in QuickReport, except for the method mentioned in the article, you can use the QRSHAPE control. However, regardless of that the method is used, it must be carefully calculated. If you need to adjust it according to the effect of the print, you can ensure that the table line does not produce a deviation.

---- After all dynamically created controls, must be released.

---- Temporary files are also emptied after use.

---- The program shown above is merely the routine that the author is simplified in order to illustrate the idea. In the actual application of the author, all used controls (including forms form) are dynamically generated. And when you generate a report, you can also dynamically generate statistics, insert charts, etc., interested friends can send a letter to chief_marshal@sina.com and I discuss details.

转载请注明原文地址:https://www.9cbs.com/read-23222.html

New Post(0)