IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Introduction à VBSCRIPT par l'exemple


précédentsommairesuivant

IV. La gestion des erreurs

En programmation, il y a une règle absolue : un programme ne doit jamais "planter" sauvagement. Toutes les erreurs qui peuvent se produire lors de l'exécution du programme doivent être gérées et des messages d'erreurs significatifs générés.

Si nous reprenons l'exemple des impôts traité précédemment, que se passe-t-il si l'utilisateur entre n'importe quoi pour le nombre d'enfants. Regardons sur cet exemple :

 
Sélectionnez

C:\>cscript impots1.vbs o xyzt 200000
C:\impots1.vbs(33, 3) Erreur d'éxecution Microsoft VBScript: Type incompatible: 'cint'

C'est ce qu'on appelle un plantage sauvage. Il y a eu "plantage" sur l'instruction enfants=cint(wscript.arguments(1)) car arguments(1) contenait la chaîne "xyzt".

Avant d'utiliser un variant dont on ne connaît pas la nature exacte, il faut vérifier son sous-type exact. On peut faire ceci de différentes façons :

  • tester le type réel de la donnée contenue dans un variant avec les fonctions vartype ou typename
  • utiliser une expression régulière pour vérifier que le contenu du variant correspond a un certain modèle
  • laisser l'erreur se produire puis l'intercepter pour ensuite la gérer Nous examinons ces différentes méthodes.

IV-A. Connaître le type exact d'une donnée

Rappelons que les fonctions vartype ou varname permettent de connaître le type exact d'une donnée. Cela ne nous est pas toujours d'un grand secours. Par exemple, lorsque nous lisons une donnée tapée au clavier, les fonctions vartype et typename vont nous dire que c'est une chaîne de caractères car c'est ainsi qu'est considérée toute donnée tapée au clavier. Cela ne nous dit pas si cette chaîne peut par exemple être considérée comme un nombre valide. On utilise alors d'autres fonctions pour avoir accès à ce type d'informations :

isNumeric(expression)

rend vrai si expression peut être utilisée comme un nombre

isDate(expression)

rend vrai si expression peut être utilisée comme une date

isEmpty(var)

rend vrai si la variable var n'a pas été initialisée

isNull(var)

rend vrai si la variable var contient des données invalides

isArray(var)

rend vrai si var est un tableau

isObject(var)

rend vrai si var est un objet

L'exemple suivant demande de taper une donnée au clavier jusqu'à ce que celle-ci soit reconnue comme un nombre :

Programme
Sélectionnez

' lecture d'une donnée jusqu'à ce que celle-ci soit reconnue comme un nombre
Option Explicit
Dim fini, nombre
' on boucle tant que la donnée saisie n'est pas correcte
' la boucle est contrôlée par un booléen fini, mis à faux au départ (= ce n'est pas
fini)
fini=false
Do While Not fini
' on demande le nombre
wscript.stdout.write "Tapez un nombre : "
' on le lit
nombre=wscript.stdin.readLine
' le type est forcément string lors d'une lecture
wscript.echo "Type de la donnée lue : " & typename(nombre) & "," & vartype(nombre)
' on teste le type réel de la donnée lue
If isNumeric(nombre) Then
fini=true
Else
wscript.echo "Erreur, vous n'avez pas tapé un nombre. Recommencez svp..."
End If
Loop
' confirmation
wscript.echo "Merci pour le nombre " & nombre
' et fin
wscript.quit 0
Résultat
Sélectionnez

Tapez un nombre : a
Type de la donnée lue : String,8
Erreur, vous n'avez pas tapé un nombre. Recommencez svp...
Tapez un nombre : -12
Type de la donnée lue : String,8
Merci pour le nombre -12

La fonction isNumeric ne nous dit pas si une expression est un entier ou pas. Pour avoir cette information, il faut faire des tests supplémentaires. L'exemple suivant demande un nombre entier >0 :

Programme
Sélectionnez

' lecture d'une donnée jusqu'à ce que celle-ci soit reconnue comme un nombre entier >0
Option Explicit
Dim fini, nombre
' on boucle tant que la donnée saisie n'est pas correcte
' la boucle est contrôlée par un booléen fini, mis à faux au départ (= ce n'est pas
fini)
fini=false
Do While Not fini
' on demande le nombre
wscript.stdout.write "Tapez un nombre entier >0: "
' on le lit
nombre=wscript.stdin.readLine
' on teste le type réel de la donnée lue
If isNumeric(nombre) Then
' est-ce un entier (nombre égal à sa partie entière) positif ?
If (nombre-int(nombre))=0 And nombre>0 Then
fini=true
End If
End If
' msg d'erreur éventuel
If Not fini Then wscript.echo "Erreur, vous n'avez pas tapé un nombre entier >0.
Recommencez svp..."
Loop
' confirmation
wscript.echo "Merci pour le nombre entier >0 : " & nombre
' et fin
wscript.quit 0
Résultats
Sélectionnez

Tapez un nombre entier >0: a
Erreur, vous n'avez pas tapé un nombre entier >0. Recommencez svp...
Tapez un nombre entier >0: -1
Erreur, vous n'avez pas tapé un nombre entier >0. Recommencez svp...
Tapez un nombre entier >0: 10.6
Erreur, vous n'avez pas tapé un nombre entier >0. Recommencez svp...
Tapez un nombre entier >0: 12
Merci pour le nombre entier >0 : 12

Commentaires :

  • int(nombre) donne la partie entière d'un nombre. Un nombre égal à sa partie entière est un entier.
  • On notera, de façon intéressante, qu'il a fallu employer le test If (nombre-int(nombre))=0 And nombre>0 parce que le test If nombre=int(nombre) And nombre>0 ne donnait pas les résultats escomptes. Il ne détectait pas les nombres entiers positifs. Nous laissons au lecteur le soin de découvrir pourquoi.
  • Le test If (nombre-int(nombre))=0 n'est pas totalement fiable. Regardons l'exemple d'exécution suivant :
    Tapez un nombre entier >0: 4,0000000000000000000000001
    Merci pour le nombre entier >0 : 4,0000000000000000000000001

Les nombres réels ne sont pas représentés de façon exacte mais de façon approchée. Et ici, l'opération nombre-int(nombre) a donné 0 à la précision près de l'ordinateur.

IV-B. Les expressions régulières

Les expressions régulières nous permettent de tester le format d'une chaîne de caractères. Ainsi on peut vérifier qu'une chaîne représentant une date est au format jj/mm/aa. On utilise pour cela un modèle et on compare la chaîne à ce modèle. Ainsi dans cet exemple, j m et a doivent être des chiffres. Le modèle d'un format de date valide est alors "\d\d/\d\d/\d\d" où le symbole \d désigne un chiffre. Les symboles utilisables dans un modèle sont les suivants (documentation Microsoft) :

Caractère

Description

\

Marque le caractère suivant comme caractère spécial ou littéral. Par exemple, "n" correspond au caractère "n". "\n" correspond à un caractère de nouvelle ligne. La séquence "\\" correspond à "\", tandis que "\(" correspond à "(".

^

Correspond au début de la saisie.

$

Correspond à la fin de la saisie.

*

Correspond au caractère précédent zéro fois ou plusieurs fois. Ainsi, "zo*" correspond à "z" ou à "zoo".

+

Correspond au caractère précédent une ou plusieurs fois. Ainsi, "zo+" correspond à "zoo", mais pas à "z".

?

Correspond au caractère précédent zéro ou une fois. Par exemple, "a?ve?" correspond à "ve" dans "lever".

.

Correspond à tout caractère unique, sauf le caractère de nouvelle ligne.

(modèle)

Recherche le modèle et mémorise la correspondance. La sous-chaîne correspondante peut être extraite de la collection Matches obtenue, à l'aide d'Item [0]…[n]. Pour trouver des correspondances avec des caractères entre parenthèses ( ), utilisez "\(" ou "\)".

x|y

Correspond soit à x soit à y. Par exemple, "z|foot" correspond à "z" ou à "foot". "(z|f)oo" correspond à "zoo" ou à "foo".

{n}

n est un nombre entier non négatif. Correspond exactement à n fois le caractère. Par exemple, "o{2}" ne correspond pas à "o" dans "Bob," mais aux deux premiers "o" dans "fooooot".

{n,}

n est un entier non négatif. Correspond à au moins n fois le caractère. Par exemple, "o{2,}" ne correspond pas à "o" dans "Bob", mais à tous les "o" dans "fooooot". "o{1,}" équivaut à "o+" et "o{0,}" équivaut à "o*".

{n,m}

m et n sont des entiers non négatifs. Correspond à au moins n et à au plus m fois le caractère. Par exemple, "o{1,3}" correspond aux trois premiers "o" dans "foooooot" et "o{0,1}" équivaut à "o?".

[xyz]

Jeu de caractères. Correspond à l'un des caractères indiqués. Par exemple, "[abc]" correspond à "a" dans "plat".

[^xyz]

Jeu de caractères négatif. Correspond à tout caractère non indiqué. Par exemple, "[^abc]" correspond à "p" dans "plat".

[a-z]

Plage de caractères. Correspond à tout caractère dans la série spécifiée. Par exemple, "[a-z]" correspond à tout caractère alphabétique minuscule compris entre "a" et "z".

[^m-z]

Plage de caractères négative. Correspond à tout caractère ne se trouvant pas dans la série spécifiée. Par exemple, "[^m-z]" correspond à tout caractère ne se trouvant pas entre "m" et "z".

\b

Correspond à une limite représentant un mot, autrement dit, à la position entre un mot et un espace. Par exemple, "er\b" correspond à "er" dans "lever", mais pas à "er" dans "verbe".

\B

Correspond à une limite ne représentant pas un mot. "en*t\B" correspond à "ent" dans "bien entendu".

\d

Correspond à un caractère représentant un chiffre. Équivaut à [0-9].

\D

Correspond à un caractère ne représentant pas un chiffre. Équivaut à [^0-9].

\f

Correspond à un caractère de saut de page.

\n

Correspond à un caractère de nouvelle ligne.

\r

Correspond à un caractère de retour chariot.

\s

Correspond à tout espace blanc, y compris l'espace, la tabulation, le saut de page, etc. Équivaut à "[ \f\n\r\t\v]".

\S

Correspond à tout caractère d'espace non blanc. Équivaut à "[^ \f\n\r\t\v]".

\t

Correspond à un caractère de tabulation.

\v

Correspond à un caractère de tabulation verticale.

\w

Correspond à tout caractère représentant un mot et incluant un trait de soulignement. Équivaut à "[A-Za-z0-9 pond à tout caractère ne représentant pas un mot. Équivaut à "[^A-Za-z0-9_]".

\num

Correspond à num, où num est un entier positif. Fait référence aux correspondances mémorisées. Par exemple, "(.)\1" correspond à deux caractères identiques consécutifs.

\n

Correspond à n, où n est une valeur d'échappement octale. Les valeurs d'échappement octales doivent comprendre 1, 2 ou 3 chiffres. Par exemple, "\11" et "\011" correspondent tous les deux à un caractère de tabulation. "\0011" équivaut à "\001" & "1". Les valeurs d'échappement octales ne doivent pas excéder 256. Si c'était le cas, seuls les deux premiers chiffres seraient pris en compte dans l'expression. Permet d'utiliser les codes ASCII dans des expressions régulières.

\xn

Correspond à n, où n est une valeur d'échappement hexadécimale. Les valeurs d'échappement hexadécimales doivent comprendre deux chiffres obligatoirement. Par exemple, "\x41" correspond à "A". "\x041" équivaut à "\x04" & "1". Permet d'utiliser les codes ASCII dans des expressions régulières.

Un élément dans un modèle peut être présent en 1 ou plusieurs exemplaires. Considérons quelques exemples autour du symbole \d qui représente 1 chiffre :

modèle

signification

\d

un chiffre

\d?

0 ou 1 chiffre

\d*

0 ou davantage de chiffres

\d+

1 ou davantage de chiffres

\d{2}

2 chiffres

\d{3,}

au moins 3 chiffres

\d{5,7}

entre 5 et 7 chiffres


Imaginons maintenant le modèle capable de décrire le format attendu pour une chaîne de caractères :

chaîne recherchée

modèle

une date au format jj/mm/aa

\d{2}/\d{2}/\d{2}

une heure au format hh:mm:ss

\d{2}:\d{2}:\d{2}

un nombre entier non signé

\d+

une suite d'espaces éventuellement vide

\s*

un nombre entier non signé qui peut être précédé ou suivi d'espaces

\s*\d+\s*

un nombre entier qui peut être signé et précédé ou suivi d'espaces

\s*[+|-]?\s*\d+\s*

un nombre réel non signé qui peut être précédé ou suivi d'espaces

\s*\d+(.\d*)?\s*

un nombre réel qui peut être signé et précédé ou suivi d'espaces

\s*[+|]?\s*\d+(.\d*)?\s*

une chaîne contenant le mot juste

\bjuste\b


On peut préciser où on recherche le modèle dans la chaîne :

modèle

signification

^modèle

le modèle commence la chaîne

modèle$

le modèle finit la chaîne

^modèle$

le modèle commence et finit la chaîne

modèle

le modèle est cherché partout dans la chaîne en commençant par le début de celle-ci.

chaîne recherchée

modèle

une chaîne se terminant par un point d'exclamation

!$

une chaîne se terminant par un point

\.$

une chaîne commençant par la séquence //

^//

une chaîne ne comportant qu'un mot éventuellement suivi ou précédé d'espaces

^\s*\w+\s*$

une chaîne ne comportant deux mot éventuellement suivis ou précédés d'espaces

^\s*\w+\s*\w+\s*$

une chaîne contenant le mot secret

\bsecret\b

Les sous-ensembles d'un modèle peuvent être "récupérés". Ainsi non seulement, on peut vérifier qu'une chaîne correspond à un modèle particulier mais on peut récupérer dans cette chaîne les éléments correspondant aux sous-ensembles du modèle qui ont été entourés de parenthèses.

Ainsi si on analyse une chaîne contenant une date jj/mm/aa et si on veut de plus récupérer les éléments jj, mm, aa de cette date on utilisera le modèle (\d\d)/(\d\d)/(\d\d).

Voyons sur cet exemple, comment on opère avec vbscript.

  • il nous faut tout d'abord créer un objet RegExp (Regular Expression)
    set modele=new regexp
  • ensuite on fixe le modèle à tester
    modele.pattern="(\d\d)/(\d\d)/(\d\d)"
  • on peut vouloir ne pas faire de différence entre majuscules et minuscules (par défaut elle est faite). Ici ça n'a aucune importance.
    modele.IgnoreCase=true
  • on peut vouloir rechercher le modèle plusieurs fois dans la chaîne (par défaut ce n'est pas fait)
    modele.Global=true
    Une recherche globale n'a de sens que si le modèle utilisé ne fait pas référence au début ou à la fin de la chaîne.
  • on recherche alors toutes les correspondences du modèle dans la chaîne :
    set correspondances=modele.execute(chaine)
    La méthode execute d'un objet RegExp rend une collection d'objets de type match. Cet objet a une propriété value qui est l'élément de chaine correspondant au modèle. Si on a écrit modele.global=true, on peut avoir plusieurs correspondances. C'est pourquoi le résultat de la méthode execute est une collection de correspondances.
  • le nombre de correspondances est donné par correspondances.count. Si ce nombre vaut 0, c'est que le modèle n'a été trouvé nulle part. La valeur de la correspondance n° i est donnée par correspondances(i).value. Si le modèle contient des sous-modèles entre parenthèses, alors l'éléments de correspondances(i) correspondant à la parenthèse j d modèle est correspondances(i).submatches(j).

Tout ceci est montré dans l'exemple qui suit :

Programme
Sélectionnez

' expression régulière
' on veut vérifier qu'une chaîne contient une date au format jj/mm/aa
Option Explicit
Dim modele
' on définit le modèle
Set modele=new regexp
modele.pattern="\b(\d\d)/(\d\d)/(\d\d)\b" ' une date n'importe  dans la chaîne
modele.global=true ' on recherchera le modèle plusieurs fois dans
la chaîne
' c'est l'utilisateur qui donne la chaîne dans laquelle on cherchera le modèle
Dim chaine, correspondances, i
chaine=""
' on boucle tant que chaine<>"fin"
Do While true
' on demande à l'utilisateur de taper un texte
wscript.stdout.writeLine "Tapez un texte contenant des dates au format jj/mm/aa et fin
pour arrêter : "
chaine=wscript.stdin.readLine
' fini si chaine=fin
If chaine="fin" Then Exit Do
' on compare la chaîne lue au modèle de la date
Set correspondances=modele.execute(chaine)
' a-t-on trouvé une correspondance
If correspondances.count<>0 Then
' on a au moins une correspondance
For i=0 To correspondances.count-1
' on affiche la correspondance i
wscript.echo "J'ai trouvé la date " & correspondances(i).value
' on récupère les sous-éléments de la correspondance i
wscript.echo "Les éléments de la date " & i & " sont (" &
correspondances(i).submatches(0) & "," _
& correspondances(i).submatches(1) & "," & correspondances(i).submatches(2) & ")"
Next
Else
' pas de correspondance
wscript.echo "Je n'ai pas trouvé de date au format jj/mm/aa dans votre texte"
End If
Loop
' fini
wscript.quit 0
Résultats
Sélectionnez

Tapez un texte contenant des dates au format jj/mm/aa et fin pour arrÛter :
aujourd'hui on est le 01/01/01 et demain sera le 02/01/02
J'ai trouvé la date 01/01/01
Les éléments de la date 0 sont (01,01,01)
J'ai trouvé la date 02/01/02
Les éléments de la date 1 sont (02,01,02)
Tapez un texte contenant des dates au format jj/mm/aa et fin pour arrÛter :
une date au format incorrect : 01/01/2002
Je n'ai pas trouvé de date au format jj/mm/aa dans votre texte
Tapez un texte contenant des dates au format jj/mm/aa et fin pour arrÛter :
une suite de dates : 10/10/10, 11/11/11, 12/12/12
J'ai trouvé la date 10/10/10
Les éléments de la date 0 sont (10,10,10)
J'ai trouvé la date 11/11/11
Les éléments de la date 1 sont (11,11,11)
J'ai trouvé la date 12/12/12
Les éléments de la date 2 sont (12,12,12)
Tapez un texte contenant des dates au format jj/mm/aa et fin pour arrÛter :
fin

Avec les expressions régulières, le programme testant qu'une saisie clavier est bien un nombre entier positif pourrait s'écrire comme suit :

Programme
Sélectionnez

' lecture d'une donnée jusqu'à ce que celle-ci soit reconnue comme un nombre
Option Explicit
Dim fini, nombre
' on définit le modèle d'un nombre entier positif (mais qui peut être nul)
Dim modele
Set modele=new regexp
modele.pattern="^\s*\d+\s*$"
' on boucle tant que la donnée saisie n'est pas correcte
' la boucle est contrôlée par un booléen fini, mis à faux au départ (= ce n'est pas
fini)
fini=false
Do While Not fini
' on demande le nombre
wscript.stdout.write "Tapez un nombre entier >0: "
' on le lit
nombre=wscript.stdin.readLine
' on teste le format de la donnée lue
Dim correspondances
Set correspondances=modele.execute(nombre)
' le modèle a-t-il été vérifié ?
If correspondances.count<>0 Then
' c'est un entier mais est-il >0 ?
nombre=cint(nombre)
If nombre>0 Then
fini=true
End If
End If
' msg d'erreur éventuel
If Not fini Then wscript.echo "Erreur, vous n'avez pas tapé un nombre entier >0.
Recommencez svp..."
Loop
' confirmation
wscript.echo "Merci pour le nombre entier >0 : " & nombre
' et fin
wscript.quit 0
Resultats
Sélectionnez

Tapez un nombre entier >0: 10.3
Erreur, vous n'avez pas tapé un nombre entier >0. Recommencez svp...
Tapez un nombre entier >0: abcd
Erreur, vous n'avez pas tapé un nombre entier >0. Recommencez svp...
Tapez un nombre entier >0: -4
Erreur, vous n'avez pas tapé un nombre entier >0. Recommencez svp...
Tapez un nombre entier >0: 0
Erreur, vous n'avez pas tapé un nombre entier >0. Recommencez svp...
Tapez un nombre entier >0: 1
Merci pour le nombre entier >0 : 1

Trouver l'expression régulière qui nous permet de vérifier qu'une chaîne correspond bien à un certain modèle est parfois un véritable défi. Le programme suivant permet de s'entraîner. Il demande un modèle et une chaîne et indique alors si la chaîne correspond ou non au modèle.

Programme
Sélectionnez

' expression régulière
' on veut vérifier qu'une chaîne correspond à un modèle
Option Explicit
' on définit le modèle
Dim modele
Set modele=new regexp
modele.global=true ' on recherchera le modèle plusieurs fois dans
la chaîne
' c'est l'utilisateur qui donne la chaîne dans laquelle on cherchera le modèle
Dim chaine, correspondances, i
Do While true
' on demande à l'utilisateur de taper un modèle
wscript.stdout.write "Tapez le modèle à tester et fin pour arrêter : "
modele.pattern=wscript.stdin.readLine
' fini ?
If modele.pattern="fin" Then Exit Do
' on demande à l'utilisateur les chaînes à comparer au modèle
Do While true
' on demande à l'utilisateur de taper un modèle
wscript.stdout.writeLine "Tapez la chaîne à tester avec le modèle [" &
modele.pattern & "] et fin pour arrêter : "
chaine=wscript.stdin.readLine
' fini ?
If chaine="fin" Then Exit Do
' on compare la chaîne lue au modèle de la date
Set correspondances=modele.execute(chaine)
' a-t-on trouvé une correspondance
If correspondances.count<>0 Then
' on a au moins une correspondance
For i=0 To correspondances.count-1
' on affiche la correspondance i
wscript.echo "J'ai trouvé la correspondance " & correspondances(i).value
Next
Else
' pas de correspondance
wscript.echo "Je n'ai pas trouvé de correspondance"
End If
Loop
Loop
' fini
wscript.quit 0
Résultats
Sélectionnez

Tapez le modèle à tester et fin pour arrêter : ^\s*\d+(\,\d+)*\s*$
Tapez la chaîne à tester avec le modèle [^\s*\d+(\,\d+)*\s*$] et fin pour arrêter :
18
J'ai trouvé la correspondance [18]
Tapez la chaîne à tester avec le modèle [^\s*\d+(\,\d+)*\s*$] et fin pour arrêter :
145.678
Je n'ai pas trouvé de correspondance
Tapez la chaîne à tester avec le modèle [^\s*\d+(\,\d+)*\s*$] et fin pour arrêter :
145,678
J'ai trouvé la correspondance [ 145,678 ]

IV-C. Intercepter les erreurs d'exécution

Une autre méthode de gestion des erreurs d'exécution est de les laisser se produire, d'en être avertis et de les gérer alors. Normalement lorsqu'une erreur se passe à l'exécution, WSH affiche un message d'erreur et le programme est arrêté. Deux instructions nous permettent de modifier ce fonctionnement :

  • on error resume next
    Cette instruction indique au système (WSH) que nous allons gérer les erreurs nous mêmes. Apres cette instruction, toute erreur est simplement ignorée. par le système.
  • on error goto 0
    Cette instruction nous ramène au fonctionnement normal de gestion des erreurs.

Lorsque l'instruction on error resume next est active, nous devons gérer nous-mêmes les erreurs qui peuvent survenir. L'objet Err nous y aide. Cet objet a diverses propriétés et méthodes dont nous retiendrons les deux suivantes :

  • number : un nombre entier numéro de la dernière erreur qui s'est produite. 0 veut dire "pas d'erreur"
  • description : le message d'erreur qu'aurait affiche le système si on n'avait pas émis l'instruction on error resume next

Regardons l'exemple qui suit :

Programme
Sélectionnez

' erreur non gérée
Option Explicit
Dim nombre
nombre=cdbl("abcd")
wscript.echo "nombre=" & nombre
Résultats
Sélectionnez

C:\ err5.vbs(6, 1) Erreur d'exécution Microsoft VBScript:
Type incompatible: 'cdbl'

Gérons maintenant l'erreur :

Programme
Sélectionnez

' erreur gérée
Option Explicit
Dim nombre
' on gère les erreurs nous-mêmes
On Error Resume Next
nombre=cdbl("abcd")
' y-a-t-il eu erreur ?
If Err.number<>0 Then
wscript.echo "L'erreur [" &
err.description & "] s'est produite"
On Error GoTo 0
wscript.quit 1
End If
' pas d'erreur - on revient au
fonctionnement normal
On Error GoTo 0
wscript.echo "nombre=" & nombre
wscript.quit 0
Résultats
Sélectionnez

L'erreur [Type incompatible] s'est produite

Réécrivons le programme de saisie d'un entier >0 avec cette nouvelle méthode :

Programme
Sélectionnez

' lecture d'une donnée jusqu'à ce que celle-ci soit reconnue comme un nombre
Option Explicit
Dim fini, nombre
' on boucle tant que la donnée saisie n'est pas correcte
' la boucle est contrôlée par un booléen fini, mis à faux au départ (= ce n'est pas
fini)
fini=false
Do While Not fini
' on demande le nombre
wscript.stdout.write "Tapez un nombre entier >0: "
' on le lit
nombre=wscript.stdin.readLine
' on teste le format de la donnée lue
On Error Resume Next
nombre=cdbl(nombre)
If err.number=0 Then
' pas d'erreur c'est un nombre
' on revient au mode normal de gestion des erreurs
On Error GoTo 0
' est-ce un entier >0
If (nombre-int(nombre))=0 And nombre>0 Then
fini=true
End If
End If
' on revient au mode normal de gestion des erreurs
On Error GoTo 0
' msg d'erreur éventuel
If Not fini Then wscript.echo "Erreur, vous n'avez pas tapé un nombre entier >0.
Recommencez svp..."
Loop
' confirmation
wscript.echo "Merci pour le nombre entier >0 : " & nombre
' et fin
wscript.quit 0
Résultats
Sélectionnez

Tapez un nombre entier >0: 4.5
Erreur, vous n'avez pas tapé un nombre entier >0. Recommencez svp...
Tapez un nombre entier >0: 4,5
Erreur, vous n'avez pas tapé un nombre entier >0. Recommencez svp...
Tapez un nombre entier >0: abcd
Erreur, vous n'avez pas tapé un nombre entier >0. Recommencez svp...
Tapez un nombre entier >0: -4
Erreur, vous n'avez pas tapé un nombre entier >0. Recommencez svp...
Tapez un nombre entier >0: 1
Merci pour le nombre entier >0 : 1

Commentaires :

  • Cette méthode est parfois la seule utilisable. Il ne faut alors pas oublier de revenir au mode normal de gestion des erreurs des que la séquence d'instructions susceptible de générer l'erreur est terminée.

IV-D. Application au programme de calcul d'impôts

Nous reprenons le programme de calcul d'impôts déjà écrit pour, cette fois, vérifier la validité des arguments passés au programme :

Programme
Sélectionnez

' 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
' aucune vérification de la validité des données n'est faite mais on
' vérifie qu'il y en a bien trois
' déclaration obligatoire des variables
Option Explicit
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
wscript.echo syntaxe & vbCRLF & vbCRLF & "erreur : nombre d'arguments incorrect"
' arrêt avec code d'erreur 1
wscript.quit 1
End If
' on récupère les arguments en vérifiant leur validité
' 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
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
' erreur
wscript.echo syntaxe & vbCRLF & vbCRLF & "erreur : argument marie incorrect"
' on quitte
wscript.quit 2
End If
' on récupère la valeur
Dim marie
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
wscript.echo syntaxe & vbCRLF & vbCRLF & "erreur : argument enfants incorrect"
' on quitte
wscript.quit 3
End If
' on récupère la valeur
Dim enfants
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
wscript.echo syntaxe & vbCRLF & vbCRLF & "erreur : argument salaire incorrect"
' on quitte
wscript.quit 4
End If
' on récupère la valeur
Dim salaire
salaire=clng(wscript.arguments(2))
' on définit les données nécessaire au calcul de l'impôt dans 3 tableaux
Dim limites, coeffn, coeffr
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)
' 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
impot=int(revenu*coeffr(i)-nbParts*coeffn(i))
' on affiche le résultat
wscript.echo "impôt=" & impot
' on quitte sans erreur
wscript.quit 0
Résultats
Sélectionnez

C:\>cscript impots2.vbs
Syntaxe : pg marié enfants salaire
marié : caractère O si marié, N si non marié
enfants : nombre d'enfants (entier >=0)
salaire : salaire annuel sans les centimes (entier >=0)
erreur : nombre d'arguments incorrect
C:\>cscript impots2.vbs a b c
Syntaxe : pg marié enfants salaire
marié : caractère O si marié, N si non marié
enfants : nombre d'enfants (entier >=0)
salaire : salaire annuel sans les centimes (entier >=0)
erreur : argument marie incorrect
C:\>cscript impots2.vbs o b c
Syntaxe : pg marié enfants salaire
marié : caractère O si marié, N si non marié
enfants : nombre d'enfants (entier >=0)
salaire : salaire annuel sans les centimes (entier >=0)
erreur : argument enfants incorrect
C:\>cscript impots2.vbs o 2 c
Syntaxe : pg marié enfants salaire
marié : caractère O si marié, N si non marié
enfants : nombre d'enfants (entier >=0)
salaire : salaire annuel sans les centimes (entier >=0)
erreur : argument salaire incorrect
C:\>cscript impots2.vbs o 2 200000
impôt=22504

précédentsommairesuivant

  

Licence Creative Commons
Le contenu de cet article est rédigé par Serge Tahé et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 3.0 non transposé.
Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright © 2002 Developpez.com.