بسم الله الرحمن الرحيم
طالما فكرت في كتابة أحد الدروس البسيطة ... ولكن كان يمنعني دائما قلقي أن تكون دون المستوى لأن ليس لي سابق خبرة ... وحين قرأت إستفسار بعض الإخوة عن نوافذ الإدخال فكرت في كتابة هذه السطور عسى أن أفيده هو وغيره ... وأستفيد أنا الآخر من ملاحظات زملائي في المنتدى.
إنها محاولة إن لم تفيد فلن تضر :happy:
الهدف : بناء نافذه عامة للإدخال، تصلح لإستخدامها في أغلب النوافذ المستخدمة بالبرنامج ... مع مراعاه الاساسيات المطلوبة في نوافذ الإدخال
الفائدة : إستغلال النافذة العامة بالوراثة منها لجميع نوافذ الإدخال في البرنامج له فوائد عديدة منها.
أ- عدم تكرار الأكواد والسرعة في الإنتهاء من نوافذ الإدخال في البرنامج.
ب- وحدة الشكل والأداء لجميع نوافذ الإدخال بالبرنامج يمثل سهولة على المستخدم.
ت- سهولة التعديل فيما بعد بضربة واحدة لجميع النوافذ في حال الرغبة بتغيير شئ.
ملاحظات
1- سافترض وجود المبادئ الأساسية لربط البيانات وإنشاء الإتصال ومعرفة المكونات
2- نوع قاعدة البيانات غير مؤثر فقد إستخدمت Ado مع الأكسس و MSSQL من دون مشاكل.
3- أستخدم دلفي 2007 .
ونبدأ على بركة الله.
قم بعمل فورم جديد ... وقم بإضافة المكونات التالية
TADOTable من القائمة DBGo
TDataSource من القائمة Data Access
TActionList من القائمة Standard
TPanel من القائمة Standard
TJvDBComboEdit أو أي مكون مشابه أو حتى TDbEdit عادي من القائمة Data Controls ونسميه Pkey
عدد 10 Buttons
(قم بالحفظ)
والآن نحن جاهزون للعمل.
أولا : ضبط مكون TADOTable : يتم ضبط المكون وربطه مع الإتصال المفترض بقاعدة البيانات.
ملحوظة لا تقم بربط المكون مع أي جدول من جداول قاعدة البيانات.
ثانيا : ضبط مكون DataSource بربطه مع TADOTable الذي يمثل DataSet الخاصه به.
ثالثا الأحداث : في أي نافذة إدخال لابد من وجود متصفح للسجلات Navigator وإما ان تستخدم مكون جاهز لهذا الغرض او تستخدم أي مجموعة من المفاتيح Buttons ... وسواء إستخدمت الأول أو الثاني فحتما ستحتاج للأحداث التي تجعل التصفح ممكننا ولإذافة هذه الأحداث إستخدمنا TActionList ...
دبل كلك على المكون لإضافة الأحداث ... في النافذة الظاهرة هناك أيقونة لإضافة حدث صغير بجانبها سهم صغير ... إضغط على السهم ومن القائمة المنسدلة إختر New Standard Action
من قائمة الأحداث الأساسية المتاحة قم بتظيل جميع الأحداث الخاصة ب DataSet كلها وإضغط موافق.
من البديهي عندما نقوم بتعريف أحداث DataSet ان نقوم بتعريف DataSource لكل حدث فيها...
ولكننا لن نفعل ذلك .. لماذا ؟؟!!
لان هذه نافذه عامة ستستخدم لنوافذ مختلفة لإدخال البيانات ... وقد تحتاج الى إلى إستخدام نفس الأزرار مع DataSource آخر بالإضافة للموجود حاليا ... كأن تكون النافذه بها جدولين ...
الآن سنأتي على كل حدث ونسجل Caption بالعربي إن أردت بدلا من الإنجليزي الموجود إفتراضيا.
قم بالحفظ
رابعا المفاتيح Button : لإنهاء تفعيل متصفح السجلات سنقوم بربط كل Button بالحدث الذي يقوم به ... والترتيب يرجع لك وللمنطق الشائع والذي تراه مناسبا.
خامسا : Pkey
أي جدول به PK مفتاح أساسي ... هذا المفتاح الأساسي سواء كان سيتم إدخاله يدويا أو سيتم زيادته آليا مع السجل الجديد ... فغالبا ما ستحتاج لعرضه للمستخدم في أغلب نوافذ الإدخال ... والفائدة الرئيسية له هنا هو تحديد هل يتم إضافة سجل جديد أم التعديل على سجل موجود دون الحاجة لستخدام مفتاح "جديد" ..
وسنقوم بذلك كالتالي
في القسم الخاص بإعلان المتغيرات سنقوم بتعريف متغييرين من نوع STRING كالتالي
private OLD_VAL,NEW_VAL:STRING;
في حدث الدخول ل Pkey سنقوم بتسجيل القيمة الحالية الموجودة بالحقل
procedure TForm1.PKEYEnter(Sender: TObject); begin OLD_VAL:=PKEY.Field.Text; PKEY.Color:=clSkyBlue; end;
وفي حدث الخروج منه سنقوم بالتأحقق من القيمة فإن كانت قد تغيرت فنقوم آليا بالتحقق من القيمة الجديدة إن كانت موجودة في قاعدة البيانات ... وإن كانت غير موجودة فنقوم بإضافة سجل جديد كالتالي
procedure TForm1.PKEYExit(Sender: TObject); var CO:TDbEdit; begin CO:=(Sender as TDbEdit); CO.Color:=clWhite; if (OLD_VAL=CO.Text) then exit; NEW_VAL:=CO.Text; CO.DataSource.DataSet.Cancel; if not CO.DataSource.DataSet.Locate(CO.DataField,NEW_VAL,[]) then begin CO.DataSource.DataSet.Append; CO.Field.Text:=NEW_VAL; end; end;
سادسا الأحداث المتعلقة بالفورم
تذكروا أننا لم نحدد إسم الجدول المرتبط ولذلك عند فتح الفورم ومحاولة فتح الجدول يجب التحقق من انه في النافذة الموروثة تم تعريف إسم الجدول لكي لا تحدث رسالة خطأ.
procedure TForm1.FormCreate(Sender: TObject); begin if TABLE.TableName<>'' then try TABLE.Close; TABLE.Open; // TABLE.Append; except end; End;
وهناك أحداث كثيرة يمكننا الإستفادة منها هنا كالتحقق من الصلاحيات .. ولكن هذا موضوع آخر
سابعا حدث الضغط على مفتاح بالفورم.
في جميع نوافذ الإدخال يكون التنقل بين الحقول بمفتاح Enter افضل كثيرا من مفتاح Tab وكذلك إستخدامات متعددة لمفاتيح أخرى وكذلك إغلاق النافذة بالضغط على مفتاح ال ESCAPE
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); VAR CO: TJvDBComboBox; begin case Key of VK_RETURN : keybd_event(VK_TAB,0,0,0); VK_ESCAPE : if Screen.ActiveControl=P_KEY then Close else P_KEY.SetFocus; end; end;
بالطبع لاتنسى ربط جميع الكائنات بالنافذة بعد ذلك بهذا الحدث
سابعا الأحداث المتعلقة بالجدول
قبل حفظ أي سجل يجب التأكد من وجود بيانات بالمفتاح الأساسي ...وإلا سينتج خطأ مزعج ...وعليه يتوقف حفظ السجل من عدم حفظ السجل. وكذلك التأكيد على المستخدم بإجراء عملية الحفظ
procedure TForm1.TABLEBeforePost(DataSet: TDataSet);
begin
if P_KEY.Text <> '' then
begin
if MessageDlg('هل تريد حفظ السجل ؟', mtCustom, [mbYes,mbNo], 0) =mrNO then
BEGIN
abort;
TABLE.Cancel;
END;
end
else
begin
abort;
TABLE.Cancel;
TABLE.First;
end;
end;كذلك الأمر قبل عملية حذف أي سجل يجب التأكد من صلاحيات الحذف لدى الشخص الذي يقوم بالحذف والتأكيد عليه أنه يريد الحذف
procedure TForm1.TABLEBeforeDelete(DataSet: TDataSet);
begin
IF NOT (DEL) THEN
BEGIN
MessageDlg('حذف سجل ليس ضمن الصلاحيات المتاحة'+#13+#10+''+#13+#10+'من فضلك راجع مسئول النظام................', mtCustom, [mbOK], 0);
TABLE.Cancel;
ABORT;
EXIT;
END;
if MessageDlg('هل تريد حذف هذا السجل ؟', mtWarning, [mbYes,mbNo], 0) = mrNo then
abort;
end;الآن أصبح لديك نافذة إدخال بها المبادئ الأساسية وجاهزة لكي ترث منها عشرات النوافذ التي تعمل كلها بنفس الطريقة
وهناك العديد من الإجرائات الأخرى التي يمكن إضافتها الى نافذة الإدخال العامة ولكن كلها تتوقف على طريقة تفكيرك وتنفيذك للبرنامج، مثل الصلاحيات وخلافه
وكذلك تختلف الطريقة السابقة في حالة وجود أكثر من مفتاح أساسي بالجدول .
في النهاية أتمنى ان أكون قد أفدت الإخوة بشئ بسيط ... وأتمنى من الجميع ان يصحح لي ما قد أخطأت فيه أو أن يكون هناك بدائل أفضل فساكون سعيدا بسماعها
تحياتي