|
تعرض هذه الحلقة من المقالة كيفية عرض اللائحة المنسدلة ضمن خلايا
لأحد الأعمدة في الـ DBGrid. و حيث يتم التعامل مع
هذه الخلية و كأنها لائحة منسدلة محملة بالقيم المسبقة التي سيتم وضع إحدى
هذه القيم ضمن خلايا الـ DBGrid.
و
هذه الحلقة هي جزء من سلسلة حلقات لمقالة تشرح كيفية وضع عناصر التحكم ضمن
الـ DBGrid راجع الحلقة
الأولى للاطلاع على الجانب النظري من المقالة.
اللائحة المنسدلة ضمن و الـ LookUp
:
يوجد كما وجدنا
سابقا عدة أسباب و دواعي لتخصيص الـ DBGrid و طريقة عرض و إدخال البيانات من
خلالها. و أحد هذه الدواعي تكون عندما نحتاج لإدخال قيمة محددة سلفا من
مجموعة ثابتة أو ديناميكة من القيم إلى أحد حقول الجدول و بالتالي نحن نحتاج
لاستخدام مايسمى بحقل البحث LoockUpField و هذا الحقل يحوي هذه المجموعة من
القيم التي سنختار إحداها لملئه في الحقل المرغوب. مثال على هذه الحالة,
هو مثلا إذا كان لدينا جدول للبضائع و هذا الجدول يحتوي على حقل للموردين
لهذه البضائع, و بالتالي سيكون لدينا عدد محدد أو متغير من الموردين و لكنهم
معروفين جيدا من قبل كل الجداول الأخرى, فليس من المعقول أن يكون لدي في جدول
البضائع مورد اسمه احمد و هذا المورد موجود في جدول للفواتير باسم حمد, و ذلك
بسبب خطأ إدخال من المسثمر و إن كان التصميم المنطقي لقاعدة المعطيات قوي
فهذا التصميم لن يسمح بوجود مثل هكذا خطأ في البيانات و لكن سيظهر رسالة
إزعاج للمستخدم بأنه إدخل مورد غير موجود, و لتجنب هكذا حالة لماذا لا نضع
الموردين ضمن لائحة منسدلة أختارهم اختيار و لا أقوم بكتابة كل مورد. و هذه
اللائحة تأخذ معلوماته مثلا من جدول يحوي على الموردين, و بالتالي أصبح لدي
هنا ما يسمى بعنصر الـ LookUp التي تأخذ فيمه من جدول الموردين و تضعها في
حقل الموردين في جدول البضائع و ذلك بمجرد النقر بزر الماوس.
مثال عملي : أولا و قبل كل شيئ سمي بالله و شغل دلفي.
ثم نضع العنصر DBGrid على الـ Form. ثم نضع عناصر قواعد المعطيات التالية
:TADOTable, TADOConnection, TDataSource. ثم نضع نقوم بضبط بعض خصائص هذه
العناصر كما يلي :
ConnectionString.ADOConnection1 =
QuickiesContest.mdb
DBGrid1.datasource = DataSource1
DataSource1.dataset= ADOTable1
ADOTable1.DataBase= ADOConnection1
: و أخير يجب أن نحثصل على الشكل التالي

و لكن
ما نريد أن نحصل عليه في هذه الحلقة هو تحويل الـ DBGrid إلى الشكل التالي :

و هذا
الشكل نحصل عليه من خلال ثلاث طرق أو أساليب هي :
-
إذا كان لديك في النافذة DBGrid تقوم بكل عمليات الإدخال و
الإخراج من خلالها فمن الأنسب أن تنشئ حقل جديد ضمن الـ Dataset المتصلة
مع هذه الـ DBGrid.
-
إذا كانت النافذة تحوي على عدة عناصر تحكم و اتصال مع قواعد
المعطيات مثل (DBEdit, DBComboBox , الخ ), فالأنسب استخدام العنصر
DBLookupComboBox مباشرة دون إنشاء أي حقل جديد.
-
الطريقة الأخيرة هي استخدام إحدى خصائص أعمدة الـ DBGrid و هي
الـ PickList, حيث يتم ملئ قيم الـ List المرتبطة مع هذه الخاصة بقيم
التي نريد و ضعها في الحقل المرغوب, تماما مثل الـ DBComboBox و لكن ضمن
خلايا الـ DBgrid.
و سوف
نشرح كل أسلوب من هذه الأساليب الثلاث على حدا و سنبدأ بآخرها.
تعريف الخاصة
PickList كحقل بحثي LookUpField :
سنتعرف خلال هذه الفقرة على الحقول
البحثية LookUp Fields, و ما هي الخيارات لاستعراض الحقول البحثية ضمن الـ
DBGrisd, و كما سنتعلم كيفية استخدام الخاصة Picklist لتميكن المستخدم من
اختيار القيمة المناسبة لحقول البحثية من خلال لائحة منسدلة.
معلومات سريعة عن خاصية الـ Columns ضمن الـ
DBGrid. تملك الـ DBGrid خاصية تدعى
بالـ Columns و هذه الخاصية هي من عبارة عن مجموعة من العناصر (Objects) من
النمط TColumn تمثل جميع الأعمدة ضمن الـ Grid. و يتم اسناد قيم لهذه الخاصة
إما خلال مرحلة التصميم ( Design Time ) من خلال محرر هذه الخاصة ضمن الـ
ObjectInspector, أو برمجيا خلال مرحلة التنفيذ ( RunTime). حيث تستطيع أن
مثلا أن تحدد عدد الأعمدة التي تظهر على الـ DBGrid و ترتيبها كما أنه كل
عمود يمكن من خلال هذه الخاصة تحديد لونه و لون الترويسة الخاصة به و لون
الخط الخاص به و العديد من الخصائص المندرجة تحت بند هذه الخاصية و أيضا
يمكنك أن تحدد هذا العمود من الـ DBGrid مع من أعمدة الجدول سيتصل من خلال
الخاصة DataField و التي هي أحد خصائص الكائن TColumn. و بالإضافة لذلك كله
يوجد خاصة تدعى الـ PickList و هي عبارة عن لائحة تحوي العناصر التي سيتم وضع
أحداها ضمن حقل الجدول الذي يرتبط العمود معه.
ملئ الـ PickList بالقيم : سنقوم الآن بملئ الـ
StrigList الخاصة بالـ PickList بالقيم التي نريدها, حيث أننا كما نذكر من
قاعدة البيانات التي نعمل عليها هو أنه لدينا جدول بالمقالات يحوي على حقل
مواضيع و حقل المواضيع هذا لا يقبل قيمه إلا من خلال جدول المواضيع. و هنا
سوف نقوم عند بدء تشكيل الـ Form باستدعاء اجرائية تدعى SetupGridPickList
لتهئية قيم الـ PickList هذه لحظة إنشاء الـ Form.
|
procedure
TForm1.FormCreate(Sender: TObject);
begin
SetupGridPickList('Subject', 'SELECT Name FROM
Subjects');
end; |
و هذه
الإجرائية نعرف ترويستها ضمن قسم الـ Private و من ثم نضغط تراكب المفاتيح
التالية Ctrl +Shift+ C لنحصل على جسم الإجرائية في قسم الـ
Implimentation.
|
...
type
TForm1 = class(TForm)
...
private
procedure SetupGridPickList(
const FieldName : string;
const sql : string);
public
... |
حيث
كما نلاحظ من خلال تعريف الإجرائية أنها تحوي على بارامترمين
- أولهما : SetupGridPickList
: و هو اسم الحقل الذي نرغب بجعله حقل
بحثي ضمن الـ DBgrid
- ثانيهما : sql و هي عبارة عن نص الاستفسار الـ Query التي سنجلب منها المعلومات لنضعها ضمن الـ List و هي في العادة تعيد حقل وحيد من
الجدول.
و جسم
الإجرائية هو التالي :
|
procedure
TForm1.SetupGridPickList(const FieldName, sql:
string);
var
slPickList:TStringList;
Query : TADOQuery;
i : integer;
begin
slPickList:=TStringList.Create;
Query := TADOQuery.Create(self);
try
Query.Connection := ADOConnection1;
Query.SQL.Text := sql;
Query.Open;
//Fill
the string list
while not Query.EOF do
begin
slPickList.Add(Query.Fields[0].AsString);
Query.Next;
end; //while
//place
the list it the correct column
for i:=0 to DBGrid1.Columns.Count-1 do
if DBGrid1.Columns[i].FieldName = FieldName
then
begin
DBGrid1.Columns[i].PickList:=slPickList;
Break;
end;
finally
slPickList.Free;
Query.Free;
end;
end;
(*SetupGridPickList*) |
و
الآن عندما نقوم بترجمة البرنامج و نصضغط F9 فسوف
نحصل على ما كنا نود الحصول عليه و هو الشكل التالي :

ما
زال لدينا قليل من العمل :
عزيزي القارئ عندما تضغط على الـ
PickUpList سوف تعرض عليك لائحة منسدلة من داخل
الخلية و لكن أنا أريد لدى اختياري لإحدى بنود هذه اللائحة أن يتم تخزين هذا
البيند ضمن الحلق المختار. و لكي أحصل على هذا الشيئ فيجب علي أن أكتب كود
يضغط على الخلية أربع مرات متتالية لماذا ؟؟ عليك أن تحذر من الكود
لماذا...
|
procedure
TForm1.DBGrid1CellClick(Column: TColumn);
begin
//Making
the drop-down pick list appear faster
if Column.PickList.Count > 0 then
begin
keybd_event(VK_F2,0,0,0);
keybd_event(VK_F2,0,KEYEVENTF_KEYUP,0);
keybd_event(VK_MENU,0,0,0);
keybd_event(VK_DOWN,0,0,0);
keybd_event(VK_DOWN,0,KEYEVENTF_KEYUP,0);
keybd_event(VK_MENU,0,KEYEVENTF_KEYUP,0);
end;
end; |
ذا
صعب عليك الجواب فهو ببساطة لتقليد عملية الضغط على مفتاح Alt +
DownArrow متبوعة بمفتاح الـ F2.
|