Skip to content

4. Gestione degli errori

In programmazione, esiste una regola assoluta: un programma non deve mai "bloccarsi" in modo imprevisto. Tutti gli errori che possono verificarsi durante l'esecuzione del programma devono essere gestiti e devono essere generati messaggi di errore significativi.

Se torniamo all'esempio delle imposte discusso in precedenza, cosa succede se l'utente inserisce un valore qualsiasi per il numero di figli? Diamo un'occhiata a questo esempio:

1
2
3
C:\>cscript impots1.vbs o xyzt 200000

C:\impots1.vbs(33, 3) Erreur d'exécution Microsoft VBScript: Type incompatible: 'cint'

Questo è ciò che viene definito un crash selvaggio. L'istruzione enfants=cint(wscript.arguments(1)) ha causato un "crash" perché arguments(1) conteneva la stringa "xyzt".

Prima di utilizzare una variante di cui non si conosce la natura esatta, è necessario verificarne il sottotipo esatto. Ci sono diversi modi per farlo:

  • verificare il tipo effettivo dei dati contenuti in una variante utilizzando le funzioni vartype o typename
  • utilizzare un'espressione regolare per verificare che il contenuto del variante corrisponda a uno schema specifico
  • lasciare che l'errore si verifichi, quindi intercettarlo e gestirlo

Esamineremo questi diversi metodi.

4.1. Determinare il tipo esatto di un elemento di dati

Ricordate che le funzioni vartype e varname consentono di determinare il tipo esatto di un dato. Questo non è sempre molto utile. Ad esempio, quando leggiamo i dati digitati sulla tastiera, le funzioni vartype e typename ci diranno che si tratta di una stringa, poiché tutti i dati digitati sulla tastiera vengono trattati come tali. Questo non ci dice se questa stringa possa, ad esempio, essere considerata un numero valido. Utilizziamo quindi altre funzioni per accedere a questo tipo di informazioni:

isNumeric(espressione)
restituisce true se l'espressione può essere utilizzata come numero
isDate(espressione)
restituisce true se l'espressione può essere utilizzata come data
isEmpty(var)
restituisce true se la variabile var non è stata inizializzata
isNull(var)
restituisce true se la variabile var contiene dati non validi
isArray(var)
restituisce true se var è un array
isObject(var)
restituisce true se var è un oggetto

L'esempio seguente richiede all'utente di inserire dati tramite la tastiera finché non vengono riconosciuti come numeri:

Programma

' read data until it is recognized as a number

Option Explicit

Dim fini, nombre

' loop until the data entered is correct
' the loop is controlled by a finite boolean, set to false at the start (= it's not finite)

fini=false
Do While Not fini
    ' we ask for the number
    wscript.stdout.write "Tapez un nombre : "
    ' we read it
    nombre=wscript.stdin.readLine
    ' the type is necessarily string when read
    wscript.echo "Type de la donnée lue : " & typename(nombre) & "," & vartype(nombre)
    ' test the actual type of data read
    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

' and end
wscript.quit 0

Risultati

1
2
3
4
5
6
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 funzione isNumeric non ci dice se un'espressione è un numero intero o meno. Per ottenere questa informazione, sono necessari ulteriori test. L'esempio seguente richiede un numero intero maggiore di 0:

Programma

' read data until it is recognized as an integer >0

Option Explicit

Dim fini, nombre

' loop until the data entered is correct
' the loop is controlled by a finite boolean, set to false at the start (= it's not finite)

fini=false
Do While Not fini
    ' we ask for the number
    wscript.stdout.write "Tapez un nombre entier >0: "
    ' we read it
    nombre=wscript.stdin.readLine
    ' test the actual type of data read
    If isNumeric(nombre) Then
        ' is it a positive integer (number equal to its integer part)?
        If (nombre-int(nombre))=0 And nombre>0 Then
            fini=true
        End If
    End If
    ' possible error msg
    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

' and end
wscript.quit 0

Risultati

1
2
3
4
5
6
7
8
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

Commenti:

  • int(numero) restituisce la parte intera di un numero. Un numero uguale alla sua parte intera è un numero intero.
  • È interessante notare che abbiamo dovuto utilizzare il test If (numero - int(numero)) = 0 And numero > 0 perché il test If numero = int(numero) And numero > 0 non ha prodotto i risultati attesi. Non ha rilevato i numeri interi positivi. Lasciamo al lettore il compito di scoprire il motivo.
  • Il test If (numero - int(numero)) = 0 non è del tutto affidabile. Diamo un'occhiata al seguente esempio:
Inserisci un numero intero >0: 4.0000000000000000000000001

Grazie per il numero intero >0: 4.0000000000000000000000001

I numeri reali non sono rappresentati in modo esatto, ma approssimativo. E in questo caso, l'operazione numero - int(numero) ha restituito 0 con la precisione del computer.

4.2. Espressioni regolari

Le espressioni regolari ci permettono di verificare il formato di una stringa. In questo modo, possiamo verificare che una stringa che rappresenta una data sia nel formato gg/mm/aa. Per farlo, usiamo un modello e confrontiamo la stringa con quel modello. Quindi, in questo esempio, g, m e a devono essere cifre. Il modello per un formato di data valido è quindi "\d\d/\d\d/\d\d", dove il simbolo \d indica una cifra. I simboli che possono essere utilizzati in un modello sono i seguenti (documentazione Microsoft):

Carattere
Descrizione
\
Indica che il carattere seguente è un carattere speciale o letterale. Ad esempio, "n" corrisponde al carattere "n". "\n" corrisponde a un carattere di nuova riga. La sequenza "\\" corrisponde a "\", mentre "\(" corrisponde a "(".
^
Corrisponde all'inizio dell'input.
$
Corrisponde alla fine dell'input.
*
Corrisponde al carattere precedente zero o più volte. Pertanto, "zo*" corrisponde a "z" o "zoo".
+
Corrisponde al carattere precedente una o più volte. Pertanto, "zo+" corrisponde a "zoo", ma non a "z".
?
Corrisponde al carattere precedente zero o una volta. Ad esempio, "a?ve?" corrisponde a "ve" in "lever".
.
Corrisponde a qualsiasi singolo carattere, eccetto il carattere di nuova riga.
(pattern)
Cerca il pattern e memorizza la corrispondenza. La sottostringa corrispondente può essere recuperata dalla collezione Matches risultante utilizzando Item [0]...[n]. Per trovare corrispondenze con caratteri all'interno di parentesi ( ), utilizzare "\(" o "\)".
x|y
Corrisponde a x o y. Ad esempio, "z|foot" corrisponde a "z" o "foot". "(z|f)oo" corrisponde a "zoo" o "foo".
{n}
n è un numero intero non negativo. Trova esattamente n occorrenze del carattere. Ad esempio, "o{2}" non trova "o" in "Bob", ma trova le prime due "o" in "fooooot".
{n,}
n è un numero intero non negativo. Trova almeno n occorrenze del carattere. Ad esempio, "o{2,}" non trova la "o" in "Bob", ma trova tutte le "o" in "fooooot". "o{1,}" equivale a "o+" e "o{0,}" equivale a "o*".
{n,m}
m e n sono numeri interi non negativi. Trova almeno n e al massimo m occorrenze del carattere. Ad esempio, "o{1,3}" trova le prime tre "o" in "foooooot", mentre "o{0,1}" trova "o?".
[xyz]
Insieme di caratteri. Trova uno qualsiasi dei caratteri specificati. Ad esempio, "[abc]" trova "a" in "plat".
[^xyz]
Insieme di caratteri negativo. Trova qualsiasi carattere non elencato. Ad esempio, "[^abc]" trova la "p" in "plat".
[a-z]
Intervallo di caratteri. Corrisponde a qualsiasi carattere compreso nell'intervallo specificato. Ad esempio, "[a-z]" corrisponde a qualsiasi carattere alfabetico minuscolo compreso tra "a" e "z".
[^m-z]
Intervallo di caratteri negativo. Trova qualsiasi carattere non compreso nell'intervallo specificato. Ad esempio, "[^m-z]" trova qualsiasi carattere non compreso tra "m" e "z".
\b
Corrisponde a un confine di parola, ovvero alla posizione tra una parola e uno spazio. Ad esempio, "er\b" corrisponde a "er" in "lever", ma non a "er" in "verb".
\B
Corrisponde a un confine che non rappresenta una parola. "en*t\B" corrisponde a "ent" in "bien entendu".
\d
Corrisponde a un carattere che rappresenta una cifra. Equivalente a [0-9].
\D
Corrisponde a un carattere che non è una cifra. Equivalente a [^0-9].
\f
Corrisponde a un carattere di interruzione di riga.
\n
Corrisponde a un carattere di nuova riga.
\r
Equivalente al carattere di ritorno a capo.
\s
Corrisponde a qualsiasi carattere di spaziatura, inclusi spazio, tabulazione, interruzione di pagina, ecc. Equivalente a "[ \f\n\r\t\v]".
\S
Corrisponde a qualsiasi carattere non spazio. Equivalente a "[^ \f\n\r\t\v]".
\t
Corrisponde a un carattere di tabulazione.
\v
Corrisponde a un carattere di tabulazione verticale.
\w
Corrisponde a qualsiasi carattere che rappresenta una parola, compreso il trattino basso. Equivalente a "[A-Za-z0-9_]".
\W
Corrisponde a qualsiasi carattere che non rappresenti una parola. Equivalente a "[^A-Za-z0-9_]".
\num
Corrisponde a num, dove num è un numero intero positivo. Si riferisce alle corrispondenze memorizzate. Ad esempio, "(.)\1" corrisponde a due caratteri identici consecutivi.
\n
Corrisponde a n, dove n è un valore di escape ottale. I valori di escape ottali devono essere composti da 1, 2 o 3 cifre. Ad esempio, "\11" e "\011" corrispondono entrambi a un carattere di tabulazione. "\0011" è equivalente a "\001" e "1". I valori di escape ottali non devono superare 256. In caso contrario, nell'espressione vengono prese in considerazione solo le prime due cifre. Consente l'uso dei codici ASCII nelle espressioni regolari.
\xn
Corrisponde a n, dove n è un valore di escape esadecimale. I valori di escape esadecimali devono essere composti esattamente da due cifre. Ad esempio, "\x41" corrisponde a "A". "\x041" è equivalente a "\x04" e "1". Consente l'uso dei codici ASCII nelle espressioni regolari.

Un elemento in un pattern può apparire una o più volte. Vediamo alcuni esempi che coinvolgono il simbolo \d, che rappresenta una singola cifra:

modello
significato
\d
una cifra
\d?
0 o 1 cifra
\d*
0 o più cifre
\d+
1 o più cifre
\d{2}
2 cifre
\d{3,}
almeno 3 cifre
\d{5,7}
da 5 a 7 cifre

Immaginiamo ora un modello in grado di descrivere il formato previsto per una stringa:

stringa di destinazione
modello
una data nel formato gg/mm/aa
\d{2}/\d{2}/\d{2}
un'ora nel formato hh:mm:ss
\d{2}:\d{2}:\d{2}
un numero intero senza segno
\d+
una sequenza di spazi, che può essere vuota
\s*
un numero intero senza segno che può essere preceduto o seguito da spazi
\s*\d+\s*
un numero intero che può essere con segno e preceduto o seguito da spazi
\s*[+|-]?\s*\d+\s*
un numero reale senza segno che può essere preceduto o seguito da spazi
\s*\d+(.\d*)?\s*
un numero reale che può essere con segno e preceduto o seguito da spazi
\s*[+|]?\s*\d+(.\d*)?\s*
una stringa contenente la parola "just"
\bjuste\b
  

È possibile specificare dove cercare il pattern nella stringa:

sequenza
significato
^motivo
il pattern inizia la stringa
pattern$
il pattern termina la stringa
^pattern$
il pattern inizia e termina la stringa
pattern
il pattern viene cercato in qualsiasi punto della stringa, a partire dall'inizio.
stringa di ricerca
modello
una stringa che termina con un punto esclamativo
!$
una stringa che termina con un punto
\.$
una stringa che inizia con la sequenza //
^//
una stringa costituita da una singola parola, facoltativamente preceduta o seguita da spazi
^\s*\w+\s*$
una stringa composta da due parole, facoltativamente seguita o preceduta da spazi
^\s*\w+\s*\w+\s*$
una stringa contenente la parola secret
\bsecret\b

I sottopattern di un pattern possono essere "estratti". Pertanto, non solo possiamo verificare che una stringa corrisponda a un particolare pattern, ma possiamo anche estrarre da quella stringa gli elementi corrispondenti ai sottopattern del pattern che sono stati racchiusi tra parentesi. Ad esempio, se stiamo analizzando una stringa contenente una data nel formato dd/mm/yy e vogliamo estrarre le componenti dd, mm e yy di quella data, useremmo il modello (\d\d)/(\d\d)/(\d\d).

Diamo un'occhiata a questo esempio per vedere come farlo con VBScript.

  • Per prima cosa, dobbiamo creare un oggetto RegExp (Espressione Regolare)
set modele=new regexp
  • Quindi impostiamo il pattern da testare
modele.pattern="(\d\d)/(\d\d)/(\d\d)"
  • Potresti voler ignorare le maiuscole e le minuscole (per impostazione predefinita, si distingue tra maiuscole e minuscole). In questo caso, non ha importanza.
modele.IgnoreCase=true
  • Potresti voler cercare il pattern più volte nella stringa (per impostazione predefinita, ciò non avviene)
modele.Global=true

Una ricerca globale ha senso solo se il modello utilizzato non si riferisce all'inizio o alla fine della stringa.

  • Cerchiamo quindi tutte le corrispondenze del modello nella stringa:
set correspondances=modele.execute(chaine)

Il metodo execute di un oggetto RegExp restituisce una raccolta di oggetti match**. Questi oggetti dispongono di una proprietà value che contiene la stringa corrispondente al pattern. Se è stato impostato pattern.global=true*, potrebbero esserci più corrispondenze. Ecco perché il risultato del metodo execute* è una raccolta di oggetti match.

  • Il numero di corrispondenze è dato da matches.count. Se questo numero è 0, significa che il pattern non è stato trovato da nessuna parte. Il valore della corrispondenza #i è dato da matches(i).value. Se il pattern contiene sottopattern tra parentesi, l'elemento di matches(i) corrispondente alla parentesi j nel pattern è matches(i).submatches(j).

Tutto ciò è illustrato nell'esempio seguente:

Programma

' regular expression

' we want to check that a string contains a date in dd/mm/yy format

Option Explicit
Dim modele

' we define the
Set modele=new regexp
modele.pattern="\b(\d\d)/(\d\d)/(\d\d)\b"  ' a date anywhere in the chain
modele.global=true                      ' we will search for the model several times in the chain

' the user specifies the string in which to search for the model
Dim chaine, correspondances, i

chaine=""
' loop as long as string<>"end"
Do While true
    ' the user is asked to type a text
    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
    ' the string read is compared with the date template
    Set correspondances=modele.execute(chaine)
    ' was a match found
    If correspondances.count<>0 Then
        ' we have at least one match
        For i=0 To correspondances.count-1
            ' the i correspondence is displayed
            wscript.echo "J'ai trouvé la date " & correspondances(i).value
            ' we retrieve the sub-elements of correspondence 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
        ' no correspondence
        wscript.echo "Je n'ai pas trouvé de date au format jj/mm/aa dans votre texte"
    End If
Loop

' finish
wscript.quit 0

Risultati

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

Utilizzando le espressioni regolari, il programma che verifica se un input da tastiera è effettivamente un numero intero positivo potrebbe essere scritto come segue:

Programma

' read data until it is recognized as a number

Option Explicit

Dim fini, nombre

' we define the model of a positive integer (which may be zero)
Dim modele
Set modele=new regexp
modele.pattern="^\s*\d+\s*$"

' loop until the data entered is correct
' the loop is controlled by a finite boolean, set to false at the start (= it's not finite)

fini=false
Do While Not fini
    ' we ask for the number
    wscript.stdout.write "Tapez un nombre entier >0: "
    ' we read it
    nombre=wscript.stdin.readLine
    ' test the format of the data read
    Dim correspondances
    Set correspondances=modele.execute(nombre)
    ' has the model been checked?
    If correspondances.count<>0 Then
        ' it's an integer, but is it >0?
        nombre=cint(nombre)
        If nombre>0 Then
            fini=true
        End If
    End If
    ' possible error msg
    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

' and end
wscript.quit 0

Risultati

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

Trovare l'espressione regolare che ci permette di verificare se una stringa corrisponde a un determinato modello può a volte essere una vera sfida. Il seguente programma ti permette di esercitarti. Ti chiede un modello e una stringa, e poi indica se la stringa corrisponde o meno al modello.

Programma

' regular expression

' we want to check that a chain corresponds to a model

Option Explicit

' we define the
Dim modele
Set modele=new regexp
modele.global=true                      ' we will search for the model several times in the chain

' the user specifies the string in which to search for the model
Dim chaine, correspondances, i

Do While true
    ' the user is asked to type in a template
    wscript.stdout.write "Tapez le modèle à tester et fin pour arrêter : "
    modele.pattern=wscript.stdin.readLine
    ' finished?
    If modele.pattern="fin" Then Exit Do
        ' the user is asked for the strings to be compared with the model
        Do While true
            ' the user is asked to type in a template
            wscript.stdout.writeLine "Tapez la chaîne à tester avec le modèle [" & modele.pattern & "] et fin pour arrêter : "
            chaine=wscript.stdin.readLine
            ' finished?
            If chaine="fin" Then Exit Do
            ' the string read is compared with the date template
            Set correspondances=modele.execute(chaine)
            ' was a match found
            If correspondances.count<>0 Then
                ' we have at least one match
                For i=0 To correspondances.count-1
                    ' the i correspondence is displayed
                    wscript.echo "J'ai trouvé la correspondance " & correspondances(i).value
                Next
            Else
                ' no correspondence
                wscript.echo "Je n'ai pas trouvé de correspondance"
            End If
    Loop
Loop

' finish
wscript.quit 0

Risultati

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   ]

4.3. Gestione degli errori di runtime

Un altro metodo per gestire gli errori di runtime consiste nel lasciarli verificarsi, ricevere una notifica e poi gestirli. Normalmente, quando si verifica un errore durante l'esecuzione, WSH visualizza un messaggio di errore e il programma si interrompe. Due istruzioni ci consentono di modificare questo comportamento:

on error resume next

Questa istruzione comunica al sistema (WSH) che gestiremo gli errori autonomamente. Dopo questa istruzione, eventuali errori vengono semplicemente ignorati dal sistema.

on error goto 0

Questa istruzione ci riporta alla normale gestione degli errori.

Quando l'istruzione on error resume next è attiva, dobbiamo gestire autonomamente eventuali errori che potrebbero verificarsi. L'oggetto Err ci aiuta a farlo. Questo oggetto ha varie proprietà e metodi, tra cui ci concentreremo sui seguenti due:

  • number: un numero intero che rappresenta il numero dell'ultimo errore verificatosi. 0 significa "nessun errore"
  • description: il messaggio di errore che il sistema avrebbe visualizzato se non avessimo emesso l'istruzione on error resume next

Diamo un'occhiata al seguente esempio:

Programma


' unhandled error
 
Option Explicit
Dim nombre
 
nombre=cdbl("abcd")
wscript.echo "nombre=" & nombre

Risultati

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

Ora gestiamo l'errore:

Programma

' managed error

Option Explicit
Dim nombre

' we manage mistakes ourselves
On Error Resume Next
nombre=cdbl("abcd")
' was there a mistake?
If Err.number<>0 Then
    wscript.echo "L'erreur [" & err.description & "] s'est produite"
    On Error GoTo 0
    wscript.quit 1
End If
' no error - returns to normal operation
On Error GoTo 0
wscript.echo "nombre=" & nombre
wscript.quit 0

Risultati

L'erreur [Type incompatible] s'est produite

Riscriviamo il programma per l'inserimento di un numero intero >0 utilizzando questo nuovo metodo:

Programma


' read data until it is recognized as a number
 
Option Explicit
 
Dim fini, nombre
 
' loop until the data entered is correct
' the loop is controlled by a finite boolean, set to false at the start (= it's not finite)
 
fini=false
Do While Not fini
  ' we ask for the number
  wscript.stdout.write "Tapez un nombre entier >0: "
  ' we read it
  nombre=wscript.stdin.readLine
  ' test the format of the data read
  On Error Resume Next
  nombre=cdbl(nombre)
  If err.number=0 Then
    ' no error it's a number
    ' returns to normal error handling mode
    On Error GoTo 0
    ' is it an integer >0
    If (nombre-int(nombre))=0 And nombre>0 Then
      fini=true
    End If
  End If
  ' returns to normal error handling mode
  On Error GoTo 0
  ' possible error msg
  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
 
' and end
wscript.quit 0

Risultati

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

Commenti:

  • Questo metodo è talvolta l'unico utilizzabile. In tal caso, non dimenticare di tornare alla normale modalità di gestione degli errori non appena la sequenza di istruzioni che potrebbe generare l'errore è completata.

4.4. Applicazione al programma di calcolo delle imposte

Riprenderemo il programma di calcolo delle imposte che abbiamo scritto in precedenza per, questa volta, verificare la validità degli argomenti passati al programma:

Programma


' 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
 
' no verification of data validity is performed, but we do
' check that there are three of them
 
' mandatory variable declaration
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)"
 
' we check that there are 3 arguments
  Dim nbArguments
  nbArguments=wscript.arguments.count
  If nbArguments<>3 Then
    ' error msg
    wscript.echo syntaxe & vbCRLF & vbCRLF & "erreur : nombre d'arguments incorrect"
    ' stop with error code 1
    wscript.quit 1
  End If

' retrieve arguments and check their validity
' an argument is passed to the program without spaces in front and behind it
' use regular expressions to check data validity
  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
    wscript.echo syntaxe & vbCRLF & vbCRLF & "erreur : argument marie incorrect"
    ' we leave
    wscript.quit 2
  End If
  ' the value
  Dim marie
  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
    wscript.echo syntaxe & vbCRLF & vbCRLF & "erreur : argument enfants incorrect"
    ' we leave
    wscript.quit 3
  End If
  ' the value
  Dim enfants
  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
    wscript.echo syntaxe & vbCRLF & vbCRLF & "erreur : argument salaire incorrect"
    ' we leave
    wscript.quit 4
  End If
  ' the value
  Dim salaire
  salaire=clng(wscript.arguments(2))

  ' we define the data needed to calculate the tax in 3 tables
  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)

  ' 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

  ' calculate the family quota 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
  impot=int(revenu*coeffr(i)-nbParts*coeffn(i))

  ' the result is displayed
  wscript.echo "impôt=" & impot

  ' leave without error
  wscript.quit 0

Risultati

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