Skip to content

5. Les fonctions et procédures

5.1. Les fonctions prédéfinies de vbscript

La richesse d'un langage dérive en grande partie de sa bibliothèque de fonctions, ces dernières pouvant être encapsulées dans des objets sous le nom de méthodes. Sous cet aspect, on peut considérer que vbscript est plutôt pauvre.

Le tableau suivant définit les fonctions de VBScript hors objets. Nous ne les détaillerons pas. Leur nom est en général une indication de leur rôle. Le lecteur consultera la documentation pour avoir des détails sur une fonction particulière.

Abs

Array

Asc

Atn

CBool

CByte

CCur

CDate

CDbl

Chr

CInt

CLng

Conversions

Cos

CreateObject

CSng

Date

DateAdd

DateDiff

DatePart

DateSerial

DateValue

Day

Derived Maths

Eval

Exp

Filter

FormatCurrency

FormatDateTime

FormatNumber

FormatPercent

GetLocale

GetObject

GetRef

Hex

Hour

InputBox

InStr

InStrRev

Int, Fixs

IsArray

IsDate

IsEmpty

IsNull

IsNumeric

IsObject

Join

LBound

LCase

Left

Len

LoadPicture

Log

LTrim; RTrim; and Trims

Maths

Mid

Minute

Month

MonthName

MsgBox

Now

Oct

Replace

RGB

Right

Rnd

Round

ScriptEngine

ScriptEngineBuildVersion

ScriptEngineMajorVersion

ScriptEngineMinorVersion

Second

SetLocale

Sgn

Sin

Space

Split

Sqr

StrComp

String

Tan

Time

Timer

TimeSerial

TimeValue

TypeName

UBound

UCase

VarType

Weekday

WeekdayName

Year

5.2. Programmation modulaire

Décrire la solution programmée d'un problème, c'est décrire la suite d'actions élémentaires exécutables par l'ordinateur et capables de résoudre le problème. Selon les langages ces opérations élémentaires sont plus ou moins sophistiquées. On trouve par exemple:

  • lire une donnée provenant du clavier ou du disque
  • écrire une donnée à l'écran, sur imprimante, sur disque, etc
  • calculer des expressions
  • se déplacer dans un fichier
  • ...

Décrire un problème complexe peut nécessiter plusieurs milliers de ces instructions élémentaires et plus. Il est alors très difficile pour l'esprit humain d'avoir une vue globale d'un programme. Devant cette difficulté d'appréhender le problème dans sa globalité, on le décompose alors en sous-problèmes plus simples à résoudre. Considérons le problème suivant : Trier une liste de valeurs numériques tapées au clavier et afficher la liste triée à l'écran.

On peut dans un premier temps décrire la solution sous la forme suivante:

  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

On a décomposé le problème en 3 sous-problèmes, plus simples à résoudre. L'écriture algorithmique est souvent plus formalisée que la précédente et l'algorithme s'écrira plutôt:

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

où T représente un tableau. Les opérations

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

sont des opérations non élémentaires qui doivent être décrites à leur tour par des opérations élémentaires. Ceci est fait dans ce qu'on appelle des modules. La donnée T est appelée un paramètre du module. C'est une information que le programme appelant passe au module appelé (paramètre d'entrée) ou reçoit du module appelé (paramètre de sortie). Les paramètres d'un module sont donc les informations qui sont échangées entre le programme appelant et le module appelé.

module lire_tableau(T)

module trier_tableau(T)

module écrire_tableau(T)

Le module lire_tableau(T) pourrait être décrit comme suit :


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

Ici, nous avons suffisamment décrit le module lire_tableau. En effet, les trois actions nécessaires ont une traduction immédiate en vbscript. La dernière nécessitera l'utilisation de la fonction split. Si vbscript n'avait pas cette fonction, l'action 3 devrait être décomposée à son tour en actions élémentaires ayant un équivalent immédiat en vbscript.

Le module écrire_tableau(T) pourrait être décrit comme suit :


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

Le module écrire_tableau(T) pourrait être décrit comme suit (on suppose que les indices des éléments de T commencent à 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

Ici l'algorithme utilise de nouveau des actions non élémentaires:


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

chercher_max(T, IFIN, IMAX) rend l'indice IMAX de l'élément le plus grand du tableau T dont l'indice du dernier élément est IFIN.

échanger(T, IMAX, IFIN) échange 2 éléments du tableau T , ceux d'indice IMAX et IFIN.

Il faut donc décrire les nouvelles opérations non élémentaires.

module chercher_max(A, IFIN, IMAX)

   début
        IMAX<--0

        pour i variant de 1 à IFIN
        faire
           si T[i]>T[IMAX] alors 
             début
                IMAX<--i
             fin
        finfaire
    fin

module échanger(T IMAX, IFIN)

  début
       temp<----T[IMAX]
       T[IMAX]<---T[IFIN]
       T[IFIN]<---temp
  fin

Le problème initial a été complètement décrit à l'aide d'opérations élémentaires vbscript et peut donc maintenant faire l'objet d'une traduction dans ce langage. On notera que les actions élémentaires peuvent différer d'un langage à l'autre et que donc l'analyse d'un problème doit à un certain moment tenir compte du langage de programmation utilisé. Un objet qui existe dans un langage peut ne pas exister dans un autre et modifier alors l'algorithme utilisé. Ainsi, si un langage avait une fonction de tri, il serait ici absurde de ne pas l'utiliser.

Le principe appliqué ici, est celui dit de l'analyse descendante. Si on représente l'ossature de la solution, on a la chose suivante :

On a une structure en arbre.

5.3. Les fonctions et procédures vbscript

Une fois l'analyse modulaire opérée, le programmeur peut traduire les modules de son algorithme en fonctions ou procédures vbscript. Les fonctions et procédures admettent toutes deux des paramètres d'entrée/sortie mais la fonction rend un résultat qui permet son utilisation dans des expressions alors que la procédure n'en rend pas.

5.3.1. Déclaration des fonctions et procédures vbscript

La déclaration d'une procédure vbscript est la suivante

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

et celle d'une fonction

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

Pour rendre son résultat, la fonction doit comporter une instruction d'affectation du résultat à une variable portant le nom de la fonction :

nomFonction=résultat

L'exécution d'une fonction ou procédure s'arrête de deux façons :

  1. à la rencontre de l'instruction de fin de fonction (end function) ou fin de procédure (end sub)
  2. à la rencontre de l'instruction de sortie de fonction (exit function) ou de procédure (exit sub)

Pour la fonction, on se rappellera que le résultat doit avoir été affecté à une variable portant le nom de la fonction avant que celle-ci ne se termine par un end function ou exit function.

5.3.2. Modes de passage des paramètres d'une fonction ou procédure

Dans la déclaration des paramètres d'entrée-sortie d'une fonction ou procédure, on précise le mode (byRef,byVal) de transmission du paramètre du programme appelant vers le programme appelé :

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

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

Lorsque le mode de transmission byRef ou byVal n'est pas précisé, c'est le mode byRef qui est utilisé.

Paramètres effectifs, paramètres formels

Soit une fonction vbscript définie par

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

Les paramètres parmamFormi utilisés dans la définition de la fonction ou de la procédure sont appelés paramètres formels. La fonction précédente pourra être utilisée à partir du programme principal ou d'un autre module par une instruction du genre :

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

Les paramètres parmamEffi utilisés dans l'appel à la fonction ou la procédure sont appelés paramètres effectifs. Lorsque l'exécution de la fonction nomFonction commence, les paramètres formels reçoivent les valeurs des paramètres effectifs correspondants. Les mots clés byRef et byVal fixent le mode de transmission de ces valeurs.

Mode de transmission par valeur (byVal)

Lorsqu'un paramètre formel précise ce mode de transmission, le paramètre formel et le paramètre effectif sont alors deux variables différentes. La valeur du paramètre effectif est copiée dans le paramètre formel avant exécution de la fonction ou procédure. Si celle-ci modifie la valeur du paramètre formel au cours de son exécution, cela ne modifie en rien la valeur du paramètre effectif correspondant. Ce mode de transmission convient bien aux paramètres d'entrée de la fonction ou procédure.

Mode de transmission par référence (byRef)

Ce mode de transmission est le mode par défaut si aucun mode de transmission du paramètre n'est indiqué. Lorsqu'un paramètre formel précise ce mode de transmission, le paramètre formel et le paramètre effectif correspondant sont une seule et même variable. Ainsi si la fonction modifie le paramètre formel, le paramètre effectif est également modifié. Ce mode de transmission convient bien :

  • aux paramètres de sortie car la valeur de ceux-ci doivt être transmise au programme appelant
  • aux paramètres d'entrée coûteux à recopier tels les tableaux

Le programme suivant montre des exemples de passage de paramètres :

Programme


Sub proc1(byval i, ByRef j, k)
  ' i est passé par valeur (byval) - le paramètre effectif et le paramètre formel sont alors différents
  ' j est passé par valeur (byref) - le paramètre effectif et le paramètre formel sont alors identiques
  ' le mode de passage de k n'est pas précisé. Par défaut, c'est par référence
  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)
  ' affiche les valeurs de i et j et k
  wscript.echo msg & " i=" & i & " j=" & j & " k=" & k
End Sub


' ------------- appels aux fonctions et procédures

' init i et j
  i=4:j=5 : k=6

' vérification
  affiche "dans programme principal, avant l'appel à proc1 :",i,j,k

' appel procédure proc1
  proc1 i,j,k

' vérification
  affiche "dans programme principal, après l'appel à proc1 :",i,j,k

' fin
  wscript.quit 0

Résultats

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

Commentaires

  • Dans un script vbscript, il n'y a pas de place particulière pour les fonctions et les procédures. Elles peuvent être n'importe où dans le texte source. En général, on les regroupe soit au début soit à la fin et on fait en sorte que le programme principal constitue un bloc continu.

5.3.3. Syntaxe d'appel des fonctions et procédures

Soit une procédure p admettant des paramètres formels pf1, pf2, ...

  • l'appel à la procédure p se fait sous la forme
p pe1, pe2, ...

sans parenthèses autour des paramètres

  • si la procédure p n'admet aucun paramètre, on peut indifféremment utiliser l'appel p ou p() et la déclaration sub p ou sub p()

Soit une fonction f admettant des paramètres formels pf1, pf2, ...

  • l'appel à la fonction f se fait sous la forme
résultat=f(pe1, pe2, ...)

les parenthèses autour des paramètres sont obligatoires. Si la fonction f n'admet aucun paramètre, on peut indifféremment utiliser l'appel f ou f() et la déclaration function f ou function f().

  • le résultat de la fonction f peut être ignoré par le programme appelant. La fonction f est alors considérée comme une procédure et suit les règles d'appel des procédures. On écrit alors f pe1, pe2, ... (sans parenthèses) pour appeler la fonction f.

Si la fonction ou procédure est une méthode d'objet, il semblerait que les règles soient quelque peu différentes et non homogènes.

  • ainsi on peut écrire MyFile.WriteLine "Ceci est un test." ou MyFile.WriteLine("Ceci est un test.")
  • mais si on peut écrire wscript.echo 4, on ne peut pas écrire wscript.echo(4).

On s'en tiendra aux règles suivantes :

  • pas de parenthèses autour des paramètres d'une procédure ou d'une fonction utilisée comme une procédure
  • parenthèses autour des paramètres d'une fonction

5.3.4. Quelques exemples de fonctions

On trouvera ci-dessous quelques exemples de définitions et utilisations de fonctions :

Programme


 Function plusgrandque(byval i, ByVal j)
  ' rend le booléen vrai si i>j, le booléen faux sinon

  ' vérification des données
  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)
  ' rend un tableau de n éléments
  tableau=array()
  ' vérification validité du paramètre 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
  ' on rend le résultat
  rendUnTableau=tableau
End Function

 Function argumentsVariables(byref arguments)
  ' arguments est un tableau de nombres dont on rend la somme
  somme=0
  For i=0 To ubound(arguments)
    somme=somme+arguments(i)
  Next
  argumentsVariables=somme
End Function

  ' deux fonctions sans paramètres déclarées de 2 façons différentes
  Function sansParametres1
    sansParametres=4
  End Function

  Function sansParametres2()
    sansParametres=4
  End Function

  
' ------------- appels aux fonctions et procédures

' appels fonction 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")

' appels à la fonction rendUnTableau
  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

' appels à la fonction argumentsVariables
  wscript.echo "somme=" & argumentsVariables(array(-1,2,7,8))
  wscript.echo "somme=" & argumentsVariables(array(-1,10,12))

' appels des fonctions sans paramètres
  res=sansParametres1
  res=sansParametres1()
  sansParametres1
  sansParametres1()

  res=sansParametres2
  res=sansParametres2()
  sansParametres2
  sansParametres2()

' fin
  wscript.quit 0

Résultats

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

Commentaires

  • la fonction rendUnTableau montre qu'une fonction peut rendre plusieurs résultats et non un seul. Il suffit qu'elle les place dans un variant tableau et qu'elle rende ce variant comme résultat.
  • inversement la fonction argumentsVariables montre qu'on peut écrire une fonction qui admet un nombre variable d'arguments. Il suffit là également de les mettre dans un variant tableau et de faire de ce variant un paramètre de la fonction.

5.3.5. Paramètre de sortie ou résultat d'une fonction

Supposons que l'analyse d'une application ait montré la nécessité d'un module M avec des paramètres d'entrée Ei et des paramètres de sortie Sj. Rappelons que les paramètres d'entrée sont des informations que le programme appelant donne au programme appelé et qu'inversement les paramètres de sortie sont des informations que le programme appelé donne au programme appelant. On a en vbscript plusieurs solutions pour les paramètres de sortie :

  • s'il n'y a qu'un seul paramètre de sortie, on peut en faire le résultat d'une fonction. Il n'y a alors plus de paramètre de sortie mais simplement un résultat de fonction.
  • s'il y a n paramètres de sortie, l'un d'entre-eux peut servir de résultat de fonction , les n-1 autres restant des paramètres de sortie. On peut aussi ne pas utiliser de fonction mais une procédure à n paramètres de sortie. On peut également utiliser une fonction qui rendra un tableau dans lequel on aura placé les n valeurs à rendre au programme appelant. On se rappellera que le programme appelé rend ses résultats au programme appelant par recopie de valeurs. Cette recopie est évitée dans le cas de paramètres de sortie passés par référence. Il y a donc dans cette dernière solution un gain de temps.

5.4. Le programme Vbscript de tri de valeurs

Nous avions commencé la discussion sur la programmation modulaire par l'étude algorithmique d'un tri de valeurs numériques tapées au clavier. Voici la traduction VBScript qui pourrait en être faite :

Programme

' programme principal
Option Explicit

Dim T        ' le tableau de valeurs à trier

' lecture des valeurs
T=lire_tableau

' tri des valeurs
trier_tableau T

' affichage des valeurs triées
ecrire_tableau T

' fin
wscript.quit 0

' ---------- fonctions & procédures

' -------- lire_tableau
Function lire_tableau
    ' on demande les valeurs
    wscript.stdout.write "Tapez les valeurs à trier sous la forme val1 val2  ... valn : "
    ' on les lit
    Dim valeurs
    valeurs=wscript.stdin.readLine
    ' on les met dans un tableau
    lire_tableau=split(valeurs," ")
End Function

' -------- ecrire_tableau
Sub ecrire_tableau(byref T)
    ' affiche le contenu du tableau T
    wscript.echo join(T," ")
End Sub

' -------- trier_tableau
Sub trier_tableau (byref T)
    ' tri le tableau T en ordre croissant

    ' on cherche l'indice imax du tableau T[0..ifin]
    ' pour échanger T[imax] avec le dernier élément du tableau T[0..ifin]
    ' ensuite on recommence avec un tableau ayant 1 élément de moins

    Dim ifin, imax, temp
    For ifin=ubound(T) To 1 Step -1
        ' on cherche l'indice imax du tableau T[0..ifin]
        imax=chercher_max(T,ifin)
        ' on l'échange le max avec le dernier élément du tableau 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)
    ' on cherche l'indice imax du tableau T[0..ifin]
    Dim i, imax
    imax=0
    For i=1 To ifin
        If cdbl(T(i))>cdbl(T(imax)) Then imax=i
    Next

    ' On rend le résultat
    chercher_max=imax    
End Function

Résultats

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

Commentaires :

  • le module échanger qui avait été identifié dans l'algorithme initial n'a pas fait ici l'objet d'un module en vbscript parce que jugé trop simple pour faire l'objet d'un module particulier.

5.5. Le programme IMPOTS sous forme modulaire

Nous reprenons le programme de calcul de l'impôt écrit cette fois sous forme modulaire

Programme

' calcul de l'impôt d'un contribuable
' le programme doit être appelé avec trois paramètres : marié enfants salaire
' marié : caractère O si marié, N si non marié
' enfants : nombre d'enfants
' salaire : salaire annuel sans les centimes

' déclaration obligatoire des variables
Option Explicit
Dim erreur

' on récupère les arguments en vérifiant leur validité
Dim marie, enfants, salaire
erreur=getArguments(marie,enfants,salaire)
' erreur ?
If erreur(0)<>0 Then wscript.echo erreur(1) : wscript.quit erreur(0)

' on récupère les données nécessaires au calcul de l'impôt
Dim limites, coeffR, coeffN
getData limites,coeffR,coeffN

' on affiche le résultat
wscript.echo "impôt=" & calculerImpot(marie,enfants,salaire,limites,coeffR,coeffN)

' on quitte sans erreur
wscript.quit 0

' ------------ fonctions et procédures

' ----------- getArguments
Function getArguments(byref marie, ByRef enfants, ByRef salaire)
    ' doit récupérer trois valeurs passées comme argument au programme principal
    ' un argument est transmis au programme sans espaces devant et derrière
    ' on utilisera des expression régulières pour vérifier la validité des données

    ' rend un variant tableau erreur à 2 valeurs
    ' erreur(0) : code d'erreur, 0 si pas d'erreur
    ' erreur(1) : message d'erreur si erreur sinon la chaîne vide

    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)"

    ' on vérifie qu'il y a 3 arguments
    Dim nbArguments
    nbArguments=wscript.arguments.count
    If nbArguments<>3 Then
        ' msg d'erreur
        getArguments= array(1,syntaxe & vbCRLF & vbCRLF & "erreur : nombre d'arguments incorrect")
        ' fin
        Exit Function
    End If

    Dim modele, correspondances
    Set modele=new regexp

    ' le statut marital doit être parmi les caractères oOnN
    modele.pattern="^[oOnN]$"
    Set correspondances=modele.execute(wscript.arguments(0))
    If correspondances.count=0 Then
        ' msg d'erreur
        getArguments=array(2,syntaxe & vbCRLF & vbCRLF & "erreur : argument marie incorrect")
        ' on quitte
        Exit Function
    End If
    ' on récupère la valeur
    If lcase(wscript.arguments(0)) = "o"Then
        marie=true
    Else
        marie=false
    End If

    ' enfants doit être un nombre entier >=0
    modele.pattern="^\d{1,2}$"
    Set correspondances=modele.execute(wscript.arguments(1))
    If correspondances.count=0 Then
        ' erreur
        getArguments= array(3,syntaxe & vbCRLF & vbCRLF & "erreur : argument enfants incorrect")
        ' on quitte
        Exit Function
    End If
    ' on récupère la valeur
    enfants=cint(wscript.arguments(1))

    ' salaire doit être un entier >=0
    modele.pattern="^\d{1,9}$"
    Set correspondances=modele.execute(wscript.arguments(2))
    If correspondances.count=0 Then
        ' erreur
        getArguments= array(4,syntaxe & vbCRLF & vbCRLF & "erreur : argument salaire incorrect")
        ' on quitte
        Exit Function
    End If
    ' on récupère la valeur
    salaire=clng(wscript.arguments(2))

    ' c'est fini sans erreur
    getArguments=array(0,"")
End Function

' ----------- getData
Sub getData(byref limites, ByRef coeffR, ByRef coeffN)  
    ' on définit les données nécessaire au calcul de l'impôt dans 3 tableaux
    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)

    ' on calcule le nombre de parts
    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

    ' on calcule le quotient familial et le revenu imposable
    Dim revenu, qf
    revenu=0.72*salaire
    qf=revenu/nbParts

    ' on calcule l'impôt
    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

Commentaires

  • la fonction getArguments permet de récupérer les informations (marie, enfants, salaire) du contribuable. Ici, elles sont passées en arguments au programme vbscript. Si cela devait changer, par exemple si ces arguments venaient d'une interface graphique, seule la procédure getArguments devrait être réécrite et pas les autres.
  • la fonction getArguments peut détecter des erreurs sur les arguments. Lorsque ceci se produit, on aurait pu décider d'arrêter l'exécution du programme dans la fonction getArguments par une instruction wscript.quit. Ceci ne doit jamais être fait dans une fonction ou procédure. Si une fonction ou procédure détecte une erreur, elle doit le signaler d'une façon ou d'une autre au programme appelant. C'est à lui de prendre la décision d'arrêter l'exécution ou non, pas à la procédure. Dans notre exemple, le programme appelant pourrait décider de redemander à l'utilisateur de retaper la donnée erronée au clavier plutôt que d'arrêter l'exécution.
  • ici, la fonction getArguments rend un variant tableau où le 1er élément est un code d'erreur (0 si pas d'erreur) et le second un message d'erreur si il y a eu erreur. En testant le résultat obtenu, le programme appelant peut savoir s'il y a eu erreur ou non.
  • la procédure getData permet d'obtenir les données nécessaires au calcul de l'impôt. Ici elles sont directement définies dans la procédure getData. Si ces données devaient provenir d'une autre source, d'un fichier ou d'une base de données par exemple, seule la procédure getData devrait être réécrite et pas les autres.
  • la fonction calculerImpot permet de calculer l'impôt une fois que toutes les données ont été obtenues quelque soit la façon dont elles ont été obtenues.
  • on notera donc qu'une écriture modulaire permet une (ré)utilisation de certains modules dans différents contextes. Ce concept a été dans les vingt dernières années fortement développé dans le concept d'objet.