delphi4arab منتديات دلفي للعرب

نسخة كاملة : تعلم معي خطوة خطوة صنع برنامج لتسيير المخزون و التسويق
أنت حالياً تتصفح نسخة خفيفة من المنتدى . مشاهدة نسخة كاملة مع جميع الأشكال الجمالية .
الصفحات : 1 2 3 4 5 6 7 8 9 10 11 12 13 14
السلام عليكم و رحمة الله تعالى و بركاته:
هذا الطرح الثالث أو الدرس الثالث في مشروعنــا ، اليوم إن شاء الله نعمل قائمة للصفحة الرئيسية و ننشئ باقي الصفحات ، بعدها نبدأ في إعداد الجداول.
طيب الآن ، سوف نبدأ بالقائمة:
من قائمة Standard نضع المكون MainMenu في الفورم FGSM ، سوف يكون تحت اسم MainMenu1 .
نضغط مرتين على المكون أو من الخاصية . (Items)
و بمجرد الضغط أو فتح خاصية Items ، سوف نتحصل على أول عنصر بالقائمة (بدون اسم) ، نكتب بالخاصية كابشن اسم Fichier
كما هو موضح بالصورة (مرفقة)
ننشئ القائمة الفرعية تحت Fichier بنفس الطريقة ، ثم الذي يليه حتى ننتهي نغلق نافذة MainMenu ، فنلاحظ القائمة التي تم انشاؤها على الفورم الرئيسي FGSM
ملاحظة :
-1- يتم إنشاء عناصر فرعية للعنصر الفرعي ، بتحديده + الضغط بيمين الفأرة ثم اختيار (Crier Un Sous-menu)
- 2- يتم عمل مطة تحت الحرف الأول من اسم العنصر بكتابة الرمز & قبل اسم العنصر بالخاصية كابشن مثلا : &Fichier .
-3- يتم عمل فراغ بين العناصر (عنصر على شكل خط وهمي) بالضغط على المطة - من قسم الآلة الحاسبة أو المتوفرة مع الرقم ستة بقسم الحروف و الرموز.
- 4- يمكن إنشاء إختصار بلوحة المفاتيح ، لأي عنصر من القائمة
من الخاصية ShurtCut لأي عنصر .
- 5- يتم وضع صور جميلة بجانب أي عنصر من الخاصية Bitmap .

حمل المرفق (MainMenu) و قم بانجاز القائمة في مشروعك كما ترى ، و قارن و تأكد.
* الآن نتكلم عن باقي الصفحات للمشروع : أظن أنه تبين لنا بعد إنجاز القائمة ، ماذا يتوجب علينا فعله بشأن هذه الصفحات . . .
-لدينا ستة صفحات خاصة بالعنصر Voir_Fiche : و أسماؤها على التوالي:
Produit - Achat - Vente ثم Fonctionnaires - Fournisseur - Client
-و واحدة فقط تحت إسم Facture et Statistique تضم كل ما يتعلق بالفاتورة و الحوصلة .
سنعمل بعض الصفحات الأخرى لاحقا ، عموما هذا كل ما نحتاج إليه الآن.

* بعد إنجاز الفورمات السبع ، نحاول ربطها مع القائمة . التي أنشأناها سابقا:
- نرجع للخاصية Items للــ Main Menu ، و نحدد العنصر Vente ، نصغط عليه مرتين و نحرر :
كود :
FVente.show;
و نعمل نفس الشي مع باقي العناصر الستة .
ملاحظة: - نسمي كل فورم باسم عنوانها على MainMenu+F يعني Achat نقوم بانشاء فورم نسميها FAchat ثم نحفظ الوحدة باسم UAchat ، ثم ننشئ التي تليها بنفس الطريقة ، نحفظ ، ثم التي تليها و هكذا . أخيرا نعدل في كابشن لكل فورم بحذف حرف F .

* أخيرا نلاحظ : إختلاف في مظهر المشروع (الفورم الترحيبية و الأساسية غير كل الفورمات الأخرى) أقصد Skins . السبب لعدم إدراج سكين لهذه الفورمات ، و بكل بساطة ننسخ مكون السكين (sSkinProvider1) من الفورم التي تحتويه و نلصقها بكل فورم من الفورمات السبع التي أنشأناها.
المشروع (GSM) حتى الآن بالمرفقات .
بالتوفيق.

..../ يتبع /...
السلام عليكم ورحمة الله
حسنا اخ نبيل/ اكمل الموضوع وعندما تنتهي منه ان شاء الله يكون هناك موضوع اخر
ملاحظة: تنظيما للموضوع سيتم حذف ردي هذا وجميع الردود باستثناء مشاركات صاحب الموضوع
b.m.abdelaziz كتب :السلام عليكم ورحمة الله
حسنا اخ نبيل/ اكمل الموضوع وعندما تنتهي منه ان شاء الله يكون هناك موضوع اخر
ملاحظة: تظيما للموضوع سيتم حذف ردي هذا وجميع الردود باستثناء مشاركات صاحب الموضوع

حسنا بارك الله فيك أستاذي ، و بخصوص حذف الردود كنت أود اقتراح ذلك لكي لا يطول الطرح من غير فائدة و التشويش على كل متابع . إذ أنه بامكان أي شخص المراسلة عن طريق المنتدى أو التشكر على الخاص عوض طرحه هنــا ، و أنا ممتن للجميع.

بالتوفيق.
السلام عليكم و رمة الله تعالى و بركاته :
هذا الجزء رقم 04 أو الدرس الرابع من مشروع انجاز برنامج لتسيير المخزون و التسويق (GSM) .
قبل الخوض في قواعد البيانات ، سوف ننجز سويا الفورم السابعة الخاصة بالفواتير و ما يتعلق بها .
ننشئ فورم جديد نسميه FFactureEtStatistique و نحفظ السورس تحت اسم UFactureEtStatistique .
لاحظنــا في القائمة الرئيسية على الفورم الرئيسي FGSM بأن هذا العنصر يضم 06 عناصر فرعية:
(Facture-Historique Client-Historique Fournisseur-Gestion de Versements-Consultation des Dettes-Gestion de Cesse)
و لعدم التكثير من الفورمات لكل عنصر (و لغرض التعرف و استعمال مكونات أخرى) سنعتمد على المكون : PageControl (تجده في Win32 )
إذن نضع هذا المكون على الفورم السابعة FFactureEtStatistique ، نضغط عليه بيمين الفأرة لعرض قائمة الخيارات ثم نختار أول خيار (NouvellePage) ، نكرر العملية لنحصل على ستة صفحات TabSheet من 1 إلى 6.
بعد ذلك نحدد TabSheet1 ( لتحديدها نضغط على الكتابة TabSheet1 سوف يتحدد بذلك PageControl ، بعدها نضط في وسطه ) و نغير الكابشن إلى Facture .
نفس الشيء مع TabSheet2 إلى 6 وتكون الكابشن على التوالي :
(Facture-Historique Client-Historique Fournisseur-Gestion de Versements-Consultation des Dettes-Gestion de Cesse)
لاحظتم معي أن Facture et statistique من القائمة (على الفورم الرئيسي ) و كل ما تضمه عوضا عن انجاز فورم لكل عنصر قمنا بضمها كلها في فورم واحد تحت اسم FFacture بواسطة المكون PageControl . ماذا بقي لنا ؟
بقي لنا إتاحة إمكانية تصفح هذه الأخيرة من القائمة على الفورم الرئيسي ، و شاهدنا أن بقية عناصر القائمة كل واحد له فورم خاصة به و نتصفحه أو نفتحه عن طريق الكود : اسم الفورم.شاو (Nom.Show ) الآن لدينا كل شيء في صفحة واحدة .
إذن : من القائمة Facture et Statistique نذهب إلى Facture نضغط مرتين و نحرر الكود التالي :
كود :
FFactureEtStatistique.TabSheet[COLOR=Blue]1[/COLOR].Show;
FFactureEtStatistique.show;
نذهب إلى Historique Client و نكتب نفس الكود مع تغيير 1 إلى 2


و نقوم بنفس الشيء مع ما تبقى.
كان هذا كل شيء عن الفورم المسماة FFacture وربط عناصر مع القائمة بالفورم FGSM.
الآن سوف نقوم بتحرير الجداول الخاصة بقواعد البيانات.
قلنا سلفا أننا نحتاج إلى 06 جداول ، نبدأ بالجدول الأول Produit (ونقصد به المواد التي تتم علبها عمليات التداول أو لنقل أنه المخزن )
كيف يتم انجاز الجداول ، من القائمة الرئيسية لبرنامج دلفي نجد Outils تحتوي على Module base de donnée (أصحاب النسخة الإنجليزية هو Database Desktop ) ، أو تجد هذا المحرر من قائمة إبدأ ثم برامج ثم دلفي7 أو النسخة التي بحوزتك ، ثم تجد هذا المحرر ، هذا أو ذاك المهم نفتح المحرر ، انظر الصورة 1 في المرفق Database Desktop ، تضغط ok ، تظهر لك الصورة 2 .

[صورة: 2h4ghgm.jpg]

هنا يتم تعريف حقول الجدول ، حيث Field Name هو اسم الحقل ، و أسماء الحقول في بارادوكس لا تتجاوز 25 حرفا ، كما يمكن استعمال أسماء عربية أو استعمال الفراغات ، غير أن ذلك غير منصوح به نظرا لما ستواجه من مشاكل مع اللغة العربية ، كذلك عدم استعمال الفراغات إذا كنت ستعتمد على SQL ( و هذا ما سنفعله ) ، كذلك ينصح بعدم استعمال أسماء محجوزة في لغة الإستفسار البنيوي SQL مثل : Select , Date و غيرها.
لدينا أيضا Type و تعني نوع الحقل أو نوع البيانات التي ستخزن في هذا الحقل ، إذا أخذ النوع الحرف A يعني أنه حقل نصي يمكن له أن يحتوي على أرقام أو حروف أو رموز و تأخذ القيمة ( Size ) من 1 إلى 255. الحرف D تعني Date ، T تعني Time ، M تستعمل إذا كنت بحاجة لادراج نص كبير يفوق 255 حرفا و تأخذ Size من 1 إلى 240 ، N تعني عدد حقيقي ، و هكذا (تقريبا هذه هي الأهم في ما سنحتاج ).
أخيرا لدينا Key إذا قمت بالضغط مرتين بزر الفأرة الأيسر سوف تتحصل على علامة نجمة * ، هذا يعني أنك جعلت هذا الحقل في هذا الجدول مفتاح أساسي ، فما هي المفاتيح الأساسية؟
باختصار يمكنك الحقل الأساسي بجدول معين من الوصول بسرعة إلى البيانات و كذا تجميعها و حصرها ، و إذا حددت الحقل على أنه مفتاح أساسي فلا يمكنك أن تجعل له قيمة خالية (Null) أثناء ملئ أو إدخال البيانات في الجدول ، و لا يمكنك تكرار نفس القيمة في حقل آخر ، يعني يمكنك و يستحسن لك جعل مفتاح أساسي في الحقول التي لا يمكن أن تكون لها نفس القيمة في حقول أخرى كأرقام التسجيل أو أرقام البطاقات أو غيرها ، حيث يعرف صاحبها من هذا الرقم و لا يمكن أن تجد رقم واحد لشخصين في آن واحد ، فإذا أردت البحث عن شخص معين تبحث عنه عن طريق هذا الرقم ( لذا لابد أن يكون الحقل المخصص لهذا الرقم مفتاح أساسي) ، لا يمكنك مثلا جعل حقل تاريخ الميلاد مفتاح أساسي لامكانية تكرار هذه القيمة لأكثر من شخص .

[صورة: sb790m.jpg]

حسب ما تقدم قم بانشاء الجداول التي نحتاجها ، على أن يتم حفظها بالأسماء المحددة ، و كذا تحديد أسماء حقولها و نوعيتها و قيمها حسب الجداول المنجزة بملف الوارد المرفق.

في المرة القادمة إن شاء الله تعالى سوف نقوم بملئ كل فورم بالمكونات المناسبة كما سوف نربط الجداول التي تم انشاؤها بمشروعنا ، و سيتم ارفاق المشروع كاملا بالجداول . إذن أنت مطالب بانشاء الجداول وحدك الآن.
بالتوفيق


../ يتبع /....
السلام عليكم و رمة الله تعالى و بركاته :
هذا الجزء رقم 05 أو الدرس الخامس من مشروع انجاز برنامج لتسيير المخزون و التسويق (GSM) .
بعد إنشاء الجداول (أولا قم بإنشاء مجلد تحت اسم Data و ضع به كل الجداول التي تم انشاؤها ، على أن يكون هذا المجلد في نفس مجلد المشروع، ثم للتنويه حدث خطأ طفيف في جدول facture في ملف الوورد المرفق التصحيح نضع حقل Code_Com_Cبدلا من nom) نقوم اليوم بحول الله بربط قاعدة البيانات بالمشروع على الفورم FGSM عن طريق المكونات المتاحة .

عن طريق المكونات الموجودة بالصفحة Data Control أو ControlBD في النسخة الفرنسية بالقائمة ، يمكننا الإطلاع على المعطيات الموجودة بقاعدة البيانات و كذا التحكم فيها من تحرير و تعديل أو حذف ، و لكن قبل ذلك يتوجب الوصول إليها و ربطها مع المشروع عن طريق الصفحة الموجودة بقائمة الدلفي المسماة BDE و AccesBD .
أولا BDE : تضم هذه الصفحة مجموعة من المكونات أهم ما نحتاج إليه هو العنصر Table و العنصر Database ، نقوم بوضع عنصر واحد من هذا الأخير على الفورم FGSM و ستة عناصر (بقدر عدد الجداول التي تم إنشاؤها) من Table .
نتوجه الآن إلى الصفحة AccesBD و نقوم بوضع ستة عناصر من DataSource ، نربط كل عنصر DataSource مع Table ، يعني نحدد DataSource1 و نعطي الخاصية Dataset القيمة Table1 ، ثم DataSource2 نعطي الخاصية Dataset الخاصة بها ، القيمة Table2 ، و هكذا .


الآن نربط العنصر Table1 مع الجدول
produit : لكي نقوم بذلك يتوجب علينا تحديد DataBaseName وهو المسار الخاص بالجدول المراد . يعني لديك جدول يسمى AAA يوجد بالمسار (\:c) تكتب في DataBaseName ما يلي : c:\AAA.db .
ننوه أنه يمكنك أن تجد أحيانا مصطلح ALIAS يصب هذا الأخير في نفس المعنى تقريبا، و قد كتب كثيرا حول هذا ،في المنتدى إذا أردت الإستزادة بعليك بالبحث.
لكن إذا كتبت القيمة (C:\AAA.db) فلن يعمل مشروعك في جهاز آخر إلا إذا وضعت قاعدة البيانات في نفس المسار المحدد.
في مشروعنا نعتمد طريقة أخرى عن طريق العنصر المذكور DataBase ، نضغط مرتين بالزر الأيسر للفأرة على هذا العنصر ، سوف تظهر نافدة ، نقوم بكتابة القيمة GSM في Nom او Name ، و نحدد Standard في Nom de Pilote ، ثم نكتب في الإعدادات : \path=data
يعني أن مسار قواعد البيانات في المجلد Data في نفس مكان تواجد المشروع ، سواء في القطاع C أو D من القرص الصلب أو غيره. و بهذا لن يحدث أي إشكال بالنسبة للمسار على أي جهاز، نعمل OK و نغلق النافذة . ثم نعطي القيمة True للخاصية Connected لنفس العنصر DataBase1 .
الآن نرجع للعنصر Table1 و نعطي الخاصية DataBaseName القيمة GSM ، ثم من الخاصية TableName إذا كان كل شيء تمام سوف تظهر لكل كل الجداول تقوم بتحديد produit.db ، و أخيرا Active تعطيها True .

نربط Table2 بالجدول vente
بعد أن اتضح الأمر بكل بساطة أقول:
DataBaseName=GSM
TableName=vente.db
Active=True
نربط Table3 مع achat ، و 4 مع client ، و 5 مع fournisseur ، و أخيرا 6 مع facture .
انتهينا من الربط الآن كما تقدم ، بحاجة إلى التحكم بقاعدة البيانات من إطلاع أو إضافة أو تعديل أو حذف عن طريق الصفحة ControlBD ، نضع المكونين DBNavigator و DBGrid و نعطيهما مثلا القيمة datasource2 من الخاصية datasource . 2 تعني جدول vente .
الآن نفذ المشروع و قم بعمليات مختلفة ، هل صار الأمر واضحــا ؟
إذن كل شيء على ما يرام . فقط سوف نتحكم في هذه الفورم بالبيانات بطريقة مختلفة عن العنصرين DBNavigator و DBGrid ، حدد و احذف هذين الأخيرين . و لنا رجعة قريبة إن شاء الله تعالى.


بالتوفيق.




..../ يتبع /....
السلام عليكم و رمة الله تعالى و بركاته :
هذا الجزء رقم 06 أو الدرس السادس من مشروع انجاز برنامج لتسيير المخزون و التسويق (GSM) .

بعد ما سلف طرحه سوف نبدأ من اليوم إن شاء الله ، التعامل الفعلي مع قواعد البيانات و غيرها برمجيا ، إلى غاية الإنتهاء بحول الله.

عل الفورم FGSM نستخدم الكل من العانصر أو المكونات : sLabel - DBlookupCombobox - sEdit - sBitBtn - sCombobox.
أولا نقوم بوضع 12 sLabel و 4 DBlookupCombobox ، و 4 sEdit ، و sCombobox1 ، و DateTimePicker ، و كذا 12 زرا من نوع sBitBtn كما تشاهدون في الصور المرفقة المسماة img_FGSM .

الآن نأتي للبرمجة لغرض التحكم في قاعدة البيانات من إضافة و تعديل و حذف و استظهار ، و ما إلى ذلك . هنا لابد لنــا أن نفهم ما نود القيام به نظريا أولا ، بما في ذلك علاقة الجداول ببعضها .


طيب الأمر بسيط جدا ، كل ماعلينا هو المتابعة و التركيز :

1- جدول المخزون أو جدول المواد الذي سميناه produit ، يضم قائمة السلع التي بامكاننا شراؤها و بيعها.
ماذا يعني هذا؟ يعني أنه لا يمكنك بيع أو شراء سلعة إلا التي تم السماح بها أو تم تعيينها بجدول produit ، ماذا يترتب عن هذا ؟ يترتب عن هذا عدم تمكين المستخدم من الحرية في تحرير اسم السلعة ، يعني أثناء تحرير الفاتورة (السلع المباعة) في مكان كود و اسم السلعة لا نضع مكون مثل edit الذي يمكن المستعمل من تحرير و كتابة ما يريد (وقد تم فعل هذا حيث وضعنا المكون DBlookupCombobox) .
إذن هناك علاقة وطيدة بين كل من جدول produit و جدول vente ، تتمثل بشكل ظاهر في كل من كود المادة-اسم المادة ، و سوف نربط بينهما عن طريق DBlookupCombobx (نرى ذلك بعد حين) .
2- نفس الشيء مع الكود و الإسم التجاري للزبون ، هناك علاقة بين جدول البيع vente و جدول client ، يعني مثلا أنت لديك زبون يحمل الاسم التجاري (ECS) ، لو تتيح امكانية التحرير لمستعمل البرنامج بالمكون edit او maskedit أو sEdit أو مكون آخر ، يكون احتمال الخطأ في التحرير كأن يكتب ESC بدلا من ECS ، حينها لن تستطيع أن تكون دقيقا و صحيحا في تعاملك مع هذا الزبون لأنه أصبح لك زبونين ECS و ESC ، مع أنهما في الحقيقة زبون واحد ، فلو أن هذا الزبون اشترى عليك في المرة الأولى و لم يسدد التكاليف ، و في المرة الثانية أيضا ، فكم لك عليه من ديون؟ بالتأكيد هو مجموع القيمتين ، فإذا كانت كل قيمة لزبون مختلف ECS و ESC فإنك سوف تقع في خطأ كبير.
3-لن أطيل في هذه الأمور ، نقطة أخيرة تتمثل في عملية الحساب أثناء البيع: يعني نضع بالحسبان أن الكمية في جدول produit هي 00 ، تزيد هذه الكمية أثناء الشراء ، و تنقص أثناء البيع ( يعني يتم حفظ عملية البيع بتفاصيلها ، ثم يتم طرح كمية المنتوج الذي بيع من إجمالي الكمية في جدول produit )
4-بعد ذلك سنتدرج في أمر مهم و هو : كلما اكتشفنا امكانية وقوع الخطأ قمنــا بتجنبه أو وضع قيود مناسبة لتفاديه.



* الآن نأتي إلى المرحلة التنفيدية و التطبيقية:

حدد العنصر DBloockupCombobox1 ، ثم نذهب لخصائص هذا المكون ، هذا المكون سوف يعمل لصالح من ؟ كغيره من كل المكونات الموضوعة على الفورم FGSM خاصة بالجدول vente ، و عليه فإن الخاصية DataSource سوف تأخذ القيمة DataSource2 .
ثم هذا العنصر (نقصد DBlookupCombobox1 ) خاص بأي حقل من الجدول vente ؟ بطبيعة الحال Code_Prod ، إذن نحدد هذه الأخير كقيمة للـخاصية DataField .
ثم هذا العنصر (نقصد DBlookupCombobox1 ) يأتي بقائمة المواد من أين ؟ من الجدول produit إذن:
DataSource=DataSource1
KeyField=Code_Prod . هذا كل شيء و قبل أن نجرب لأن قائمة المواد خالية من الجدول produit ، سوف نعمل نفس الشيء مع كل من DBLookupCombobox2+3+4 علما أن3+4 من جدول الزبائن يعني DataSource=DataSource4.

أخيرا : نذهب للفورم FProduit و نضيف العنصرين DBNavigator و DBGrid و نكتب في الخاصية DataSource=FGSM.DataSource1
لكليهما ، نقوم باضافة مواد مختلفة بملئ الحقول ن و على وجه الخصوص الحقلين:
Code_Prod / Des_Prod ، بعد ذلك نعود إلى الفورم FGSM و سوف نلاحظ أن المواد التي أضيفت في الجدول Produit أصبحت تظهر بالمكون DbLookupCombobox ، حسب اسم كل حقل .
نستطيع فعل نفس الشيء فيما يخص فورم و جدول الزبائن.


و هاهو مشروعنا إلى غاية هذه المرحلة بالمرفقات.
بالتوفيق.

[صورة: 2uesmj6.jpg]

.../ يتبع / ....

وعليكم السلام ورحمة الله وبركاته
أخي نبيل بارك الله لك وجزاك خيرا
يمكن أن يساعدك هذا الرابط للاقتباس، أساسيات تصميم قواعد البيانات من Microsoft
كود :
http://office.microsoft.com/ar-sa/access/HA012242471025.aspx
بالتوفيق.
فعلا هو رابط مفيد جدا و أكثر من رائع . ستأتي المرحلة التي نحتاج فيها إليه .
مشكوووور أخي العزيز .

بالتوفيق.
السلام عليكم و رحمة الله تعالى و بركاته : هذا الجزء رقم 07 أو الدرس السابع من مشروع انجاز برنامج
لتسيير المخزون و التسويق (GSM) .
اليوم إن شاء الله سنخطو شوطا كبيرا و هاما في مشروعنــا ، ما عليك أخي الحبيب إلا الجاهزية و التركيز و خطوة خطوة إن شاء الله نبدأ:

سيكون عملنا كله اليوم على الفورم الرئيسي FGSM :
أولا قم باضاقة حقل من نوع تاريخ (d) في الجدول vente تحت اسم Date .
-قم باعطا الخاصية ReadOnly القيمة True لكل من DBLookupCombobox1+2+3+4
- قم بحذف العناصر sCombobox1+sEdit3+sEdit4 .
- قم بوضع العنصر GroupBox1 من القائمة أو الصفحة Standard ، اجعل الكابشن لهذا الأخير هي ( Montant de Produit ) .
داخل أو فوق العنصر GroupBox1 ، ضع 3 من sEdit ، سوف تكون أسماؤها على التوالي :
sEdit3+sEdit4+sEdit5 . بعد ذلك ضع عنوان لكل sEdit بعنصر sLabel . يعني فوق الأولى ضع sLabel يأخذ الكابشن Total HT ، و الثانية اجعل لها 2 من sLabel الأولى TVA و الثانية %00 ، و أما الـ sEdit5 اجعل لها sLabel بكابشن Total_TTC .
- أخيرا قم بوضع (DBGrid+DBNavigator) و اربط هما مع الجدول 6 ، ثم ضع آخرين و اربطهما من الجدول 2 . و آخرين للجدول Produit . للتنبيه : سوف يتم لاحقا حذف هذه العناصر الستة ، فقط قمنا بوضعها هنا لكي نشاهد و نراقب نتائج العمل عليهما أثناء البرمجة بشكل مباشر.

نأتي للجانب البرمجي:
بعد أن نذهب إلى المكون MainMenu (نضغط عليه مرتين) ، ثم نحدد Parametrès de vente ثم TVA ثم 00% ، على هذا الأخير الذي يأحذ الكابشن %00 و الإسم N01 ، نقوم باعطاء القيمة True للخاصية Checked ، يعني نجعله افتراضيا مع بداية المشروع محددا بتلك العلامة (Checked أو Cocher).
نغلق العنصر MainMenu ، و نحدد نفس العنصر %00 من قائمة الفورم FGSM ، نضغط عليه ليعطينا امكانية تحرير الكود سورس ثم نكتب :
كود :
N01.Checked:=true;
N71.Checked:=false;
N171.Checked:=false;
sLabel5.Caption:='00 %' ;
sEdit1.SetFocus;
sEdit2.SetFocus;
ثم على %7 نحرر
كود :
N01.Checked:=false;
N71.Checked:=true;
N171.Checked:=false;
sLabel5.Caption:='7 %' ;
sEdit1.SetFocus;
sEdit2.SetFocus;
أخيرا على %17 نحرر
كود :
N01.Checked:=false;
N71.Checked:=false;
N171.Checked:=true;
sLabel5.Caption:='17 %' ;
sEdit1.SetFocus;
sEdit2.SetFocus;
أولا sLabel5 للتنبيه هي الموجود على GroupBox1 و المتعلقة بــ Tva ، و التي تأخذ الكابشن %00 .
ماذا يعني هذا الكود ؟ يعني بعد تنفيد البرنامج يكون %00 محددا افتراضيا ، و عند الضغط على غيره تقوم بتحديده مع حذف اشارة التحديد على البقية ، هذا يعرف المستخدم أي قيمة ضريبة يجري بها عملية البيع لأن قيمة الضريبة مختلفة و تضاف لقيمة البيع كما هو معروف ، أما Setfocus هذا لتحديد أو الانتقال إلى sEdit و سنعرف الغاية من ذلك فيما يلي.

- الآن نحدد العنصر sEdit1 و نذهب إلى évenements و نضغط مرتين على الحدث Onchange و نحرر :
كود :
if (sEdit1.Text<>'') and (sEdit2.Text<>'') and (sEdit1.Text>=floattostr(0))
and (sEdit2.Text>=floattostr(0)) and (N01.Checked=true) then begin
sEdit3.Text:=floattostr(strtofloat(sEdit1.Text)*strtofloat(sEdit2.text));
sEdit4.Text:=floattostr(0);
sEdit5.Text:=floattostr(strtofloat(sEdit3.Text)+strtofloat(sEdit4.Text)) end

else if (sEdit1.Text<>'') and (sEdit2.Text<>'') and (sEdit1.Text>=floattostr(0))
and (sEdit2.Text>=floattostr(0)) and (N71.Checked=true) then begin
sEdit3.Text:=floattostr(strtofloat(sEdit1.Text)*strtofloat(sEdit2.text));
sEdit4.Text:=floattostr(strtofloat(sEdit3.Text)*0.07);
sEdit5.Text:=floattostr(strtofloat(sEdit3.Text)+strtofloat(sEdit4.Text)) end

else if (sEdit1.Text<>'') and (sEdit2.Text<>'') and (sEdit1.Text>=floattostr(0))
and (sEdit2.Text>=floattostr(0)) and (N171.Checked=true) then begin
sEdit3.Text:=floattostr(strtofloat(sEdit1.Text)*strtofloat(sEdit2.text));
sEdit4.Text:=floattostr(strtofloat(sEdit3.Text)*0.17);
sEdit5.Text:=floattostr(strtofloat(sEdit3.Text)+strtofloat(sEdit4.Text)) end;
نفس الكود نريده في الحدث OnEnter لتفادي عدم كتابته مرة أخرى فقط نقوم بنسخ أو كتابة العبارة : sEdit1Change في الحدث OnEnter ، يعني بمجرد الدخول أو تغيير قيمة sEdit1 سوف ينفد الكود الذي كتبناه.
ماذا يعني هذا الكود ؟ باختصار الغرض منه حساب القيمة الإجمالية و قيمة الضريبة و القيمة الإجمالي بكل الرسوم ، فقط قيدناه بمجموعة من الشروط ، مثلا شرط عدم كون sEdit2 خالية لأنه لا يمكن اجراء عملية الحساب على قيمة غير موجودة أصلا.

طيب إذا كانت توجد قيمة في sEdit2 و قمة بكتابة قيمة في sEdit1 و قمة بتغيير هذه الأخيرة سوف تلحظ تغيير الناتج من حين لآخر و عليه فإن الأمور على مايرام ، و لكن إذا قمت بتغيير قيمة sEdit2 فلا يوجد أي فرق و السبب واضخ لأننا لم نبرمج شيئا على هذا الأخير.

إذا لم يكن هناك أي فرق في الكود الذي حررناه فنحن سوف نتجنب تكرار المود و فقط كما قمنا سابقا ، نكتب sEdit1Change في الحدثين OnChange و OnEnter للعنصر sEdit2 و بذلك كل شيء تمام. لكننا سوف نضيف سطرا في نفس الحدثين للعنصر sEdit1 و وهو يختلف عن sEdit2 ، و على هذا قم باعادة كتابة (أو نسخ) الكود ، يعني قم بنفس ما قمنا به مع sEdit1 .

بعد ما قمنا به مع tva و قما قمنا به مع sEdit1+2 ، الآن سوف نعرج على أمر ثالث وهو أهم و يتمثل برمجة عمل الأزرار.
نبدأ بالزر Nouveau Facture :
المستعمل للبرنامج ليقوم بعملية أو عمليات بيع ، سوف تكون ضمن فواتير و لكل فاتورة رقم مستقل و لا يتكرر ، يعني هو مجبر أولا بتحديد فاتورة جديدة عن طريق هذا الزر ، و بعد ذلك يقوم بعمليات البيع بتحديد Nouveau Produit من حين لآخر حسب حاجة الزبون ، يعني يريد الزبون مثلا 5 مواد و كل مادة بكمية معينة ، يقوم المستعمل للبرنامج من ضغط مرة واحدة على Nouveau Facture و بعد ذلك يستعمل 5 مرات الزر Nouveau Produit ، إذا أراد الزبون فاتورة أخرى أو جاء زبون آخر ، يضغط المستخدم على فاتورة جديدة فتأخذ الرقم الموالي و يقوم بنفس ما تقدم ، و هكذا.
إذن نضغط مرتين على Nouveau Facture و نحرر :
كود :
var x:real;
begin

if Table6.IsEmpty Then Begin Table6.Edit;
                  Table6.FieldValues['N_Facture']:='1' ; Table6.Post;
                  sLabel2.Caption:=table6.FieldValues['N_Facture'];
                  end else

If Not Table6.IsEmpty Then begin
   Table6.Last;
   if Not Table6.FieldByName('Date_Facture').IsNull
   Then Begin
   Table6.Last;  X:= table6.FieldValues['N_Facture'];
   Table6.Insert; Table6.FieldValues['N_Facture']:=X+1;  table6.Post;
   sLabel2.Caption:=table6.FieldValues['N_Facture'];
   End;
   End;

sBitBtn1.Enabled:=false;
sBitBtn3.Enabled:=false;
sBitBtn4.Enabled:=false;
sBitBtn5.Enabled:=false;
sBitBtn6.Enabled:=false;
sBitBtn7.Enabled:=false;
sBitBtn8.Enabled:=false;
sBitBtn2.Enabled:=true;
end;
ماذا يعني هذا ؟
لدينا امكانية أن الجدول فارغا يعني أول استعمال ، و على هذا الشرط (الجدول فارغا_Empty) نقوم مباشرة بادخال أول رقم و هو 1 و نحفظ العملية.
لدينا امكانية أن الجدول ليس فارغا بينما حقل التاريخ فارغا ، أولا لماذا هذه الإمكانية؟ مثلا المستعمل يضغط فاتورة جديدة و لا يواصل العملية ، مثلا يغلق البرنامج أو يتوقف و يغلق الحاسوب ، و بعد فتح البرنامج مجددا ، و لولا هذا الشرط فإنه سوف يعمل رقم جديد موالي ، مع بقاء الرقم السابق محجوزا و لا يتضمن أي عملية بيع . على هذا الشرط أو هذه الحالة المتمثلة في عدم فراغ الجدول إضافة إلى عدم خلو حقل التاريخ من أي قيمة ، يقوم بالكود المطلوب ، و إلا فإنه لا يفعل أي شيء و بالتالي يتيح لك استخدام نفس الرقم للفاتورة التي توقفنا من العملية (سابقا) بعد تحديد رقمها.
و لماذا الشرط حول حقل التاريخ ؟ هذا الحقل أو غيره ، المهم أنه لن يكون خاليا بعد اجراء عملية البيع لأنه سيأخذ تاريخا معينا عند اتمام عملية البيع بالضغط على الزر Ajouter و سوف نرى كود سورس هذا الزر لاحقا.
و لماذا تعطيل بقية الأزرار ؟ لأن المستخدم لا يحتاجها في هذه الحالة ، و أيضا تركها مفعلة يمكن من الوقوع في الخلل ، إضافة إلى توجيه و تسهيل العملية على المستعمل فلن يذهب فكره بعيدا مع كثرة الأزرار و لن يتوه أو يضيع الوقت أو يخطئ.

الزر Nouveau Produit :
في حدث OnClick أو كالعادة نضغط مرتين على هذا الزر و نحرر:
كود :
if not Table6N_Facture.IsNull then begin

DbLookupCombobox1.ReadOnly:=False;
DbLookupCombobox2.ReadOnly:=False;
DbLookupCombobox3.ReadOnly:=False;
DbLookupCombobox4.ReadOnly:=False;
DateTimePicker1.DateTime:=now;
DbLookupCombobox2.DropDown;

sBitBtn2.Enabled:=False;   //  Nouveau Produit
sBitBtn3.Enabled:=true;    //  Ajouter
sBitBtn4.Enabled:=False;   //  Imprimer
sBitBtn5.Enabled:=False;   //  Suprimer
sBitBtn6.Enabled:=False;   //  Modifier
sBitBtn7.Enabled:=False;   //  Valider
sBitBtn8.Enabled:=true;   //  Anuler
sBitBtn9.Enabled:=False;   //  Suivant
sBitBtn10.Enabled:=False;  //  Précedent
sBitBtn11.Enabled:=False;  //  Début
sBitBtn12.Enabled:=False;  //  Fin
Filtrage1.Enabled:=false;   // Fiche facture et Statistique
Vente1.Enabled:=false;       // Fiche Vente

Table2.first;
table2.Insert; end else
showmessage('Priciser une Facture ou bien Nouveau Facture D''abord');
الزر Ajouter :
الآن الأمر مهم جدا ، و يتطلب التركيز، فقط للإشارة:
بعد تحديد Nouveau Facture ثم Nouveau Produit و ملئ كل الحقول بما في ذلك السعر و الكمية ، ستحفظ البيانات في الجدول Table2 يعني جدول Vente ، يتطلب الأمر تحيين (Mise ajour) للجدول Produit من حيث الكمية ، إذا كان لديك مثلا منتوج بكمية 100 في جدول المواد ، و قمت ببيع 10 فإنه حتما يتبقى 90 في جدول المواد ، و للقيام بالعملية يعني حفظ 10 بجدول البيع و طرح 10 من 100 ليكون الناتج90 بجدول المواد ثم الحفظ .
ثم في الكود قمنا باضافة شرط رائع و هام جدا يتمثل في تنبيه صاحب المحل أو المستعمل أن الكمية أوشكت على النفاد من المخزن في حال أصبحت الكمية تساوي أو تقل عن قيمة العتبة ، و يتمثل هذا في الحقل Seuil_Qut من جدول Produit ، يعني بعد كل عملية بيع يقارن الكمية المتبقية (الحقل Qut) مع العتبة (Seuil_Qut) لتظهر رسالة التنبيه أو لا.
كذلك شرط إجبارية ملء كل الحقول لتفادي الوقوع في مشاكل حسابية كثيرة ، في حالة وقع المستعمل سهوا أو خطأ في اجراء عملية بيع من دون اتمام ملئ كل الحقول.
إذن نحرر:
كود :
if sEdit1.text<>'' then  If sEdit2.text<>'' then
if sEdit1.text<>FloatToStr(0) then if sEdit2.text<>FloatToStr(0)
then if sEdit3.text<>'' then If dblookupcombobox1.text<>'' then
if dblookupcombobox3.text<>'' then begin

Table6.Last;
table2.edit;
Table2.FieldValues['N_Fact']:=Table6.FieldValues['N_Facture'];
Table2.FieldValues['Code_Prod']:=DBLookupComboBox1.Text;
Table2.FieldValues['Des_Prod']:=DBLookupComboBox2.Text;
Table2.FieldValues['Qut']:=sEdit1.Text;
Table2.FieldValues['Prix_U']:=sEdit2.Text;
Table2.FieldValues['Prix_T']:=sEdit3.Text;
Table2.FieldValues['TVA']:=sEdit4.Text;
Table2.FieldValues['Prix_TTC']:=strtofloat(sEdit5.Text);
Table2.FieldValues['Code_Client']:=DBLookupComboBox3.Text;
Table2.FieldValues['Code_Com_C']:=DBLookupComboBox4.Text;
Table2.FieldValues['Date']:=DateTimePicker1.DateTime;
Table2.Post;
Table6.Edit;
Table6.FieldValues['Code_Client']:=DBLookupComboBox3.Text;
Table6.FieldValues['Code_Com_C']:=DBLookupComboBox4.Text;
Table6.FieldValues['Date_facture']:=DateTimePicker1.DateTime;
Table6.Post;

Table1.edit;
table1.FieldValues['Qut']:=Table1.FieldValues['Qut']-strtofloat(sEdit1.Text);
Table1.Post;

if table1.FieldValues['Seuil_Qut']>=Table1.FieldValues['Qut'] then
begin showmessage (' La Quantité de ce produit est Diminue En Dessous...'); end;

sBitBtn1.Enabled:=True;
sBitBtn2.Enabled:=True;
sBitBtn3.Enabled:=False;
sBitBtn4.Enabled:=True;
sBitBtn5.Enabled:=True;
sBitBtn6.Enabled:=True;
sBitBtn7.Enabled:=False;
sBitBtn8.Enabled:=False;

Filtrage1.Enabled:=true;   // Fiche facture et Statistique
Vente1.Enabled:=true;       // Fiche Vente

DblookupCombobox1.ReadOnly:=True; DblookupCombobox2.ReadOnly:=True;
DblookupCombobox3.ReadOnly:=True; DblookupCombobox4.ReadOnly:=True;

end;
begin
   if (Dblookupcombobox1.Text='') Or  (Dblookupcombobox3.Text='') Or
   (sEdit1.Text='') Or (sEdit2.Text='')
   then begin  ShowMessage ('Compliter tous les champs'); end;

   if (sEdit1.Text=FloatToStr(0)) Or (sEdit2.Text=FloatToStr(0))then begin
              ShowMessage ('Valeur Impossible') ; sEdit2.SetFocus; end;

end;

if not table1.IsEmpty then  begin
   sBitBtn9.Enabled:=true; sBitBtn10.Enabled:=true; sBitBtn11.Enabled:=true;
   sBitBtn12.Enabled:=true; sBitBtn5.Enabled:=true; end;


end;
الزر Suprimer :
نحرر :
كود :
if not table2.IsEmpty then begin
if MessageDLG
('êtes vous sûr de vouloir suprimer l''enregistrement ?'
, MtConfirmation,[MbYes,MbNo],0)=MrYes  then
Table2.Delete;  end;

if table2.IsEmpty then  begin
    sBitBtn2.Enabled:=False;  sBitBtn3.Enabled:=False;
    sBitBtn4.Enabled:=False;  sBitBtn5.Enabled:=False;
    sBitBtn6.Enabled:=False;  sBitBtn7.Enabled:=False;
    sBitBtn8.Enabled:=False;  sBitBtn9.Enabled:=False;
    sBitBtn10.Enabled:=False;  sBitBtn11.Enabled:=False;
    sBitBtn12.Enabled:=False;
end;
الزر Anuler :
نحرر :
كود :
table2.Cancel;
الزر Suivant :
نحرر :
كود :
table2.Next;
sLabel2.Caption:=Table2.Fieldbyname('N_Fact').AsString +' /'+
formatdatetime('yyyy',Table2.Fieldbyname('date').AsDateTime);
sEdit1.Text:=Table2.FieldValues['Qut'];
sEdit2.Text:=Table2.FieldValues['Prix_U'];
sEdit4.Text:=Table2.FieldValues['TVA'];
DateTimePicker1.DateTime:=Table2.FieldValues['Date'];
الزر Précedent :
نحرر نفس الكود فقط استبدال Next بــ : Prior

الزر Début :
نحرر نفس الكود فقط استبدال Next بــ : First


الزر Fin :
نحرر نفس الكود فقط استبدال Next بــ : Last

للتنفيد و للتجريب قم أولا باعطاء قيم متعدد على الجدول Produit ، مع الإشارة إلى عدم تكرار نفس القيمة في الحقل المفهرس. بعد ذلك قم بتجريب كل ما تم برمجته و لاحظ و قارن و تمعن و ابحث فيما إذا كان هناك خطأ أو إشكالية .
ننبه على وجود أمرين هامين أو إشكاليتين بخصوص الكمية بين الجدولين Produit و Vente ، تشملهما البرمجة في زر Suprimer و sEdit1 لاحقا ، المطلوب منك بعد هذا التبسيط البحث و الطرح ، و لنــا عودة لاكمال مشوارنا هذا إن شاء الله عز و جل.

ملاحظة: ليكون كل شيء على مايرام و تظهر Checked في القائمة الخاصة بــ Tva لابد أن يكون مسار السكين (الخاصية SkinDirectory) صحيحا .


بالتوفيق.


.../ يتبــع / .....
الصفحات : 1 2 3 4 5 6 7 8 9 10 11 12 13 14