بسم الله الرحمن الرحيم
ما هو الإجراء ؟
الإجراء - بكل بساطة - هو عبارة عن مجموعة من الجمل والأوامر العادية، يتم تجميعها معاً، وإعطائها عنواناً معيناً كاسم لهذا الإجراء .. وبعد ذلك يمكننا استخدام هذه الأوامر جميعها في أي مكان من البرنامج، عن طريق كتابة اسم هذا الإجراء ..
وسنعرض الآن مثالاً بسيطاً لذلك:
أولاً سنقوم بإنشاء إجراء جديد اسمه EndProgram وستكون وظيفته الأساسية عرض رسالة تأكيد للمستخدم عند محاولته الخروج من البرنامج ..
لاحظ أننا سنقوم بكتابة هذا الإجراء في قسم ال General_Declarations .. انظر للصورة التالية:

وسيكون الكود كما في الصورة:
Sub EndProgram()
Dim Result As String
Result = MsgBox("هل تريد بالتأكيد الخروج من البرنامج", vbYesNo, "تأكيد الخروج")
If Result = 6 Then
End
Else
Exit Sub
End If
End Subلاحظ أننا - في الإجراء السابق - عند ضغط المستخدم على Yes/نعم فإننا نقوم بتنفيذ الأمر End، بينما لو قام المستخدم بالضغط على No/لا فإننا نقوم بالخروج من الإجراء عن طريق الأمر Exit Sub ..
الآن لاستخدام الإجراء بشكل فعلي قم بوضع زر على النموذج واجعل عنوانه/Caption = "خروج" ..
اضغط على هذا الزر مرتين للانتقال لنافذة الكود ..
قم بكتابة الأمر Call ثم اكتب اسم الإجراء ..
ويمكتك الاستغناء عن الأمر Call وكتابة اسم الإجراء مباشرة ولن يؤثر ذلك على شيء ..
إذاً بإمكاننا أن نكتب في حدث النقر على الزر:
Call EndProgram
أو
EndProgram
تهانينا :wink: .. لقد استخدمت الإجراء بنجاح ..
ما هي فائدة الإجراءات ؟
لا نريد أن نعدد في فوائد الإجراءات وهي كثيرة بالفعل، وتتحدد هذه الفائدة بحسب الحاجة إليها، ولكن أهم ما يُمكن أن نشير إليه هو:
- دور الإجراءات الواضح في تقليل الكود المكتوب:
على سبيل المثال لو كنا نستخدم في النموذج أكثر من إمكانية لإنهائه ( عن طريق زر إنهاء أو عن طريق البند إنهاء من قائمة .. )

هل سنقوم بكتابة كود تأكيد الخروج مرتين، الأولى في حدث النقر على الزر إنهاء، والثانية في حدث النقر على البند إنهاء من القائمة :blink: ؟؟
بإمكاننا عمل ذلك ولكنه يعني المزيد من الجهد في الكتابة والمزيد من الكود الذي لا فائدة منه :( ..
الأفضل في مثل هذه الحالة أن نقوم بعمل إجراء كالإجراء EndProgram الذي قمنا بعمله بالأعلى، ثم يمكننا بعد ذلك استدعاء هذا الإجراء من أي مكان في البرنامج عن طريق كتابة اسم الإجراء فقط ..
- دور الإجراءت في تنظيم الكود وتقسيمه:
وهذا واضح تماماً حيث أن تقسيم الأكواد إلى إجراءات يجعل الأمر أكثر تنظيماً، كما أنه يجعل من السهل عليك - وعلى غيرك - فهم الكود واستخدامه في أي وقت ..
تخيل أنك تريد التغيير في كود يحتوي على آلاف الأسطر المتتالية، إذاً أنت بحاجة إلى قراءة هذه الأسطر كلها، والتغيير في أماكن عديدة، وهذا ما يمكننا تفاديه باستخدام الإجراءات ..
تمرير المعاملات أو القيم إلى الإجراء:
من الممكن عند استدعاء الإجراء أن نقوم بتمرير قيمة أو معامل إلى الإجراء، مثلاً لو كان لدينا إجراء يقوم بالتحقق من وجود أرقام فقط في مربع النص أم لا، فمن الطبيعي عند استدعاء هذا الإجراء أننا سنقوم بتمرير اسم مربع النص - الذي نريد التحقق منه - إليه..
وبصفة العموم فإننا نحتاج عند إتاحة التمرير إلى الإجراء ثلاثة أشياء ..
1. الكلمة ByVal أو الكلمة ByRef.
2. اسم القيمة أو المعامل.
3. نوعهـــــا.
ولنأخذ مثالاً على ذلك الإجراء التالي، وهو يقوم بتغيير لون الخلفية وكتابة "بسم الله الرحمن الرحيم" في مربع النص الذي نحدده له، وسيكون كالتالي:
Sub WriteInText(ByVal TextName As Control) TextName.BackColor = vbGreen TextName.Text = "بسم الله الرحمن الرحيم" End Sub
لاحظ أننا استخدمنا الكلمة ByVal ..
وكان من الممكن أن نستخدم الكلمة ByRef، وسيأتي الفرق بينها وبين زميلتها لاحقاً.
ولاحظ أننا استخدمنا لاسم القيمة الكلمة TextName ..
ويمكننا تغيير هذا الاسم لأي اسم نريده إطلاقاً.
ولاحظ أيضاً أننا استخدمنا النوع Control ..
وذلك لأن نوع القيمة الممررة إلى الإجراء هي أداة أي Control.
بعد ذلك يمكننا استخدام هذا الإجراء من أي مكان، وتنفيذه على أي مربع نص عن طريق استدعاء (كتابة اسم) الإجراء وهو WriteInText ثم كتابة اسم مربع النص الذي نريد التطبيق عليه، وفي حالتنا هذه سنجعله TextBox1 مع إمكانية التغيير حسب اسم مربع النص ..
WriteInText Text1
الآن لديك مهلة دقيقتين فقط للتفكير في طريقة تجعلنا نحدد اسم مربع النص وكذلك النص الذي سيُكتب بداخله ..
هل عرفت الحل :ohh ؟
أعتقد أن الأمر ليس صعباً، فكما أننا قمنا بتمرير اسم مربع النص في المثال السابق، فيمكننا أيضاً بنفس الطريقة تمرير النص المكتوب، حيث أن الإجراء يسمح بتمرير قيمة أو أكثر حسب الحاجة ..
وبهذا سيتم تغيير المثال ليصبح الإجراء كالتالي:
Sub WriteInText(ByVal TextName As Control, ByVal WritedText As String) TextName.BackColor = vbGreen TextName.Text = WritedText End Sub
بعد ذلك نقوم باستدعاء الإجراء مع تمرير القيمتين إليه، كالتالي:
WriteInText Text1, "الفريق العربي لتكنولوجيا الويب"
والآن ننتقل إلى إمكانية أخرى، ولاحظ أننا نحاول الإلمام بجميع الإمكانيات لاستخدامها فيما بعد طوع إرادتنا ..
سنسمح الآن للمستخدم بتمرير قيمة النص المكتوب وفي نفس الوقت لن نجبره على ذلك، بمعنى أنه لو قام المستخدم بتمريره فإنه سيظهر كالعادة، وإذا لم يمرر شيئاً فسيقوم الإجراء بتمرير القيمة الافتراضية، والتي سنحددها نحن في الإجراء، وسيكون الكود كالتالي:
Sub WriteInText(ByVal TextName As Control, Optional ByVal WritedText As String = "www.al-ebda3.info") TextName.BackColor = vbGreen TextName.Text = WritedText End Sub
كما ترى قمنا بإضافة الكلمة optional قبل الكلمة ByVal، كما أننا قمنا بتحديد القيمة الافتراضية والتي سيتم وضعها في حال لم يمرر المستخدم أي قيمة ..
لاحظ أنه لابد أن تحدد المعامل أو القيمة الافتراضية ..
ولاحظ أنه لابد أن تكون المعاملات - سواء كان واحداًً أو أكثر - في آخر الإجراء ولا يمكن أن يتقدم المعامل الاختياري على المعامل الإجباري ..
الفرق بين الكلمة ByVal و ByRef:
الكلمة ByVal تقوم بتمرير قيمة المتغير فقط، أي أنه لو قمنا بتمرير متغير إلى الإجراء فإنه سيأخذ نسخة من القيمة الموجودة في المتغير، وبعدها يتعامل مع هذه القيمة بالزيادة أو النقص أو التغيير، ولن يؤثر ذلك شيئاً على القيمة الأصلية الموجودة في المتغير، لأن التغيير كله سيقع على النسخة المأخوذة من قيمة المتغير ..
أما الكلمة ByRef فإنها تقوم بتمرير عنوان المتغير نفسه إلى الإجراء، وبالتالي فعند تغيير القيمة الممررة فإن ذلك سيتم في المتغير الأساسي، وسيتغير بناء على ذلك ..
مثال لتوضيح المسألة:
في البداية سنقوم بتعريف متغير عام على مستوى النموذج بالاسم TestText كالتالي:
Dim TestText As String
بعد ذلك نقوم بكتابة الإجراء التالي:
Sub Test(ByVal NameTest As String) NameTest = "النص بعد التغيير" End Sub
لاحظ أننا استخدمنا الكلمة ByVal ..
بعد ذلك نقوم بتمرير متغير إلى هذا الإجراء ونرى إن كان سيتغير أم لا !
ضع هذا الكود في حدث النقر على الزر مثلاً ..
TestText = "النص الأصلي" Test(TestText) MsgBox(TestText)
كما ترى السطر الأول يقوم بملء المتغير TestText الذي عرفناه سابقاً بقيمة معينة ..
وفي السطر الثاني نقوم بتمرير هذا المتغير إلى الإجراء NameTest ..
وفي السطر الثالث نقوم بعرض محتوى المتغير TestText لنرى هل تغير أم لا !!
النتيجة طبعاً لا لأننا استخدمنا الكلمة ByVal ..
أعد المثال نفسه مع تغيير الكلمة ByRef بالكلمة ByVal وستجد أن قيمة المتغير قد تغيرت ..
أتمنى أن يكون الأمر واضحاً ..
في الختام أتمنى أن تكونوا قد استفدتم، وفي حال وجود تصحيحات أو استفسارات أرجو وضعها هنا وسنسعد بها قطعاً ..
حتى ألقاكم لكم مني خالص التحية
ع . ف . ر

