----Dans les travaux précédents de l'auteur utilisant Delphi pour développer une base de données, l'utilisateur a mis en avant une telle exigence : générer dynamiquement des rapports basés sur ses propres résultats de requête, puis les imprimer. Après de nombreuses explorations, l'auteur a utilisé la méthode de génération dynamique de contrôles QuickReport pour répondre aux besoins des utilisateurs. Cette méthode est expliquée ci-dessous, dans l'espoir de fournir quelques conseils utiles aux amis qui ont un travail similaire à faire.
1. Idées de base
----Écrivez d'abord certains paramètres de requête (tels que les commandes SQL, les noms de champs, les largeurs de champs, etc.) dans un fichier temporaire dans un certain format. Lors de la génération d'un rapport, générez simplement dynamiquement divers contrôles QuickReport en fonction des paramètres enregistrés dans le fichier temporaire.
2. Mise en œuvre du programme
2.1 Format de fichier temporaire
----Le format du fichier temporaire peut être personnalisé selon les besoins. L'auteur utilise le format de fichier INI. Delphi fournit une classe TInifile, ce qui rend très pratique l'exploitation des fichiers au format INI dans Delphi. Il existe de nombreux articles sur le format et les opérations spécifiques des fichiers INI, je n'entrerai donc pas dans les détails ici. Le format du fichier temporaire est le suivant :
Rapport.ini
:Détails du rapport
[rep_detail]
Titre=Tableau XXXXX
: Paramètres du papier d'impression, 1 est du papier A4, 2 est du papier B5, 3 est du 16K
Page=1
: Mode d'impression, 1 signifie impression horizontale, 0 signifie impression verticale.
Orientation=1
: Nombre de champs inclus dans le rapport
colonnes = 8
:Informations sur le composant TQurey
[Données de requête]
: Contenu de la commande SQL du composant Tqurey dans le composant QuickReport
Sql_command=sélectionnez V_XM,V_JGZW,V_BMMC,V_DWMC,V_DWZW,V_ZY,V_ZC,V_BGDH à partir de Hvzzjg où V_XM LIKE '李%'
[col_0]
Légende=Nom
DataFiled=V_XM
Largeur=60
…
…
2.2 Générer dynamiquement des rapports QuickReport
--- Les principaux contrôles du rapport et leurs principaux paramètres de propriétés sont les suivants
Nom du contrôle | Nom de la classe | propriété | valeur d'attribut |
Formulaire_rep | TForm | légende | rapport dynamique |
Réponse rapide | TQuickRep | Ensemble de données | REP_QUERY |
DétailBand1 | Bande TQR | Type de bande | rbDétail |
ColonneEn-TêteBand1 | Bande TQR | Type de bande | rbColumnHeader |
REP_DataSource | TDataSource | Ensemble de données | Rep_Query |
Rep_Query | TQuery | Nom de la base de données | REPDATABASE |
Rep_Base de données | Base de données T | Connecté | Vrai |
Params.Strings | 'NOM DU SERVEUR=XXX 'UTILISATEUR MAME=XXX' 'Mot DE PASSE=XXX' | ||
Nom de la base de données | REPDATABASE |
Les contrôles présentés dans le tableau ci-dessus ont été créés manuellement dans le programme. D'autres contrôles doivent être créés dynamiquement dans le programme.
2.2.2 Principales procédures
unité f_rep ;
interface
utilise
Windows, messages, SysUtils, variantes, classes, graphiques, contrôles, formulaires,
Boîtes de dialogue, ExtCtrls, QuickRpt, QRCtrls, DB, DBTables, IMPRIMANTES, QRCrntr, fichiers ini,
TeeProcs, TeEngine, DbChart, QRTEE ;
taper
TForm_rep = classe(TForm)
QuickRep : TQuickRep ;
DétailBand1 : TQRBand ;
ColonneHeaderBand1 : TQRBand ;
REP_DataSource : TDataSource ;
REP_QUERY : TQuery ;
rep_Database : TDatabase ;
procédure TForm_rep.QuickRepAfterPreview(Sender: TObject);//Après la navigation, libérez tous les composants créés
privé
{Déclarations privées}
publique
{Déclarations publiques}
fin;
var Form_rep:TForm_Rep;
tapez //Informations récapitulatives du rapport
C_rep_Summary=enregistrement
Title:string;//Le titre du rapport
Page:TQRPaperSize;//Les paramètres de page du rapport, quel type de papier est utilisé
Orientation:TPrinterOrientation;//La mise en page du rapport, qu'elle soit horizontale ou verticale
Colonnes : entier ;//Nombre de colonnes incluses dans le rapport
fin;
taper
C_Rep_Col_Summary=record//Informations récapitulatives des colonnes du rapport
Légende : chaîne ; // nom de la colonne du rapport
DataFiled:string;//Le nom du champ dans la base de données correspondant à la colonne du rapport
Largeur:entier;//largeur de colonne du rapport
fin;
taper
C_Rep_Col_Sum_store=record //Stockage des informations récapitulatives des colonnes du rapport
Caption_array : tableau de chaînes ;
DataFiled_array : tableau de chaînes ;
width_array : tableau d'entiers ;
fin;
var
rep_Summary : C_rep_Summary ;
Rep_Col_Summary : C_Rep_Col_Summary ;
Rep_Col_Sum_store :C_Rep_Col_Sum_store ;
Colum_Name : tableau de tQRRichText ;
Colum_Data : tableau de TQRDBRichText ;
C_Query : TQuery ;
procédure Form_rep_init();
procédure DynCreat_TQRDBText(Colum_Num:integer;Colum_Height:integer;DataSet_Name:TQuery);//Créer dynamiquement un contrôle TQRDBText
procédure DynCreat_TQRRichtext(Colum_Num:integer);//Créer dynamiquement un contrôle TQRRichtext
procédure DynCreat_TQuery(Inifile_Name:Tinifile);//instruction SQL pour créer dynamiquement un contrôle TQuery
procédure Get_PageCount();//Obtenir le nombre total de pages imprimées
function Open_IniFile():Tinifile;//Ouvrir le fichier temporaire
procédure Read_Col_Summary(Inifile_Name:Tinifile);//Lire les informations récapitulatives des colonnes du rapport
procédure Read_Rep_Summary(Inifile_Name:Tinifile);//Lire les informations récapitulatives du rapport
function rep_chanslateOrientation(var Rep_Orientation:integer):TPrinterOrientation;//Convertir les paramètres du mode d'impression
function rep_chanslatepage(var Rep_Page:integer):TQRPaperSize;//Convertir le paramètre de taille de page d'impression
mise en œuvre
{$R *.dfm}
function rep_chanslatepage(var Rep_Page:integer):TQRPaperSize;//Convertir le paramètre de type de page d'impression
commencer
cas Rep_Page de
1 : commencer
résultat :=A4 ;
Form_rep.QuickRep.PrinterSettings.PaperSize:=A4;
fin;
2 : commencer
résultat :=B5 ;
Form_rep.QuickRep.PrinterSettings.PaperSize:=B5
fin;
3 : commencer
result:=Exécutif;
Form_rep.QuickRep.PrinterSettings.PaperSize:=Executive;
fin;
fin;
fin;
function rep_chanslateOrientation(var Rep_Orientation:integer):TPrinterOrientation;//Convertir les paramètres du mode d'impression
commencer
cas Rep_Orientation de
0 : début
result:=poPortrait;//0 est vertical
Form_rep.QuickRep.PrinterSettings.Orientation:=poPortrait;
fin;
1 : commencer
result:=poLandscape;//1 est horizontal
Form_rep.QuickRep.PrinterSettings.Orientation:=poLandscape;
fin;
fin;
fin;
function Open_IniFile():Tinifile;//Ouvrir le fichier temporaire
var Nom du fichier : chaîne ;
Ini_Filename:chaîne;
commencer
Nom du fichier :='Rapport.ini' ;
Ini_Filename:=File_Path+Filename;
Résultat :=Tinifile.Create(Ini_Filename);
fin;
procédure Read_Rep_Summary(Inifile_Name:Tinifile);//Lire les informations récapitulatives du rapport
var Rep_Page,Rep_Orientation:entier;
commencer
rep_Page:=Inifile_Name.Readinteger('rep_detail','Page',1);
Rep_Orientation:=Inifile_Name.Readinteger('rep_detail','Orientation',0);
avec rep_Summary faire
commencer
Colonnes :=Inifile_Name.Readinteger('rep_detail','columns',0);
Title:=Inifile_Name.Readstring('rep_detail','Title','Rapport sans nom');
page:=rep_chanslatepage(Rep_Page);//Convertir la taille de la page d'impression
Orientation:=rep_chanslateOrientation(Rep_Orientation);//Convertir les paramètres du mode d'impression
fin;
fin;
procédure Read_Col_Summary(Inifile_Name:Tinifile);//Lire les informations récapitulatives des colonnes du rapport
var i_count:entier;
commencer
//Enregistrer les informations de la colonne dans le tableau
avec Rep_Col_Sum_store faire
commencer
SetLength(Caption_array,rep_Summary.Columns);
SetLength(DataFiled_array,rep_Summary.Columns);
SetLength(Width_array,rep_Summary.Columns);
fin;
pour i_count:=0 à rep_Summary.Columns-1 faites
commencer
avec Rep_Col_Summary faire
commencer
Légende :=Inifile_Name.Readstring('col_'+inttostr(i_count),'Caption','Unnamed');
DataFiled:=Inifile_Name.Readstring('col_'+inttostr(i_count),'DataFiled','');
Largeur:=Inifile_Name.Readinteger('col_'+inttostr(i_count),'Width',0);
fin;
avec Rep_Col_Sum_store faire
commencer
Caption_array[i_count]:=Rep_Col_Summary.Caption;
DataFiled_array[i_count]:=Rep_Col_Summary.DataFiled;
width_array[i_count]:=Rep_Col_Summary.Width;
fin;
fin;
fin;
procédure DynCreat_TQRRichtext(Colum_Num:integer);//Créer dynamiquement un contrôle TQRRichtext, qui permet d'afficher le nom chinois de chaque colonne du rapport
var Colum_Name_list:TStrings;
commencer
Colum_Name[Colum_Num]:=tQRRichtext.Create(application); //Créer un contrôle TQRRichtext
Nom_Colonne[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;
Nom_Colonne[Num_Colonne].Hauteur :=40 ;
Nom_Colonne[Num_Colonne].Font.Hauteur :=-14 ;
Colum_Name[Colum_Num].Font.Name:='Corps de l'enfer';
Nom_Colonne[Num_Colonne].Top:=0;
Nom_Colonne[Num_Colonne].Alignment:=taCenter;
Nom_Colonne[Num_Colonne].AutoStretch:=false;
//Dessiner des lignes de tableau
Colum_Name[Colum_Num].Frame.Style:=psSolid;
Nom_Colonne[Num_Colonne].Frame.Width:=1;
Colum_Name[Colum_Num].Frame.DrawRight:=true;
Colum_Name[Colum_Num].Frame.DrawBottom:=true;
si Colum_Num=0 alors
commencer
Colum_Name[Colum_Num].Frame.DrawLeft:=true;
fin;
//Attribuer les informations de l'enregistrement RRep_Col_Sum_store à Colum_Name
Colum_Name_list:=TStringList.Create;
Colum_Name_list.Add(Rep_Col_Sum_store.Caption_array[Colum_Num]);
Colum_Name[Colum_Num].Lines:=Colum_Name_list;
Colum_Name[Colum_Num].Width:=Rep_Col_Sum_store.Width_array[Colum_Num];
Nom_Colonne[Num_Colonne].Visible:=true;
//Calculer la limite gauche
si Numéro_Colonne>0 alors
Nom_Colonne[Num_Colonne].Gauche :=Nom_Colonne[Num_Colonne-1].Left+Nom_Colonne[Num_Colonne-1].Largeur
autre
Nom_Colonne[Num_Colonne].Gauche:=0;
fin;
Remarque : Le contrôle TQRRichtext est utilisé ici car il peut automatiquement renvoyer à la ligne les lignes lorsque le nom est trop long.
procédure DynCreat_TQRDBText(Colum_Num:integer;Colum_Height:integer;DataSet_Name:TQuery);//Créer dynamiquement un contrôle TQRDBText, qui est utilisé pour afficher la valeur de chaque colonne
commencer
Colum_Data[Colum_Num]:=tQRDBText.Create(application);
Colum_Data[Colum_Num].Parent:=Form_rep.DetailBand1;
//Définir l'ensemble de données
Colum_Data[Colum_Num].DataSet:=DataSet_Name;
//Définissez la propriété du tableau Colum_Data.DateField sur le nom du champ dans 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].Hauteur :=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;
//Dessiner des lignes de tableau
Colum_Data[Colum_Num].Frame.Style:=psSolid;
Colum_Data[Colum_Num].Frame.DrawRight:=true;
Colum_Data[Colum_Num].Frame.DrawBottom:=true;
si Colum_Num=0 alors
Colum_Data[Colum_Num].Frame.DrawLeft:=true;
//Calculer la limite gauche
si Numéro_Colonne>0 alors
Colum_Data[Colum_Num].Left:=Colum_Data[Colum_Num-1].Left+Colum_Data[Colum_Num-1].Width
autre
Colum_Data[Colum_Num].Left:=0;
fin;
procédure DynCreat_TQuery(Inifile_Name:Tinifile);//Définir dynamiquement l'instruction SQL du contrôle TQuery
var
Commande_Sql : chaîne ;
commencer
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);
sinon Form_rep.REP_QUERY.Prepared alors
Form_rep.REP_QUERY.Prepare ;
essayer
Form_rep.REP_QUERY.ExecSQL ;
Form_rep.REP_QUERY.Active:=true;
Form_rep.REP_QUERY.AutoCalcFields:=true;
Flag_CreatQuery :=true ;
sauf
Application.MessageBox('Erreur d'instruction SQL !','Invite système',MB_ICONWARNING);
Flag_CreatQuery :=false ;
fin;
fin;
procédure Form_rep_init();
var i_count:entier;
Rep_IniFile:Tinifile;//