Skip to content

4. Gestione degli errori

Nella 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 riprendiamo l’esempio delle imposte trattato in precedenza, cosa succede se l’utente inserisce un valore qualsiasi per il numero di figli? Vediamo 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 si definisce un "arresto anomalo". Si è verificato un "arresto anomalo" nell’istruzione enfants=cint(wscript.arguments(1)) poiché 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ò può essere fatto in diversi modi:

  • verificare il tipo effettivo dei dati contenuti in una variabile con le funzioni vartype o typename
  • utilizzare un'espressione regolare per verificare che il contenuto del variante corrisponda a un determinato modello
  • lasciare che l’errore si verifichi, intercettarlo e gestirlo

Esaminiamo questi diversi metodi.

4.1. Conoscere il tipo esatto di un dato

Ricordiamo che le funzioni vartype o varname consentono di conoscere il tipo esatto di un dato. Ciò non sempre ci è di grande aiuto. Ad esempio, quando leggiamo un dato digitato dalla tastiera, le funzioni vartype e typename ci diranno che si tratta di una stringa di caratteri, poiché è così che viene considerato qualsiasi dato digitato dalla tastiera. Ciò non ci dice se questa stringa possa, ad esempio, essere considerata un numero valido. Si utilizzano quindi altre funzioni per accedere a questo tipo di informazioni:

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

L'esempio seguente richiede di digitare un dato dalla tastiera finché non viene riconosciuto come un numero:

Programma
' si legge un dato finché non viene riconosciuto come numero

Option Explicit

Dim fini, nombre

' si esegue un ciclo finché il dato inserito non è corretto
' il ciclo è controllato da una variabile booleana finita, impostata su falso all'inizio (= non è finito)

fini=false
Do While Not fini
    ' si richiede il numero
    wscript.stdout.write "Tapez un nombre : "
    ' lo si legge
    nombre=wscript.stdin.readLine
    ' il tipo è necessariamente stringa durante la lettura
    wscript.echo "Type de la donnée lue : " & typename(nombre) & "," & vartype(nombre)
    ' si verifica il tipo effettivo del dato letto
    If isNumeric(nombre) Then 
        fini=true
    Else
        wscript.echo "Erreur, vous n'avez pas tapé un nombre. Recommencez svp..."
    End If
Loop

' conferma
wscript.echo "Merci pour le nombre " & nombre

' e fine
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, è necessario eseguire ulteriori test. L'esempio seguente richiede un numero intero >0:

Programma
' lettura di un dato fino a quando non viene riconosciuto come un numero intero >0

Option Explicit

Dim fini, nombre

' si esegue un ciclo finché il dato inserito non è corretto
' il ciclo è controllato da una variabile booleana finita, impostata inizialmente su falso (= non è finito)

fini=false
Do While Not fini
    ' si richiede il numero
    wscript.stdout.write "Tapez un nombre entier >0: "
    ' lo si legge
    nombre=wscript.stdin.readLine
    ' si verifica se il dato letto è di tipo reale
    If isNumeric(nombre) Then
        ' È un numero intero (pari alla sua parte intera) positivo?
        If (nombre-int(nombre))=0 And nombre>0 Then
            fini=true
        End If
    End If
    ' eventuale messaggio di errore
    If Not fini Then wscript.echo "Erreur, vous n'avez pas tapé un nombre entier >0. Recommencez svp..."
Loop

' conferma
wscript.echo "Merci pour le nombre entier >0 : " & nombre

' e fine
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

Note:

  • int(nombre) restituisce la parte intera di un numero. Un numero uguale alla sua parte intera è un numero intero.
  • È interessante notare che è stato necessario utilizzare il test If (numero - int(numero)) = 0 And numero > 0 perché il test If numero = int(numero) And numero > 0 non forniva i risultati attesi. Non rilevava i numeri interi positivi. Lasciamo al lettore il compito di scoprire il motivo.
  • Il test If (numero - int(numero)) = 0 non è del tutto affidabile. Osserviamo il seguente esempio di esecuzione:
Tapez un nombre entier >0: 4,0000000000000000000000001

Merci pour le nombre entier >0 : 4,0000000000000000000000001

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

4.2. Le espressioni regolari

Le espressioni regolari ci consentono di verificare il formato di una stringa di caratteri. In questo modo è possibile verificare che una stringa che rappresenta una data sia nel formato gg/mm/aa. A tal fine si utilizza un modello e si confronta la stringa con tale modello. Pertanto, in questo esempio, g, m e a devono essere cifre. Il modello di un formato di data valido è quindi "\d\d/\d\d/\d\d", dove il simbolo \d indica una cifra. I simboli utilizzabili in un modello sono i seguenti (documentazione Microsoft):

Carattere
Descrizione
\
Indica il carattere successivo come 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 a "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.
(modello)
Cerca modèle e memorizza la corrispondenza. La sottostringa corrispondente può essere estratta dalla collezione Matches ottenuta, utilizzando Item [0]...[n]. Per trovare corrispondenze con caratteri tra parentesi ( ), utilizzare "\(" o "\)".
x|y
Corrisponde sia a x sia a y. Ad esempio, "z|foot" corrisponde a "z" o a "foot". "(z|f)oo" corrisponde a "zoo" o a "foo".
{n}
n è un numero intero non negativo. Corrisponde esattamente a n moltiplicato per il carattere. Ad esempio, "o{2}" non corrisponde a "o" in "Bob," ma alle prime due "o" in "fooooot".
{n,}
n è un numero intero non negativo. Corrisponde ad almeno n volte il carattere. Ad esempio, "o{2,}" non corrisponde alla "o" in "Bob", ma a 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. Corrisponde ad almeno n e al massimo m volte il carattere. Ad esempio, "o{1,3}" corrisponde alle prime tre "o" in "foooooot" e "o{0,1}" equivale a "o?".
[xyz]
Insieme di caratteri. Corrisponde a uno dei caratteri indicati. Ad esempio, "[abc]" corrisponde alla "a" in "plat".
[^xyz]
Set di caratteri negativo. Corrisponde a qualsiasi carattere non indicato. Ad esempio, "[^abc]" corrisponde alla "p" in "plat".
[a-z]
Intervallo di caratteri. Corrisponde a qualsiasi carattere compreso nella serie specificata. Ad esempio, "[a-z]" corrisponde a qualsiasi carattere alfabetico minuscolo compreso tra "a" e "z".
[^m-z]
Intervallo di caratteri negativo. Corrisponde a qualsiasi carattere non presente nella serie specificata. Ad esempio, "[^m-z]" corrisponde a qualsiasi carattere non compreso tra "m" e "z".
\b
Corrisponde a un delimitatore che rappresenta una parola, ovvero alla posizione tra una parola e uno spazio. Ad esempio, "er\b" corrisponde a "er" in "lever", ma non a "er" in "verbe".
\B
Corrisponde a un limite che non rappresenta una parola. "en*t\B" corrisponde a "ent" in "bien entendu".
\d
Corrisponde a un carattere che rappresenta una cifra. Equivale a [0-9].
\D
Corrisponde a un carattere che non rappresenta una cifra. Equivale a [^0-9].
\f
Corrisponde a un carattere di fine pagina.
\n
Corrisponde a un carattere di nuova riga.
\r
Corrisponde a un carattere di ritorno a capo.
\s
Corrisponde a qualsiasi carattere di spaziatura, inclusi spazio, tabulazione, salto di pagina, ecc. Equivale a "[ \f\n\r\t\v]".
\S
Corrisponde a qualsiasi carattere non bianco. Equivale 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 rappresenti una parola e includa un trattino basso. Equivale a "[A-Za-z0-9_]".
\W
Corrisponde a qualsiasi carattere che non rappresenti una parola. Equivale a "[^A-Za-z0-9_]".
\num
Corrisponde a num, dove num è un numero intero positivo. Fa riferimento 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 comprendere 1, 2 o 3 cifre. Ad esempio, sia "\11" che "\011" corrispondono a un carattere di tabulazione. "\0011" equivale a "\001" e "1". I valori di escape ottali non devono superare 256. In caso contrario, nell'espressione verrebbero prese in considerazione solo le prime due cifre. Consente di utilizzare i codici ASCII nelle espressioni regolari.
\xn
Corrisponde a n, dove n è un valore di escape esadecimale. I valori di escape esadecimali devono obbligatoriamente comprendere due cifre. Ad esempio, "\x41" corrisponde a "A". "\x041" equivale a "\x04" e "1". Consente di utilizzare i codici ASCII nelle espressioni regolari.

Un elemento in un modello può essere presente una o più volte. Consideriamo alcuni esempi relativi al simbolo \d, che rappresenta una 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 il modello in grado di descrivere il formato previsto per una stringa di caratteri:

stringa ricercata
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, eventualmente 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 "giusto"
\bjusto\b
  

È possibile specificare dove cercare il modello nella stringa:

modello
significato
^modello
il modello inizia la stringa
modello$
il modello conclude la stringa
^modello$
il modello inizia e termina la stringa
modello
il modello viene cercato in tutta la stringa a partire dall'inizio della stessa.
stringa cercata
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 composta da una sola parola, eventualmente preceduta o seguita da spazi
^\s*\w+\s*$
una stringa contenente due parole, eventualmente precedute o seguite da spazi
^\s*\w+\s*\w+\s*$
una stringa contenente la parola "secret"
\bsecret\b

I sottoinsiemi di un modello possono essere "recuperati". In questo modo, non solo è possibile verificare che una stringa corrisponda a un modello specifico, ma è anche possibile recuperare all'interno di tale stringa gli elementi corrispondenti ai sottoinsiemi del modello racchiusi tra parentesi. Pertanto, se si analizza una stringa contenente una data gg/mm/aa e si desidera inoltre estrarre gli elementi gg, mm, aa di tale data, si utilizzerà il modello (\d\d)/(\d\d)/(\d\d).

Vediamo, con questo esempio, come si procede con VBScript.

  • Per prima cosa dobbiamo creare un oggetto RegExp (Espressione regolare)
set modele=new regexp
  • poi si imposta il modello da testare
modele.pattern="(\d\d)/(\d\d)/(\d\d)"
  • Si potrebbe voler ignorare la distinzione tra maiuscole e minuscole (per impostazione predefinita è attiva). In questo caso non ha alcuna importanza.
modele.IgnoreCase=true
  • si può voler cercare il modello più volte nella stringa (per impostazione predefinita non viene fatto)
modele.Global=true

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

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

Il metodo execute di un oggetto RegExp restituisce una collezione di oggetti di tipo match. Questo oggetto ha una proprietà value che è l'elemento di chaine corrispondente al modello. Se si è scritto modele.global=true, si possono avere più corrispondenze. Ecco perché il risultato del metodo execute è una collezione di corrispondenze.

  • Il numero di corrispondenze è dato da correspondances.count. Se tale numero è pari a 0, significa che il modello non è stato trovato da nessuna parte. Il valore della corrispondenza n. i è dato da correspondances(i).value. Se il modello contiene sottomodelli tra parentesi, allora l'elemento di correspondances(i) corrispondente alla parentesi j del modello è correspondances(i).submatches(j).

Tutto ciò è illustrato nell'esempio seguente:

Programma
' espressione regolare

' si vuole verificare che una stringa contenga una data nel formato gg/mm/aa

Option Explicit
Dim modele

' si definisce il modello
Set modele=new regexp
modele.pattern="\b(\d\d)/(\d\d)/(\d\d)\b"  ' une date n'importe où dans la chaîne
modele.global=true                      ' on recherchera le modèle plusieurs fois dans la chaîne

' è l'utente a fornire la stringa in cui si cercherà il modello
Dim chaine, correspondances, i

chaine=""
' si esegue un ciclo finché stringa <> "fine"
Do While true
    ' si chiede all'utente di digitare un testo
    wscript.stdout.writeLine "Tapez un texte contenant des dates au format jj/mm/aa et fin pour arrêter : "
    chaine=wscript.stdin.readLine
    ' si termina se stringa = "fine"
    If chaine="fin" Then Exit Do
    ' si confronta la stringa letta con il modello della data
    Set correspondances=modele.execute(chaine)
    ' è stata trovata una corrispondenza
    If correspondances.count<>0 Then
        ' c'è almeno una corrispondenza
        For i=0 To correspondances.count-1
            ' si visualizza la corrispondenza i
            wscript.echo "J'ai trouvé la date " & correspondances(i).value
            ' si recuperano i sottoelementi della corrispondenza 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
        ' nessuna corrispondenza
        wscript.echo "Je n'ai pas trouvé de date au format jj/mm/aa dans votre texte"
    End If
Loop

' fine
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

Con le espressioni regolari, il programma che verifica che un valore immesso dalla tastiera sia effettivamente un numero intero positivo potrebbe essere scritto come segue:

Programma
' lettura di un dato fino a quando non viene riconosciuto come numero

Option Explicit

Dim fini, nombre

' si definisce il modello di un numero intero positivo (che però può essere zero)
Dim modele
Set modele=new regexp
modele.pattern="^\s*\d+\s*$"

' si esegue un ciclo finché il dato inserito non è corretto
' il ciclo è controllato da una variabile booleana iniziale impostata a falso (= non è terminato)

fini=false
Do While Not fini
    ' si richiede il numero
    wscript.stdout.write "Tapez un nombre entier >0: "
    ' lo si legge
    nombre=wscript.stdin.readLine
    ' si verifica il formato del dato letto
    Dim correspondances
    Set correspondances=modele.execute(nombre)
    ' Il modello è stato verificato?
    If correspondances.count<>0 Then
        ' è un numero intero, ma è >0?
        nombre=cint(nombre)
        If nombre>0 Then
            fini=true
        End If
    End If
    ' eventuale messaggio di errore
    If Not fini Then wscript.echo "Erreur, vous n'avez pas tapé un nombre entier >0. Recommencez svp..."
Loop

' conferma
wscript.echo "Merci pour le nombre entier >0 : " & nombre

' e fine
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 permetta di verificare se una stringa corrisponde effettivamente a un determinato modello è talvolta una vera sfida. Il seguente programma permette di esercitarsi. Richiede un modello e una stringa e indica quindi se la stringa corrisponde o meno al modello.

Programma
' espressione regolare

' si vuole verificare che una stringa corrisponda a un modello

Option Explicit

' si definisce il modello
Dim modele
Set modele=new regexp
modele.global=true                      ' on recherchera le modèle plusieurs fois dans la chaîne

' è l'utente a fornire la stringa in cui si cercherà il modello
Dim chaine, correspondances, i

Do While true
    ' si chiede all'utente di digitare un modello
    wscript.stdout.write "Tapez le modèle à tester et fin pour arrêter : "
    modele.pattern=wscript.stdin.readLine
    ' finito?
    If modele.pattern="fin" Then Exit Do
        ' si chiede all'utente quali stringhe confrontare con il modello
        Do While true
            ' si chiede all'utente di digitare un modello
            wscript.stdout.writeLine "Tapez la chaîne à tester avec le modèle [" & modele.pattern & "] et fin pour arrêter : "
            chaine=wscript.stdin.readLine
            ' finito?
            If chaine="fin" Then Exit Do
            ' si confronta la stringa letta con il modello della data
            Set correspondances=modele.execute(chaine)
            ' È stata trovata una corrispondenza?
            If correspondances.count<>0 Then
                ' si ha almeno una corrispondenza
                For i=0 To correspondances.count-1
                    ' si visualizza la corrispondenza i
                    wscript.echo "J'ai trouvé la correspondance " & correspondances(i).value
                Next
            Else
                ' nessuna corrispondenza
                wscript.echo "Je n'ai pas trouvé de correspondance"
            End If
    Loop
Loop

' fine
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. Intercettare gli errori di esecuzione

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

on error resume next

Questa istruzione indica al sistema (WSH) che gestiremo gli errori autonomamente. Dopo questa istruzione, qualsiasi errore viene semplicemente ignorato dal sistema.

on error goto 0

Questa istruzione ripristina il normale funzionamento della gestione degli errori.

Quando l’istruzione on error resume next è attiva, dobbiamo gestire autonomamente gli errori che possono verificarsi. L’oggetto **Err** ci aiuta in questo. Questo oggetto presenta diverse proprietà e metodi, tra cui ricorderemo i seguenti due:

  • number: un numero intero che indica il numero dell’ultimo errore verificatosi. 0 significa “nessun errore”
  • description: il messaggio di errore che il sistema avrebbe visualizzato se non fosse stata emessa l’istruzione on error resume next

Diamo un’occhiata all’esempio seguente:

Programma
Risultati

' errore non gestito

Option Explicit
Dim nombre

nombre=cdbl("abcd")
wscript.echo "nombre=" & nombre
C:\ err5.vbs(6, 1) Erreur d'exécution Microsoft VBScript: Type incompatible: 'cdbl'

Gestiamo ora l'errore:

Programma
Risultati
' errore gestito

Option Explicit
Dim nombre

' gestiamo gli errori autonomamente
On Error Resume Next
nombre=cdbl("abcd")
' si è verificato un errore?
If Err.number<>0 Then
    wscript.echo "L'erreur [" & err.description & "] s'est produite"
    On Error GoTo 0
    wscript.quit 1
End If
' nessun errore - si torna al funzionamento normale
On Error GoTo 0
wscript.echo "nombre=" & nombre
wscript.quit 0
L'erreur [Type incompatible] s'est produite

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

Programma

' lettura di un dato fino a quando non viene riconosciuto come numero

Option Explicit

Dim fini, nombre

' si ripete il ciclo finché il dato inserito non è corretto
' il ciclo è controllato da una variabile booleana finita, impostata su falso all'inizio (= non è finito)

fini=false
Do While Not fini
  ' si richiede il numero
  wscript.stdout.write "Tapez un nombre entier >0: "
  ' lo si legge
  nombre=wscript.stdin.readLine
  ' si verifica il formato del dato letto
  On Error Resume Next
  nombre=cdbl(nombre)
  If err.number=0 Then
    ' nessun errore, è un numero
    ' si torna alla modalità normale di gestione degli errori
    On Error GoTo 0
    ' è un numero intero >0
    If (nombre-int(nombre))=0 And nombre>0 Then
      fini=true
    End If
  End If
  ' si torna alla modalità normale di gestione degli errori
  On Error GoTo 0
  ' eventuale messaggio di errore
  If Not fini Then wscript.echo "Erreur, vous n'avez pas tapé un nombre entier >0. Recommencez svp..."
Loop

' conferma
wscript.echo "Merci pour le nombre entier >0 : " & nombre

' e fine
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

Note:

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

4.4. Applicazione al programma di calcolo delle imposte

Riprendiamo il programma di calcolo delle imposte già scritto per verificare, questa volta, la validità degli argomenti passati al programma:

Programma

' calcolo dell'imposta di un contribuente
' il programma deve essere richiamato con tre parametri: coniugato, figli, stipendio
' coniugato: carattere O se coniugato, N se non coniugato
' figli: numero di figli
' stipendio: stipendio annuo senza i centesimi

' non viene effettuata alcuna verifica della validità dei dati, ma
' si verifica che ce ne siano effettivamente tre

' dichiarazione obbligatoria delle variabili
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)"

' si verifica che ci siano 3 argomenti
  Dim nbArguments
  nbArguments=wscript.arguments.count
  If nbArguments<>3 Then
    ' messaggio di errore
    wscript.echo syntaxe & vbCRLF & vbCRLF & "erreur : nombre d'arguments incorrect"
    ' interruzione con codice di errore 1
    wscript.quit 1
  End If
  
' si recuperano gli argomenti verificandone la validità
' un argomento viene trasmesso al programma senza spazi né all'inizio né alla fine
' si utilizzeranno espressioni regolari per verificare la validità dei dati
  Dim modele, correspondances
  Set modele=new regexp

  ' lo stato civile deve essere uno dei caratteri oOnN
  modele.pattern="^[oOnN]$"
  Set correspondances=modele.execute(wscript.arguments(0))
  If correspondances.count=0 Then
    ' errore
    wscript.echo syntaxe & vbCRLF & vbCRLF & "erreur : argument marie incorrect"
    ' si esce
    wscript.quit 2
  End If
  ' si recupera il valore
  Dim marie
  If lcase(wscript.arguments(0)) = "o"Then
    marie=true
  Else
    marie=false
  End If
  
  ' il numero di figli deve essere un numero intero >=0
  modele.pattern="^\d{1,2}$"
  Set correspondances=modele.execute(wscript.arguments(1))
  If correspondances.count=0 Then
    ' errore
    wscript.echo syntaxe & vbCRLF & vbCRLF & "erreur : argument enfants incorrect"
    ' uscita
    wscript.quit 3
  End If
  ' si recupera il valore
  Dim enfants
  enfants=cint(wscript.arguments(1))

  ' lo stipendio deve essere un numero intero >=0
  modele.pattern="^\d{1,9}$"
  Set correspondances=modele.execute(wscript.arguments(2))
  If correspondances.count=0 Then
    ' errore
    wscript.echo syntaxe & vbCRLF & vbCRLF & "erreur : argument salaire incorrect"
    ' uscita
    wscript.quit 4
  End If
  ' si recupera il valore
  Dim salaire
  salaire=clng(wscript.arguments(2))
  
  ' si definiscono i dati necessari per il calcolo dell'imposta in 3 tabelle
  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)

  ' si calcola il numero di quote
  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
  
  ' si calcola il quoziente familiare e il reddito imponibile
  Dim revenu, qf
  revenu=0.72*salaire
  qf=revenu/nbParts
  
  ' si calcola l'imposta
  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))
  
  ' viene visualizzato il risultato
  wscript.echo "impôt=" & impot
  
  ' si esce senza errori
  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