Skip to content

5. الوظائف والإجراءات

5.1. وظائف VBScript المحددة مسبقًا

يستمد ثراء اللغة إلى حد كبير من مكتبة وظائفها، حيث يمكن تغليف هذه الوظائف في كائنات تحت اسم الأساليب. في هذا الصدد، يمكن اعتبار VBScript محدودة إلى حد ما.

يسرد الجدول التالي وظائف VBScript خارج الكائنات. لن ندخل في تفاصيلها. تشير أسماؤها عمومًا إلى الغرض منها. يجب على القراء الرجوع إلى الوثائق للحصول على تفاصيل حول وظيفة معينة.

Abs
مصفوفة
Asc
Atn
CBool
CByte
CCur
CDate
CDbl
Chr
CInt
CLng
التحويلات
Cos
إنشاء كائن
CSng
Date
DateAdd
DateDiff
DatePart
التسلسل الزمني
قيمة التاريخ
اليوم
الرياضيات المشتقة
التقييم
Exp
تصفية
تنسيق العملة
تنسيق التاريخ والوقت
تنسيق الأرقام
تنسيق النسبة المئوية
GetLocale
GetObject
GetRef
سداسي عشري
ساعة
مربع الإدخال
InStr
InStrRev
Int، Fixs
IsArray
IsDate
IsEmpty
IsNull
IsNumeric
IsObject
الانضمام
LBound
LCase
Left
Len
تحميل الصورة
Log
LTrim؛ RTrim؛ و Trims
الرياضيات
متوسط
دقيقة
الشهر
اسم الشهر
مربع الرسالة
الآن
أكتوبر
استبدال
RGB
يمين
Rnd
دائري
محرك البرنامج النصي
إصدار بناء محرك البرامج النصية
الإصدار الرئيسي لمحرك البرامج النصية
الإصدار الثانوي لمحرك البرمجة النصية
الثانية
تعيين الإعدادات المحلية
Sgn
الخطيئة
الفضاء
انقسام
Sqr
مقارنة السلسلة
سلسلة
تان
الوقت
Timer
TimeSerial
قيمة_الوقت
اسم النوع
UBound
حالة الأحرف
نوع المتغير
Weekday
اسم_اليوم_الأسبوعي
السنة

5.2. البرمجة المعيارية

وصف الحل المبرمج لمشكلة ما يعني وصف تسلسل العمليات الأساسية التي يمكن للكمبيوتر تنفيذها والتي هي قادرة على حل المشكلة. تختلف هذه العمليات الأساسية في تعقيدها حسب لغة البرمجة. ومن الأمثلة على ذلك:

  • قراءة البيانات من لوحة المفاتيح أو القرص
  • كتابة البيانات على الشاشة أو الطابعة أو القرص، إلخ
  • حساب التعبيرات
  • التنقل عبر ملف
  • ...

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

يمكننا في البداية وصف الحل بالشكل التالي:

  début
        lire les valeurs et les mettre dans un tableau T
        trier le tableau T
        écrire les valeurs triées du tableau T à l'écran
  fin

لقد قسمنا المشكلة إلى 3 مشاكل فرعية، وهي أسهل في الحل. غالبًا ما تكون صيغة الخوارزمية أكثر رسمية من السابقة، وستُكتب الخوارزمية على النحو التالي:

   début
         lire_tableau(T)
         trier_tableau(T)
         écrire_tableau(T)
   fin

حيث يمثل T مصفوفة. العمليات

    . lire_tableau(T)
    . trier_tableau(T)
    . écrire_tableau(T)

هي عمليات غير أولية يجب وصفها بدورها بعمليات أولية. ويتم ذلك في ما يُسمى بالوحدات النمطية. وتُسمى البيانات T معلمة الوحدة النمطية. وهي معلومات يمررها البرنامج المستدعي إلى الوحدة النمطية المستدعاة (معلمة الإدخال) أو يتلقاها من الوحدة النمطية المستدعاة (معلمة الإخراج). وبالتالي، فإن معلمات الوحدة النمطية هي المعلومات المتبادلة بين البرنامج المستدعي والوحدة النمطية المستدعاة.

الوحدة النمطية read_array(T)
الوحدة النمطية sort_array(T)
الوحدة النمطية read_array(T)

يمكن وصف الوحدة النمطية read_array(T) على النحو التالي:


début
    écrire "Tapez la suite de valeurs à trier sous la forme val1 val2 ... : "
    lire valeurs
    construire tableau T à partir de la chaîne valeurs
fin

هنا، قمنا بوصف وحدة read_array بشكل كافٍ. في الواقع، فإن الإجراءات الثلاثة الضرورية لها ترجمة فورية إلى VBScript. سيتطلب الإجراء الأخير استخدام دالة Split. إذا لم تكن VBScript تحتوي على هذه الدالة، فسيتعين بدوره تقسيم الإجراء 3 إلى إجراءات أولية لها ما يعادلها مباشرة في VBScript.

يمكن وصف الوحدة النمطية write_array(T) على النحو التالي:


début
    construire chaîne texte "valeur1,valeur2,...." à partir du tableau T
    écrire texte
fin

يمكن وصف الوحدة النمطية write_array(T) على النحو التالي (بافتراض أن مؤشرات عناصر T تبدأ من 0):

début
      N<-- indice dernier élément du tableau T
      pour IFIN variant de N à 1
      faire
          //on recherche l'indice IMAX du plus gd élément de T
          // IFIN est l'indice du dernier élément de T

          chercher_max(T, IFIN, IMAX) 

          // on échange l'élément le plus grand de T avec le dernier élément de T

          échanger (T, IMAX, IFIN)

      finfaire
FIN

هنا، تستخدم الخوارزمية مرة أخرى إجراءات غير أولية:


 . chercher_max(T, IFIN, IMAX)
 . échanger(T, IMAX, IFIN)

تُرجع الدالة find_max(T, IFIN, IMAX) الفهرس IMAX للعنصر الأكبر في المصفوفة T الذي يكون الفهرس IFIN هو فهرس العنصر الأخير فيها.

تقوم الدالة swap(T, IMAX, IFIN) بتبديل عنصرين في المصفوفة T، وهما العنصران الموجودان عند الفهرسين IMAX و IFIN.

لذلك يجب علينا وصف العمليات الجديدة غير الأولية.

الوحدة النمطية find_max(A, IFIN, IMAX)
   begin
        IMAX<--0

        لـ i تتراوح من 1 إلى IFIN
        افعل
           إذا كان T[i] > T[IMAX]
             ابدأ
                IMAX<--i
             نهاية
        finfaire
    نهاية
وحدة التبادل (T IMAX، IFIN)
  بداية
       temp<----T[IMAX]
       T[IMAX]<---T[IFIN]
       T[IFIN]<---temp
  نهاية

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

يُعرف المبدأ المطبق هنا بالتحليل من أعلى إلى أسفل. إذا حددنا إطار عمل الحل، فسنحصل على ما يلي:

لدينا بنية شجرية.

5.3. وظائف وإجراءات VBScript

بمجرد إجراء التحليل المعياري، يمكن للمبرمج ترجمة وحدات الخوارزمية الخاصة به إلى دوال أو إجراءات VBScript. تقبل كل من الدوال والإجراءات معلمات الإدخال/الإخراج، لكن الدالة تُرجع نتيجة تسمح باستخدامها في التعبيرات، بينما لا تفعل الإجراء ذلك.

5.3.1. إعلان دوال وإجراءات VBScript

يكون إعلان إجراء VBScript كما يلي

sub nomProcédure([Byref/Byval] param1, [Byref/Byval] param2, ...)
    instructions
end sub

وذلك الخاص بالدالة

function nomFonction([Byref/Byval] param1, [Byref/Byval] param2, ...)
    instructions
end sub

لإرجاع النتيجة، يجب أن تتضمن الدالة عبارة تعيين تعين النتيجة لمتغير يحمل نفس اسم الدالة:

اسم\_الدالة=النتيجة

ينتهي تنفيذ الدالة أو الإجراء بطريقتين:

  1. عند الوصول إلى عبارة end function أو end sub
  2. عند الوصول إلى عبارة exit function أو exit sub

بالنسبة للدالة، لاحظ أنه يجب تعيين النتيجة إلى متغير يحمل اسم الدالة قبل أن تنتهي الدالة بعبارة end function أو exit function.

5.3.2. أوضاع تمرير المعلمات لدالة أو إجراء

في إعلان معلمات الإدخال والإخراج لدالة أو إجراء، يتم تحديد وضع (byRef، byVal) تمرير المعلمات من البرنامج المستدعي إلى البرنامج المستدعى:

sub nomProcédure([Byref/Byval] param1, [Byref/Byval] param2, ...)

function nomFonction([Byref/Byval] param1, [Byref/Byval] param2, ...)

عندما لا يتم تحديد وضع byRef أو byVal، يتم استخدام وضع byRef.

المعلمات الفعلية، المعلمات الشكلية

لنفترض وجود دالة VBScript محددة على النحو التالي

function nomFonction([Byref/Byval] paramForm1, [Byref/Byval] paramForm2, ...)
...
end function

تسمى المعلمات paramForm1 المستخدمة في تعريف الدالة أو الإجراء بالمعلمات الشكلية. يمكن استدعاء الدالة السابقة من البرنامج الرئيسي أو من وحدة نمطية أخرى باستخدام عبارة مثل:

résultat=nomFonction(paramEff1, paramEff2, ...)

تُسمى المعلمات paramEffi المستخدمة في استدعاء الدالة أو الإجراء «المعلمات الفعلية». وعندما يبدأ تنفيذ الدالة functionName، تتلقى المعلمات الشكلية قيم المعلمات الفعلية المقابلة لها. وتحدد الكلمتان الرئيسيتان byRef وbyVal طريقة نقل هذه القيم.

وضع التمرير بالقيمة (byVal)

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

وضع التمرير بالمرجع (byRef)

يُعد وضع التمرير هذا هو الوضع الافتراضي في حالة عدم تحديد أي وضع لتمرير المعلمات. عندما تحدد معلمة شكلية وضع التمرير هذا، فإن المعلمة الشكلية والمعلمة الفعلية المقابلة لها تكونان متغيرًا واحدًا. وبالتالي، إذا قامت الدالة بتعديل المعلمة الشكلية، يتم تعديل المعلمة الفعلية أيضًا. يُعد وضع التمرير هذا مناسبًا تمامًا لـ:

  • معلمات الإخراج، حيث يجب إعادة تمرير قيمها إلى البرنامج المستدعي
  • معلمات الإدخال التي يكون نسخها مكلفًا، مثل المصفوفات

يُظهر البرنامج التالي أمثلة على تمرير المعلمات:

البرنامج


Sub proc1(byval i, ByRef j, k)
  ' i is passed by value (byval) - the effective parameter and the formal parameter are then different
  ' j is passed by value (byref) - the effective parameter and the formal parameter are then identical
  ' the k passage mode is not specified. The default is by reference
  i=i+1
  j=j+1
  k=k+1
  affiche "dans proc1",i,j,k
End Sub
 
 Sub affiche(byval msg, ByVal i, ByVal j, ByVal k)
  ' displays the values of i and j and k
  wscript.echo msg & " i=" & i & " j=" & j & " k=" & k
End Sub
 
 
' ------------- calls to functions and procedures
 
' init i and j
  i=4:j=5 : k=6
 
' check
  affiche "dans programme principal, avant l'appel à proc1 :",i,j,k

' call proc1 procedure
  proc1 i,j,k
 
' check
  affiche "dans programme principal, après l'appel à proc1 :",i,j,k
 
' end
  wscript.quit 0

النتائج

dans programme principal, avant l'appel à proc1 : i=4 j=5 k=6
dans proc1 i=5 j=6 k=7
dans programme principal, après l'appel à proc1 : i=4 j=6 k=7

تعليقات

  • في نص VBScript، لا يوجد مكان محدد للوظائف والإجراءات. يمكن أن تكون في أي مكان في شفرة المصدر. عمومًا، يتم تجميعها إما في البداية أو في النهاية، ويتم تنظيم البرنامج الرئيسي ككتلة متصلة.

5.3.3. قواعد استدعاء الدوال والإجراءات

لنفترض أن p إجراء يقبل المعلمات الشكلية pf1، pf2، ...

  • يأخذ استدعاء الإجراء p الشكل
p pe1, pe2, ...

بدون أقواس حول المعلمات

  • إذا كانت الإجراء p لا تقبل أي معلمات، فيمكن استخدام إما call p أو p() والإعلان sub p أو sub p()

لنفترض أن f هي دالة تقبل المعلمات الشكلية pf1 و pf2 و...

  • يتم استدعاء الدالة f بالشكل
résultat=f(pe1, pe2, ...)

يجب وضع الأقواس حول المعلمات. إذا كانت الدالة f لا تأخذ أي معلمات، فيمكن استخدام إما الاستدعاء f أو f() والإعلان function f أو function f().

  • قد يتم تجاهل نتيجة الدالة f من قبل البرنامج المستدعي. عندئذ تُعتبر الدالة f إجراءً وتخضع لقواعد استدعاء الإجراءات. نكتب عندئذ f pe1, pe2, ... (بدون أقواس) لاستدعاء الدالة f.

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

  • وبالتالي، يمكننا كتابة MyFile.WriteLine "This is a test." أو MyFile.WriteLine("This is a test.")
  • ولكن بينما يمكننا كتابة wscript.echo 4، لا يمكننا كتابة wscript.echo(4).

سنتقيد بالقواعد التالية:

  • لا تضع أقواسًا حول معلمات الإجراء أو الدالة المستخدمة كإجراء
  • أقواس حول معلمات الدالة

5.3.4. بعض أمثلة الدوال

فيما يلي بعض الأمثلة على تعريفات الدوال واستخداماتها:

برنامج


 Function plusgrandque(byval i, ByVal j)
  ' returns boolean true if i>j, boolean false otherwise
 
  ' data verification
  If isnumeric(i) And isnumeric(j) Then
    If i>j Then
      plusgrandque=true
    Else
      plusgrandque=false
    End If
  Else
    wscript.echo "Arguments (" & i & "," & j & ") erronés"
    plusgrandque=false
  End If
  Exit Function
End Function
 
 Function rendUnTableau(byval n)
  ' makes an array of n elements
  tableau=array()
  ' check validity of parameter n
  If isnumeric(n) And n>=1 Then
    ReDim Preserve tableau(n)
    For i= 0 To n-1
      tableau(i)=i
    Next
  Else
    wscript.echo "Argument [" & n & "] erroné"
  End If
  ' we return the result
  rendUnTableau=tableau
End Function
 
 Function argumentsVariables(byref arguments)
  ' arguments is an array of numbers whose sum is returned
  somme=0
  For i=0 To ubound(arguments)
    somme=somme+arguments(i)
  Next
  argumentsVariables=somme
End Function
 
  ' two parameter-free functions declared in 2 different ways
  Function sansParametres1
    sansParametres=4
  End Function
 
  Function sansParametres2()
    sansParametres=4
  End Function
 

' ------------- calls to functions and procedures
 
' calls function plusgrandque
  wscript.echo "plusgrandque(10,6)=" & plusgrandque(10,6)
  wscript.echo "plusgrandque(6,10)=" & plusgrandque(6,10)
  wscript.echo "plusgrandque(6,6)=" & plusgrandque(6,6)
  wscript.echo "plusgrandque(6,'a')=" & plusgrandque(6,"a")
 
' calls to the rendUnTableau function
  monTableau=rendUnTableau(10)
  For i=0 To ubound(monTableau)
    wscript.echo monTableau(i)
  Next
  monTableau=rendUnTableau(-6)
  For i=0 To ubound(monTableau)
    wscript.echo monTableau(i)
  Next
 
' calls to the argumentsVariables function
  wscript.echo "somme=" & argumentsVariables(array(-1,2,7,8))
  wscript.echo "somme=" & argumentsVariables(array(-1,10,12))
 
' function calls without parameters
  res=sansParametres1
  res=sansParametres1()
  sansParametres1
  sansParametres1()
 
  res=sansParametres2
  res=sansParametres2()
  sansParametres2
  sansParametres2()
 
' end
  wscript.quit 0

النتائج

plusgrandque(10,6)=Vrai
plusgrandque(6,10)=Faux
plusgrandque(6,6)=Faux
Arguments (6,a) erronés
plusgrandque(6,'a')=Faux
0
1
2
3
4
5
6
7
8
9

Argument [-6] erroné
somme=16
somme=21
somme=10

تعليقات

  • توضح الدالة `rendUnTableau` أن الدالة يمكنها إرجاع نتائج متعددة بدلاً من نتيجة واحدة فقط. كل ما تحتاجه هو وضعها في متغير صفيف وإرجاع هذا المتغير كنتيجة.
  • وعلى العكس من ذلك، توضح الدالة argumentsVariables أنه يمكنك كتابة دالة تقبل عددًا متغيرًا من الوسيطات. هنا أيضًا، ما عليك سوى وضعها في متغير صفيف وجعل هذا المتغير معلمة دالة.

5.3.5. معلمة الإخراج أو نتيجة الدالة

لنفترض أن تحليل أحد التطبيقات أظهر الحاجة إلى وحدة نمطية M مع معلمات إدخال Ei ومعلمات إخراج Sj. تذكر أن معلمات الإدخال هي المعلومات التي يوفرها البرنامج المستدعي للبرنامج المستدعى، وبالعكس، معلمات الإخراج هي المعلومات التي يوفرها البرنامج المستدعى للبرنامج المستدعي. في VBScript، هناك عدة حلول لمعلمات الإخراج:

  • إذا كان هناك معلمة إخراج واحدة فقط، فيمكن جعلها نتيجة الدالة. عندئذٍ لن تكون هناك معلمة إخراج، بل مجرد نتيجة دالة.
  • إذا كان هناك n معلمات إخراج، يمكن أن تكون إحداها نتيجة الدالة، بينما تعمل n-1 المتبقية كمعلمات إخراج. بدلاً من ذلك، يمكن استخدام إجراء مع n معلمات إخراج بدلاً من الدالة. يمكن أيضًا استخدام دالة تُرجع مصفوفة تحتوي على القيم n التي سيتم إرجاعها إلى البرنامج المستدعي. تذكر أن البرنامج المستدعى يعيد نتائجه إلى البرنامج المستدعي بالقيمة. يتم تجنب هذا النسخ عندما يتم تمرير معلمات الإخراج بالرجوع. وبالتالي، فإن الحل الأخير يوفر الوقت.

5.4. برنامج VBScript لفرز القيم

بدأنا مناقشتنا حول البرمجة المعيارية بدراسة خوارزمية لفرز القيم العددية التي يتم إدخالها عبر لوحة المفاتيح. فيما يلي تطبيق VBScript الذي يمكن استخدامه:

البرنامج

' main program
Option Explicit

Dim T        ' the table of values to be sorted

' reading values
T=lire_tableau

' value sorting
trier_tableau T

' display of sorted values
ecrire_tableau T

' end
wscript.quit 0

' ---------- functions & procedures

' -------- lire_tableau
Function lire_tableau
    ' values are requested
    wscript.stdout.write "Tapez les valeurs à trier sous la forme val1 val2  ... valn : "
    ' we read them
    Dim valeurs
    valeurs=wscript.stdin.readLine
    ' we put them in a table
    lire_tableau=split(valeurs," ")
End Function

' -------- ecrire_tableau
Sub ecrire_tableau(byref T)
    ' displays the contents of table T
    wscript.echo join(T," ")
End Sub

' -------- trier_tableau
Sub trier_tableau (byref T)
    ' sorts array T in ascending order

    ' find the imax index of the T[0..ifin] array
    ' to exchange T[imax] with the last element of array T[0..ifin]
    ' then start again with an array with 1 fewer element

    Dim ifin, imax, temp
    For ifin=ubound(T) To 1 Step -1
        ' find the imax index of the T[0..ifin] array
        imax=chercher_max(T,ifin)
        ' we exchange the max with the last element of array T[0..ifin]
        temp=T(ifin):T(ifin)=T(imax):T(imax)=temp
    Next
End Sub

' -------- chercher_max
Function chercher_max(byRef T, ByVal ifin)
    ' find the imax index of the T[0..ifin] array
    Dim i, imax
    imax=0
    For i=1 To ifin
        If cdbl(T(i))>cdbl(T(imax)) Then imax=i
    Next

    ' We return the result
    chercher_max=imax
End Function

النتائج

Tapez les valeurs à trier sous la forme val1 val2  ... valn : 10 9 8 7 6 1
1 6 7 8 9 10

تعليقات:

  • لم يتم تنفيذ وحدة التبديل المحددة في الخوارزمية الأولية كوحدة VBScript هنا لأنها اعتُبرت بسيطة جدًا بحيث لا تستدعي إنشاء وحدة منفصلة.

5.5. برنامج TAX في شكل وحدات

نعيد النظر في برنامج حساب الضرائب، الذي تمت كتابته هذه المرة في شكل وحدات

البرنامج

' calculating a taxpayer's tax liability
' the program must be called with three parameters: married children salary
' married: character Y if married, N if unmarried
' children: number of children
' salary: annual salary without cents

' mandatory variable declaration
Option Explicit
Dim erreur

' retrieve arguments and check their validity
Dim marie, enfants, salaire
erreur=getArguments(marie,enfants,salaire)
' mistake?
If erreur(0)<>0 Then wscript.echo erreur(1) : wscript.quit erreur(0)

' retrieve the data needed to calculate taxes
Dim limites, coeffR, coeffN
getData limites,coeffR,coeffN

' the result is displayed
wscript.echo "impôt=" & calculerImpot(marie,enfants,salaire,limites,coeffR,coeffN)

' leave without error
wscript.quit 0

' ------------ functions and procedures

' ----------- getArguments
Function getArguments(byref marie, ByRef enfants, ByRef salaire)
    ' must retrieve three values passed as arguments to the main program
    ' an argument is passed to the program without spaces in front and behind it
    ' use regular expressions to check data validity

    ' returns an error array variant with 2 values
    ' error(0): error code, 0 if no error
    ' error(1): error message if error otherwise empty string

    Dim syntaxe
    syntaxe= _
    "Syntaxe : pg marié enfants salaire" & vbCRLF & _
    "marié : caractère O si marié, N si non marié" & vbCRLF & _
    "enfants : nombre d'enfants (entier >=0)" & vbCRLF & _
    "salaire : salaire annuel sans les centimes (entier >=0)"

    ' we check that there are 3 arguments
    Dim nbArguments
    nbArguments=wscript.arguments.count
    If nbArguments<>3 Then
        ' error msg
        getArguments= array(1,syntaxe & vbCRLF & vbCRLF & "erreur : nombre d'arguments incorrect")
        ' end
        Exit Function
    End If

    Dim modele, correspondances
    Set modele=new regexp

    ' marital status must be among the characters oOnN
    modele.pattern="^[oOnN]$"
    Set correspondances=modele.execute(wscript.arguments(0))
    If correspondances.count=0 Then
        ' error msg
        getArguments=array(2,syntaxe & vbCRLF & vbCRLF & "erreur : argument marie incorrect")
        ' we leave
        Exit Function
    End If
    ' the value
    If lcase(wscript.arguments(0)) = "o"Then
        marie=true
    Else
        marie=false
    End If

    ' children must be an integer >=0
    modele.pattern="^\d{1,2}$"
    Set correspondances=modele.execute(wscript.arguments(1))
    If correspondances.count=0 Then
        ' error
        getArguments= array(3,syntaxe & vbCRLF & vbCRLF & "erreur : argument enfants incorrect")
        ' we leave
        Exit Function
    End If
    ' the value
    enfants=cint(wscript.arguments(1))

    ' salary must be an integer >=0
    modele.pattern="^\d{1,9}$"
    Set correspondances=modele.execute(wscript.arguments(2))
    If correspondances.count=0 Then
        ' error
        getArguments= array(4,syntaxe & vbCRLF & vbCRLF & "erreur : argument salaire incorrect")
        ' we leave
        Exit Function
    End If
    ' the value
    salaire=clng(wscript.arguments(2))

    ' finished without error
    getArguments=array(0,"")
End Function

' ----------- getData
Sub getData(byref limites, ByRef coeffR, ByRef coeffN)
    ' we define the data needed to calculate the tax in 3 tables
    limites=array(12620,13190,15640,24740,31810,39970,48360, _
    55790,92970,127860,151250,172040,195000,0)
    coeffr=array(0,0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.4,0.45, _
    0.5,0.55,0.6,0.65)
    coeffn=array(0,631,1290.5,2072.5,3309.5,4900,6898.5,9316.5, _
    12106,16754.5,23147.5,30710,39312,49062)
End Sub

' ----------- calculerImpot
Function calculerImpot(byval marie,ByVal enfants,ByVal salaire, ByRef limites, ByRef coeffR, ByRef coeffN)

    ' the number of shares is calculated
    Dim nbParts
    If marie=true Then
        nbParts=(enfants/2)+2
    Else
        nbParts=(enfants/2)+1
    End If
    If enfants>=3 Then nbParts=nbParts+0.5

    ' we calculate the family quotient and taxable income
    Dim revenu, qf
    revenu=0.72*salaire
    qf=revenu/nbParts

    ' tax calculation
    Dim i, impot
    i=0
    Do While i<ubound(limites) And qf>limites(i)
        i=i+1
    Loop
    calculerImpot=int(revenu*coeffr(i)-nbParts*coeffn(i))
End Function

تعليقات

  • تسترد الدالة getArguments معلومات دافع الضرائب (الزوج/الزوجة، الأبناء، الراتب). وهنا، يتم تمريرها كمعاملات إلى برنامج VBScript. إذا تغير هذا الأمر — على سبيل المثال، إذا جاءت هذه المعاملات من واجهة مستخدم رسومية — فسيكون من الضروري إعادة كتابة الإجراء getArguments فقط، وليس الإجراءات الأخرى.
  • يمكن لدالة getArguments اكتشاف الأخطاء في الحجج. وعندما يحدث ذلك، كان من الممكن أن يقرر المرء إيقاف تنفيذ البرنامج داخل دالة getArguments باستخدام عبارة wscript.quit. ولا ينبغي أبدًا القيام بذلك داخل دالة أو إجراء. فإذا اكتشفت دالة أو إجراء خطأً، يجب أن تشير إلى ذلك بطريقة ما إلى البرنامج المستدعي. ويترك للبرنامج المستدعي أن يقرر ما إذا كان سيوقف التنفيذ أم لا، وليس للإجراء. في مثالنا، قد يقرر البرنامج المستدعي أن يطلب من المستخدم إعادة إدخال البيانات غير الصحيحة عبر لوحة المفاتيح بدلاً من إيقاف التنفيذ.
  • هنا، تُرجع دالة getArguments متغير صفيف حيث يكون العنصر الأول رمز خطأ (0 في حالة عدم وجود خطأ) والثاني رسالة خطأ في حالة حدوث خطأ. من خلال التحقق من النتيجة المُرجعة، يمكن للبرنامج المستدعي تحديد ما إذا كان قد حدث خطأ أم لا.
  • تسترد الإجراء getData البيانات اللازمة لحساب الضريبة. هنا، يتم تعريف هذه البيانات مباشرةً داخل الإجراء getData. إذا كانت هذه البيانات قادمة من مصدر آخر — مثل ملف أو قاعدة بيانات — فسيكون من الضروري إعادة كتابة الإجراء getData فقط، وليس الإجراءات الأخرى.
  • تحسب الدالة `calculerImpot` الضريبة بمجرد الحصول على جميع البيانات، بغض النظر عن كيفية الحصول عليها.
  • لاحظ، إذن، أن البرمجة المعيارية تسمح بإعادة استخدام وحدات معينة في سياقات مختلفة. وقد تطور هذا المفهوم بشكل كبير على مدار العشرين عامًا الماضية ضمن مفهوم الكائنات.