توجد في أي لغة برمجة مفاهيم مثل الإجراءات والوظائف. تم تضمينها أيضًا في لغة البرمجة المضمنة VBA لـ Excel.
في هذه المرحلة ، تكون جميع الإجراءات التي أنشأناها من النوع Public ، مما يعني أنه يمكن الوصول إليها من أي وحدة نمطية.
Sub example() 'مطابقة ل: Public Sub example()
لجعل الإجراء متاحًا فقط في وحدة نمطية معينة ، يتم استخدام الكلمة الأساسية Private:
Private Sub example()
لتنفيذ إجراء من داخل إجراء آخر ، ما عليك سوى إدخال اسمه.
فيما يلي مثال بسيط جدًا على هذا:
Private Sub warning() MsgBox "Caution !!!" '"تحذير!" End Sub Sub macro_test() If Range("A1") = "" Then warning '=> تنفيذ الإجراء "warning" End If 'إلخ... End Sub
تجعل الوسيطات من الممكن استخدام قيم من إجراء في إجراء فرعي (تذكر أنه افتراضيًا ، لا تتوفر المتغيرات إلا من الإجراء الذي تم التصريح بها).
Private Sub warning(var_text As String) MsgBox "Caution : " & var_text & " !" End Sub Sub macro_test() If Range("A1") = "" Then warning "empty cell" '"خلية فارغة" ElseIf Not IsNumeric(Range("A1")) Then warning "non-numerical value" '"قيمة غير رقمية" End If End Sub
تمت إضافة وسيطة إلى الإجراء "warning" ، وهي في هذه الحالة متغير "var_text" من النوع "String" (الشريط):
Private Sub warning(var_text As String)
يأخذ هذا الروتين وسيطًا ، لذلك نحتاج إلى وضع قيمة بعد "warning" لتنفيذه:
warning "empty cell"
عندما نريد كتابة عدة وسيطات ، فيجب فصلها بفواصل.
بشكل افتراضي ، إذا كان الإجراء يحتوي على وسيطات ، فيجب توفيرها ، وإذا لم يتم توفيرها ، فلن يتم تنفيذ الإجراء.
يمكن إضافة وسيطة اختيارية بعد الوسيطة الإلزامية باستخدام الكلمة الأساسية الاختيارية. مثال:
Private Sub dialog_boxes(last_name As String, Optional first_name, Optional age)
يمكن الآن تنفيذ هذا الإجراء باستخدام وسيطة اختيارية أو بدونها ، كما هو الحال هنا:
'مثال 1: اعرض الاسم الأخير: dialog_boxes last_name1 'مثال 2: نعرض اللقب والاسم الأول: dialog_boxes last_name1, first_name1 'مثال 3: اعرض الاسم الأخير والعمر: dialog_boxes last_name1, , age1 'مثال 4: عرض الاسم الأخير والاسم الأول والعمر: dialog_boxes last_name1, first_name1, age1
يجب إدخال الوسيطات بالترتيب الصحيح.
لاختبار ما إذا كانت الوسيطة الاختيارية موجودة في إجراء ما ، نستخدم وظيفة IsMissing. هذه الوظيفة متوافقة فقط مع بعض أنواع الوظائف (من النوع Variant) وهذا أمر بالغ الأهمية لأنه لم يتم التصريح عن نوع الوسيطات الاختيارية (نوع غير معرّف = Variant).
فيما يلي مثال يستخدم مقتطفات التعليمات البرمجية التي تمت مناقشتها أعلاه:
Sub macro_test() Dim last_name1 As String, first_name1 As String, age1 As Integer last_name1 = Range("A1") first_name1 = Range("B1") age1 = Range("C1") 'مثال 1: اعرض الاسم الأخير: dialog_boxes last_name1 'مثال 2: نعرض اللقب والاسم الأول: dialog_boxes last_name1, first_name1 'مثال 3: اعرض الاسم الأخير والعمر: dialog_boxes last_name1, , age1 'مثال 4: عرض الاسم الأخير والاسم الأول والعمر: dialog_boxes last_name1, first_name1, age1 End Sub Private Sub dialog_boxes(last_name As String, Optional first_name, Optional age) If IsMissing(age) Then 'إذا كان متغير العمر مفقودًا ... If IsMissing(first_name) Then 'إذا كان المتغير first_name مفقودًا ، فحينئذٍ 'سيتم عرض الاسم الأخير فقط MsgBox last_name Else 'خلاف ذلك ، سيتم عرض الاسم الأخير والاسم الأول MsgBox last_name & " " & first_name End If Else 'إذا كان متغير العمر موجودًا ... If IsMissing(first_name) Then 'إذا كان المتغير first_name مفقودًا ، فحينئذٍ 'سيتم عرض اسم العائلة والعمر MsgBox last_name & ", " & age & " years old" Else 'خلاف ذلك ، سيتم عرض الاسم الأخير والاسم الأول والعمر MsgBox last_name & " " & first_name & ", " & age & " years old" End If End If End Sub
يرى الصورة أدناه (المثال 1):
بشكل افتراضي ، تكون الوسائط من النوع ByRef ، مما يعني أنه إذا تم تمرير متغير كوسيطة ، فسيتم أيضًا تمرير مرجع إليه. بمعنى آخر ، إذا تم تغيير متغير بواسطة إجراء فرعي آخر ، فسيتم تغييره أيضًا في الإجراء الخارجي الذي يستدعي هذا الإجراء الفرعي.
مثال:
Sub macro_test() Dim var_number As Integer var_number = 30 calcul_square var_number MsgBox var_number End Sub Private Sub calcul_square(ByRef var_value As Integer) 'ByRef اختياري '(هي القيمة الافتراضية) var_value = var_value * var_value End Sub
لتوضيح ذلك ، يوجد أدناه مثال لما سيحدث إذا بدأ تنفيذ الماكرو:
var_number = 30 'القيمة الأولية للمتغير "var_number" هي 30 calcul_square var_number 'يتم تشغيل الإجراء الفرعي باستخدام "var_number" كوسيطة Private Sub calcul_square(ByRef var_value As Integer) 'المتغير "var_value" يخدم إلى حد ما للوصول السريع إلى المتغير "var_number" ، 'مما يعني أنه إذا تم تغيير المتغير "var_value" ، فسيتم أيضًا تغيير المتغير "var_number" '(وليس لديهم نفس الاسم) var_value = var_value * var_value 'تم تغيير قيمة المتغير "var_value" (وبالتالي يتم تغيير "var_number" أيضًا في نفس الوقت) End Sub 'نهاية الإجراء الفرعي MsgBox var_number 'تم تغيير المتغير "var_number" لذلك سيتم عرض 900 الآن في مربع الحوار
الطريقة الثانية هي استخدام ByVal.
بخلاف ByRef ، الذي يمرر مرجعًا (تسمية) ، يمرر ByVal قيمة ، مما يعني أن القيمة التي تم تمريرها كوسيطة لم يتم تعديلها.
يمكنك أدناه معرفة كيفية عمل الكود السابق و ByVal:
var_number = 30 'القيمة الأولية للمتغير "var_number" هي 30 calcul_square var_number 'يتم تشغيل الإجراء الفرعي باستخدام "var_number" كوسيطة Private Sub calcul_square(ByVal var_value As Integer) 'المتغير "var_value" ينسخ قيمة المتغير "var_number" (المتغيران غير مرتبطين) var_value = var_value * var_value 'تم تغيير قيمة المتغير "var_value" End Sub 'نهاية الإجراء الفرعي (في هذا المثال ، ليس للإجراء الفرعي أي تأثير على أي شيء) MsgBox var_number 'لم يتم تغيير المتغير "var_number" وبالتالي سيتم عرض 30 في مربع الحوار
ما تحتاج إلى تذكره: استخدم ByVal عندما لا يجب تغيير المتغير.
الفرق الرئيسي بين الإجراء والدالة هو أن الدالة ترجع قيمة.
اليك مثال بسيط:
Function square(var_number) square = var_number ^ 2 'ترجع الدالة "التربيعية" قيمة "الجذر التربيعي" End Function Sub macro_test() Dim result As Double result = square(9.876) 'يتم تعيين القيمة التي تم حسابها بواسطة الدالة إلى متغير النتيجة MsgBox result 'يتم عرض النتيجة (في هذه الحالة مربع 9.876) End Sub
يمكن استخدام الوظيفة في ورقة عمل تمامًا مثل أي دالة أخرى في Excel.
على سبيل المثال ، للحصول على مربع القيمة التي تم إدخالها في الخلية A1: