----In der vorherigen Arbeit des Autors, der Delphi zur Entwicklung einer Datenbank verwendete, stellten Benutzer eine solche Anforderung: Berichte basierend auf ihren eigenen Abfrageergebnissen dynamisch zu generieren und diese dann auszudrucken. Nach langer Recherche nutzte der Autor die Methode der dynamischen Generierung von QuickReport-Steuerelementen, um den Anforderungen der Benutzer gerecht zu werden. Im Folgenden wird diese Methode erläutert, in der Hoffnung, einige nützliche Tipps für Freunde zu geben, die ähnliche Arbeiten zu erledigen haben.
1. Grundideen
----Schreiben Sie zunächst einige Abfrageparameter (z. B. SQL-Befehle, Feldnamen, Feldbreiten usw.) in eine temporäre Datei in einem bestimmten Format. Wenn Sie einen Bericht erstellen, generieren Sie einfach dynamisch verschiedene QuickReport-Steuerelemente basierend auf den in der temporären Datei aufgezeichneten Parametern.
2. Programmumsetzung
2.1 Temporäres Dateiformat
----Das Format der temporären Datei kann je nach Bedarf angepasst werden. Der Autor verwendet das INI-Dateiformat. Delphi bietet eine TInifile-Klasse, die den Betrieb von Dateien im INI-Format in Delphi sehr bequem macht. Es gibt viele Artikel über das Format und die spezifischen Vorgänge von INI-Dateien, daher werde ich hier nicht näher darauf eingehen. Das temporäre Dateiformat ist wie folgt:
Report.ini
:Details melden
[rep_detail]
Titel=XXXXX-Tabelle
: Druckpapiereinstellungen, 1 ist A4-Papier, 2 ist B5-Papier, 3 ist 16K
Seite=1
: Druckmodus, 1 bedeutet horizontales Drucken, 0 bedeutet vertikales Drucken.
Ausrichtung=1
: Anzahl der im Bericht enthaltenen Felder
Spalten=8
:TQurey-Komponenteninformationen
[QureyData]
: Inhalt des SQL-Befehls der Tqurey-Komponente in der QuickReport-Komponente
Sql_command=wählen Sie V_XM,V_JGZW,V_BMMC,V_DWMC,V_DWZW,V_ZY,V_ZC,V_BGDH aus Hvzzjg aus, wobei V_XM LIKE '李%'
[col_0]
Bildunterschrift=Name
DataFiled=V_XM
Breite=60
…
…
2.2 Erstellen Sie dynamisch QuickReport-Berichte
--- Die wichtigsten Steuerelemente des Berichts und ihre wichtigsten Eigenschaftseinstellungen sind wie folgt
Kontrollname | Klassenname | Eigentum | Attributwert |
Form_rep | TForm | Untertitel | dynamischer Bericht |
QuickRep | TQuickRep | Datensatz | REP_QUERY |
DetailBand1 | TQRBand | Bandtyp | rbDetail |
ColumnHeaderBand1 | TQRBand | Bandtyp | rbColumnHeader |
REP_DataSource | TDataSource | Datensatz | Rep_Query |
Rep_Query | TQuery | Datenbankname | REPDATABASE |
Rep_Database | TDatabase | Verbunden | WAHR |
Parameter.Strings | 'SERVERNAME=XXX 'USER MAME=XXX' 'PASSWord=XXX' | ||
Datenbankname | REPDATABASE |
Die in der Tabelle oben gezeigten Steuerelemente wurden manuell im Programm erstellt. Andere Steuerelemente müssen dynamisch im Programm erstellt werden.
2.2.2 Hauptverfahren
Einheit f_rep;
Schnittstelle
verwendet
Windows, Nachrichten, SysUtils, Varianten, Klassen, Grafiken, Steuerelemente, Formulare,
Dialoge, ExtCtrls, QuickRpt, QRCtrls, DB, DBTables,PRINTERS,QRPrntr,inifiles,
TeeProcs, TeEngine, DbChart, QRTEE;
Typ
TForm_rep = Klasse(TForm)
QuickRep: TQuickRep;
DetailBand1: TQRBand;
ColumnHeaderBand1: TQRBand;
REP_DataSource: TDataSource;
REP_QUERY: TQuery;
rep_Database: TDatabase;
procedure TForm_rep.QuickRepAfterPreview(Sender: TObject);// Nach dem Durchsuchen alle erstellten Komponenten freigeben
Privat
{Private Erklärungen}
öffentlich
{Öffentliche Erklärungen}
Ende;
var Form_rep:TForm_Rep;
Typ //Zusammenfassende Informationen des Berichts
C_rep_Summary=Datensatz
Title:string;//Der Titel des Berichts
Page:TQRPaperSize;//Die Seiteneinstellungen des Berichts, welche Papiersorte verwendet wird
Orientation:TPrinterOrientation;//Die Seiteneinstellung des Berichts, ob horizontal oder vertikal
Columns:integer;//Anzahl der im Bericht enthaltenen Spalten
Ende;
Typ
C_Rep_Col_Summary=record//Zusammenfassende Informationen der Berichtsspalten
Caption:string;//Spaltenname des Berichts
DataFiled:string;//Der Feldname in der Datenbank, der der Spalte des Berichts entspricht
Breite:integer;//Spaltenbreite des Berichts
Ende;
Typ
C_Rep_Col_Sum_store=record //Speicherzusammenfassungsinformationen der Berichtsspalten
Caption_array:Array von String;
DataFiled_array:array of string;
Breite_Array:Array von Ganzzahl;
Ende;
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 von tQRRichText;
Colum_Data:Array von TQRDBRichText;
C_Query:TQuery;
Prozedur Form_rep_init();
procedure DynCreat_TQRDBText(Colum_Num:integer;Colum_Height:integer;DataSet_Name:TQuery);//TQRDBText-Steuerelement dynamisch erstellen
procedure DynCreat_TQRRichtext(Colum_Num:integer);// TQRRichtext-Steuerelement dynamisch erstellen
procedure DynCreat_TQuery(Inifile_Name:Tinifile);//SQL-Anweisung zum dynamischen Erstellen eines TQuery-Steuerelements
procedure Get_PageCount();//Ermitteln Sie die Gesamtzahl der gedruckten Seiten
function Open_IniFile():Tinifile;//Temporäre Datei öffnen
procedure Read_Col_Summary(Inifile_Name:Tinifile);//Zusammenfassungsinformationen der Berichtsspalten lesen
procedure Read_Rep_Summary(Inifile_Name:Tinifile);//Zusammenfassende Informationen des Berichts lesen
function rep_chanslateOrientation(var Rep_Orientation:integer):TPrinterOrientation;// Konvertieren Sie die Druckmoduseinstellungen
function rep_chanslatepage(var Rep_Page:integer):TQRPaperSize;// Konvertieren Sie die Einstellung für die Druckseitengröße
Durchführung
{$R *.dfm}
function rep_chanslatepage(var Rep_Page:integer):TQRPaperSize;// Konvertieren Sie die Einstellung für den Druckseitentyp
beginnen
Fall Rep_Page von
1: beginnen
Ergebnis:=A4;
Form_rep.QuickRep.PrinterSettings.PaperSize:=A4;
Ende;
2: beginnen
Ergebnis:=B5;
Form_rep.QuickRep.PrinterSettings.PaperSize:=B5
Ende;
3: beginnen
result:=Executive;
Form_rep.QuickRep.PrinterSettings.PaperSize:=Executive;
Ende;
Ende;
Ende;
function rep_chanslateOrientation(var Rep_Orientation:integer):TPrinterOrientation;// Konvertieren Sie die Druckmoduseinstellungen
beginnen
Fall Rep_Orientation von
0:beginnen
result:=poPortrait;//0 ist vertikal
Form_rep.QuickRep.PrinterSettings.Orientation:=poPortrait;
Ende;
1: beginnen
result:=poLandscape;//1 ist horizontal
Form_rep.QuickRep.PrinterSettings.Orientation:=poLandscape;
Ende;
Ende;
Ende;
function Open_IniFile():Tinifile;//Temporäre Datei öffnen
var Dateiname: string;
Ini_Filename:string;
beginnen
Dateiname:='Report.ini';
Ini_Filename:=File_Path+Filename;
Ergebnis:=Tinifile.Create(Ini_Filename);
Ende;
procedure Read_Rep_Summary(Inifile_Name:Tinifile);//Zusammenfassende Informationen des Berichts lesen
var Rep_Page,Rep_Orientation:integer;
beginnen
rep_Page:=Inifile_Name.Readinteger('rep_detail','Page',1);
Rep_Orientation:=Inifile_Name.Readinteger('rep_detail','Orientation',0);
mit rep_Summary tun
beginnen
Columns:=Inifile_Name.Readinteger('rep_detail','columns',0);
Title:=Inifile_Name.Readstring('rep_detail','Title','Unbenannter Bericht');
page:=rep_chanslatepage(Rep_Page);//Konvertieren Sie die Druckseitengröße
Orientation:=rep_chanslateOrientation(Rep_Orientation);//Konvertieren Sie die Druckmoduseinstellungen
Ende;
Ende;
procedure Read_Col_Summary(Inifile_Name:Tinifile);//Zusammenfassungsinformationen der Berichtsspalten lesen
var i_count:integer;
beginnen
//Spalteninformationen im Array speichern
mit Rep_Col_Sum_store tun
beginnen
SetLength(Caption_array,rep_Summary.Columns);
SetLength(DataFiled_array,rep_Summary.Columns);
SetLength(Width_array,rep_Summary.Columns);
Ende;
für i_count:=0 bis rep_Summary.Columns-1 tun
beginnen
mit Rep_Col_Summary tun
beginnen
Caption:=Inifile_Name.Readstring('col_'+inttostr(i_count),'Caption','Unnamed');
DataFiled:=Inifile_Name.Readstring('col_'+inttostr(i_count),'DataFiled','');
Breite:=Inifile_Name.Readinteger('col_'+inttostr(i_count),'Width',0);
Ende;
mit Rep_Col_Sum_store tun
beginnen
Caption_array[i_count]:=Rep_Col_Summary.Caption;
DataFiled_array[i_count]:=Rep_Col_Summary.DataFiled;
width_array[i_count]:=Rep_Col_Summary.Width;
Ende;
Ende;
Ende;
procedure DynCreat_TQRRichtext(Colum_Num:integer);// Erstellen Sie dynamisch ein TQRRichtext-Steuerelement, das verwendet wird, um den chinesischen Namen jeder Spalte im Bericht anzuzeigen
var Colum_Name_list:TStrings;
beginnen
Colum_Name[Colum_Num]:=tQRRichtext.Create(application); //TQRRichtext-Steuerelement erstellen
Colum_Name[Colum_Num].Parent:=Form_rep.ColumnHeaderBand1;
Spaltenname[Spaltennummer].Frame.DrawTop:=true;
Colum_Name[Colum_Num].Frame.DrawBottom:=true;
Form_rep.ColumnHeaderBand1.Height:=40;
Spaltenname[Spaltennummer].Höhe:=40;
Spaltenname[Spaltennummer].Font.Height:=-14;
Colum_Name[Colum_Num].Font.Name:='Höllenkörper';
Spaltenname[Spaltennummer].Top:=0;
Colum_Name[Colum_Num].Alignment:=taCenter;
Colum_Name[Colum_Num].AutoStretch:=false;
//Zeichne Tabellenzeilen
Colum_Name[Colum_Num].Frame.Style:=psSolid;
Spaltenname[Spaltennummer].Frame.Width:=1;
Colum_Name[Colum_Num].Frame.DrawRight:=true;
Colum_Name[Colum_Num].Frame.DrawBottom:=true;
wenn Colum_Num=0 dann
beginnen
Colum_Name[Colum_Num].Frame.DrawLeft:=true;
Ende;
//Weisen Sie die Informationen im Datensatz RRep_Col_Sum_store zu Colum_Name zu
Colum_Name_list:=TStringList.Create;
Colum_Name_list.Add(Rep_Col_Sum_store.Caption_array[Colum_Num]);
Spaltenname[Spaltennummer].Lines:=Spaltennamenliste;
Colum_Name[Colum_Num].Width:=Rep_Col_Sum_store.Width_array[Colum_Num];
Spaltenname[Spaltennummer].Visible:=true;
//Berechne die linke Grenze
wenn Colum_Num>0 dann
Spaltenname[Spaltennummer].Links:=Spaltenname[Spaltennummer-1].Links+Spaltenname[Spaltennummer-1].Breite
anders
Spaltenname[Spaltennummer].Links:=0;
Ende;
Hinweis: Das TQRRichtext-Steuerelement wird hier verwendet, da das TQRRichtext-Steuerelement Zeilen automatisch umbrechen kann, wenn der Name zu lang ist.
procedure DynCreat_TQRDBText(Colum_Num:integer;Colum_Height:integer;DataSet_Name:TQuery);// Dynamisch ein TQRDBText-Steuerelement erstellen, das zur Anzeige des Werts jeder Spalte verwendet wird
beginnen
Colum_Data[Colum_Num]:=tQRDBText.Create(application);
Colum_Data[Colum_Num].Parent:=Form_rep.DetailBand1;
//Setzen Sie den Datensatz ein
Colum_Data[Colum_Num].DataSet:=DataSet_Name;
//Setzen Sie die Array-Eigenschaft Colum_Data.DateField auf den Feldnamen 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[Colum_Num].Height:=Colum_Height;
Form_rep.DetailBand1.Height:=Colum_Height;
Colum_Data[Colum_Num].Top:=0;
Colum_Data[Colum_Num].AutoSize:=false;
Colum_Data[Colum_Num].AutoStretch:=false;
Colum_Data[Colum_Num].WordWrap:=false;
Colum_Data[Colum_Num].Visible:=true;
//Zeichne Tabellenzeilen
Colum_Data[Colum_Num].Frame.Style:=psSolid;
Colum_Data[Colum_Num].Frame.DrawRight:=true;
Colum_Data[Colum_Num].Frame.DrawBottom:=true;
wenn Colum_Num=0 dann
Colum_Data[Colum_Num].Frame.DrawLeft:=true;
//Berechne die linke Grenze
wenn Colum_Num>0 dann
Colum_Data[Colum_Num].Left:=Colum_Data[Colum_Num-1].Left+Colum_Data[Colum_Num-1].Width
anders
Colum_Data[Colum_Num].Left:=0;
Ende;
procedure DynCreat_TQuery(Inifile_Name:Tinifile);//Legen Sie die SQL-Anweisung des TQuery-Steuerelements dynamisch fest
var
Sql_command:string;
beginnen
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);
Wenn nicht Form_rep.REP_QUERY.Prepared, dann
Form_rep.REP_QUERY.Prepare;
versuchen
Form_rep.REP_QUERY.ExecSQL;
Form_rep.REP_QUERY.Active:=true;
Form_rep.REP_QUERY.AutoCalcFields:=true;
Flag_CreatQuery:=true;
außer
Application.MessageBox('SQL-Anweisungsfehler!','Systemaufforderung',MB_ICONWARNING);
Flag_CreatQuery:=false;
Ende;
Ende;
Prozedur Form_rep_init();
var i_count:integer;
Rep_IniFile:Tinifile;//