----في العمل السابق للمؤلف باستخدام دلفي لتطوير قاعدة بيانات، طرح المستخدم مثل هذا المطلب: إنشاء تقارير ديناميكيًا بناءً على نتائج الاستعلام الخاصة به ثم طباعتها. بعد الكثير من الاستكشاف، استخدم المؤلف طريقة إنشاء عناصر تحكم QuickReport ديناميكيًا لتلبية احتياجات المستخدمين. سيتم شرح هذه الطريقة أدناه، على أمل تقديم بعض النصائح المفيدة للأصدقاء الذين لديهم أعمال مماثلة للقيام بها.
1. الأفكار الأساسية
----اكتب أولاً بعض معلمات الاستعلام (مثل أوامر SQL وأسماء الحقول وعرض الحقول وما إلى ذلك) في ملف مؤقت بتنسيق معين. عند إنشاء تقرير، ما عليك سوى إنشاء عناصر تحكم QuickReport متنوعة ديناميكيًا استنادًا إلى المعلمات المسجلة في الملف المؤقت.
2. تنفيذ البرنامج
2.1 تنسيق الملف المؤقت
---- يمكن تخصيص تنسيق الملف المؤقت وفقًا للاحتياجات. يستخدم المؤلف تنسيق الملف INI. توفر دلفي فئة TInifile، مما يجعلها مريحة للغاية لتشغيل ملفات بتنسيق INI في دلفي. هناك العديد من المقالات حول التنسيق والعمليات المحددة لملفات INI، لذا لن أخوض في التفاصيل هنا. تنسيق الملف المؤقت هو كما يلي:
Report.ini
: تفاصيل التقرير
[rep_detail]
العنوان=جدول XXXXXX
: إعدادات ورق الطباعة، 1 ورق A4، 2 ورق B5، 3 ورق 16K
الصفحة=1
: وضع الطباعة، 1 يعني الطباعة الأفقية، 0 يعني الطباعة العمودية.
التوجه=1
: عدد الحقول المضمنة في التقرير
الأعمدة=8
:معلومات مكون TQurey
[بيانات الاستعلام]
: محتويات أمر SQL الخاص بمكون Tqurey في مكون QuickReport
Sql_command=حدد V_XM,V_JGZW,V_BMMC,V_DWMC,V_DWZW,V_ZY,V_ZC,V_BGDH من Hvzzjg حيث V_XM LIKE '李%'
[col_0]
التسمية التوضيحية = الاسم
DataFiled=V_XM
العرض=60
…
…
2.2 إنشاء تقارير QuickReport ديناميكيًا
--- الضوابط الرئيسية للتقرير وإعدادات خصائصها الرئيسية هي كما يلي
اسم التحكم | اسم الفئة | ملكية | قيمة السمة |
Form_rep | TForm | التسمية التوضيحية | تقرير ديناميكي |
QuickRep | TQuickRep | DataSet | REP_QUERY |
التفاصيل:1 | TQRBand | نوع النطاق | rbDetail |
ColumnHeaderBand1 | TQRBand | نوع النطاق | rbColumnHeader |
REP_DataSource | TDataSource | DataSet | Rep_Query |
Rep_Query | TQuery | اسم قاعدة البيانات | قاعدة البيانات |
Rep_Database | قاعدة البيانات | متصل | حقيقي |
Params.Strings | 'اسم الخادم=XXX "المستخدم MAME=XXX" 'كلمة المرور=XXX' | ||
اسم قاعدة البيانات | قاعدة البيانات |
تم إنشاء عناصر التحكم الموضحة في الجدول أعلاه يدويًا في البرنامج. يجب إنشاء عناصر التحكم الأخرى بشكل حيوي في البرنامج.
2.2.2 الإجراءات الرئيسية
وحدة f_rep؛
واجهة
الاستخدامات
النوافذ، الرسائل، SysUtils، المتغيرات، الفئات، الرسومات، عناصر التحكم، النماذج،
مربعات الحوار، ExtCtrls، QuickRpt، QRCtrls، DB، DBTables، PRINTERS، QRPrntr، inifiles،
تيبروكس، تينجين، دبشارت، QRTEE؛
يكتب
TForm_rep = الفئة(TForm)
QuickRep: TQuickRep؛
ديتيلباند 1: تي كيو آر باند؛
ColumnHeaderBand1: TQRBand;
REP_DataSource: TDataSource;
REP_QUERY: TQuery؛
rep_Database: TDatabase;
الإجراء TForm_rep.QuickRepAfterPreview(Sender: TObject);// بعد التصفح، حرر جميع المكونات التي تم إنشاؤها
خاص
{تصريحات خاصة}
عام
{التصريحات العامة}
نهاية؛
فار Form_rep:TForm_Rep;
اكتب // ملخص معلومات التقرير
C_rep_Summary=سجل
العنوان: سلسلة؛ // عنوان التقرير
Page:TQRPaperSize;// إعدادات صفحة التقرير ونوع الورق المستخدم
Orientation:TPrinterOrientation;//إعداد صفحة التقرير سواء كان أفقيًا أو رأسيًا
Columns:integer;// عدد الأعمدة المضمنة في التقرير
نهاية؛
يكتب
C_Rep_Col_Summary=record//ملخص معلومات أعمدة التقرير
تسمية توضيحية: سلسلة؛ // اسم عمود التقرير
DataFiled:string;// اسم الحقل في قاعدة البيانات المطابق لعمود التقرير
العرض: عدد صحيح؛ // عرض عمود التقرير
نهاية؛
يكتب
C_Rep_Col_Sum_store=record // معلومات ملخص التخزين لأعمدة التقرير
Caption_array: مجموعة من السلسلة؛
DataFiled_array: صفيف من السلسلة؛
Width_array:صفيف عدد صحيح؛
نهاية؛
فار
rep_Summary:C_rep_Summary;
Rep_Col_Summary:C_Rep_Col_Summary;
Rep_Col_Sum_store:C_Rep_Col_Sum_store;
Colum_Name: صفيف tQRRichText؛
Colum_Data:صفيف TQRDBRichText؛
C_Query:TQuery;
الإجراء Form_rep_init();
الإجراء DynCreat_TQRDBText(Colum_Num:integer;Colum_Height:integer;DataSet_Name:TQuery);// إنشاء عنصر تحكم TQRDBText ديناميكيًا
الإجراء DynCreat_TQRRichtext(Colum_Num:integer);// إنشاء عنصر تحكم TQRRichtext ديناميكيًا
الإجراء DynCreat_TQuery(Inifile_Name:Tinifile);// عبارة SQL لإنشاء عنصر تحكم TQuery ديناميكيًا
الإجراء Get_PageCount();// احصل على العدد الإجمالي للصفحات المطبوعة
وظيفة Open_IniFile():Tinifile;// فتح ملف مؤقت
الإجراء Read_Col_Summary(Inifile_Name:Tinifile);// قراءة المعلومات الموجزة لأعمدة التقرير
الإجراء Read_Rep_Summary(Inifile_Name:Tinifile);// قراءة المعلومات الموجزة للتقرير
وظيفة rep_chanslateOrientation(var Rep_Orientation:integer):TPrinterOrientation;//تحويل إعدادات وضع الطباعة
وظيفة rep_chanslatepage(var Rep_Page:integer):TQRPaperSize;// تحويل إعداد حجم صفحة الطباعة
تطبيق
{$R *.dfm}
وظيفة rep_chanslatepage(var Rep_Page:integer):TQRPaperSize;// تحويل إعداد نوع صفحة الطباعة
يبدأ
حالة Rep_Page of
1: البدء
النتيجة:=A4;
Form_rep.QuickRep.PrinterSettings.PaperSize:=A4;
نهاية؛
2: البدء
النتيجة:=B5;
Form_rep.QuickRep.PrinterSettings.PaperSize:=B5
نهاية؛
3: البدء
result:=Executive;
Form_rep.QuickRep.PrinterSettings.PaperSize:=Executive;
نهاية؛
نهاية؛
نهاية؛
وظيفة rep_chanslateOrientation(var Rep_Orientation:integer):TPrinterOrientation;//تحويل إعدادات وضع الطباعة
يبدأ
حالة Rep_Orientation of
0:ابدأ
result:=poPortrait;//0 عمودي
Form_rep.QuickRep.PrinterSettings.Orientation:=poPortrait;
نهاية؛
1: البدء
result:=poLandscape;//1 أفقي
Form_rep.QuickRep.PrinterSettings.Orientation:=poLandscape;
نهاية؛
نهاية؛
نهاية؛
وظيفة Open_IniFile():Tinifile;// فتح ملف مؤقت
فار اسم الملف: سلسلة؛
Ini_Filename:string;
يبدأ
اسم الملف:='Report.ini';
Ini_Filename:=File_Path+Filename;
النتيجة:=Tinifile.Create(Ini_Filename);
نهاية؛
الإجراء Read_Rep_Summary(Inifile_Name:Tinifile);// قراءة المعلومات الموجزة للتقرير
var Rep_Page,Rep_Orientation:integer;
يبدأ
rep_Page:=Inifile_Name.Readinteger('rep_detail','Page',1);
Rep_Orientation:=Inifile_Name.Readinteger('rep_detail','Orientation',0);
مع rep_Summary افعل
يبدأ
Columns:=Inifile_Name.Readinteger('rep_detail','columns',0);
Title:=Inifile_Name.Readstring('rep_detail','Title','Unnamed report');
page:=rep_chanslatepage(Rep_Page);//تحويل حجم صفحة الطباعة
Orientation:=rep_chanslateOrientation(Rep_Orientation);//تحويل إعدادات وضع الطباعة
نهاية؛
نهاية؛
الإجراء Read_Col_Summary(Inifile_Name:Tinifile);// قراءة المعلومات الموجزة لأعمدة التقرير
فار i_count:عدد صحيح;
يبدأ
// احفظ معلومات العمود في المصفوفة
مع Rep_Col_Sum_store افعل
يبدأ
SetLength(Caption_array,rep_Summary.Columns);
SetLength(DataFiled_array,rep_Summary.Columns);
SetLength(Width_array,rep_Summary.Columns);
نهاية؛
من أجل i_count:=0 إلى rep_Summary.Columns-1 افعل ذلك
يبدأ
مع Rep_Col_Summary افعل
يبدأ
Caption:=Inifile_Name.Readstring('col_'+inttostr(i_count),'Caption','Unnamed');
DataFiled:=Inifile_Name.Readstring('col_'+inttostr(i_count),'DataFiled','');
Width:=Inifile_Name.Readinteger('col_'+inttostr(i_count),'Width',0);
نهاية؛
مع Rep_Col_Sum_store افعل
يبدأ
Caption_array[i_count]:=Rep_Col_Summary.Caption;
DataFiled_array[i_count]:=Rep_Col_Summary.DataFiled;
Width_array[i_count]:=Rep_Col_Summary.Width;
نهاية؛
نهاية؛
نهاية؛
إجراء DynCreat_TQRRichtext(Colum_Num:integer);// إنشاء عنصر تحكم TQRRichtext ديناميكيًا، والذي يستخدم لعرض الاسم الصيني لكل عمود في التقرير
فار Colum_Name_list:TSTrings;
يبدأ
Colum_Name[Colum_Num]:=tQRRichtext.Create(application); //إنشاء عنصر تحكم نص TQRRich
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].الارتفاع:=40;
Colum_Name[Colum_Num].Font.Height:=-14;
Colum_Name[Colum_Num].Font.Name:='جسد الجحيم';
Colum_Name[Colum_Num].Top:=0;
Colum_Name[Colum_Num].Alignment:=taCenter;
Colum_Name[Colum_Num].AutoStretch:=false;
// ارسم خطوط الجدول
Colum_Name[Colum_Num].Frame.Style:=psSolid;
Colum_Name[Colum_Num].Frame.Width:=1;
Colum_Name[Colum_Num].Frame.DrawRight:=true;
Colum_Name[Colum_Num].Frame.DrawBottom:=true;
إذا Colum_Num=0 ثم
يبدأ
Colum_Name[Colum_Num].Frame.DrawLeft:=true;
نهاية؛
// قم بتعيين المعلومات الموجودة في السجل 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];
Colum_Name[Colum_Num].Visible:=true;
// احسب الحد الأيسر
إذا Colum_Num>0 ثم
Colum_Name[Colum_Num].Left:=Colum_Name[Colum_Num-1].Left+Colum_Name[Colum_Num-1].Width
آخر
Colum_Name[Colum_Num].Left:=0;
نهاية؛
ملاحظة: يتم استخدام عنصر التحكم TQRRichtext هنا لأن عنصر التحكم TQRRichtext يمكنه التفاف الأسطر تلقائيًا عندما يكون الاسم طويلًا جدًا.
الإجراء DynCreat_TQRDBText(Colum_Num:integer;Colum_Height:integer;DataSet_Name:TQuery);// إنشاء عنصر تحكم TQRDBText ديناميكيًا، والذي يستخدم لعرض قيمة كل عمود
يبدأ
Colum_Data[Colum_Num]:=tQRDBText.Create(application);
Colum_Data[Colum_Num].Parent:=Form_rep.DetailBand1;
// قم بتعيين مجموعة البيانات
Colum_Data[Colum_Num].DataSet:=DataSet_Name;
// قم بتعيين خاصية الصفيف Colum_Data.DateField على اسم الحقل في 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;
// ارسم خطوط الجدول
Colum_Data[Colum_Num].Frame.Style:=psSolid;
Colum_Data[Colum_Num].Frame.DrawRight:=true;
Colum_Data[Colum_Num].Frame.DrawBottom:=true;
إذا Colum_Num=0 ثم
Colum_Data[Colum_Num].Frame.DrawLeft:=true;
// احسب الحد الأيسر
إذا Colum_Num>0 ثم
Colum_Data[Colum_Num].يسار:=Colum_Data[Colum_Num-1].Left+Colum_Data[Colum_Num-1].العرض
آخر
Colum_Data[Colum_Num].Left:=0;
نهاية؛
الإجراء DynCreat_TQuery(Inifile_Name:Tinifile);// قم بتعيين عبارة SQL لعنصر تحكم TQuery ديناميكيًا
فار
Sql_command:string;
يبدأ
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);
إذا لم يكن Form_rep.REP_QUERY.Prepared بعد ذلك
Form_rep.REP_QUERY.تحضير؛
يحاول
Form_rep.REP_QUERY.ExecSQL;
Form_rep.REP_QUERY.Active:=true;
Form_rep.REP_QUERY.AutoCalcFields:=true;
Flag_CreatQuery:=true;
يستثني
Application.MessageBox('خطأ في بيان SQL!','موجه النظام',MB_ICONWARNING);
Flag_CreatQuery:=false;
نهاية؛
نهاية؛
الإجراء Form_rep_init();
فار i_count:عدد صحيح;
Rep_IniFile:Tinifile;//