مشاهدة النسخة كاملة : تعلم معي خطوة خطوة صنع برنامج لتسيير المخزون و التسويق
nabilkeb
05-12-2008, 07:23 PM
السلام عليكم و رحمة الله و بركاته
تمت اعادة الدرس باضافات جديدة...
nabilkeb
21-01-2010, 03:53 PM
السلام عليكم و رحمة الله و بركاته.
سنشرع في هذا الطرح إن شاء الله ، صنع برنامج لتسيير المخزون و كذا التسويق .
بعد نهاية طرح الموضوع ، سوف تكون أخي :
ـ مدركا ، وقادرا على صنع البرنامج بمفردك ، لا سيمـــا أن تكون عملية البرمجة على طريقتك ، يعني :
ـ/ـ بامكانك تغيير الشكل الخارجي و المنظر الجمالي و كذا ترتيب المكونات كيفما شئت ، و كيفمــا تراها مناسبة.
ـ/ـ بامكانك حذف و إضافة ما تشاء ، كتعديل قاعدة البيانات باضافة أو حذف حقول معينة .
ـ/ـ إذا تابعت كل الطرح جيدا و تمكنت من الفهم الحقيقي ، أخيرا أقول أنه بامكانك برمجة هكذا برامج بمفردك و بأفكارك الخاصة ، بدون أي تغيير أو إضافة أو حذف ، بل سيكون 100/100 انجازك الخاص ، و لا يقتصر الأمر على صنع برنامج لتسيير المخزون و التسويق فحسب بل كل برنامج على تلك الشاكلة ، كتسيير مؤسسة تعليمية و ماشابه.
هل تريد التأكد ممــا أقول ؟ هل أنت مهتم ؟ إذن هل أنت جاهز ؟
فلنبدأ على بركة الله:
نظرة عامة عن ماهية و استعمالات البرنامج :
إذا كان لديك أو لغيرك مثلا ، محل لبيع الحواسيب و ما يتعلق بها من لواحق كلوحة المفاتيح و الفأرة و الشاشة و اللوحات الأم ، و كذا وحدات التخزين المختلفة والمعالجات و...و.... ، وكل قطعة لك منها عدة أنواع و عدة شركات مصنعة و بكميات مختلفة ، فهل تستطيع أن تكون مدركا لكل ما يحوز عليه محلك ؟ بالطبع لا .
و إذا كنت تدون كل شيء يدويا على سجل خاص ، فهل تستطيع أن ترد على زبون واحد (أقول 01 فقط) يسألك : أحتــاج شراء كل ما لديك من الشاشات ، فكم لديك ؟ و أحتـاج 98 لوحة مفاتيح ، فهل بحوزتك هذه الكمية ؟ يليه مباشرة زبون آخر يقول: أريــد كل ما تبقى لديك من لوحات المفاتيح ، كم لديك ؟ و زبون آخر يسألك .... و آخر و آخر .
يأتيك بعد ذلك بائع بالجملة يعرض صفقة معينة ، فهل أنت مدرك للمبلغ الذي بحوزتك لغرض إتمام الصفقة ؟
و هل أنت مدرك لما للكمية المناسبة التي تحتاجها ؟
يضيع منك مبلغ معين (يسرق مثلا من طرف زبون أو أحد عمالك ) فهل تستطيع أن تدرك ذلك ؟
نقطة أخيرة على سبيل التوضيح و ليس الحصر : كل التجارات لا تخلو من المديونية (لها أو عليها) ، و....و.... فهل تستطيع السيطرة و الإحاطة بكل ذلك ؟ بالطبع لا
ـ لا أريــد الإطالة و إدخالك بمتاهات لا مخرج لك منهــا . و بكل بساطة أقول أنه يستحيل عليك إدرة و تسيير تجارتك من غير سيطرة كاملة ، و الإحاطة بكل كبيرة و صغيرة ، وعلى هذا فلا مناص لك إلا أن تستعمل الحاسوب ببرنامج خاص (برنامج لتسيير المخزون و كذا التسويق_وهو باب القصيد)، يزيل عنك كل عناء ، و تكون النتائج على كل المستويات إجابية 100/100.
قاعدة المعطيات أو البيانات:
قاعدة المعطيات (database) هي تركيب تستطيع من خلاله تخزين كمية كبيرة من المعطيات التي تربطها علاقات معينة ، و حقيقة الأمر فإن قاعدة البيانات ماهي إلا ملف أو مجموعة ملفات كباقي الملفات ، تخزن على القرص الصلب ، و لكن ما يميزها هو قدرتك على كتابة و قراءة المعطيات منها ، باستخدام الوسائل التي تمنحها لك برامج قواعد البيانات ، دون الحاجة إلى التعامل المباشر مع الملف ، و هو ما يجعل الأمر أكثر ليونة و غاية في السهولة و التنظيم.
العنصر الأساسي بقواعد البيانات هو الجدول ، و يتكون من عدة أعمدة (و تسمى الحقول) و عدة أسطر ( و تسمى السجلات )
سوف نرى كيف يتم إنشاء الجداول ، و قبل ذلك سوف نتطرق نظريا إلى الجداول التي سوف ننشئها أو نحتاجها في برنامجنــا.
1/ ـ لدينــا مخزن للسلع ، و عليه فنحن بحاجة لإنشاء جدول خاص لذلك ، يتكون من :
رمز أو كود المادة (السلعة) / اسم المادة / الكمية / العتبة (أو الحد الأذنى: و هي الكمية المحددة من طرفنـا التي يخبرنا البرنامج أثناءها أنه علينـا تزويد الكمية (شراء هذا النوع) لأنه يكاد ينفذ من المخزون ، أو لنقل أنه عبارة عن تنبيه لعدم الوقوع في مشكلة مع الزبائن بعد نفاد مفاجئ لهذه المادة) / رمز أو كود الممون الذي نشتري منه السلع / الاسم التجاري للممون / تاريخ الشراء / سعر البيع / الحد الأذنى لسعر البيع (وهو السعر الممنوع تجاوزه ، مثلا سعر البيع :100 ، الأذنى : 80 ، بحيث يمنع بيع المادة بأقل من : 80 ) .
إذن في الجدول لدينـا 09 حقول .
2/ ـ يتردد علينا عدة زبائن ، و عليه فنحن بحاجة لجدول خاص بالزبائن ، يضم ما يلي :
رمز الزبون / الإسم التجاري / الإسم و اللقب (ليكن حقل واحد للاسم و اللقب للتسهيل و عدم الحاجة الكبيرة لذلك ، فهي معلومات محلية في حالة الحاجة للإطلاع عليها من طرفنـا نحن فقط ، و هي أقل أهمية) / الهاتف و العنوان (أيضا حقل واحد فقط).
إذن لدينا 04 حقول.
3/ ـ جدول خاص بالممولين الذين نقتني منهم السلع ، يضم ما يلي:
رمز الممون / الإسم التجاري / الإسم و اللقب / الهاتف و العنوان .
إذن لدينا 04 حقول.
4/ ـ جدول خاص بمعلومات عن الفاتورة ، و الفائدة تتمثل في اتاحة امكانية أرشفة الفواتير ، للإطلاع عند الحاجة على أي فاتورة معينة استنادا إلى رقمها ، و تاريخها و صاحبها ، حتى إذا حصل منا أي خطأ يمكن تداركه و اكتشافه ، و كذلك إذا تقدم أي زبون يحمل فاتورة معينة يمكن لنا معاينتها بالبرنامج من خلال النسخة المتوفرة لدينا الكترونيا. كذلك نحتاجها في قضية تسيير الديون مثلا فاتورة بمبلغ 200 دفع الزبون 120 فقط تحت الحساب و بقي 80 ، عاود نفس الزبون عملية شراء أخر لفاتورة قيمتها 70 و دفع فقط 50 و بقي 20 ، بهذا الزبون عليه دين قيمته 80+20=100 و هذا فيه تفصيل و اثبات لكل العمليات التي اجريت مع كل زبون على حدى ، لاتاحة امكانية تسيير محكم و دقيق . و هناك فوائد حقيقية أخرى نراها لاحقا.
يضم الجدول ما يلي 04 حقول :
رقم الفاتورة / رمز الزبون / الاسم التجاري للزبون / تاريخ الفاتورة .
5/ ـ جدول خاص بالمواد التي تم بيعها، يضم ما يلي:
رقم الفاتورة / رمز المادة / اسم المادة / الكمية / سعر الوحدة / السعر الإجمالي / الضريبة / السعر الإجمالي بكل الرسوم / رمز الزبون / الاسم التجاري للزبون .
إذن لدينـا 10 حقول .
6/ ـ جدول خاص بالمواد التي تم شرائها، يضم ما يلي:
رمز المادة / اسم المادة / الكمية / الحد الأدنى للكمية / سعر الوحدة / السعر الإجمالي / الضريبة / السعر الإجمالي بكل الرسوم / رمز الممون / الاسم التجاري للممون / تاريخ الشراء / سعر البيع / الحد الأدنى لسعر البيع .
إذن لدينـا 13 حقل .
إذن استعملنا 06 جداول ، و لك أيضا أن تضيف جداول أخر حسب الحاجة ، كجدول خاص بالموظفين لديك مثلا ،كأمين المال ، أمين المخزن .
عموما نقتصر على 06 جداول فقط ، بعد اختتام الموضوع كليا ، لك أن تعدل أو تضيف ما شئت حسب حاجتك كما سلف ، الآن عليك فقط التقيد بالطرح فقط والمتابعة معنا ، خطوة خطوة .
كانت هذه نظرة عامة حول البرنامج و قواعد البيانات الخاصة به ، و سوف نباشر التنفيد برمجيا في الدرس التالي إن شاء الله.
..../ يتبع /...
B.M.AbdelAziZ
21-01-2010, 04:38 PM
السلام عليكم ورحمة الله
بعض الملاحظات السريعة اخي نبيل
5/ ـ جدول خاص بالمواد التي تم بيعها
هناك تكرار بالمعلومات بالجدول دون فائدة كمثال
الحقول التي يتم حسابها لاداعي منها، مثل: السعر الإجمالي / السعر الإجمالي بكل الرسوم
من " رمز الزبون" يمكن معرفة " الاسم التجاري للزبون" فلا داعي لتكراره
ثم " رمز الزبون" من الاحسن وضعه بحدول معلومات عن الفاتورة
نفس الشيئ بالنسبة للمواد التي تم شرائها
و من الاحسن ان يكون مكون من جدولين ايضا
nabilkeb
21-01-2010, 04:50 PM
لكي يكون البرنامج متكامل نسبيا ، أحببنـا عدم اهمال الجانب الجمالي :
1ـ يتطلب الأمر تنصيب Skin خاص لذلك.
إن صح التعبير هو عبارة جلد خاص يغلف البرنامج بمكونات جميلة ، و بذلك يأخذ المشروع حلة جمالية على الطريقة الإحترافية ، التي تريح المستعمل .
هناك الكثير جدا من Skins و هي مكونات خارجية (ليست تابعة للدلفي).
نطرح واحدا هنــا : اسم المكون Alpha Lite موجود بالمرفقات تحت اسم D7 لدلفي 7 فقط ، باقي النسخ يتم تحميلها لاحقا في حالة الحاجة (دلفي5-6-7-2005-2006 فقط) . أما شرح طريقة التثبيت فقد مرت معنا ،تفضل بزيارة هـــذا الـــرابــط . (http://www.delphi4arab.com/forum/showthread.php?t=490)
2ـ الشاشة الترحيبية: لمن أراد عمل شاشة ترحيبية فليسترشد بهــذا الـــرابـــط (http://www.delphi4arab.com/forum/showthread.php?t=183)
أو بطريقة أخرى أسهل و أجمل (وإن كانت تستهلك شيئا من موارد النظام) :
ننشئ مجلد مستقل نسميه GSM نحفظ فيه كل المشروع. نفتح برنامج دلفي ، نبدأ مشروعا جديدا ، نسمي الفورم الأولى FSplash ، نعمل حفظ السورس باسم USplash ، و نحفظ المشروع باسم : GSM .
ننشئ فورم ثانية تحت اسم FGSM و نحفظ السورس تحت اسم UGSM.
الإسم يعني Name و ليس Caption فهذه الأخيرة حسب اختيارك أخي .
Gestion de Stock et Marketing = GSM
U=Unite - F=Form.
في الفورم الأولى (Fsplash) نضع مكون Timer من System ، و مكون sGauge من Alpha Lite
على المكون تايمر نكتب :
procedure TFsplash.Timer1Timer(Sender: TObject);
begin
sGauge1.progress:=sGauge1.progress+1;
if sGauge1.progress=100 then begin
FGSM.Show;
Fsplash.hide;
timer1.Enabled:=false
end ;
end;
في الفورم الأولى (Fsplash) نعدل في خاصية interval للمكون تايمر نجعلها مثلا 100 ، نعدل في الخاصية progress للمكون sGauge نجعلها 0 .
في الفورم الثانية (FGSM) في الحدث Onclose نكتب :
Application.Terminate;
هذا الكود الأخير لإغلاق البرنامج في حالة اغلاق الفورم2 ، لأنه كما هو معلوم الفورم الرئيسية هي الأولى و يؤدي غلقها إلى غلق البرنامج كليا ، بينما في مثالنــا قمنا باخفائها (الفورم الأولى) فقط ، يعني غلق الفورم2 لا يغلق البرنامج كليا ، لذلك أضفنــا هذا الكود.
(يمكن لك في الشاشة الترحيبية (الفورم1) وضع صورة أو استعمال فلاش جميل أو أفكار أخرى)
نحفظ ، نـجـرب ....
.../ يتبع / ....
nabilkeb
21-01-2010, 05:32 PM
هناك تكرار بالمعلومات بالجدول دون فائدة ...
أنت محق تماما :
- بالنسبة للتكرار ، أنا على علم بذلك ، القاعدة تقول : أي حقل يمكن تكراره أو نحتاجه في أكثر من جدول ، يتم انشاء جدول خاص به ، حيث يشترك الجميع في استعماله من غير ادخاله (اعادة كتابته) في كل مرة و في كل جدول . هذا أفضل من ناحية البرمجة في تقليص نسبة الوقوع في الخطأ ، و كذا حجم و سرعة البرنامج. قد كتبت شيئا عن ذلك ( استعمال (ادخال) قيم حقل لجدول معين ، من جدول آخر (2/1) (http://www.delphi4arab.com/forum/showthread.php?t=519)) .
- بالنسبة للحقول التي لا داع منها كالسعر الاجمالي+بكل الرسوم فهذه يمكن حسابها برمجيا و الإطلاع على الناتج عند الحاجة ، من دون التخزين ، فعلا هذا أمر سلبي يمكن تفاديه ، لكن بالمقابل سوف يكون اكتظاظ حقيقي في البرمجة و الشرح ممكن يصعب الفهم على المبتدإ ، لأنني و ضعت بالحسبان أن هذا المشروع في قسم للمبتدئين . و الوصول إلى غاية تتمثل في صنع برنامج يفي بالغرض بدون أي خطأ + من الناحية الجمالية فيه ميزة أو شيء من الاحترافية (لا أقول أنه برنامج احترافي 100/100 ، نظرا لوجود بعض السلبيات أو الملاحظات كتكرار أو استعمال حقول يمكن ، بل يجب _احترافيا_ الإستغناء عنها ).
في النهاية سنحصل على برنامج يمكن فعليا و واقعيا استغلاله في تسيير المخزون و التسويق بحلة جميلة أو أقرب من ذلك ( و أكيد هذا يفيد فعلا المبتدإ) ، في النهاية و في آخر مرحلة من هذا الموضوع نرتقي بالمبتدإ قليلا لنبرز له بعض العيوب و السلبيات (كالتي تقدمت بها _بارك الله فيك) و بعض الأفكار الأخرى التي تسوقه نحو الإحتراف . و فتح المجال نحو الإبداع و الإجتهاد الخاص بكل فرد .
و هذا أكثر ما يعجبني في البرمجة ، حيث لا توجد قاعدة واحدة ثابتة تقيد الجميع 1+1=2 ، بل الوصول إلى الغرض كل بابداعه و طريقته (طبعا مع مراعاة بعض الأسس و القواعد ) ، فمن منـا لم يصنع برنامجا فوجد بعد حين امكانية تطويره فيزيد هنــا و ينقص هنــا ، و يضيف تارة و يستغني تارة أخرى.
شكرا جزيلا أستاذنــا عبد العزيز على الإهتمام و على ملاحظاتكم التي دوما تفيد و تكون في الصميم.
بالتوفيق للجميع.
nabilkeb
21-01-2010, 06:05 PM
هذه المرة ببساطة ، نتطرق فقط إلى مكون Skin + إضافات طفيفة على الفورم الأول.
في الفورم الأولى (Fsplash) نضع المكون : sSkinmanager1 ، هذا الأخير له عدة خواص أهمها الخاصية : Skindirectory
بالمرفقات تجد مجلد اسمه Skins نضعه داخل مجلد المشروع GSM . من الخاصية المذكورة نحدد مسار المجلد Skins في مجلد المشروع GSM .
بعد ذلك نختار MacOS2 أو WLM (internal) extracted من الخاصية Skinname لنفس المكون.
نجرب.
الآن نضع المكون sSkinprovider على الفورم الأولى دائما ، هذا المكون به عدة خصائص للسكين لك أن تجربها و تكتشفها بنفسك.ننسخ هذا المكون نضعه على الفورم الثانية أيضا .
لازلنا مع الفورم الأولى (FSplash) و الآن نريد كتابة إسم البرنامج مرفق بالإصدار ، و الحقوق . . .
اكتب ما شئت ثم قم بالتجريب .
شاهد المرفقات.
.../ يتبع /...
B.M.AbdelAziZ
21-01-2010, 07:28 PM
أخ نبيا، بما ان غذا الجمعة (عطلة!)
ما رايك ان اتابع معك الدرس لكن بطريقة بديلة
مثلا بدلا من Alpha Skin استخدم VCL Skin
بدلا من Paradox التي حتما ستستخدمها اغيرها بشيئ أخر
تعديل بسيط هنا وهناك لاعطاء القارئ نظرة من زاوية اخرى وتفكير مختلف
nabilkeb
22-01-2010, 06:07 PM
مادامت تدخلاتك أستاذي متواصلة ، فلن أضيع على نفسي فرصة التعلم منك (و بهذا أضنك مطالب بالإستمرار ، لقلة خبرتي إذا تعدى التغيير ما لا أجيد) ، الرأي رأيك.
بالتوفيق
بعد السلام عليكم
انا مع الاخ عبدالعزيز فيما طرحه في رده
فالأصح ان نعطي حتى المبتدئين دروس على قاعدة صحيحة , ولا نعلمهم استسهال طرق البرمجة , بسلوك اسهلها,فهذا بظني لا يصنع منهم مبرمجين على درجة عالية من الاحتراف فيما بعد ,
وتطبيع البيانات حسب نماذج التطبيع المعروفة هي من اهم الاساسيات الاولى في تصميم قاعدة بيانات سليمة خالية من التداخلات والمتعة في البرمجة هي ان تكتب كود يعطي نتائج دقيقة مهما كان التعقيد في هذا الكود
هذا رأيي والأمر يرجع لك في النهاية
والسلام
nabilkeb
23-01-2010, 10:08 AM
السلام عليكم :
أخي العزيز gigi ، شكرا جزيلا على الإهتمام و المشاركة ، و على هذا المرور الطيب و الكريم .
أنت قلت ( ولا نعلمهم استسهال طرق البرمجة ) و كذلك ( المتعة في البرمجة هي ان تكتب كود يعطي نتائج دقيقة مهما كان التعقيد في هذا الكود )
مبدئيا أنا أوافقك الرأي و كلامك صحيح تماما ، لكن : في رأي الخاص مستعمل الدلفي المبتدإ لا بد له أن يقتنع بأمرين:
الأول أنه مطالب في ظل المعلومات المتوفرة لديه أن يصل إلى مبتغاه بأي طريقة صحيحة ممكنة و أحسنها.
الثاني يقتنع بأن أي طريقة أو فكرة مستعملة هناك بالمقابل ما هو أحسن و أرقى منها ، هذا يمكنه من الإجتهاد المتواصل و التحسين من الأسس التي و ضعها و الأكواد البرمجية التي برمج بها.
هكذا يسلك طريقة البرمجة و الطريق نحو الإحتراف خطوة بخطوة ، فلا يمل و لا ييأس ، و المتعة الحقيقية عندما يكتشف و يتعلم ما هو أحسن ممــا سلكه من قبل.
و إلا فكيف نفسر كبرى شركات (أقول شركات يعني مجموعة ضخمة من المتمكنين و المحترفين على الطراز العالي) البرمجة مثل ميكروسفت التي تطرح الاصدارات التجريبة و حتى النهائية ، يكتشف فيها من حين لآخر أخطاء و ثغرات خطيرة (و أحيانا تكلفها خسائر معتبة) ؟
لو أن هذه الشركات بعد نهاية الإصدار ظلت و بقيت تحسن و تبحث عن الأخطاء و تبحث عما هو أحسن ، لبقيت في حلقة مغلقة و ظلت في دوامة ، و لن يعرف منتوجها الظهور أو النور.
بطبيعة الحال ، أنا لا أقول على المبتدإ أن يتعلم أي شيء حتى و إن كان خاطئا ، و بعدها يصحح و يجتهد و يحسن .
في ظل الخمول الذي يشهده المنتدى منذ مدة ، و في ظل وجود غالبية كبرى من المبتدئين الذين لا يعرفون ماهي قاعدة البيانات و كيف ننشئ جدولا أو ماهي أنواع الحقول ، أو كيف يتم ربط العلاقة بين الجداول ، أو حتى كيف نضيف أو نحذف أو نعدل على جدول ,أو طرق البحث و الفلترة ، و ..... ، كان المقصود من الموضوع و من هذا الطرح :
صنع برنامج كامل لتسيير المخزون و التسويق يفي بالغرض و يمكن لك استعماله ميدانيا ، و يخلو من الأخطاء البرمجية في الحسابات ( الكميات و المبالغ و المداخيل و الديون و ... ) .
بعد أن يفهم و يتمكن المبتدإ من هذا ، ننور عقله و فكره البرمجي ، بأن هذا برنامج بسيط ، يمكن له صنع أرقى منه ، يتساءل المبتدإ : كيف ذلك ، مادام وافيا و شاملا و يفي بالغرض ؟ نعطيه بعض الأفكار بمسـاعــدة الأعضاء المحترفين مثلا:
مسألة الإختزال في الأكواد ، نأتي ببعض الأكواد و نقوم بتعويضها بأكواد أقلها أسطرا و أدقها ، و نشرحها ، و نفضلها بطبيعة الحال عن سابقتها.
نتكلم عن حجم قاعدة البيانات و ما يمكن لنا فعله من أجل تقليص الحجم. عن قاعدة البيانات في حد ذاتها (بارادوكس) ، نتكلم عن وجود قواعد بديلة و نعطي أمثلة . نتكلم عن الأمن في هذه القاعدة ، و نرتقي بالمبتدإ نحو الإحترافية بعدم اعتماد هذا الأمن لأنه سهل الكسر و نبين ذلك . نتكلم عن أحسن القواعد و أأمنها و بعض الشركات الكبرى التي تعتمدها. نتكلم عن تأمين البرنامج الموجه للسوق ، و نوجه المبتدإ لوجود ما بعرف بالهندسة العكسية فنضعه على الطريق و نوجهه أحسن توجيه.
نتكلم عن تقرير الطباعة (كويكربورت) و نلفت الإنتباه لوجود بدائل و نقدم الأحسن .
هكذا سنترك العنان للخبراء بالإفادة و نستفيد كلنــــا.
و بذلك يتفتح عقل المبتدإ و يعي حينها أن هذا مجال واسع و لا ينحصر في 1+1=2 و بذلك بامكانه التشمير على ساعديه و طرح ابداعه الخاص.
أمــــا إذا بقينا من البداية نصعب و نعقد و نطرح الأحسن ، و أحسن الأكواد القصيرة و إن كانت معقدة ، فلا أضنه منهجا صحيحا للمبتدإ ، و أأكد أن كل مبتدإ له شيئ من الرغبة في الإنطلاق فإنه لن ينطلق أبدا.
(برنامج كهذا بالطرح المميز و الأكواد و الأسسس الإحترافية مكـانهـا قسم البرامج الجماعية_ و ليس للمبتدئين ).
بالتوفيق.
nabilkeb
23-01-2010, 07:15 PM
السلام عليكم و رحمة الله تعالى و بركاته:
هذا الطرح الثالث أو الدرس الثالث في مشروعنــا ، اليوم إن شاء الله نعمل قائمة للصفحة الرئيسية و ننشئ باقي الصفحات ، بعدها نبدأ في إعداد الجداول.
طيب الآن ، سوف نبدأ بالقائمة:
من قائمة 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
24-01-2010, 11:02 AM
السلام عليكم ورحمة الله
حسنا اخ نبيل/ اكمل الموضوع وعندما تنتهي منه ان شاء الله يكون هناك موضوع اخر
ملاحظة: تنظيما للموضوع سيتم حذف ردي هذا وجميع الردود باستثناء مشاركات صاحب الموضوع
nabilkeb
24-01-2010, 12:04 PM
السلام عليكم ورحمة الله
حسنا اخ نبيل/ اكمل الموضوع وعندما تنتهي منه ان شاء الله يكون هناك موضوع اخر
ملاحظة: تظيما للموضوع سيتم حذف ردي هذا وجميع الردود باستثناء مشاركات صاحب الموضوع
حسنا بارك الله فيك أستاذي ، و بخصوص حذف الردود كنت أود اقتراح ذلك لكي لا يطول الطرح من غير فائدة و التشويش على كل متابع . إذ أنه بامكان أي شخص المراسلة عن طريق المنتدى أو التشكر على الخاص عوض طرحه هنــا ، و أنا ممتن للجميع.
بالتوفيق.
nabilkeb
25-01-2010, 05:01 PM
السلام عليكم و رمة الله تعالى و بركاته :
هذا الجزء رقم 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.TabSheet1.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 .
http://i37.tinypic.com/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) أثناء ملئ أو إدخال البيانات في الجدول ، و لا يمكنك تكرار نفس القيمة في حقل آخر ، يعني يمكنك و يستحسن لك جعل مفتاح أساسي في الحقول التي لا يمكن أن تكون لها نفس القيمة في حقول أخرى كأرقام التسجيل أو أرقام البطاقات أو غيرها ، حيث يعرف صاحبها من هذا الرقم و لا يمكن أن تجد رقم واحد لشخصين في آن واحد ، فإذا أردت البحث عن شخص معين تبحث عنه عن طريق هذا الرقم ( لذا لابد أن يكون الحقل المخصص لهذا الرقم مفتاح أساسي) ، لا يمكنك مثلا جعل حقل تاريخ الميلاد مفتاح أساسي لامكانية تكرار هذه القيمة لأكثر من شخص .
http://i35.tinypic.com/sb790m.jpg
حسب ما تقدم قم بانشاء الجداول التي نحتاجها ، على أن يتم حفظها بالأسماء المحددة ، و كذا تحديد أسماء حقولها و نوعيتها و قيمها حسب الجداول المنجزة بملف الوارد المرفق.
في المرة القادمة إن شاء الله تعالى سوف نقوم بملئ كل فورم بالمكونات المناسبة كما سوف نربط الجداول التي تم انشاؤها بمشروعنا ، و سيتم ارفاق المشروع كاملا بالجداول . إذن أنت مطالب بانشاء الجداول وحدك الآن.
بالتوفيق
../ يتبع /....
nabilkeb
26-01-2010, 12:15 PM
السلام عليكم و رمة الله تعالى و بركاته :
هذا الجزء رقم 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 ، حدد و احذف هذين الأخيرين . و لنا رجعة قريبة إن شاء الله تعالى.
بالتوفيق.
..../ يتبع /....
nabilkeb
27-01-2010, 02:37 PM
السلام عليكم و رمة الله تعالى و بركاته : هذا الجزء رقم 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 ، حسب اسم كل حقل .
نستطيع فعل نفس الشيء فيما يخص فورم و جدول الزبائن.
و هاهو مشروعنا إلى غاية هذه المرحلة بالمرفقات.
بالتوفيق.
http://i38.tinypic.com/2uesmj6.jpg
.../ يتبع / ....
kachwahed
27-01-2010, 03:35 PM
وعليكم السلام ورحمة الله وبركاته
أخي نبيل بارك الله لك وجزاك خيرا
يمكن أن يساعدك هذا الرابط للاقتباس، أساسيات تصميم قواعد البيانات من Microsoft
http://office.microsoft.com/ar-sa/access/HA012242471025.aspx
بالتوفيق.
nabilkeb
27-01-2010, 03:59 PM
فعلا هو رابط مفيد جدا و أكثر من رائع . ستأتي المرحلة التي نحتاج فيها إليه .
مشكوووور أخي العزيز .
بالتوفيق.
nabilkeb
30-01-2010, 01:09 PM
السلام عليكم و رحمة الله تعالى و بركاته : هذا الجزء رقم 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)*st rtofloat(sEdit2.text));
sEdit4.Text:=floattostr(0);
sEdit5.Text:=floattostr(strtofloat(sEdit3.Text)+st rtofloat(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)*st rtofloat(sEdit2.text));
sEdit4.Text:=floattostr(strtofloat(sEdit3.Text)*0. 07);
sEdit5.Text:=floattostr(strtofloat(sEdit3.Text)+st rtofloat(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)*st rtofloat(sEdit2.text));
sEdit4.Text:=floattostr(strtofloat(sEdit3.Text)*0. 17);
sEdit5.Text:=floattostr(strtofloat(sEdit3.Text)+st rtofloat(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) لتظهر رسالة التنبيه أو لا.
كذلك شرط إجبارية ملء كل الحقول لتفادي الوقوع في مشاكل حسابية كثيرة ، في حالة وقع المستعمل سهوا أو خطأ في اجراء عملية بيع من دون اتمام ملئ كل الحقول.
إذن نحرر:
nabilkeb
30-01-2010, 01:11 PM
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').AsSt ring +' /'+
formatdatetime('yyyy',Table2.Fieldbyname('date').A sDateTime);
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) صحيحا .
بالتوفيق.
.../ يتبــع / .....
nabilkeb
31-01-2010, 12:53 PM
السلام عليكم و رحمة الله تعالى و بركاته : هذا الجزء رقم 08 أو الدرس الثامنمن مشروع انجاز برنامج
لتسيير المخزون و التسويق (GSM) .
اليوم أيضا إن شاء الله سنخطو شوطا كبيرا و هاما في مشروعنــا ، و لا زلنــا مع الفورم FGSM :
و قبل التطرق إلى النقطة التي أنهينـا بها درسنا السابق ، سوف نبرمج عمل كل من الأزرار: Modifier-Valider-Anuler :
الزر Modifier : مباشرة نحرر:
table2.Edit;
sBitBtn1.Enabled:=false;
sBitBtn2.Enabled:=false;
sBitBtn4.Enabled:=false;
sBitBtn6.Enabled:=false;
sBitBtn7.Enabled:=True;
sBitBtn8.Enabled:=True;
DateTimePicker1.enabled:=true;
Filtrage1.Enabled:=false; // fact_Statistique
Vente1.Enabled:=false; // Fiche Vente
DblookupCombobox1.ReadOnly:=False;
DblookupCombobox2.ReadOnly:=False;
DblookupCombobox3.ReadOnly:=False;
DblookupCombobox4.ReadOnly:=False;
و هذا واضح و لا يتطلب أي شرح.
الزر Valider :
هذا يشبه كثيرا الزر Ajouter ، لكن هذا الأخير يتعلق بإضافة مادة جديدة (الزر Nouveau Produit) إلى قائمة مواد المبيعات ، و عليه بمجرد الضغط على Nouveau Produit و ملئ الحقول يقوم الزر Ajouter بإضافة القيم التي ملئت إلى الجداول مع التعديل في قيمة الكمية بالنسبة لجدول المواد Produit ، كذلك يقوم الزر باجراء تحقق من قيمة الكمية في حال أوشكت على النفاد من المخزون ليظر رسالة التنبيه.
تماما و نفس الشيء تقريبا بالنسبة للزر Valider ، لكن هذا الأخير يخص فقط التعديل ، يعني أنه سيكون معطلا و لن يكون مفعلا إلا بعد الضغط على زر Modifier ، الإختلاف يكمن فقط في حساب الكمية نالنسبة لرسالة التنبيه المتضمنة أن الكمية غير متوفرة في حال كانت تفوق الكمية المتوفرة بالمخزون+حفظ البيانات في جدول المواد Produit ، و أخيرا أمر هام جدا و هو تحديد السجل المراد تغيير كمية مادته بالنسبة للجدول Produit (انظر الكود باللون البرتقال_و للمزيد عن هذا الكود تفضل بزيارة هذا الرابط (http://www.delphi4arab.com/forum/showthread.php?t=519) ) و السبب هو: إذا ضغط المستعمل زر Modifier ثم بطريقة أو بأخرى ذهب إلى الفورم FProduit و حدد سجلا مغايرا سوف يتم بذلك تغيير كمية المادة المتوقف المؤشر عن سجلها و ليست المقصودة و يحدث بذلك خلل كبير كما تقدم.
بعد هذا التوضيح أترككم مع:
if sEdit1.text>table1.FieldValues['Qut']+ table2.FieldValues['Qut']
then begin
if messageDlg('Vous navez pas cette valeur,vouler vous savoir La_Qut?',MtConfirmation
,[mbyes,mbno],0)=mryes then begin showmessage(Format('vous avez sellement: %s' ,
[table1.FieldValues['Qut']+ table2.FieldValues['Qut']]));
sEdit1.Text:=table1.FieldValues['Qut']+ table2.FieldValues['Qut'];
sEdit1.SetFocus; end; end
else begin
if Table1.FindKey([Table2.FieldValues['Code_Prod']]) then begin
Table1.Edit;
Table1.FieldValues['Qut']:=Table1.FieldValues['Qut']
+Table2.FieldValues['Qut'] ;
Table2.Post ;
Table2.edit;
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;
Table1.Edit;
Table1.FieldValues['Qut']:=Table1.FieldValues['Qut']
-Table2.FieldValues['Qut'] ;
Table1.Post;
if table1.FieldValues['Seuil_Qut']>=Table1.FieldValues['Qut'] then
begin showmessage (' La Quantité de ce produit est Diminue En Dessous...'); end;
sBitBtn2.Enabled:=true;
sBitBtn3.Enabled:=false;
sBitBtn4.Enabled:=true;
sBitBtn5.Enabled:=true;
sBitBtn6.Enabled:=True;
sBitBtn7.Enabled:=False;
sBitBtn8.Enabled:=false;
Filtrage1.Enabled:=true; // fact_Statistique
Vente1.Enabled:=true; // Fiche Vente
DblookupCombobox1.ReadOnly:=true;
DblookupCombobox2.ReadOnly:=true;
DblookupCombobox3.ReadOnly:=true;
DblookupCombobox4.ReadOnly:=true;
end;
end;
الزر Anuler :
واضح و سهل الفهم ، نحرر:
if Table2.IsEmpty then begin
sBitBtn1.Enabled:=True;
sBitBtn2.Enabled:=True;
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 else begin
table2.Cancel;
sBitBtn1.Enabled:=True;
sBitBtn2.Enabled:=True;
sBitBtn3.Enabled:=False;
sBitBtn4.Enabled:=True;
sBitBtn5.Enabled:=True;
sBitBtn6.Enabled:=True;
sBitBtn7.Enabled:=True;
sBitBtn8.Enabled:=False;
DateTimePicker1.enabled:=true;
end;
كان هذا بخصوص الأزرار Modifier-Valider-Anuler ، الآن نعرج على الإشكالية المذكورة موضوع الدرس السابع:
ننبه على وجود أمرين هامين أو إشكاليتين بخصوص الكمية بين الجدولين Produit و Vente ، تشملهما البرمجة في زر Suprimer و sEdit1 لاحقا ، المطلوب منك بعد هذا التبسيط البحث و الطرح ، و لنــا عودة لاكمال مشوارنا هذا إن شاء الله عز و جل.
تابع معي: لو أن المستعمل بينما هو يكتب رقم معين في خانة الكمية (sEdit1) لامس سهوا إشارة الطرح بقسم الآلة الحاسبة من لوحة المفاتيح (وبديهيا هو يستخدم ذلك القسم) ماذا سيحدث بالنسبة لحقل الكمية في كل من جدول Produit و Vente ؟
يمكن بذلك إضافة شرط أن تكون القيمة موجبة يعني أكبر من الصفر ، يمكن و ضع الشرط في الزر Ajouter قبل تنفيد العملية ، كما يمكن التحقق منه (في الحدث) بعد مغادرة أو التغيير في sEdit1 .
في نفس السياق أقول أن sEdit1+2 هي خانة للأرقام ، لا يعقل تحرير أي حرف أو رمز و لعدم إتاحة المستخدم ارتكاب هكذا أخطاء ، نجبره على كتاة ما يلزم وفقط .
نذهب للحدث OnKeyPress الخاص بـ sEdit1 و نحرر:
if key=#13 then sEdit2.SetFocus;
if key in ['.' , ','] then
begin key:= DecimalSeparator; end;
if Not (Key in ['0'..'9',DecimalSeparator, #8 ]) then begin
Key := #0; Beep;
end;
الأمر Setfocus يعني الإنتقال ، يعني بعد ملئ الخانة نضغط على زر Enter فننتقل مباشرة إلى sEdit2 كوسيلة للسرعة و الراحة.
نذهب إلى sEdit2 (دوما في الحدث OnKeyPress) و نحرر :
if key=#13 then DBLookupCombobox4.SetFocus;
if key in ['.' , ','] then
begin key:= DecimalSeparator; end;
if Not (Key in ['0'..'9',DecimalSeparator, #8 ]) then begin
Key := #0; Beep;
end;
- الآن في الزر Suprimer : يؤدي الضغط عليه لحذف سجل معين من قائمة المبيعات (من جدول Vente) في حال أخطأ المستخدم للبرنامج أو تراجع الزبون عن شراء هذه المادة مثلا ، المهم أن الحذف بواسطة الكود السالف طرحه يقتصر على الجدول Vente فقط ، هنا خطأ من حيث الكمية في الجدول Produit .
التوضيح: بيعت الكمية 10 من أصل 100 من مادة معينة ، و بالتالي المبيعات=10 و المتبقي في المخزن 90 ، بعد الحذف تبقى الكمية بالمخزن 90 و هذا خطأ لأن المفروض أن تبقى100 .
التصحيح: في الزر Suprimer نحرر :
if not table2.IsEmpty then begin
if MessageDLG
('êtes vous sûr de vouloir suprimer l''enregistrement ?'
, MtConfirmation,[MbYes,MbNo],0)=MrYes then
begin
Table1.Edit;
Table1.FieldValues['Qut']:= Table1.FieldValues['Qut']+Table2.FieldValues['Qut'];
Table1.Post; Table2.Delete; Table6.Delete; end;end;
if table2.IsEmpty then begin
sBitBtn1.Enabled:=True; 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;
انتهت مادة الدرس الثامن . إذا واجهت أخي الحبيب أي خلل أو إشكال تفضل بالسؤال.
بالتوفيق.
... / يتبع / ....
nabilkeb
01-02-2010, 10:13 PM
- الآن أخي المتابع سوف نتطرق للواجهة (الفورم) الخاصة بالزبون - المبيعات - المشتريات - المواد :
و لأن العناصر المستعملة من أزرار و غيرها مرت معنا في الفورم الرئيسي ، فقد فضلت توفير الجهد و عناء الشرح ، المطلوب منك فقط انشاء عناصر كل فورم و ترتيبها (الملف مرفق) ، و في الدرس الموالي إن شاء الله سوف نباشر برمجة عمل كل زر ، و سيكون الأمر سهلا فعمل كل زر يشبه إلى حد كبير ما مر معنــا.
ليبقى أهم شيء بعدها و المتمثل في الفورم FFactureEtStatistique ، هذه المرحلة تتطلب شرح مفصل نظرا لأهميتها البالغة و نظرا لأننا سنستعمل SQL الذي لم يمر معنا أي شيء عنه.
و ختاما نأتي لتقارير الطباعة و ينتهي كل شيء.
بالتوفيق.
nabilkeb
03-02-2010, 04:19 PM
السلام عليكم و رحمة الله تعالى و بركاته : هذا الجزء رقم 09 أو الدرس التاسع مشروع انجاز برنامج
لتسيير المخزون و التسويق (GSM) .
بصفة فردية و مباشرة اختزالا للجهد و الوقت ، قمت باضافة العناصر اللازمة في كل من الفورم FProduit-FClient-FFournisseur-FAchat ، فأما الفورم المواد أو فورم المخزن فقد قمت ببرمجة عمل كل عنصر ، المطلوب من على نفس الشاكلة تقريبا إتمام العمل في يخص برمجة عناصر و أزرار كل من فورم الزبائن و الممونين ، كذلك على نفس شاكلة الفرم FGSM المتضمنة عملية البيع أو العملية على جدول المبيعات قم باتمام ما يلزم بخصوص فورم المشتريات .
بهذا أكون قد فضلت عدم شرح أمور سبق التطرق إليها من جهة ، و من جهة أخرى أحببت تفاعلك معي و اختبار مدى استعابك لما سلف ، لذلك قم بما هو مطلوب و عجل الإنجاز.
بالتوفيق.
الآن سنتكلم عن أمر آخر تم إضافته في الفورم FGSM:
عندما يباشر المستعمل ، القيام بعمليات بيع لمختلف المواد ، و مع كثرة المواد و ربما تشابه أسمائها قد يغيب عنه كود أو اسم مادة معينة (خصوصا إذا كان موظف جديد) الشيء الذي سيجبره على فتح قائمة DBLookupCombobox2 و التمعن و البحث في كل القائمة ، أو سيذهب إلى الفورم FProduit ليبحث في الجدول بكامله عن المادة المقصودة ، و ماذا لو كان المحل يتعامل بقدر هائل من البيانات لا سيما مئات الأنواع من المواد ؟ نفس الشيء لو كان المحل يتعامل مع زبائن كثر ، رغم أن الزبون سيقول لك مثلا نحن مؤسسة MagiInfo (كإسم تجاري) و لنفرض أن لك زبائن كثر تتشابه أسماؤها و لديك الكثير كل يبدأ بحرف M ، أكيد أنك تخسر وقتا أنت بحاجة إليه.
مما ذكر ، جاءت فكرة مضمونها العام هو اتاحة طريقة سريعة للبحث عن كود أو إسم مادة أو زبون .
الطريقة:
نستعمل كل من العناصر: زر واحد ، عنصر واحد من ComboBox ، و 5 عناصر من RadioButton .(تجدها من القائمة في صفحة Standard )
و لأننا استعملنا سكين فإننا نفضل البحث عن نفس العناصر الشبيهة من صفحة AlphaLite سنجد
sBitBtn و sComboBox و لا نجد بديل عن RadioButton ، لكننا نجد كبديل عن هذا الأخير العنصر sCheckBox و الفرق بينهما واضح و هو أن الأول لا يتيح لك امكانية تحديد عنصرين معا ، بينما الآخر يمكنك من ذلك ، و يمكننا تجاوز ذلك بالطبع بإضافة شرط حذف التحديد عن البقية في حال تم تحديد أحدها.
أترككم مع الكود ، نضغط مرتين على العنصر sCheckBox1 و نكتب :
if sCheckBox1.Checked=true then begin
sCheckBox2.Checked:=false;
sCheckBox3.Checked:=false;
sCheckBox4.Checked:=false;
sCheckBox5.Checked:=false;
sComboBox1.SetFocus;
end; نفس الشيء مع sCheckBox2 :
if sCheckBox2.Checked=true then begin
sCheckBox1.Checked:=false;
sCheckBox3.Checked:=false;
sCheckBox4.Checked:=false;
sCheckBox5.Checked:=false;
sComboBox1.SetFocus;
end; و نفس الشيء مع sCheckBox3-4-5 .
- الآن مع sCombobox1 : أولا نجعل الخاصية Style لهذا العنصر تأخذ القيمة csSimple ، ثم في الحدث OnEnter للــ sCombobox1 نكتب :
If sCheckBox1.Checked=true then Begin
sCombobox1.Items.Clear;
Table1.first;
While not Table1.EOF Do Begin
sCombobox1.Items.Add(Table1.FieldByName('Code_Prod ').asString);
Table1.Next; End;
Table1.First;
While Not Table1.EOF Do
If Table1.FieldValues['Code_Prod']=sCombobox1.text Then
BREAK
Else Table1.Next;
end;
If sCheckBox2.Checked=true then Begin
sCombobox1.Items.Clear;
Table1.first;
While not Table1.EOF Do Begin
sCombobox1.Items.Add(Table1.FieldByName('Des_Prod' ).asString);
Table1.Next; End;
Table1.First;
While Not Table1.EOF Do
If Table1.FieldValues['Des_Prod']=sCombobox1.text Then
BREAK
Else Table1.Next;
end;
If sCheckBox3.Checked=true then Begin
sCombobox1.Items.Clear;
Table4.first;
While not Table4.EOF Do Begin
sCombobox1.Items.Add(Table4.FieldByName('Code_Clie nt').asString);
Table4.Next; End;
Table4.First;
While Not Table4.EOF Do
If Table4.FieldValues['Code_Client']=sCombobox1.text Then
BREAK
Else Table4.Next;
end;
If sCheckBox4.Checked=true then Begin
sCombobox1.Items.Clear;
Table4.first;
While not Table4.EOF Do Begin
sCombobox1.Items.Add(Table4.FieldByName('Code_Com_ C').asString);
Table4.Next; End;
Table4.First;
While Not Table4.EOF Do
If Table4.FieldValues['Code_Com_C']=sCombobox1.text Then
BREAK
Else Table4.Next;
end;
If sCheckBox5.Checked=true then Begin
sCombobox1.Items.Clear;
Table4.first;
While not Table4.EOF Do Begin
sCombobox1.Items.Add(Table4.FieldByName('Nom_C').a sString);
Table4.Next; End;
Table4.First;
While Not Table4.EOF Do
If Table4.FieldValues['Nom_C']=sCombobox1.text Then
BREAK
Else Table4.Next;
end;
الآن الزر الذي أضفنـاه أنا عندي هو sBitBtn13 :
نجعل الكابشن الخاصة به تأخذ القيمة Plus D'information يعني معلومات إضافية أو معلومات أخرى . نريد من هذا الزر إعطاء معلومات إضافية يمكن للمستعمل أن يحتاجها (و أنا غرضي منه تمكينك من رؤية طريقة بحث بواسطة الأمر Lookup و للمزيد راجع هذا الرابط (http://www.delphi4arab.com/forum/showthread.php?t=519) )
var LookupResult : Variant;
begin
if sCheckBox1.Checked=true then begin
lookupResult := Table1.Lookup('Code_Prod',sCombobox1.Text,'Des_Pro d;Qut');
if Not VarIsnull( lookupResult) then Showmessage
('- Code de Produit : '+sCombobox1.text+#13+'- Designation de Produit : '+vartostr(lookupresult[0])+ #13+'- Qut : ' + vartostr(lookupresult[1] ) );
end;
if sCheckBox2.Checked=true then begin
lookupResult := Table1.Lookup('Des_Prod',sCombobox1.Text,'Code_Pro d;Qut');
if Not VarIsnull( lookupResult) then Showmessage
('- Code de Produit : '+vartostr(lookupresult[0])+#13+'- Designation de Produit : '+sCombobox1.text+ #13+'- Qut : ' + vartostr(lookupresult[1] ) );
end;
if sCheckBox3.Checked=true then begin
lookupResult := Table4.Lookup('Code_Client',sCombobox1.Text,'Code_ Com_C;Nom_C');
if Not VarIsnull( lookupResult) then Showmessage
('- Code de Client : '+sCombobox1.text+#13+'- Code Commercial de Client : '+vartostr(lookupresult[0])+ #13+'- Nom et Prénom de Client : ' + vartostr(lookupresult[1] ) );
end;
if sCheckBox4.Checked=true then begin
lookupResult := Table4.Lookup('Code_Com_C',sCombobox1.Text,'Code_C lient;Nom_C');
if Not VarIsnull( lookupResult) then Showmessage
('- Code de Client : '+vartostr(lookupresult[0])+#13+'- Code Commercial de Client : '+sCombobox1.text+ #13+'- Nom et Prénom de Client : ' + vartostr(lookupresult[1] ) );
end;
if sCheckBox5.Checked=true then begin
lookupResult := Table4.Lookup('Nom_C',sCombobox1.Text,'Code_Client ;Code_Com_C');
if Not VarIsnull( lookupResult) then Showmessage
('- Code de Client : '+vartostr(lookupresult[0])+#13+'- Code Commercial de Client : '+vartostr(lookupresult[1] )+ #13+'- Nom et Prénom de Client : ' +sCombobox1.text);
end;
end;
ملاحظة: المرفق بواجهة فرنسية ، بعد أن سبق إدراج مرفق المشروع بواجهة عربية (نزولا لرغبة أحد الأعضاء) ، و بهذا يمكن للأي عضو لا يفهم اللغة الفرنسية (و أنا أصلا لا أجيدها) ، فهم معنى كل عبارة عن طريق المقارنة بين المرفقين عند الحاجة .
- في الدرس القادم سوف نرفق المشروع مع اتمام برمجة كل من فورم المشتريات و الزبائن و الممونين ، مع بداية الطرح لغرض ما يلزم بخصوص الفورم FFactureEtStatistique ، و نذكر بأن هذا الأخير في غاية الأهمية و سنعطي بعض الوقت قبل الطرح لغرض اللحاق لجميع المشاركين و المهتمين.
بالتوفيق .
..../ يتبـع / ....
nabilkeb
03-02-2010, 09:39 PM
قبل إتمام المشروع بما تبقى ، هناك خطأ أو نقص في برمجة زر الحذف في الفورم FGSM قد يؤدي إلى الوقوع في الخطأ.
المطلوب ايجاد هذا النقص و تعديله ، لكي لا تقع فيه أيضا في نفس الزر على الفورم FAchat لأن وظيفة الأزرار تتشابه كما سلف الذكر.
بالتوفيق.
nabilkeb
05-02-2010, 02:16 PM
قبل إتمام المشروع بما تبقى ، هناك خطأ أو نقص في برمجة زر الحذف في الفورم FGSM قد يؤدي إلى الوقوع في الخطأ.
المطلوب ايجاد هذا النقص و تعديله ، لكي لا تقع فيه أيضا في نفس الزر على الفورم FAchat لأن وظيفة الأزرار تتشابه كما سلف الذكر.
بالتوفيق.
فقط إضافة الشرط المكتوب باللون البرتقالي:
if not table2.IsEmpty then begin
if (MessageDLG ('êtes vous sûr de vouloir suprimer l''enregistrement ?'
, MtConfirmation,[MbYes,MbNo],0)=MrYes) and (Table1.FindKey([Table2.FieldValues['Code_Prod']])) then
begin
Table1.Edit;
Table1.FieldValues['Qut']:= Table1.FieldValues['Qut']+Table2.FieldValues['Qut'];
Table1.Post; Table2.Delete;
end; لأنه إذا تم تحديد سجل مغاير (على DBGrid في الفورم FVente) فإنه سيحذف السجل المحدد ، و هو غير المقصود حذفه على الفورم FGSM . سبق التطرق إلى هذا الأمر في الدرس الثامن (الكود باللون البرتقالي أيضا).
- إذن المشروع مرفق ، و به التعديل المذكور إضافة إلى اتمام برمجة وظيفة العناصر على الفورم(المشتريات و الزبائن و الممونين):
FAchat - FِClient - FFournisseur
فقط تنبيه : عن سهو و من غير قصد لم أطلب فهرسة حقل Code_Client في الجدول Client ، و كذلك Code_Fournisseur في الجدول Fournisseur .
- كذلك سميت حقل الإسم التجاري في الجدول Produit بالإسم Code_ Com_F عوضا عن Code_Com_F ، يعني هناك فراغ قبل Com ، و قد تم تعديل التسمية بالجدول و كذا موضوع الفهرسة . فعذرا لأنني أسرع و لا أحضر للطرح ، رغبة مني في اكمال الموضوع لنستفيد من نقد و توجيه و أفكار المحترفين أصحاب الخبرة.
-كما ألفت الإنتباه إلى أنني أضيف أشياء طفيفة لا أذكرها ، في المرفقات من مرفق لآخر ، لبساطة تلك الإضافة و لعدم التحدث و طرح كل شيء لكي لا أطيل و ربما تختلط الأمور عليك صديقي ، فإني أراعي أنه قسم للمبتدئين أمثالي.
المهم المشروع إلى غاية هذه المرحلة مرفق .
لم يتبق الكثير ، في الدرس القادم إن شاء الله سنعمل على الفورم FFactureEtStatistique و بعدها تقارير الطباعة و ينتهي كل شيء.
بالتوفيق.
nabilkeb
05-02-2010, 09:41 PM
قبل بداية الدرس العاشر بحول الله ، و لاختزال الوقت و عدم التكثير من الطرح الممل و الحديث عن إضافة عناصر مرت معنا ، المطلوب انشاء و ترتيب مكونات الفورم FFactureEtStatistique ، إستنادا إلى المرفق ، و سنباشر البرمجة على هذه الأخيرة في الطرح اللاحقا إن شاء الله .
بالتوفيق
nabilkeb
06-02-2010, 08:06 PM
السلام عليكم و رحمة الله تعالى و بركاته : هذا الدرس العاشر من مشروع انجاز برنامج
لتسيير المخزون و التسويق (GSM) .
نربط DataSource1 مع Query1 من الخاصية DataSet ، و 2 مع 2 ، و هكذا.
نربط DBGrid1 مع DataSource1
نحدد العنضر Query1 و من الخاصية SQL في TStrings نكتب
Select * from Vente
where N_Fact=:afficher_Facture يعني قمنا بتحديد كل الحقول من الجدول Vente إذا تحقق الشرط المتمثل في رقم الفاتورة يساوي القيمة afficher_Facture ، و هذه الأخيرة إختيارية يعني اكتب ماتشاء ، المهم شيء يدلك على المراد (وهنا المراد لعرض الفاتورة).
نذهب الآن إلى الخاصية Params ، يوف تظهر لنا القيمة التي كتبناها (afficher_Facture) ، نحددها و نذهب إلى خصائصها و نعدل على الخاصية DataType ، و نحدد ftFloat لأن هذه القيمة بطبيعة الحال عدد حقيقي لأنها توازي نوع الحقل (N_Fact) .
ثم من الحدث OnChange للــ sEdit1 نكتب
if sEdit1.text='' then begin sEdit1.text:=floattostr(0); sEdit1.SelectAll ; end;
Query1.Close;
Query1.ParamByName('Afficher_Facture').Value:=sEdi t1.text;
Query1.Open;
if sEdit1.Text=Query1.FieldValues['N_Fact'] then begin
sLabel3.Caption:=Query1.FieldValues['Date'] ;
sLabel5.Caption:=Query1.FieldValues['Code_Com_C'] ;
end else begin
sLabel3.Caption:='. . . . . . . . . . . . . . .';
sLabel5.Caption:='. . . . . . . . . . . . . . .' ; end;
-أولا : قيمة sEdit1 هي لرقم الفاتورة ، يعني نكتب رقم الفاتورة فيها فنتحصل على عرض للفاتورة بالــ DBgrid ، لابد ألا تكون قيمة sEdit1 خالية ، هذا كود بسيط يرجع القيمة 0 إذا كانت خالية .
-كتبنا في الكود أعلاه الشرط where N_Fact=:afficher_Facture و موازاة مع ذلك فعلينا أن نعطي قيمة sEdit1 للــ Query1.ParamByName('Afficher_Facture').Value
و قبل ذلك يتطلب الأمر إغلاق Query1 ، بعد ذلك نقوم بفتحه. بهذا تعرض الفاتورة بالـ DBGrid1 . و في sLabel3 و 5 يتم عرض تاريخ الفاتورة و الإسم التجاري للزبون كما يمكن إضافة كود الزبون في sLabel آخر .
- بقي الآن جمع قيمة السعر و كذا الضريبة و السعر الإجمالي :
في الحدث OnChange للــ sEdit1 كتب فقط الجز الذي شرحته ، الكود الكامل:
begin
if sEdit1.text='' then begin sEdit1.text:=floattostr(0); sEdit1.SelectAll ; end;
Query1.Close;
Query1.ParamByName('AFficher_Facture').Value:=sEdi t1.text;
Query1.Open;
if sEdit1.Text=Query1.FieldValues['N_Fact'] then begin
sLabel3.Caption:=Query1.FieldValues['Date'] ;
sLabel5.Caption:=Query1.FieldValues['Code_Com_C'] ;
end else begin
sLabel3.Caption:='. . . . . . . . . . . . . . .';
sLabel5.Caption:='. . . . . . . . . . . . . . .' ; end;
(* Majmoo3e Total_HT*)
RecordPlaceTotal_HT := Query1.GetBookmark;
MajmoueTotal_HT:=0;
Query1.First;
while not Query1.Eof Do
begin
MajmoueTotal_HT:= MajmoueTotal_HT+Query1.FieldByName('prix_T').AsCur rency;
Query1.Next;
end;
sEdit2.text:=CurrToStr(MajmoueTotal_HT);
(* Majmoo3eTVA *)
RecordPlaceTVA := Query1.GetBookmark;
MajmoueTVA:=0;
Query1.First;
while not Query1.Eof Do
begin
MajmoueTVA:= MajmoueTVA+Query1.FieldByName('tva').AsCurrency;
Query1.Next;
end;
sEdit3.text:=CurrToStr(MajmoueTVA);
sEdit4.text:=FloatToStr(StrToFloat(sEdit2.text) + StrToFloat(sEdit3.text));
If FGSM.Table7.FindKey( [(sEdit1.text)] ) Then sBitBtn2.Enabled:=True else
sBitBtn2.Enabled:=False;
end;
و نعرف (أعلاه) في Var قبل implementation :
(*Pour Majmoo3eTotal_HT*) MajmoueTotal_HT: Currency;
RecordPlaceTotal_HT: TBookmark ;
(*Pour Majmoo3eTVA*) MajmoueTVA: Currency;
RecordPlaceTVA: TBookmark ;
(*Pour Majmoo3eDettesTotales*) MajmoueDettesTotales: Currency;
RecordPlaceDettesTotales: TBookmark ;
(*Pour Majmoo3eDettesClient*) MajmoueDettesClient: Currency;
RecordPlaceDettesClient: TBookmark ; - في الحدث ONchange للــ sEdit4 نكتب :
begin
If FGSM.Table7.FindKey( [(sEdit1.text)] ) Then
sEdit6.Text:= FGSM.Table7.FieldValues['Valeur_Reste'] else
sEdit5.Text:=FloatTostr(StrToFloat(sEdit4.Text));
end;
- في الحدث ONchange للــ sEdit5 نكتب :
Var Total_TTC:real;
begin
if sEdit5.Text='' then begin sEdit5.Text:=floattostr(0); sEdit5.SelectAll;end;
Total_TTC:=StrToFloat(sEdit4.Text);
if Total_TTC>=StrToFloat(sEdit5.text) then
sEdit6.Text:=floattostr(Total_TTC-strtofloat(sEdit5.text))
else begin showmessage('Valeur Incorrecte'); sEdit5.text:=FloatToStr(Total_TTc);
sEdit5.SelectAll; end;
end;
- في الحدث ONchange للــ sEdit6 نكتب :
Var Total_TTC:real;
begin
if sEdit6.Text='' then begin sEdit6.Text:=floattostr(0); sEdit6.SelectAll;end;
Total_TTC:=StrToFloat(sEdit4.Text);
if Total_TTC>=StrToFloat(sEdit6.text) then
sEdit5.Text:=floattostr(Total_TTC-strtofloat(sEdit6.text))
else begin showmessage('Valeur Incorrecte'); sEdit5.text:=FloatToStr(Total_TTc);
sEdit6.SelectAll; end;
end;
-نتابع الجزء2 ، من الدرس العاشر في المرة المقبلة ، و سيكون المشروع مرفق.
بالتوفيق.
... / يتبــع / ....
nabilkeb
06-02-2010, 09:17 PM
- الجزء2 من الدرس العاشر
على الفورم FFactureEtStatistique نمر إلى الصفحة : Consultation des Dettes نعمل عليها لأنها متعلقة بشكل مباشر مع Facture .
* أولا لا ننسى مع كل Query نحدد الخاصية : DataBaseName=GSM
- الآن نحن بحاجة لانشاء جدولين جديدين ، الأول للديون ، و الثاني خاص بوصل الدفع.
لم أذكر هذين الجدولين سابقين ، أولا لعدم الحاجة ، ثانيا لعدم لخبطة الأمور ، لكننا في المرحلة الأخيرة (الدرس ما قبل الأخير) و لن ننشئ بعدهما أي جدول.
أسماء الجداول و الحقول و أنواع الحقول ، مرفقة (Table).
- في Query2 في الخاصية SQL نكتب:
SELECT *
FROM Dettes_Client - في Query3 في الخاصية SQL نكتب:
SELECT *
FROM Dettes_Client
where Code_Client=:Code_Client في الخاصية Params للــ Query3 نحدد Code_Clientو نعطيه في DataType القيمة ftString لأنه خاص بحقل نوع نصي.
- نربط DBGrid7 و DBNavigator1 بــ DataSource2
نجعل sEdit17 (الخاصية) : ReadOnly=True.
- في الحدث OnChange للــ sEdit16 :
if sEdit16.Text='*' then begin
Query2.Close;
Query3.Close;
(* Majmoo3eDettesTotales *)
RecordPlaceDettesTotales:= Query2.GetBookmark;
MajmoueDettesTotales:=0;
Query2.Active:=true;
Query2.First;
while not Query2.Eof Do
begin
MajmoueDettesTotales:= MajmoueDettesTotales
+Query2.FieldByName('Valeur_reste').AsCurrency;
Query2.Next;
end; sEdit17.text:=CurrToStr(MajmoueDettesTotales);
end else begin
Query2.Close;
Query3.Close;
Query3.ParamByName('Code_Client').Value:=sEdit16.t ext;
DbGrid6.DataSource:=DataSource3;
Query3.Open;
(* Majmoo3eDettesClient *)
RecordPlaceDettesClient := Query3.GetBookmark;
MajmoueDettesClient:=0;
Query3.First;
while not Query3.Eof Do
begin
MajmoueDettesClient:= MajmoueDettesClient
+Query3.FieldByName('Valeur_reste').AsCurrency;
Query3.Next;
end; sEdit17.text:=CurrToStr(MajmoueDettesClient);
end;
- نرجع للصفحة Facture و على الضغط للزر sBitBtn1 نكتب :
If Not FGSM.Table7.FindKey( [(sEdit1.text)] ) Then begin
FGSM.Table7.Insert;
FGSM.Table7.FieldValues['Code_Client']:=query1.FieldValues['Code_Client'] ;
FGSM.Table7.FieldValues['Code_Com_C']:=query1.FieldValues['Code_Com_C'] ;
FGSM.Table7.FieldValues['N_Fact']:=query1.FieldValues['N_Fact'] ;
FGSM.Table7.FieldValues['Date']:=query1.FieldValues['Date'] ;
FGSM.Table7.FieldValues['Prix_TTC']:=sEdit4.text ;
FGSM.Table7.FieldValues['Valeur_Reste']:=sEdit6.text ;
FGSM.Table7.post;
sBitbtn2.Enabled:=true; ShowMessage('Les données sont enregistrées avec succès');
end else begin if messageDLG
(' Le Mode De Paiment est deja Valider ,Voulez-vous changer ?',
MtConfirmation,[MbYes,MbNo],0)=MrYes
then begin
FGSM.Table7.Edit;
FGSM.Table7.FieldValues['Valeur_Reste']:=sEdit6.text ;
FGSM.Table7.post;
sBitbtn2.Enabled:=true; end;
end;
-كل شيء على مايرام ، المشروع مرفق.
بالتوفيق.
.../ يتبع / ....
nabilkeb
07-02-2010, 09:38 PM
- الجزء 3 من الدرس العاشر
على الفورم FFactureEtStatistique دائما ، نمر إلى الصفحة : Gestion de Versements ، نجعل ReadOnly=True لكل من العناصر : sBitBtn9-sBitBtn10-sEdit14-sEdit15-DBLookupcimboBox1-DBLookupcomboBox2 .
للتعريف ، نكتب قبل implementation :
(*Pour Majmoo3eVersement_Totals*) MajmoueVersement_Totals: Currency;
RecordPlaceVersement_Totals: TBookmark ;
(*Pour Majmoo3eVersement_Client*) MajmoueVersement_Client: Currency;
RecordPlaceVersement_Client: TBookmark ;
- نجعل الخاصية SQL للــ Query4 تأخذ القيمة :
Select *
From Bon_Versement
- نجعل الخاصية SQL للــ Query5 تأخذ القيمة :
Select *
From Bon_Versement
Where Code_Client=:Code_Client و من Params نحدد Code_Client و نجعل DataType تأخذ القيمة : ftString
- من الحدث OnChange للــ sEdit12 نكتب :
if sEdit12.Text='*' then begin Query4.Close;
sBitBtn5.Enabled:=false;
DbGrid4.DataSource:=DataSource4; Query4.Open;
(* Majmoo3eVersement_Totals *)
RecordPlaceVersement_Totals := Query4.GetBookmark;
MajmoueVersement_Totals:=0;
Query4.Active:=true;
Query4.First;
while not Query4.Eof Do
begin
MajmoueVersement_Totals:= MajmoueVersement_Totals
+Query4.FieldByName('Somme_Versée').AsCurrency;
Query4.Next;
end;sEdit13.text:=CurrToStr(MajmoueVersement_Total s);
FGSM.Table8.Refresh; Query4.Refresh;
end else begin
Query5.Close;
Query5.ParamByName('Code_Client').Value:=sEdit12.t ext;
DbGrid4.DataSource:=DataSource5;
Query5.Open;
if Query5.FieldValues['Code_Client']=sEdit12.text then
begin sBitBtn5.Enabled:=true ; end else begin
sBitBtn5.Enabled:=false; end;
(* Majmoo3eVersement_Client *)
RecordPlaceVersement_Client := Query5.GetBookmark;
MajmoueVersement_Client:=0;
Query5.Active:=true;
Query5.First;
while not Query5.Eof Do
begin
MajmoueVersement_Client:= MajmoueVersement_Client
+Query5.FieldByName('Somme_Versée').AsCurrency;
Query5.Next;
end; sEdit13.text:=CurrToStr(MajmoueVersement_Client);
FGSM.Table8.Refresh; Query5.Refresh;
end;
في OnEnter للــ sEdit12 نكتب : sEdit12Change
- نضغط مرتين على DBLookupComboBox1 و نكتب :
DBLookupComboBox2.KeyValue:=FGSM.Table4.FieldValue s['Code_Com_C']; ثم DBLookupComboBox2
DBLookupComboBox1.KeyValue:=FGSM.Table4.FieldValue s['Code_Client'] ; - على الزر sBitBtn7 الذي يحمل الكابشن : Nouveau ، نكتب:
var NumBV:integer;
begin
if not FGSM.Table8.IsEmpty then begin
FGSM.Table8.Last;
NumBV:=FGSM.Table8.FieldValues['N_Bon'];
sEdit14.Text:=inttostr(NumBV+1); end
else begin sEdit14.Text:=inttostr(1); end;
FGSM.Table8.Insert;
sEdit12.Enabled:=False;
sEdit15.Clear;
sEdit14.ReadOnly:=false;
sEdit15.ReadOnly:=false;
DBLookupComBobox1.ReadOnly:=false;
DBLookupComBobox2.ReadOnly:=false;
DBGrid5.Enabled:=False;
sBitBtn7.Enabled:=False;
sBitBtn8.Enabled:=False;
sBitBtn9.Enabled:=True;
sBitBtn10.Enabled:=True;
sBitBtn11.Enabled:=False;
sBitBtn12.Enabled:=False;
sBitBtn13.Enabled:=False;
sBitBtn14.Enabled:=False;
sBitBtn15.Enabled:=False;
sBitBtn16.Enabled:=False;
DateTimePicker5.DateTime:=Now;
end;
- الزر sBitBtn8 المسمى Modifier
if not FGSM.Table8.IsEmpty then begin
sEdit14.Text:= FGSM.Table8.FieldValues['N_Bon'];
FGSM.Table8.Edit;
FGSM.Table8.FieldValues['N_Bon']:='0';
sEdit14.ReadOnly:=True;
sEdit15.text:=FGSM.Table8.FieldValues['Somme_Versée'];
sEdit15.ReadOnly:=false;
DBLookupComBobox1.ReadOnly:=false;
DBLookupComBobox2.ReadOnly:=false;
DBGrid5.Enabled:=False;
sBitBtn7.Enabled:=False;
sBitBtn8.Enabled:=False;
sBitBtn9.Enabled:=True;
sBitBtn10.Enabled:=True;
sBitBtn11.Enabled:=False;
sBitBtn12.Enabled:=False;
sBitBtn13.Enabled:=False;
sBitBtn14.Enabled:=False;
sBitBtn15.Enabled:=False;
sBitBtn16.Enabled:=False;
sEdit12.Enabled:=False;
end else sBitBtn8.Enabled:=False;
-الزر Valider المسمى sBitBtn9 نكتب:
Var DBL1,DBL2:String;
begin
if (Dblookupcombobox1.Text='') Or (Dblookupcombobox2.Text='') Or
(sEdit14.Text='') Or (sEdit15.Text='')
then showmessage('compliter touts les champs') else
begin
DBL1:= DBLookupComboBox1.Text;
DBL2:= DBLookupComboBox2.Text;
if FGSM.Table8.FindKey( [(sEdit14.text)] ) then begin ShowMessage
('N°_Bon Existe Déjà ,Essayez à Nouveau') ;
if FGSM.Table8.FindKey(['']) then FGSM.Table8.Delete;
sBitBtn7.Enabled:=true;
sBitBtn8.Enabled:=true;
sBitBtn9.Enabled:=False;
sBitBtn10.Enabled:=False;
sBitBtn11.Enabled:=true;
sBitBtn12.Enabled:=true;
sBitBtn13.Enabled:=true;
sBitBtn14.Enabled:=true;
sBitBtn15.Enabled:=true;
sBitBtn16.Enabled:=true;
end else
if (Not FGSM.Table8.FindKey([(sEdit14.text)])) then
begin
FGSM.Table8.Edit;
FGSM.Table8.FieldValues['N_Bon']:=sEdit14.Text;
FGSM.Table8.FieldValues['Code_Client']:=DBL1;
FGSM.Table8.FieldValues['Code_com_C']:=DBL2;
FGSM.Table8.FieldValues['Somme_Versée']:=sEdit15.Text;
FGSM.Table8.FieldValues['Date_Versement']:=DateTimePicker3.DateTime;
FGSM.Table8.Post;
sBitBtn7.Enabled:=true;
sBitBtn8.Enabled:=true;
sBitBtn9.Enabled:=False;
sBitBtn10.Enabled:=False;
sBitBtn11.Enabled:=true;
sBitBtn12.Enabled:=true;
sBitBtn13.Enabled:=true;
sBitBtn14.Enabled:=true;
sBitBtn15.Enabled:=true;
sBitBtn16.Enabled:=true;
sEdit12.Enabled:=True;
sEdit12.SetFocus;
DBGrid5.Enabled:=True;
sEdit14.ReadOnly:=True;
sEdit15.ReadOnly:=True;
DBLookupComboBox1.ReadOnly:=True;
DBLookupComboBox2.ReadOnly:=True;
end;
end;
end;
-الزر Anuler المسمى sBitBtn10 :
FGSM.Table8.Cancel;
sBitBtn7.Enabled:=true;
sBitBtn8.Enabled:=true;
sBitBtn9.Enabled:=False;
sBitBtn10.Enabled:=False;
sEdit12.Enabled:=True;
sEdit12.SetFocus;
sEdit14.Clear;
sEdit15.Clear;
sEdit14.ReadOnly:=True;
sEdit15.ReadOnly:=True;
DBLookupComboBox1.ReadOnly:=True;
DBLookupComboBox2.ReadOnly:=True;
DBGrid5.Enabled:=True;
if FGSM.Table8.IsEmpty then begin
sBitBtn11.Enabled:=False;
sBitBtn12.Enabled:=False;
sBitBtn13.Enabled:=False;
sBitBtn14.Enabled:=False;
sBitBtn15.Enabled:=False;
sBitBtn16.Enabled:=true; end else begin
sBitBtn11.Enabled:=True;
sBitBtn12.Enabled:=true;
sBitBtn13.Enabled:=true;
sBitBtn14.Enabled:=true;
sBitBtn15.Enabled:=true;
sBitBtn16.Enabled:=true end;
-الزر Supprimer المسمى sBitBtn11 :
if not FGSM.table8.IsEmpty then begin
if MessageDLG
('êtes vous sûr de vouloir suprimer l''enregistrement ?'
, MtConfirmation,[MbYes,MbNo],0)=MrYes then
FGSM.Table8.Delete; end else if FGSM.table8.IsEmpty then begin
sBitBtn11.Enabled:=False; sBitBtn12.Enabled:=False;
sBitBtn13.Enabled:=False; sBitBtn14.Enabled:=False;
sBitBtn15.Enabled:=False; sBitBtn16.Enabled:=False; end;
-الزر Vider LaTableالمسمى sBitBtn12
if messageDLG
('cette méthode de suppression conduira à la perte de toutes les données '
,MTinformation,[mbyes,mbcancel],0)
=MRyes then
if messageDLG
('êtes vous sûr de vouloir vider toute les données de la table Bon_Versement ?',MTconfirmation,[mbyes,mbno],0)
=MRyes then
begin sBitBtn11.Enabled:=False;
sBitBtn12.Enabled:=False; sBitBtn13.Enabled:=False;
sBitBtn14.Enabled:=False; sBitBtn15.Enabled:=False;
sBitBtn16.Enabled:=False;
While not FGSM.table8.isEmpty Do
FGSM.table8.Delete; end; -الزر Suivant المسمى sBitBtn13
if Not FGSM.Table8.IsEmpty then begin
FGSM.Table8.Next;
sEdit14.Text:=FGSM.Table8.FieldValues['N_Bon'];
DblookupCombobox1.KeyValue:=FGSM.Table8.FieldValue s['Code_Client'];
DblookupCombobox2.KeyValue:=FGSM.Table8.FieldValue s['Code_com_C'];
sEdit15.Text:=FGSM.Table8.FieldValues['Somme_Versée'];
DateTimePicker3.DateTime:=FGSM.Table8.FieldValues['Date_Versement'];
end; - نفس الشيء بالنسبة الأزرار: Précedent-Début-Fin فقط نكتب مكان Next ما يلزم ( Prior-First-Last)
أخيرا في الخاصية DataSource للـ DBGrid5 نكتب (FGSM.DataSource8) ، و مع نفس العنصر نختار ما يناسب من الأحداث مثل OnKeyDown+UP :
if Not FGSM.Table8.IsEmpty then begin
sEdit14.Text:=FGSM.Table8.FieldValues['N_Bon'];
DblookupCombobox1.KeyValue:=FGSM.Table8.FieldValue s['Code_Client'];
DblookupCombobox2.KeyValue:=FGSM.Table8.FieldValue s['Code_com_C'];
sEdit15.Text:=FGSM.Table8.FieldValues['Somme_Versée'];
DateTimePicker3.DateTime:=FGSM.Table8.FieldValues['Date_Versement'];
.
بالتوفيق.
... / يتبع / ...
nabilkeb
08-02-2010, 05:00 PM
- الجزء 4 من الدرس العاشر
على الفورم FFactureEtStatistique دائما ، نمر إلى الصفحة : Historique Client ،
* على هذه الأخيرة نريد إتاحة امكانية معرفة كل عمليات الشراء التي قام بها زبون معين ، و كذا معرفة مجموع ما دان به ، مرفق بمجموع المبالغ المدفوعة تحت الحساب و بذلك معرفة رصيده الحالي و بما يدين أحدنا للآخر ، كما يمكن إتاحة معرفة حوصلة عمليات الشراء المقيدة بين تاريخين و القيمة المالية لكل هذه العمليات . دون الخوض بالحاجة و الغرض من هذه الإتاحة فهي لأسباب عديدة و معروفة .
نبدأ بعون الله:
نجعل ReadOnly=True لكل من العناصرsEdit8-9-10 .
- سوف نستعمل العنصرين Query6-7 .
قبل كل شيء ، و رغم أنني نبهت في الدرس 4 ، على عدم استعمال اسماء حقول محجوزة في لغة الإستفسار البنيوي (SQL) ، إلا أنني سميت حقل التاريخ في الجدول Vente باسم Date عوضا مثلا عن Date_Vente ، مما سبب لي مشكلة أثناء العمل على Historique Client ، و هو الشيء الذي جعلني أكتشفه . فمعذرة مرة أخرى (و بما أننا مبتدئين أخي الكريم ، فحتى في هذه الأخطاء و العمل على تصحيحها فيه فائدة) .
الحل ببساطة نعدل الجدول بتسمية الحقل بــ (Date_Vente) ، و نعدل هذه التسمية في مكان استعمالها ، و لم نستعملها إلا في الفورم FGSM و FFactureEtStatistique ، يعني كلما وجدنــا ('Date') نغيرها بــ ('Date_Vente') .
- الآن في الخاصية SQL للــ Query6 نكتب :
SELECT *
FROM Vente
Where Code_Client=:Code_Client
and Date_Vente Between :Date01 and :Date02
و في الخاصية Params نحدد : Code_Client و نجعل DataType تأخذ القيمة ftString . و نفس الشيء مع Date01-02 نجعل ftDate .
- الآن في الخاصية SQL للــ Query7 نكتب :
SELECT *
FROM Vente
Where Code_Client=:Code_Client
و من Params نحدد : Code_Client و نجعل DataType تأخذ القيمة ftString.
- في الحدث OnChange للــ sEdit7 :
sEdit12.text:=sEdit7.Text ;
sEdit16.text:=sEdit7.Text ;
sEdit9.text:=sEdit13.Text ;
sEdit8.Text:=sEdit17.text;
if (sCheckBox1.Checked=True) and (sEdit7.text<>'') then begin
Query6.Close;
Query6.ParamByName('Code_Client').Value:=sEdit7.te xt;
DbGrid2.DataSource:=DataSource6;
Query6.Open;
(* Majmoo3eClient_TTC_Date *)
RecordPlaceClient_TTC_Date := Query2.GetBookmark;
MajmoueClient_TTC_Date:=0;
Query6.Active:=true;
Query6.First;
while not Query6.Eof Do
begin
MajmoueClient_TTC_Date:= MajmoueClient_TTC_Date
+Query6.FieldByName('Prix_TTC').AsCurrency;
Query6.Next;
end; sLabel19.Caption:=CurrToStr(MajmoueClient_TTC_Date );
sLabel19.Caption:=FormatFloat('0.00 DA',StrtoFloat(sLabel19.Caption));
if FGSM.Table4.Locate('Code_Client',sEdit7.Text,[ ]) then
sLabel17.Caption:=sEdit7.Text +' / '+FGSM.Table4.FieldValues['Code_Com_C'] else
sLabel17.Caption:='. . . . . . . . . . . . . . . . . . ';
end;
if (sCheckBox1.Checked=False) and (sEdit7.text<>'') then begin
Query7.Close;
Query7.ParamByName('Code_Client').Value:=sEdit7.te xt;
DbGrid2.DataSource:=DataSource7;
Query7.Open;
(* Majmoo3eClient_TTC *)
RecordPlaceClient_TTC := Query7.GetBookmark;
MajmoueClient_TTC:=0;
Query7.Active:=true;
Query7.First;
while not Query7.Eof Do
begin
MajmoueClient_TTC:= MajmoueClient_TTC
+Query7.FieldByName('Prix_TTC').AsCurrency;
Query7.Next;
end; sLabel19.Caption:=CurrToStr(MajmoueClient_TTC);
sLabel19.Caption:=FormatFloat('0.00 DA',StrtoFloat(sLabel19.Caption));
if FGSM.table4.Locate('Code_Client',sEdit7.Text,[ ]) then
sLabel17.Caption:=sEdit7.Text +' / '+FGSM.table4.FieldValues['Code_Com_C'] else
sLabel17.Caption:='. . . . . . . . . . . . . . . . . . ';
end;
- نضغط مرتين على sCheckBox1 : نكتب
if sCheckBox1.Checked=true then begin
sPanel5.Visible:=true; DateTimePicker1.Visible:=true; DateTimePicker2.date:=Now;
DateTimePicker2.Visible:=true; DateTimePicker1.SetFocus; end else
if sCheckBox1.Checked=false then begin
sPanel5.Visible:=false; DateTimePicker1.Visible:=false;
DateTimePicker2.Visible:=false; sEdit7.SetFocus; end;
- في الحدث Onchange للــ DateTimePicker1 نكتب:
Query6.Close;
Query6.ParamByName('date01').AsDate:=DateTimePicke r1.date;
Query6.ParamByName('date02').AsDate:=DateTimePicke r2.date;
Dbgrid2.DataSource:=datasource6;
Query6.Open;
if (sCheckBox1.Checked=true) and (sEdit7.text<>'') then begin
Query6.Close;
Query6.ParamByName('Code_Client').Value:=sEdit7.te xt;
DbGrid2.DataSource:=DataSource6;
Query6.Open;
(* Majmoo3eClient_TTC_Date *)
RecordPlaceClient_TTC_Date := Query6.GetBookmark;
MajmoueClient_TTC_Date:=0;
Query6.Active:=true;
Query6.First;
while not Query6.Eof Do
begin
MajmoueClient_TTC_Date:= MajmoueClient_TTC_Date
+Query6.FieldByName('Prix_TTC').AsCurrency;
Query6.Next;
end; sLabel19.Caption:=CurrToStr(MajmoueClient_TTC_Date );
sLabel19.Caption:=FormatFloat('0.00 DA',StrtoFloat(sLabel19.Caption));
if FGSM.Table4.Locate('Code_Client',sEdit7.Text,[ ]) then
slabel17.Caption:=sEdit7.Text +' / '+FGSM.table4.FieldValues['Code_Com_C'] else
slabel17.Caption:='. . . . . . . . . . . . . . . . . . ';
end;
نجعل الخاصية OnEnter لهذا العنصر تأخذ القيمة DateTimePicker1Change
كما نجعل نفس القيمة للحدث OnChange للـعنصـر DateTimePicker2 .
* أخيرا نعرف عملية حساب المجموع : قبل implementation نكتب :
(*Pour Majmoo3eClient_TTC_Date*) MajmoueClient_TTC_Date: Currency;
RecordPlaceClient_TTC_Date: TBookmark ;
(*Pour Majmoo3eClient_TTC*) MajmoueClient_TTC: Currency;
RecordPlaceClient_TTC: TBookmark ;
* المشروع مرفق ، حاول العمل و تدبر أمورك ، و قارن مع المرفق .
- المطلوب : هناك شبه كامل و واضح بالنسبة لهذا العمل و ما يلزم فعله على الصفحة Historique Fournisseur ، المطلوب استعمال Query8-9 على التوالي و اتمام مايلزم .
بالتوفيق .
.../ يتبــع / ....
nabilkeb
09-02-2010, 09:17 PM
- الجزء 5 و الأخيــــــــــــــر من الدرس العاشر
على الفورم FFactureEtStatistique دائما ، نمر إلى الصفحة : Consultation De Cesse
على هذه الأخيرة نريد إظهار المبلغ الإجمالي لكل المبيعات ، المبلغ الإجمالي لكل الديون ، كل المبالغ المدفوعة ، و عليه نعرف كم يوجد في رصيد مؤسستنا (لهذه الأخيرة أقصد الرصيد نضيف sEdit أخرى ستأخذ الإسم sEdit21 )
- نحدد TabSheet6 و في الحدث OnShow لهذه الأخيرة نكتب :
(* Majmoo3e SommeVentes_Cesse *)
RecordPlaceSommeVentes_Cesse := FGSM.table2.GetBookmark;
MajmoueSommeVentes_Cesse:=0;
FGSM.table2.First;
while not FGSM.table2.Eof Do
begin
MajmoueSommeVentes_Cesse:=MajmoueSommeVentes_Cesse
+FGSM.table2.FieldByName('Prix_TTC').AsCurrency;
FGSM.table2.Next;
end;
sEdit18.Text:=CurrToStr(MajmoueSommeVentes_Cesse);
sEdit18.Text:=formatfloat('0.00',strtofloat(sEdit1 8.Text))+' DA';
(* Majmoo3e SommeDettes_Clients *)
RecordPlaceSommeDettes_Clients := FGSM.table7.GetBookmark;
MajmoueSommeDettes_Clients:=0;
FGSM.table7.First;
while not FGSM.table7.Eof Do
begin
MajmoueSommeDettes_Clients:=MajmoueSommeDettes_Cli ents
+FGSM.table7.FieldByName('Valeur_Reste').AsCurrenc y;
FGSM.table7.Next;
end;
sEdit19.Text:=CurrToStr(MajmoueSommeDettes_Clients );
sEdit19.Text:=formatfloat('0.00',strtofloat(sEdit1 9.Text))+' DA';
(* Majmoo3e SommeVersements_Clients *)
RecordPlaceSommeVersements_Clients := FGSM.table8.GetBookmark;
MajmoueSommeVersements_Clients:=0;
FGSM.table8.First;
while not FGSM.table8.Eof Do
begin
MajmoueSommeVersements_Clients:=MajmoueSommeVersem ents_Clients
+FGSM.table8.FieldByName('Somme_Versée').AsCurrenc y;
FGSM.table8.Next;
end;
sEdit20.Text:=CurrToStr(MajmoueSommeVersements_Cli ents);
sEdit20.Text:=formatfloat('0.00',strtofloat(sEdit2 0.Text))+' DA';
sEdit21.Text:=floattostr(strtofloat(CurrToStr(Majm oueSommeVentes_Cesse))
- (strtofloat(CurrToStr(MajmoueSommeDettes_Clients))
- strtofloat(CurrToStr(MajmoueSommeVersements_Client s)) ));
sEdit21.Text:=FormatFloat('0.00',StrToFloat(sEdit2 1.Text))+' DA';
قبل implementation نكتب :
(* Majmoo3e SommeSommeVentes_Cesse *) MajmoueSommeVentes_Cesse: Currency;
RecordPlaceSommeVentes_Cesse: TBookmark ;
(* Majmoo3e SommeDettes_Clients *) MajmoueSommeDettes_Clients: Currency;
RecordPlaceSommeDettes_Clients: TBookmark ;
(* Majmoo3e SommeVersements_Clients *) MajmoueSommeVersements_Clients: Currency;
RecordPlaceSommeVersements_Clients: TBookmark ;
* - المطلوب : هناك شبه كامل و واضح بالنسبة لهذا العمل و ما يلزم فعله على الصفحة Historique Fournisseur ، المطلوب استعمال Query8-9 على التوالي و اتمام مايلزم .
المطلوب رفقة ما تقدم طرحه ، كل شيء بالمرفقات.
في المرة القادمة نبدأ في الطباعة .
بالتوفيق.
.../ يتبع / ....
nabilkeb
13-02-2010, 06:06 PM
السلام عليكم و رحمة الله تعالى و بركاته : هذا الجزء رقم 11 أو الدرس الحادي عشر و الأخير من مشروع انجاز برنامج لتسيير المخزون و التسويق (GSM) .
الجزء1
الموضوع : الطباعة
للطباعة هناك عدة تقارير منها ماهو مجاني و منها العكس ، منها ماهو صعب و منها العكس ، و لعل أشهرها و أبسطها (و مجاني أيضا_مرفق مع الدلفي) هو QuickRep ، يأتي مع دلفي6 بشكل أوتوماتيكي بعد التنصيب ، و مع دلفي7 يتم إضافته.
الآن لدينا عدة أمور حسب مشروعنا تتطلب الطباعة أما أنا فسأكتفي بطباعة شيء واحد أو إثنين ، و الباقي بنفس الأسلوب هو مهمتك أنت.
سنقوم باتاحة امكانية طباعة الفاتورة.
نقوم أولا بانشاء فورم جديد نسميه ( FPrintFacture ) و احفظ السورس الخاص بها تحت نفس الإسم مع تبديل أول حرف F بــ U .على هذا الفورم أو الصفحة نضيف QuickRep1 ، نحدد هذا الأخير و نذهب للخواص ، هناك عدة خواص أهمها و التي سنستخدمها :
1- الخاصية Bands :
تضم هذه الأخير ستة أقسام للصفحة المراد طباعتها ، نقوم بتفعيلها كلها إلا الأخير (HasTiltle) ، إذن نفعل خمسة:
- HasPageHeader هذه الأخيرة أو En-Tete de page هي القسم العلوي من صفحة الطباعة و التي ستبقى تظهر في كل صفحات الطباعة يعني هذا القسم سنقوم عليه باضافة معلومات المؤسسة من هاتف و اسمها التجاري و العنوان و غير ذلك و ممكن اسم الزبون و رقم الفاتورة و التاريخ لنستطيع تمييز الصفحة الثانية بأنها تابعة للأولى فلا تختلط الأمور ، فإذا اشترى الزبون سلعا كثيرة في فاتورة واحدة حيث تمثلت الطباعة في صفحتين يبقى رأس الصفحة هذا يتكرر في الصفحة الأولى و كل مايليها من صفحات مطبوعة .
HasColumnHeader : أو En-Tete de colonne : من تسمية هذا الأخير فهو واضح مثل الذي سبق و لكن يخص هذا عنوان الحقل في الجدول و يتكرر أيضا في كل الصفحات .
- HasDetail : هو جسم و تفاصيل الصفحة يعني يربط مع محتويات الحقول في الجدول المراد طباعتها .
- HasSummary يعني الخلاصة Résumé و في هذا القسم نضع المبلغ الإجمالي و ما إلى ذلك و لا يظهر هذا القسم أثناء الطباعة إلا في الصفحة الأخيرة ، سواء كانت الطباعة متمثلة في صفحة أو أكثر .
- HasPageFooter يعني Bas de Page أسفل الصفحة و يتكرر هذا القسم في كل الصفحات مثل الأول الذي يتكرر بالأعلى ، هذا يتكرر بالأسفل و نضع فيه رقم الصفحة .
كان هاذا عن الخاصية Bands ، الآن تملئ هذه الأقسام كل حسب مايراه و يقوم بالتجميل و كأنه في الوارد باستعمال العناصر مثلا : QRLabel-QRDBtext- QRShape ، و لكي لا نخوض في كل شيء هذا المرفق أدناه به مشروع من فورم واحد فقط و يحتوي تقرير الطباعة يمكنك عمل مثله أو بزيادة فيه حسب ماتره مناسبا ، لكن المهم نتفق على تسمية العناصر باللون الأحمر و الأزرق نثل التي عندي ، لكي لا نختلف على أسمائها أثناء البرمجة.
http://i46.tinypic.com/21cysf8.jpg
إذا كنت متمكنا من الأمر (تقريري كويكراب) يمكنك نسخه مباشرة بتحديده و الصاقه في مشروعنا على الصفحة أو الفورم FPrintFacture .
بالتوفيق
.../ يتبع /....
nabilkeb
15-02-2010, 10:30 AM
السلام عليكم و رحمة الله تعالى و بركاته : هذا الجزء رقم 11 أو الدرس الحادي عشر و الأخير من مشروع انجاز برنامج لتسيير المخزون و التسويق (GSM) .
الجزء 2
لازلنـا مع طباعة الفاتورة ، طيب الآن العنصر QuickRep1 يتعلق بالفاتورة ، و بيانات الفاتورة نجدها بكل تأكيد بــجدول المبيعات Vente و الذي جعلنا له في الفورم FFactureEtStatistique العنصر Query1 ، و على هذا يتوجب ربط QuickRep1 مع هذا الأخير ، يعني الخاصية DataSet للعنصر QuickRep1 نعطيها القيمة:
FFactureEtStatistique.Query1 لدينا العناصر QrLabel اسمها يدل عليها ، هي مثل العناصر Label فقط هي خاصة بـ Quickrep ، و لدينا العناصر QrDBText اسمها أيضا كفيل بشرحها يعني هي خاصة بـ QuickRep و هي متعلقة بقاعدة البيانات (DB يعني DataBase) و على هذا فهذه الأخيرة يتوجب ربها مع قاعدة معينة ، و بكل تأكيد يتم ربطها كما تم مع QuickRep1 عن طريق الخاصية DataSet و نعطيها نفس القيمة :
FFactureEtStatistique.Query1 يكون هذا مع كل العناصر الستة (QrDBText) و نحدد حقل كل واحد الذي يختلف عن غيره / مثلا QrDBText1 الذي يمثل رقم الفاتورة نعين الخاصية DataField باعطائها القيمة:
DataField=N_Fact و نفس الشيء مع البقية .
ملاحظة : لانكتب يدويا N_Fact ، فقط بمجرد تحديد قيمة DataSet ، نتمكن بــ DataField من رؤية كل الحقول المتضمنة ، و سنجد حتمــا الحقل N_Fact أو إذا سميته باسم غير ذلك فستجده ، المهم تقوم بتحديد الحقل المناسب ، و إن لم تظهر الحقول فتفقد الخلل ، هذا لنكون منهجيين و نتدارك الخلل في حينه .
- بعد اتمام ما سلف نحدد العنصر QuickRep1 و من الحدث OnStartPage نكتب :
QrLabel001.Caption:=FFactureEtStatistique.query1.f ieldbyname('Date_Vente').AsString;
QrLabel002.Caption:=formatdatetime('yy',now)+' / ';
QrLabel003.Caption:=FFactureEtStatistique.query1.f ieldbyname('Code_Client').AsString;
QrLabel004.Caption:=FFactureEtStatistique.query1.f ieldbyname('Code_Com_C').AsString;
QrLabel005.Caption:= FFactureEtStatistique.sEdit2.text +' DA';
QrLabel006.Caption:= FFactureEtStatistique.sEdit3.text +' DA';
QrLabel007.Caption:= FFactureEtStatistique.sEdit4.text +' DA';
QrLabel008.Caption:=formatfloat('0.00',strtofloat( FFactureEtStatistique.sEdit5.text)) +' DA' ;
QrLabel009.Caption:=formatfloat('0.00',strtofloat( FFactureEtStatistique.sEdit6.text)) +' DA' ;
QrLabel010.Caption:=FFactureEtStatistique.Memo1.te xt; - في الزر sBitBtn2 الذي أعطيناه الكابشن Apercu L'impression ، في الفورم FFactureEtStatistique نكتب :
FPrint_Facture.QuickRep1.Preview; لعرض تقرير الطباعة (موضوع العمل) .
- هذا ببساطة تقريبا كل شيء عن طباعة الفاتورة ، جرب لترى (قم ببيع مواد معينة لفاتورة جديدة بملأ الحقول ، ثم جرب موضوع الطباعة) .
المشروع إلى هذه المرحلة مرفق (فقط ملاحظة السكين و مجلد قواعد البيانات غير مرفق _ نظرا لادراجه مسبقا و تقليصا في حجم المرفق).
بالتوفيق.
.../ يتبع / ....
kachwahed
17-02-2010, 07:34 PM
السلام عليكم ورحمة الله
بارك الله لك أخي نبيل
مجهودك رائع يثمر عن موضوع أروع :)
كمساهمة صغيرة، رأيت في التقرير عبارة:
Arrêter la présente facture à la somme de:
أحسن ما وجدت لتحويل الأرقام إلى حروف (بالفرنسية) هذه الدالة:
function NombreEnLettres(n: Integer): string;
Const
unite: array [1 .. 19] of string = ('un', 'deux', 'trois', 'quatre', 'cinq',
'six', 'sept', 'huit', 'neuf', 'dix', 'onze', 'douze', 'treize',
'quatorze', 'quinze', 'seize', 'dix sept', 'dix huit', 'dix neuf');
dizaineF: array [2 .. 9] of string = ('vingt', 'trente', 'quarante',
'cinquante', 'soixante', '', 'quatre-vingt', '');
dizaineB: array [2 .. 9] of string = ('vingt', 'trente', 'quarante',
'cinquante', 'soixante', 'septante', 'octante', 'nonante');
coefs: array [0 .. 3] of string = ('cent', 'mille', 'million', 'milliard');
Var
temp: String;
c, d, u: Integer;
coef: Integer;
I: Integer;
neg: Boolean;
Begin
Result := '';
// Cas particulier de zéro
If n = 0 then
begin
Result := ' zero';
Exit;
end;
// Mémorisation du signe
neg := n < 0;
If neg then
n := -n;
coef := 0;
Repeat
// Récupération de l'unité du bloc de trois chiffres en cours
u := n mod 10;
n := n div 10;
// Récupération de la dizaine du bloc de trois chiffres en cours
d := n mod 10;
n := n div 10;
// Traitement des dizaines
temp := '';
// Passage sur la dizaine inférieure pour 10 à 19
// et pour 70-79 90-99 dans le cas de la France
If (d = 1) Or ((d in [7, 9])) then
begin
Dec(d);
Inc(u, 10);
end;
if d > 1 then
begin
temp := ' ' + dizaineF[d];
// Ajout du cas particulier de 'et' entre la dizaine et 1
if (d < 8) and ((u = 1) or (u = 11)) then
temp := temp + ' et';
end;
// ajout du texte de l'unité
if u > 0 then
temp := temp + ' ' + unite[u];
// ajout du 's' à Quatre-vingt si rien ne suit
If (Result = '') and (d = 8) and (u = 0) then
Result := 's';
Result := temp + Result;
// Récupération de la centaine du bloc de trois chiffres en cours
c := n mod 10;
n := n div 10; { Récupère centaine }
If c > 0 then
begin
temp := '';
if c > 1 then
temp := ' ' + unite[c] + temp;
temp := temp + ' ' + coefs[0];
// Traitement du cas particulier du 's' à cent si rien ne suit
If (Result = '') and (c > 1) then
Result := 's';
Result := temp + Result;
end;
// Traitement du prochain groupe de 3 chiffres
if n > 0 then
begin
Inc(coef);
I := n mod 1000;
If (I > 1) and (coef > 1) then
Result := 's' + Result;
If I > 0 then
Result := ' ' + coefs[coef] + Result;
// Traitement du cas particulier 'mille' ( non pas 'un mille' )
If (I = 1) and (coef = 1) then
Dec(n);
end;
until n = 0;
Result := Trim(Result);
// Ajout du signe en cas de besoin
if neg then
Result := 'moins ' + Result;
End;
المميز فيها مراعاة دقيقة للقواعد النحوية الفرنسية والحالات الخاصة.
أيضا السرعة واختصار في الكود، غير أنها لا تأخذ الفواصل في الحسبان
المصدر: Developpez.com بتصرف (حذفت الجزء المتعلق بحالة استثنائية للفرنسيين).
ملاحظة: طرح أسئلتك في قسم الأسئلة، وأي سؤال خارج عن الموضوع هنا سيحذف، كما قد تحذف المشاركات التي لا تضيف إلى الموضوع
بالتوفيق أخي نبيل.
nabilkeb
17-02-2010, 08:11 PM
السلام عليكم و رحمة الله تعالى و بركاته :
أخي العزيز أتينا الآن إلأى نهاية الطرح للدروس الخاصة بموضوعنا هذا ، و قد تتساءل أن المشروع غير مكتمل بعد؟
الجواب : تركت لك المبادرة بعد أن تم التعرف على الأساسيات لذلك ، فمثلا في موضوع الطباعة ، بعد تعرضنا لكيفية طباعة الفاتورة ، و شرح تقرير الطباعة المستخدم ، أكيد أنه صار بوسعك إكمال ماتبقى في هذا الشأن.
ملاحظة أخرى ممكن بشأن خاصية ملئ الشاشة و العكس في القائمة على الصفحة الرئيسية ، في هذا الصدد ممكن أن أدلك على هــــذا الرابط (http://www.delphi4arab.com/forum/showthread.php?t=1828&highlight=%C7%E1%D4%C7%D4%C9)الذي سيغنيك عن أي طرح و شرح .
- لكتابة الصيغة الحرفية لمجموع قيم الحقول العددية (Memo1+2 في فورم الفاتورة) إليك هذا الرابط (http://www.delphi4arab.com/forum/showthread.php?t=1174&highlight=Centaine)
ممكن أضيف نقطة أخرى مثلا جعل كل أو بعض الصفحات تتطلب كلمة مرور للعرض ، مثلا و تكون كلمة المرور تختلف عن غيرها ، يعني أنت مثلا يستعمل هذا البرنامج موظف لك لا تريده أن يطلع على صفحة الممونين أو صفحة المواد (المخزن) التي تتضمن تفاصيل الشراء و سعر شراء كل مادة ( مثال عن هذا الأمر بالذات بسيتم إرفاقه قريبا ) ، و ممكن تريد .... و تريد ....
أقول لك أخي الكريم لا يمكن لأحد الإحاطة بكل الإحتمالات الواردة و كل الإحتياجات إلا أنت في حد ذاتك ، لماذا ؟ بكل بساطة لأنك الأدرى بما تحتاج إليه و ماهو مطلوب منك لتضعه في يد زبونك.
أقصد أن نقطة البداية الحقيقية لك بدأت الآن و لابد لزاما أن تشمر عن ساعديك للجد و العلم و العمل .
الشيء الذي سيكون خاتمة الموضوع بالنسبة لي لأفسح المجال للأعضاء و الإخوة الأعزاء في إبداء آرائهم و نصائحهم و ملاحظاتهم و كذا العيوب و الأخطاء و تصحيحها ، لنتعلم منهم و تعم الفائدة ، هو البداية مني على عجالة بطرح ملاحظة أو تعليق هام :
- قواعد البيانات:
ممكن أهم ملاحظة أطرحها تتمثل في تكرار واضح في حقول الجداول من عير فائدة.
طيب سأعطي مثال للتضح الفكرة و تفهم أخي ماعليك عمله لتحصد فوائد لبرنامجك أهمها سرعة البرنامج خصوصا أثناء البحث و كذا توفير مساحة التخزين و التقليل من نسبة الوقوع في الخطأ.
المثــال: ليكن لدينا جدول للكتب بمشروع تسيير مكتبة مثلا ، به 3 حقول هي : رقم الكتاب-اسم الكتاب-اسم المؤلف . وجدول آخر للمؤلفين يتكون من حقلين : رقم المؤلف - اسم المؤلف .
سنركز على الجدول الأخير و كذا الحقل الأخير بالجدول الأول.
أثناء استغلال قاعدة البيانات ، تلاحظ أنه عليك أولا تحديد المؤلفين بالجدول الثاني ، بالنسبة للجدول الأول أي كتاب تقوم بادراجه يتطل منك الأمر كتابة اسم المؤلف لهذا الكتاب على أن يكون المؤلف ضمن المؤلفين لديك بالجدول الثاني .
ماذا نلاحظ : أولا حقل المؤلف في كلا الجدولين هو من النوع النصي ، يعني لابد عليك كتابة الإسم الكامل للمؤلف أثناء إدراجك لكتاب ما بالجدول الأول ، و مع العلم أنه يحتمل أن يكون لديك عدة كتب للمؤلف الواحد فإنه عليك في كل مرة كتابة اسم المؤلف ، ماذا سيترتب عن هذا ؟
- احتمال الوقوع في الخطأ : إذا كان لديك مثلا المؤلف (طه حسين) فإنك ستكرر كتابة هذا الإسم عدد الكتب التي لديك له ، و أيضا في كل مرة تقتني كتابا لهذا المؤلف ، ما يقربك للخطأ فتكتب مثلا (طه حسن) . افرض معي أنك اعتقدت أن اسمه كذلك و كررت هذا الإسم الخاطئ في كل كتبه ، كم من سجل عليك تعديل اسم المؤلف فيه ؟
- بطئ البحث في قاعدة البيانات: معلوم أن البحث في الحقول العددية أسرع منه في الحقول النصية ، ستقول و ما دخل هذا الأمر مادام لزوما سيكون اسم المؤلف من النوع النصي ؟ لكن تابع معي لتتضح الفكرة و الغاية .
- استهلاك مساحة تخزين أكبر : للعلم أنه فب الحقل النصي كل حرف يخزن في بايت واحد ، يعني (طه حسين ) 7 بايت باعتبار الفراغ ، و لو تكرر هذا الإسم معنـا 20 مرة مثلا فستكون مساحة التخزين 140 بايت ، بينما تخزين رقم يصل إلى 32000 يحتاج إلى 2 بايت فقط ، و لكن الأمر لن يقتصر على هذه الملاحظة فحسب لأن الحقل النصي لا بد أن تحجز له مثلا 25 حرفا ، مما يعني 25 بايت ، و إذا كان لديك بالمكتبة 2000 كتاب مثلا فستكون المساحة 2000*25 = 50000 بايت ، بينما لو كان الحقل عددي (2000*2 = 4000بايت) فقط ، و الفرق واضح.
* الحل ببساطة في الجدول الأول اسم المؤلف نجعله رقم المؤلف (حقل عددي) ، بحيث نكتب اسم المؤلف مرة واحدة بجدول المؤلفين ، و بجدول الكتب يتكرر المؤلف على اعتبار رقمه بجدول المؤلفين فقط ، يعني يربط كلا الجدولين عن طريق هذا الحقل ( و للطريقة و المزيد ابحث بالمنتدى) و هذه الطريقة تعرف بالتطبيع Normalization .
إذا استوعبت المثال و الفكرة فبامكانك التمعن في قواعد البيانات لمشروعنــا هذا ، و ستعرف ما عليك فعله .
و أكيد أن هناك ملاحظات و تعقيبات أخرى ، أفضل كرم الإخوة معنا هنا ، أو في في أقسام أخرى كما ترى إدرة المنتدى .
nabilkeb
23-02-2010, 05:15 PM
ماهذا الخمول يا إخوان ، لم يتكرم إلى حد الساعة أحد بتدخلات و تعقيبات نافعة .
ليس كل الإخوة بطبيعة الحال ، لكني أرى الكثير لا يدخل و يتصفح إلا بحثا عما ينفعه و يريده فقط ، رغم أنه بوسعه أن ينفعنا بتدخلات و ملاحظات قيمة .
أتمنى ممن رأى في هذا العمل مجهودا ، أن يتفضل و يتكرم بالمشاركة.
Anter2010
24-02-2010, 02:45 PM
السلام عليكم و رحمة الله تعالى و بركاته
اخي نبيل اردت فقط المشاركة و شكرك على مجهودك
اطلعت على برنامجك و اردت اضافةهذا الكود الخاص بالتفقيط
Function Convert_ch_let(chiffre: real; SM: String): string;
var tab_1_19 : array[0..19] of string[10];
tab_20_90: array[2..9] of string[20];
tab: array[1..5] of string[10];
ch_int: string[20];
ch, ch_r: string;
i, fin_I : integer;
Function result_1_99(ch: string): string;
begin
result_1_99 := '';
case strtoint(ch) of
0..19 : result_1_99 := tab_1_19[strtoint(ch)];
20..99 : case strtoint(ch) of
20,30,40,50,60: result_1_99 := tab_20_90[strtoint(copy(ch,1,1))];
21,31,41,51,61: result_1_99 := tab_20_90[strtoint(copy(ch,1,1))] + ' et' + tab_1_19[strtoint(copy(ch,2,1))];
80: result_1_99 := tab_20_90[strtoint(copy(ch,1,1)) ];
70..79 : result_1_99 := tab_20_90[strtoint(copy(ch,1,1)) - 1] + '-' + copy(tab_1_19[strtoint(ch) - 60],2,length(tab_1_19[strtoint(ch) - 60]) -1);
81..89 : result_1_99 := tab_20_90[strtoint(copy(ch,1,1)) ] + '-' + copy(tab_1_19[strtoint(ch) - 80],2,length(tab_1_19[strtoint(ch) - 80]) -1);
90..99 : result_1_99 := tab_20_90[strtoint(copy(ch,1,1)) - 1] + '-' + copy(tab_1_19[strtoint(ch) - 80],2,length(tab_1_19[strtoint(ch) - 80])-1 );
else
result_1_99 := tab_20_90[strtoint(copy(ch,1,1))] + '-' + copy(tab_1_19[strtoint(copy(ch,2,1))],2,length(tab_1_19[strtoint(copy(ch,2,1))]) -1);
end;
end;
end;
begin
if length(floattostr(int(chiffre))) > 15 then // s'il y a autre chose après le Billion, alors remplacer le 15 par 18
begin
messagedlg('Valeur incorrecte ',mtinformation,[mbok],0);
exit;
end;
tab_1_19[0] := '';
tab_1_19[1] := ' un'; tab_1_19[2] := ' deux'; tab_1_19[3] := ' trois';
tab_1_19[4] := ' quatre'; tab_1_19[5] := ' cinq'; tab_1_19[6] := ' six';
tab_1_19[7] := ' sept'; tab_1_19[8] := ' huit'; tab_1_19[9] := ' neuf';
tab_1_19[10] := ' dix'; tab_1_19[11] := ' onze'; tab_1_19[12] := ' douze';
tab_1_19[13] := ' treize'; tab_1_19[14] := ' quatorze'; tab_1_19[15] := ' quinze';
tab_1_19[16] := ' seize'; tab_1_19[17] := ' dix-sept'; tab_1_19[18] := ' dix-huit';
tab_1_19[19] := ' dix-neuf';
tab_20_90[2] := ' vingt'; tab_20_90[3] := ' trente'; tab_20_90[4] := ' quarante';
tab_20_90[5] := ' cinquante'; tab_20_90[6] := ' soixante';
tab_20_90[7] := ' soixante-dix'; tab_20_90[8] := ' quatre-vingt'; tab_20_90[9] := ' quatre-vingt-dix';
tab[1] := ' cent';
tab[2] := ' mille';
tab[3] := ' million';
tab[4] := ' milliard';
tab[5] := ' billion';
ch_int := floattostr(int(chiffre));
ch_r := '';
fin_i := length(ch_int) div 3;
if length(ch_int) > fin_i * 3 then
begin
ch := copy(ch_int,1, length(ch_int) - fin_i * 3);
ch_r := result_1_99(ch);
if (strtoint(ch) = 1) and (fin_i = 1) then
ch_r := tab[fin_i + 1]
else
if length(ch_int) > 2 then
ch_r := ch_r + tab[fin_i + 1];
end;
For i := fin_i downto 1 do
begin
ch := copy(ch_int, length(ch_int) - i * 3 + 1 , 3);
case strtoint(copy(ch,1,1)) of
0: ch_r := ch_r + result_1_99(copy(ch,1,1)); // dans le cas 0, on peut remplacer result_1_99(copy(ch,1,1)) par une chaine vide. C'est à dire ch_r := ch_r + '';
1: ch_r := ch_r + tab[1]; // là aussi on peut mettre cent à la place de tab[1]
else
ch_r := ch_r + result_1_99(copy(ch,1,1)) + tab[1];
end;
if (i = 2) and (strtoint(ch) = 1) then // pour le cas de: par ex 125001489
ch_r := ch_r + copy(result_1_99(copy(ch,2,2)),3,length(result_1_9 9(copy(ch,2,2))) - 3 )
else
ch_r := ch_r + result_1_99(copy(ch,2,2));
if (i > 1) and (strtoint(ch) > 0) then
ch_r := ch_r + tab[i];
end;
if SM <> '' then
begin
ch_r := Uppercase(copy(ch_r,2,1)) + copy(ch_r,3,length(ch_r) - 2) + SM;
if frac(chiffre) > 0 then
ch_r := ch_r + ', et ' + copy(floattostr(frac(chiffre) + 1.005 ),3,2) + ' cts.';
// le 1.005 pour obtenir le bon resultat, enlever le et essayer avec les montants suivants: par ex 15,20 ou 147,50
end;
Convert_ch_let := ch_r;
end;
procedure TForm1.DBEdit1Change(Sender: TObject);
begin
If (DbEdit15.text = '') then // si la chaine S est vide Erreur
begin
Application.MessageBox('Veuillez Saisir une somme d''abord.', 'Erreur: Rien à convertir !',mb_IconError+mb_Ok);
end
else
DbEdit17.text := Convert_ch_let(strtofloat(DbEdit15.text),' Dinars');
end;
end.
justnick
25-02-2010, 02:45 PM
السلام علكيم ورحمة الله وبركاته
تحية طيبة وبعد
شرح وافى وقوى جدا
حاولت ان استخدم مكون الskins المرفق فى بداية المشروع ولكن بشتى الطرق لم يعمل معى الا بعد ان قمت بتنزيل النسخة الجديدة هذه:
http://www.alphaskins.com/sfiles/alite.zip
اشكرك جدا انا بدات اتابع الموضوع وربنا يسهل ان شاء الله ويكون فيه استفسارات ومشركات قد تكون فعالة
ما يؤخرنى هو انى لا اجيد الفرنسية
ولكن مع البحث واستخدام المترجمات قد نصل الى المراد
شكرا لك حبيب قلبى واتمنى ان يكون هناك قاعدة بيانات portable لتسهيل نقل البرامج
شكرا لك وان شاء الله لنا عودة
justnick
25-02-2010, 04:57 PM
السلام عليكم ورحمة الله وبركاته
تحية طيبة وبعد
وصلت الى ربط قاعدة البانات وكل شئ على ما يرام (انشات جدول للمنتجات فقط وذلك لصعوبة الترجمة من الفرنسية لاسماء الحقول )
تظهر لكل كل الجداول تقوم بتحديد produit.db ، و أخيرا active تعطيها true .
هل يعنى هذا اننا بمجرد نقل الملف التنفيزى ووضع قاعدة البيانات فى المسار المحدد مسبقا هل سيعمل بدون الحاجة الى تثبيت برامج اضافية تهتم بقاعدة البيانات الخاصة بنا ؟؟
انتظر منك الاجابة
nabilkeb
25-02-2010, 06:49 PM
سيعمل بجهازك فقط ، لتوفر محرك قواعد البيانات ، و أي جهاز آخر لا يتوفر عليه ، لن يعمل
قضية إنشاء setup للبرنامج (تجميعه ليصبح يتنصب في أي جهاز و يعمل عادي ) هذا أمر آخر ، ابحث في المنتدى عن
InstallShield
بالتوفيق
omf_12000
26-02-2010, 12:02 PM
السلام عليكم ورحمة الله وبركاته
الأخ الكريم: nabilkeb
تحية طيبة وبعد
أحييك على المجهود الممتاز الذي بذلته في إعداد هذه الدروس القيمة، وأتمنى لك التوفيق. فعلا مجهود تشكر عليه بارك الله فيك وجعله في ميزان حسناتك يوم القيامة.
وأتمنى أن تسمح لي بإعادة نشر هذه الدروس في منتدى "الهندسة نت" حيث أني أقوم حاليا بنشر سلسلة "دروس في البرمجة بلغة دلفي بالصوت والصورة". وأعتقد أن هذا الموضوع سوف يسهم في نشر الثقافة والفائدة على مدى أوسع في المنتديات العربية، هذا مع المحافظة على الأمانة في النقل وذكر المصدر.
وفي الختام تقبلوا فائق التقدير والإحترام
تحياتي...!
O. M. Fares
nabilkeb
26-02-2010, 12:38 PM
أجل أخي الكريم ، نحن لا يهمنا سوى التعلم و التعليم و نشره ، و إفادة غيرنا ، لكن و مع ذكر المصدر لابأس بل و بالتوفيق ، فقط أنبه بالتأني ، لعل الإخوة أصحاب الخبرة تكون لهم تداخلات قيمة و مفيدة للموضوع . فيكون نقلك أكثر فائدة.
بالتوفيق
medreg
27-02-2010, 02:09 PM
جزاكم الله عنا كل خير
إنه فعلا لعمل رائع ويستحق المتابعة والتدقيق
اخي
عندما حاولت تنفيذه
اشار الى ان الكلمة FPostion الموجودة في هذا السطر
DbGrid1.Height:=sScrollBar1.FPosition;
غير مصرح بها
ما المشكل في هذا
DbGrid1.Height:=sScrollBar1.FPosition;
نكتب
DbGrid1.Height:=sScrollBar1.Position;
الخطأ هو زيادة حرف F
يجب ان يحذف
nabilkeb
27-02-2010, 02:54 PM
أجل هو كذلك، الخلل بإضافة حرف F ، الخاصية هي Position و ليس FPosition .
بالتوفيق.
hichem123
30-05-2010, 01:55 PM
شكرا جزيلا أخي شرح جميل و كامل
لكن وجدت مشكل في table7
مرة لا يوجد date لقد قمت بتغييره بـ date_vente لكن لاجدوى و مرة index table7 لايوجد
هل ممكن إعادة البرنامج مع كامل المرفقات كي يتسنى لي فهمه بالإضافة الى انني مبتدأ و يجب ان اتعلم
S.FATEH
15-07-2010, 01:04 PM
السلام عليكم
عفوا لوصولي متأخر
لقد استعملت طريقة الـ Splash الموجودة ف هذا الموضوع لكنها ناقصة
procedure TFsplash.Timer1Timer(Sender: TObject);
begin
sGauge1.progress:=sGauge1.progress+1;
if sGauge1.progress=100 then begin
FGSM.Show;
Fsplash.hide;
timer1.Enabled:=false
end ;
end;
لان عند ظهور الفورم الثاني و عند عمل reduire ( _ ) الفورم لا يذهب الى الاسفل و انما الى اقصى يسار
النافذة
لانه لا يعتبر الفورم الرئيسي
حاولت جعله الفورم الرئيسي
بواسطة
application.MainForm
لكن لم افلح
لذلك قمت بانشاءه
Pbar.Position:=PBar.Position+1;
if Pbar.Position = 100 then
begin
Timer1.Enabled:=false;
Form5.Destroy;
Application.CreateForm(TForm1,Form1);
Form1.Show;
end;
و نجح الامر لكن اعتقد يوجد طرق اخرى ....بدل من استعمل
Application.CreateForm(TForm1,Form1);
سلامي
ma_7odaa
04-08-2010, 01:12 PM
كل ماأعمل رن للبرنامج يظهرلى رسالة
[Fatal Error] Usplash.pas(8): File not found: 'sCustomLabel.dcu'
kachwahed
04-08-2010, 01:32 PM
@ma_7odaa
يجب تثبيت المكونات اللازمة لتشغيل البرنامج.
kachwahed
05-08-2010, 05:04 AM
يبدو أنه يستخدم نسخة دلفي أخرى.
...
المهم سأعلق على الموضوع
أولا آسف على التأخير الشديد عن المشاركة من البداية لأنشغالي بأمور أخرى...
ما سأذكره من التعليقات هو وجهة نظر شخصية ولا تعني بالضرورة وجود خطأ من أي نوع. لن أعلق على كل نقطة وسأكتفي بالتعليق على (فيما أراه من) أهم النقاط.
لأن تصميم البرامج الأعمال التجارية عموما وبرامج التسيير التجاري خصوصا من أعقد أنواع البرامج، لا تكاد تجد برنامج متكامل يتأقلم مع كل أنواع التعاملات التجارية ويلبي احتياجات جميع المحلات/الشركات التجارية.
لذلك لا يمكن اعتبار هذا النموذج ولا غيره من النماذج، نموذجا متكاملا يصلح لتسيير كل نشاط تجاري. هذا بغض النظر عن التفاصيل الكثيرة التي قد يحتاجها (أو يجب إضافتها إلى) البرنامج.
ـ لدينــا مخزن للسلع ، و عليه فنحن بحاجة لإنشاء جدول خاص لذلك ، يتكون من :
صحيح وخطأ!
صحيح، نحن بحاجة إلى جدول لتخزين الأصناف (السلع/المنتجات... أيا كان)، لكن ليس لأجل أن لدينا مخزون للسلع...
عملية تصميم نموذج قاعدة بيانات تتطلب تفاصيل أعمق ولا تأتي من استنتاج بديهي
باختصار... للاستزادة ينظر: الأسس العلمية لتصميم نماذج قواعد البيانات العلائقية (http://www.delphi4arab.com/forum/showpost.php?p=17982&postcount=2).
طبعا، الأخ نبيل (جزاه الله خيرا) لا يمكنه تفصيل كل شيء في هذا الموضوع لذلك فهو يختصر.
رمز أو كود الممون الذي نشتري منه السلع / الاسم التجاري للممون ...
في هذه الحالة سيخزن الاسم التجاري للممون في جدول السلع من جهة، وفي جدول الممولين من جهة أخرى...
=> إزدواجية في التخزين => خطأ في تصميم النموذج
=> الحل: الاكتفاء بإضافة رمز (أو كود) الممون وجلب اسمه التجاري من مصدره بحقل Lookup
نفس الملاحظة هنا أيضا:
رقم الفاتورة / رمز الزبون / الاسم التجاري للزبون / تاريخ الفاتورة .
نفس الملاحظة في جدول تفاصيل فاتورة البيع وجدول تفاصيل فاتورة الشراء...
أيضا لا أدري ما وظيفة هذه الحقول في جدول تفاصيل الشراء:
- الحد الأدنى للكمية
- الحد الأدنى لسعر البيع
وإذا كان المقصود ما ورد في جدول الأصناف (المواد) فهذه ازدواجية أيضا تجب إزالتها.
kachwahed
05-08-2010, 05:15 AM
ملحوظة صغيرة بخصوص تسمية المتغيرات/الأنماط والمكونات، إذ يحسن تسميتها بشكل نمطي (لاحقة +اسم المكون) يجعل من السهل التعرف على دورها أو البحث عنها كما يجعل المصادر أكثر مقروئية.
مثال: مكون TDataSource المخصص لربط الجدول المبيعات Vente يسمى dsVente، ومكون الحذف (Supprimer) نسميه مثلا btSupprimer وقس على ذلك باقي المكونات...
ليتعرف مكون الـ Skin يستحسن أن نجعله يبحث عن المسار بشكل أكثر ديناميكية. شيء مثل هذا:
عند إنشاء أول نموذج OnCreate نضيف:
//تحديد المسار الحالي
sSkinManager1.SkinDirectory := ExtractFilePath(Application.ExeName) + '\Skins';
//تحديد المظهر
sSkinManager1.SkinName := 'MacOS2';
//تفعيل المكون
sSkinManager1.Active := True;
بخصوص مكونات AlphaControls Free Edition هي نسخة مجانية غير مفتوحة المصدر (ملفات dcu فقط)، يمكن الحصول عليها من الموقع الرسمي:
http://www.alphaskins.com/dwnld.php
-----
@S.FATEH
الخلل في طريقة عرض شاشة الاستقبال، رغم ذلك يمكن إصلاح الخلل باقتناص حدث WM_SYSCOMMAND وإجبار النموذج على Minimize فور استقباله قيمة SC_MINIMIZE. شيء مثل:
private
procedure WMMinimize(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
...
procedure TFGSM.WMMinimize(var Msg: TWMSysCommand);
begin
if msg.CmdType = SC_MINIMIZE then
Application.Minimize
else
DefaultHandler(Msg);
end;
حاولت تعديل جميع المرفقات لكنني فشلت، فقمت ببعض التعديلات الشكلية على المرفقات الأولى وآخر مرفق هنا.
بالتوفيق أخي نبيل.
S.FATEH
05-08-2010, 02:33 PM
السلام عليكم
شكرا للتوضيحات القيمة استاذ
kachwahed
كنت أطلع على الاسس العلمية
اربد فقط ان انوه يوجد خطأ بسيط جدا ف الصفحة 57 في قوله الحقل الغريب من خصائه عدم امكانية التكرار
بالتركيز يمكن الادراك انه سهو لكن قلت اخبر عنه احسن
سلامي
kachwahed
05-08-2010, 03:13 PM
اربد فقط ان انوه يوجد خطأ بسيط جدا ف الصفحة 57 في قوله الحقل الغريب من خصائه عدم امكانية التكرار
صحيح، الجملة كاملة من المصدر الأصل:
عدم إمكانية التكرار (إلا إذا أردت الربط على شكل واحد إلى واحد)
والصواب:
إمكانية التكرار (إلا إذا أردت الربط على شكل واحد إلى واحد)
بارك الله فيك على التنبيه :)
nabilkeb
26-08-2010, 01:27 PM
أولا صح رمضانكم ، و تقبل الله منا و منكم صالح الأعمال :
بداية أشكر الإخوة على المشاركة و الإهتمام و الردود المباركة عموما ، وشكر خاص لــ كاش واحد -ولست كذلك بل أنت أحسن واحد- هههه
---- بخصوص تكرار الحقول في الجداول :
في هذه الحالة سيخزن الاسم التجاري للممون في جدول السلع من جهة، وفي جدول الممولين من جهة أخرى...
=> إزدواجية في التخزين => خطأ في تصميم النموذج
=>
بارك الله فيك ،هذا أمر أكثر من مهم ، و لكنها مجرد طريقة في التبسيط للمبتدئ و عدم التعقيد ، و مع ضرورة التنبيه و الترفع عن مثل هذه الطرق في البرمجة كما تكرمت أنت ، و لم يفتني أنا أيضا هذا الأمر المتعمد ، و قد فصلت فيه بما يكفي إن شاء الله :
- قواعد البيانات:
ممكن أهم ملاحظة أطرحها تتمثل في تكرار واضح في حقول الجداول من عير فائدة .....إلى غاية..... فبامكانك التمعن في قواعد البيانات لمشروعنــا هذا ، و ستعرف ما عليك فعله
---- بخصوص الحقلين : الحد الأدنى كمية-سعر:
بطبيعة الحال أن هناك أسس علمية و عملية على المبتدئ خصوصا التقيد بها أثناء البرمجة ، و لكن أكثر ما أحب في البرمجة أنها فن و لكل منا ابداعه و تصوره ، حسب ما يقتضيه الموقف و الحاجة ، و لامكن بأي حال من الأحوال أن نجعل هذا الموضوع أو الطرح عبارة عن برنامج كامل و احترافي في مجال التسيير التجاري و التسويق ، فلا يعدو إلا أن يكون طرح مبسط جدا لكل مبتدئ ، عليه أن يتدارك بعدها و يترفع عن عدة أشياء و أمور.
عموما : كما هو معروف فنحن نستغل البرامج في التسهيل و التنظيم لمختلف حاجياتنا و عمل ما لايمكن لنا عمله ، فقط كان لدا محل لبيع الحواسيب و مختلف اللواحق المتعلق بذلك ، و كانت تعمل معي أخت مكلفة بالتسويق و التعامل مع الزبائن بواسطة برنامج تسيير مطور بالدلفي ، فكانت كثيرا ما تسهى عن تذكيري بما يجب اقتناؤه لنظرا لنفاده أو اقتراب ذلك ، الأمر الثاني حدوث أخطاء في تحديد سعر البيع نظرا لعدم استقرار الأسعار ، فأذكر أنا DDR128 وصل سعرها الأدنى 800 و أعلى سعر لها 2800 دج أنظر الفرق الشاسع في السعر ، و نظرا لذلك كانت تقع أخطاء في سعر البيع لعدم الثبات من جهة ، و لوجود عدة قطع بماركات متعددة ما يجعل تذكر و حفظ أسعارها مسحيلا .
من هذا قمت يتحيين (mise ajour) البرنامج بزيادة حقلين :
الأول الحد الأدنى للكمية ،أو ما يعرف بالعتبة ، فإذا تطابق الحد مع الكمية المتوفرة بالمخزن ينبهنا البرنامج لاقتناء هذا النوع.
الثاني السعر الأدنى للبيع ، إذ ينبه المستخدم أثناء تحديد السعر و كذا التخفيض بعدم تجاوز الحد المعلوم أو المحدد.
أجدد شكري للجميع و أتأسف على طول الغياب بسبب ضروف خاصة و أخرى مهنية حرمتني من الولوج للمنتدى .
بالتوفيق
عندي مشكلة في تثبيت Alpha Lite
لما اقوم بالخطوة واتي لاضافة مكون
واضغط على موافق لاضافته
تظهر لي نافدة مكتوب عليها
n'est pas un idenficatuer correct
nabilkeb
04-11-2010, 06:20 PM
راجع هذا الرابط (http://www.delphi4arab.com/forum/showthread.php?t=490)
فقط أنبه أن هذا الطرح موجه للمبتدئين ، و هو سبب وجوده في هذا القسم بالذات ، ربما سوف تجد الكثير من الأمور التي تهمك من الناحية البرمجية و استغلال قاعدة البيانات و افكار اخرى ، و لا تركز على تصميم القاعدة في حد ذاته (فالتصميم كان سيئا ولعلي مزجت بين أخطاء متعمدة (أشرت لها ، كما يمكن الإستغناء على حقول عديدة بالجداول كالمكررة أو الحقول الحسابية ، و كذا انشاء جداول أخرى) و أخرى غير ذلك _وكأنني مزجت بين ق ب المسطحة و العلائقية_ ، و الغرض هو مبادرة طرح ما يفيد المبتدئ من الناحية البرمجية و كذا التسهيل و التبسيط) .
- بالنسبة للأخ kachwahad و ما يخص : الأسس العلمية لتصميم نماذج قواعد البيانات العلائقية (http://www.delphi4arab.com/forum/showpost.php?p=17982&postcount=2).
قرأته من الصفحة1إلى120 (و حسبت كل صفحاته حول موضوعه )، من المؤكد أنه مقال مفيد جدا ، و لكن ما يخدم هذا الطرح من حيث قواعد البيانات يمكن اختزاله في بضع صفحات أو أقل ، و لست أنقص من مادته العلمية أبدا و أنا الفقير للخبرة ، و بالمقابل أنصح كل مبتدئ مراجعة كتاب لغة البرمجة دلفي لـ ناصر آغا و الله ما قرأت كتابا عربيا في الدلفي أسهل و أبسط و أكثر إفادة من هذا الكتاب . و بالمقارنة بينهما تقريبا سوف يغنيك الكتاب عن المقال.
بالتوفيق للجميع
krimos
19-11-2010, 06:50 PM
بارك الله فيك غلى المجهود لكن عندما أردت فتحه يكتب لي رسالة خطأ علما أنني مبتدأ في برمجة الديلفي و أملك نسخة ديلفي 7 الرجاء الافادة في كيفية فتح البرنامج
شكرا الاخ نبيل فعلا عمل جبار
عاشور قلب الاسد
14-12-2010, 07:58 AM
السلام عليكم
بارك الله فيكم على ما تقومون به فى سبيل نشر العلم ووفقكم الله لما يحبه ويرضي
لي سؤال:
قمت بعمل نضومه شبيهه بهذه ولكن المشكله .. التى واجهتنى ...هي فى تايخ الصلاحيه للأصناف كيف يتم التصرف معها
لو قلنا ان لدينا صنف موجود منه 3 قطع متلا حبوب بانادول وتاريخ صلاحيتها 31/12/2010
وقمنا بشراء كميه جديده .. وكانت صلاحيتها 31/12/2012
فكيف لي ان اعرف فى حالة صنعت تقرير خاص بالصلاحيات بعد بيع 5 قطع على سبيل المثال !
زالسلام عليكم ورحمه الله وبركاته
B.M.AbdelAziZ
14-12-2010, 08:12 AM
وعليكم السلام ورحمة الله
وقمنا بشراء كميه جديده .. وكانت صلاحيتها 31/12/2012
كل صنف بصلاحية مختلفة بسجل مختلف
القديم بسجل والجديد بسجل وفرضا هناك حقل اضافي للتفرقة بين السجلات
عند البيع/اخراج صنف فانت تختاره وتنقص قيمته
ومنه عند صنع التقرير يظهر كل صنف والكمية وتاريخ الصلاحية
بالتوفيق
عاشور قلب الاسد
15-12-2010, 07:18 AM
السلام عليكم
B.M.AbdelAziZ .. اخي .. هي ذات الفكره التى كانت تدور فى رأسي .. بأن اضهر الصلاحيات فى combobox ومنها تختار اي الصلاحيات بعت
ولكن عمليا متعبه قليلا ..لو كانت المنظومة بيعت لمكان مزدحم .. على سبيل المثال ..سوق مواد غذائيه!
ــــــــــــــــــــــــــــــــــــــــــــــــــ ــــــــــــــــــــــــــــــــــــــــــــــــــ ـــــــــــــــــــــــــــــــ
لا اخفيك سراً ان الفكره التى كانت تدور فى رأسي ايضا .. ان اجعل الاصناف فى جدول على سبيل المثال
باركود الصنف / الكميه الموجوده / تاريخ الصلاحيه
جمله الادخال تكون مره واحده ، ومن ثم التعديل ، اذا قام بتعديل صنف مازالت حتى قطعه واحده موجوده يترك التاريخ القديم، اما لو كان الصنف قد انتهي اي الكميه الموجوده صفر فيعتمد التاريخ القديم
ولكن اعتقد انها غير مفيده ايضا ً كونها تعطي تقارير غير صحيحه ايضا
B.M.AbdelAziZ
15-12-2010, 08:09 AM
وعليكم السلام
اضهر الصلاحيات فى combobox ومنها تختار
حسب الحالة وطريقة تفكيرك لتسهيل الأمر للمستخدم
يمكن ان تستخدم StringGrid, DBGrid , أي مكون Grid أو TreeView, ListView أو اي مكون مرئي للعرض
redouane
19-12-2010, 05:09 PM
نأتي للجانب البرمجي:
بعد أن نذهب إلى المكون MainMenu (نضغط عليه مرتين) ، ثم نحدد Parametrès de vente ثم TVA ثم 00% ، على هذا الأخير الذي يأحذ الكابشن %00 و الإسم N01 ، نقوم باعطاء القيمة True للخاصية Checked ، يعني نجعله افتراضيا مع بداية المشروع محددا بتلك العلامة (Checked أو Cocher).
نغلق العنصر MainMenu ، و نحدد نفس العنصر %00 من قائمة الفورم FGSM ، نضغط عليه ليعطينا امكانية تحرير الكود سورس ثم نكتب :
كود:
لم أفهم اخي اين اجد Parametrès de vente
krimos
21-12-2010, 02:55 PM
السلام عليكم
لم أستطع تتبع الخطوات و في كل مرة يكتب لي رسالة خطأ علما أنني مبتدأ في الديلفي و لدي ديلفي 7
كيف أستطيع العمل أو الاستفادة من البرنامج
nabilkeb
24-12-2010, 02:56 AM
لم أفهم اخي اين اجد Parametrès de vente
حاول التمعن و بالتسلسل و المتابعة ، Parametrès de vente هو أحد عناصر القائمة في الفورم الأساسي (أحد العناصر الأساسية في Main_Menu).
بالتوفيق
nabilkeb
24-12-2010, 02:59 AM
لم أستطع تتبع الخطوات...
أولا المطلوب تثبيت ما يلزم لعمل البرنامج ، ثانيا المتابعة بالتسلسل ، خطوة خطوة مطلوبة ، أبن أنت بالضبط أخي؟ حاول البداية من الأول و كما سلف لا بد من تثبيت المكونات اللازمة لذلك.
إذا بقي الإشكال ، تفضل بطرحه بقما يكفي من التفصيل (إدراج رسالة الخطأ)
بالتوفيق أخي
delnadji
25-12-2010, 02:28 PM
اشكرك جزيل الشكر nabilkeb
مجموعة برامج شخصية
daho28
15-01-2011, 05:02 PM
السلام عليكم
لم أجد تخزين لقاعدة البيانات و استرجاعها
على أن تكون مثلا سنويا.
أي عمل باكوب(backup) للمعطيات و استرجاعها .
مشكور على الجهد والعمل
مروان نزيه رضا
15-01-2011, 05:35 PM
السلام عليكم ورحمة الله تعالى وبركاته
مشكور على الافادة وبالمناسبة أهنئك على البرنامج ، فهو رائع ومدهش للسادة المهتمين بالموضوع ، لكنني يا أخي لا أفقه هذه اللغة وأود أن أتعلمها لكن لا أعرف الخطوات التي علي القيام بها ، ولا أخفيك سرا فأنا بحاجة ماسة لعمل برنامج بلغة دلفي عن صيانة شاشة الحاسوب فهو مشروع تخرج
amicale21
19-01-2011, 09:17 PM
السلام عليكم
كما احي الاخ Nbilkeb
على هذاالمجهود الجبار و بما انني مبتدئ في عالم الدلفي
سوف اشرع في تنفيذ دروسك في انشاء برنامج gsm
amicale21
21-01-2011, 10:03 AM
السلام عليكم
منخلال هذه المعطيات
حدد العنصر DBloockupCombobox1 ، ثم نذهب لخصائص هذا المكون ، هذا المكون سوف يعمل لصالح من ؟ كغيره من كل المكونات الموضوعة على الفورم FGSM خاصة بالجدول vente ، و عليه فإن الخاصية DataSource سوف تأخذ القيمة DataSource2 .
ثم هذا العنصر (نقصد DBlookupCombobox1 ) خاص بأي حقل من الجدول vente ؟ بطبيعة الحال Code_Prod ، إذن نحدد هذه الأخير كقيمة للـخاصية DataField .
ثم هذا العنصر (نقصد DBlookupCombobox1 ) يأتي بقائمة المواد من أين ؟ من الجدول produit إذن:
DataSource=DataSource1
KeyField=Code_Prod
السؤال
عدم ظهور cod_prod في الخاصية Keyfield
لقد اعطينا للعنصر dbloockupCombobox1 القيمة datasource2 كيف نعطي له القيمة كيف نعطي له نفس القيمة في نفس الوقتdatasource1
لقد ظهر معي قيمة keyfield عند استعمال الخاصة listsource
و شكرا
nabilkeb
22-01-2011, 08:34 PM
لقد اعطينا للعنصر dbloockupCombobox1 القيمة datasource2 كيف نعطي له القيمة كيف نعطي له نفس القيمة في نفس الوقتdatasource1
السؤال غير واضح ، إذا أردت إعطاء قيمتين ، لا يمكن حدوث ذلك في نفس الوقت ، أما إذا أردت استخذام عنصر واحد باستعمال قيمتين ، يكون ذلك برمجيا كلما كانت الحاجة ، أقصد أنه لا تعطى القيمة من خلال Inspecteur d'objets
nabilkeb
09-02-2011, 11:32 AM
... يا ريت لو تعمل المشروع كتاب الكتروني
اقتراخ جيد و أكثر نفعا ، سيكون هذا إن شاء الله في القريب ، مع أكثر تفصيل و تنظيم و تدقيق .
بالتوفيق
aghroutsoft
01-03-2011, 10:36 AM
اطلعت على برنامجك و اردت اضافةهذا الكود الخاص بالتفقيط
السلام عليكم
اين نضع هذا الكود
عكرمة
03-04-2011, 07:49 PM
أستاذي الكريم أنا ممتن لك كثيرا وأشكرك
و رجائي من الله أن يجعلها في ميزان حسناتك لكن عندي مشكلتين أولاهما لم أفهم وجود Filtrage1.Enabled:=true; // Fiche facture et Statistique
عند برمجة الأزرار وثانيهما ظهور نافذة بعد التنفيذ كتب عليها
sEdit1'is not a valid floating point value '
ELARAPY
13-04-2011, 08:36 AM
السلام عليكم ورحمة الله
بارك الله فيك استاذ نبيل على الموضوع وعلى متابعتك للموضوع حيث انك تفضلت بالشرح منذ فترة كبيره وما شاء الله
مداوم على الموضوع فهذا يكفي لكل تقدير واحترام
ان شاء الله قريبا يمن الله علي وادرك قواعد البيانات واشارك مرة اخرى بطرحك الكريم
جعله الله في ميزان حسناتك
dliouahb
08-09-2011, 05:05 PM
السلام عليكم ..
لا ننسى أن نشكر لك المجهودات الكبيرة ربي يجازيك..
بالنسبة للكود على الصفحة 17
وهو :
if not table2.IsEmpty then begin
if (MessageDLG ('êtes vous sûr de vouloir suprimer l''enregistrement ?'
, MtConfirmation,[MbYes,MbNo],0)=MrYes) and (Table1.FindKey([Table2.FieldValues['Code_Prod']])) then
begin
Table1.Edit;
Table1.FieldValues['Qut']:= Table1.FieldValues['Qut']+Table2.FieldValues['Qut'];
Table1.Post; Table2.Delete;
end;
أنت أشرت إلى إضافة الكود "اللون البرتقالي" في الكود المشار إليه..
لم يمش معي !!
أليس مكانه إلى الأعلى ؟ بعد begin الأولى ؟
شكرا مرة أخرى
riadh1909
26-10-2011, 11:24 PM
السلام عليكم
أولا قبل أن أكمل دراسة كل الموضوع علي أن أشكرك جزيل الشكر لانك لم تبخل على الذين
يريدون هذا النوع من البرامج . لانك شجعتني على قراءة موضوعك و قد قررت أن أتعلم منك طريقة
البرمجة في هذا المجال الله يوفقنا جميعا ان شاء الله بارك الله فيك
khalmoh1971
30-11-2011, 11:03 PM
شكرا على المجهود أقترح ترجمة البرنامج بالعربية او الانجليزية
صفاء ومروة
12-01-2012, 08:03 PM
شكرا على هذه المعلومات الدقيقة و أود الإنضمام إليكم في هذه الدروس الشيقة و الرائعة التي نتمنى من الجميع الإستفاذة منها و إفادة الغير منها وكذلك معرفة الأخطاء التي يرتكبها و أنا بطبيعة الحال بدأت في كتابة برنامج لكن و عندما فشلت في وضع شاشة للترحيب فقد توقفت ولكني كتبت كل ما يتعلق بالبرنامج ولكن لعدم معرفتي جيدا بالبرمجة فقد ظننت نفسي أني لا أستطيع أن أكتب برنامجا و خاصة أنه يعتمد كثيرا على اللغة العربية أكثر من الفرنسية و لهذا لم أستطيع البداية رغم أنني كتبت لمحة عامة عن الموضوع والاشياء التي أحتاجها و عندي سؤال فهل أستطيع كتابة قاعدة المعطيات التي تعتمد على اللغة الفرنسية بالفرنسية ثم عند البدأ في تطبيق البرنامج أكتب العناصر باللغة العربية؟ و شكرا جزيلا
alouma
14-01-2012, 07:40 PM
عمل جبار يستحق التوثيق
جزاك الله خيرا
وأأيد فكرة slman من أجل تحويل هذا العمل على شكل ملف pdf مرفوقا بالأمثلة والملحقات اللازمة لذلك
بارك الله فيك
nabilkeb
22-01-2012, 05:29 PM
و فيك بركة ـ هذا ما كنت عازما فعله لولا بعض الإنشغالات ، لكن بإذن الله سيكون الأمر كذالك متى وجدت الوقت الكافي . كما أن فيه جملة من الملاحظات و بعض الأخطاء التي سنتجاوزها بحول الله في الكتاب الإلكتروني.
و يبقى الموضوع برمته بسيطا و مبسطا ، موجه للمبتدئين أمثالي.
بالتوفيق للجميع.
vBulletin® , Copyright ©2008-2012