Skip to content

4. Gestión de errores

En programación, hay una regla absoluta: un programa nunca debe "bloquearse" de forma incontrolada. Los errores que puedan producirse durante la ejecución del programa deben gestionarse y generar mensajes de error significativos.

Si volvemos al ejemplo de los impuestos comentado anteriormente, ¿qué ocurre si el usuario introduce cualquier cosa para el número de hijos? Veamos este ejemplo:

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

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

Esto es lo que llamamos un choque salvaje. Hubo un "choque" en la instrucción children=cint(wscript.arguments(1)) porque argumentos(1) contenía la cadena "xyzt".

Antes de utilizar una variante cuya naturaleza exacta desconocemos, debemos comprobar su subtipo exacto. Hay varias formas de hacerlo:

  • comprobar el tipo real de los datos contenidos en una variante con las funciones vartype o typename
  • utilizar una expresión regular para comprobar que el contenido de la variante corresponde a un determinado modelo
  • permitir que se produzca el error, interceptarlo y solucionarlo

Examinamos estos diferentes métodos.

4.1. Conocer el tipo exacto de datos

Recuerde que el vartype o varname se utilizan para identificar el tipo exacto de datos. Esto no siempre es muy útil. Por ejemplo, cuando leemos datos tecleados en el teclado, la etiqueta vartype y typename nos dirá que es una cadena de caracteres, porque así es como se considera cualquier dato escrito en el teclado. Esto no nos dice si la cadena puede considerarse un número válido, por ejemplo. A continuación, utilizaremos otras funciones para acceder a este tipo de información:

isNumeric(expresión)
hace verdadero si la expresión puede utilizarse como un número
isDate(expresión)
hace verdadero si la expresión puede utilizarse como fecha
isEmpty(var)
devuelve true si la variable var no ha sido inicializada
isNull(var)
devuelve true si la variable var contiene datos no válidos
isArray(var)
devuelve true si var es un array
isObject(var)
devuelve true si var es un objeto

El siguiente ejemplo le pide que escriba datos en el teclado hasta que sean reconocidos como un número :

Programa
' leer los datos hasta que se reconozcan como un número

Option Explicit

Dim fini, nombre

' bucle hasta que los datos introducidos sean correctos
' el bucle está controlado por un booleano finito, puesto a false al principio (= no es finito)

fini=false
Do While Not fini
    ' pedimos el número
    wscript.stdout.write "Tapez un nombre : "
    ' lo leemos
    nombre=wscript.stdin.readLine
    ' el tipo es necesariamente string cuando se lee
    wscript.echo "Type de la donnée lue : " & typename(nombre) & "," & vartype(nombre)
    ' comprobamos el tipo real de datos leídos
    If isNumeric(nombre) Then 
        fini=true
    Else
        wscript.echo "Erreur, vous n'avez pas tapé un nombre. Recommencez svp..."
    End If
Loop

' confirmación
wscript.echo "Merci pour le nombre " & nombre

' y fin
wscript.quit 0
Resultados
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 función isNumeric no nos dice si una expresión es un entero o no. Para obtener esta información, necesitamos hacer algunas pruebas adicionales. El siguiente ejemplo pide un entero >0 :

Programa
' leer datos hasta que se reconozcan como enteros >0

Option Explicit

Dim fini, nombre

' bucle hasta que los datos introducidos sean correctos
' el bucle está controlado por un booleano finito, puesto a false al principio (= no es finito)

fini=false
Do While Not fini
    ' pedimos el número
    wscript.stdout.write "Tapez un nombre entier >0: "
    ' lo leemos
    nombre=wscript.stdin.readLine
    ' comprobar el tipo real de datos leídos
    If isNumeric(nombre) Then
        ' ¿es un número entero positivo (un número igual a su parte entera)?
        If (nombre-int(nombre))=0 And nombre>0 Then
            fini=true
        End If
    End If
    ' posible mensaje de error
    If Not fini Then wscript.echo "Erreur, vous n'avez pas tapé un nombre entier >0. Recommencez svp..."
Loop

' confirmación
wscript.echo "Merci pour le nombre entier >0 : " & nombre

' y fin
wscript.quit 0
Resultados
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

Comentarios :

  • int(número) da la parte entera de un número. Un número igual a su parte entera es un número entero.
  • Curiosamente, fue necesario utilizar el Si (número-int(número))=0 Y número>0 porque la prueba Si número=int(número) Y número>0 no dio los resultados esperados. No detectó números enteros positivos. Dejamos que el lector averigüe por qué.
  • La prueba Si (número-int(número))=0 no es totalmente fiable. Veamos el siguiente ejemplo:
Tapez un nombre entier >0: 4,0000000000000000000000001

Merci pour le nombre entier >0 : 4,0000000000000000000000001

Los números reales no se representan de forma exacta, sino aproximada. Y aquí, la operación número-int(número) dio 0 a la precisión más cercana del ordenador.

4.2. Expresiones regulares

Las expresiones regulares nos permiten comprobar el formato de una cadena de caracteres. Por ejemplo, podemos comprobar que una cadena que representa una fecha tiene el formato dd/mm/aa. Para ello, utilizamos una plantilla y comparamos la cadena con esta plantilla. En este ejemplo, d m y a deben ser números. El modelo para un formato de fecha válido es entonces "\d\d/\d\d/\d\d" donde el símbolo \d designa un número. En un modelo pueden utilizarse los siguientes símbolos (documentación de Microsoft) :

Carácter
Descripción
\
Marca el carácter siguiente como carácter especial o literal. Por ejemplo, "n" corresponde al carácter "n". "\n" corresponde a un nuevo carácter de línea. La secuencia "\" corresponde a "\", mientras que "\(" corresponde a "(".
^
Corresponde al inicio de la entrada.
$
Corresponde al final de la entrada.
*
Corresponde al carácter anterior cero veces o varias veces. Por ejemplo, "zo*" corresponde a "z" o "zoo".
+
Corresponde al carácter anterior una o más veces. Por ejemplo, "zo+" coincide con "zoo", pero no con "z".
?
Corresponde al carácter anterior cero o una vez. Por ejemplo, "a?ve?" corresponde a "ve" en "lever".
.
Corresponde a cualquier carácter individual, excepto el carácter de nueva línea.
(modelo)
Buscar modelo y almacena la coincidencia. La subcadena correspondiente puede extraerse de la colección Partidos obtenido mediante Item [0]...[n]. Para encontrar coincidencias con caracteres entre paréntesis ( ), utilice "\(" o "\)".
x|y
Corresponde a x o a y. Por ejemplo, "z|foot" corresponde a "z" o "foot". "(z|f)oo" corresponde a "zoo" o "foo".
{n}
n es un número entero no negativo. Corresponde exactamente a n veces el carácter. Por ejemplo, "o{2}" no corresponde a la "o" de "Bob", sino a las dos primeras "o "s de "fooooot".
{n,}
n es un número entero no negativo. Corresponde como mínimo a n veces el carácter. Por ejemplo, "o{2,}" no corresponde a la "o" de "Bob", sino a todas las "o "s de "fooooot". "o{1,}" equivale a "o+" y "o{0,}" a "o*".
{n,m}
m y n son enteros no negativos. Corresponde como mínimo a n y como máximo m veces el carácter. Por ejemplo, "o{1,3}" corresponde a las tres primeras "o "s de "foooooot" y "o{0,1}" equivale a "o?".
[xyz]
Juego de caracteres. Corresponde a uno de los caracteres indicados. Por ejemplo, "[abc]" corresponde a la "a" de "plat".
[^xyz]
Conjunto de caracteres negativos. Corresponde a cualquier carácter no especificado. Por ejemplo, "[^abc]" corresponde a "p" en "plat".
[a-z]
Rango de caracteres. Corresponde a cualquier carácter del rango especificado. Por ejemplo, "[a-z]" corresponde a cualquier carácter alfabético minúsculo entre "a" y "z".
[^m-z]
Rango de caracteres negativo. Corresponde a cualquier carácter que no se encuentre en el intervalo especificado. Por ejemplo, "[^m-z]" corresponde a cualquier carácter que no esté entre "m" y "z".
\b
Corresponde a un límite que representa una palabra, es decir, la posición entre una palabra y un espacio. Por ejemplo, "er" corresponde a "er" en "palanca", pero no a "er" en "verbo".
\B
Corresponde a un límite que no representa una palabra. "en*t\B" corresponde a "ent" en "bien entendu".
\d
Corresponde a un carácter que representa un número. Equivale a [0-9].
\D
Corresponde a un carácter que no representa un dígito. Equivale a [^0-9].
\f
Corresponde a un carácter de salto de página.
\n
Corresponde a un nuevo carácter de línea.
\r
Corresponde a un carácter de retorno de carro.
\s
Corresponde a cualquier espacio en blanco, incluyendo espacio, tabulación, salto de página, etc. Equivale a "[ ]".
\S
Corresponde a cualquier carácter que no sea un espacio en blanco. Equivale a "[^ \f\r\t\v]".
\t
Corresponde a un carácter de tabulación.
\v
Corresponde a un carácter de tabulación vertical.
\w
Corresponde a cualquier carácter que represente una palabra e incluya un guión bajo. Equivale a "[A-Za-z0-9_]".
\W
Corresponde a cualquier carácter que no represente una palabra. Equivale a "[^A-Za-z0-9_]".
\num
Corresponde a numdonde num es un número entero positivo. Se refiere a coincidencias almacenadas. Por ejemplo, "(.)\1" corresponde a dos caracteres idénticos consecutivos.
\n
Corresponde a ndonde n es un valor de escape octal. Los valores de escape octales deben contener 1, 2 ó 3 dígitos. Por ejemplo, "\11" y "\011" corresponden ambos a un carácter de tabulación. "\0011" equivale a "\001" & "1". Los valores de escape octales no deben superar 256. Si este fuera el caso, sólo se tendrían en cuenta en la expresión los dos primeros dígitos. Permite utilizar códigos ASCII en expresiones regulares.
\xn
Corresponde a ndonde n es un valor de escape hexadecimal. Los valores de escape hexadecimales deben contener dos dígitos. Por ejemplo, "\x41" equivale a "A". "\x041" equivale a "\x04" & "1". Permite utilizar códigos ASCII en expresiones regulares.

Un elemento de un modelo puede estar presente en 1 o más copias. Veamos algunos ejemplos en los que interviene el símbolo \d que representa 1 dígito :

modelo
significado
\d
un número
\d?
0 o 1 dígito
\d*
0 o más dígitos
\d+
1 o más dígitos
\d{2}
2 cifras
\d{3,}
al menos 3 dígitos
\d{5,7}
entre 5 y 7 dígitos

Imaginemos ahora un modelo capaz de describir el formato esperado para una cadena de caracteres:

cadena de búsqueda
modelo
una fecha en formato dd/mm/aa
\d{2}/\d{2}/\d{2}
una hora en formato hh:mm:ss
\d{2}:\d{2}:\d{2}
un entero sin signo
\d+
una secuencia de espacios que pueden estar vacíos
\s*
un entero sin signo que puede ir precedido o seguido de espacios
\s*\d+\s*
un número entero que puede ir con signo y precedido o seguido de espacios
\...que no es lo mismo..
un número real sin signo que puede ir precedido o seguido de espacios
\s*\d+(.\d*)?\s*
un número real que puede ir con signo y precedido o seguido de espacios
\s*[+|]?\s*\d+(.\d*)?\s*
una cadena que contenga la palabra correcta
\bjuste\b
  

Puede especificar en qué punto de la cadena busca el modelo:

modelo
significado
^modelo
el modelo inicia la cadena
modelo$
el modelo termina la cadena
^model$
el modelo inicia y termina la cadena
modelo
el modelo se busca en toda la cadena, empezando por el principio.
cadena de búsqueda
modelo
una cadena acabada en signo de exclamación
!$
una cadena acabada en punto
\.$
una cadena que comienza con la secuencia //
^//
una cadena que contiene una sola palabra, posiblemente seguida o precedida de espacios
^\s*\w+\s*$
una cadena que contiene sólo dos palabras, posiblemente seguidas o precedidas de espacios
^\s*\w+\s*\w+\s*$
una cadena que contiene la palabra secreta
\bsecret\b

Los subconjuntos de un modelo pueden "recuperarse". De este modo, no sólo podemos comprobar que una cadena corresponde a un modelo determinado, sino que también podemos recuperar de esta cadena los elementos correspondientes a los subconjuntos del modelo que se han encerrado entre paréntesis. Así, si analizamos una cadena que contiene una fecha dd/mm/aa y también queremos recuperar los elementos dd, mm, yy de esta fecha, utilizaremos el modelo (\d)/(\d)/(\d).

Utilicemos este ejemplo para ver cómo funciona vbscript.

  • primero tenemos que crear un RegExp (Expresión regular)
set modele=new regexp
  • entonces establecemos el modelo a probar
modele.pattern="(\d\d)/(\d\d)/(\d\d)"
  • puede que no quieras diferenciar entre mayúsculas y minúsculas (por defecto sí). Aquí no importa.
modele.IgnoreCase=true
  • es posible que desee buscar el modelo varias veces en la cadena (esto no se hace por defecto)
modele.Global=true

Una búsqueda global sólo tiene sentido si el modelo utilizado no hace referencia al principio o al final de la cadena.

  • buscamos todas las coincidencias en el archivo :
set correspondances=modele.execute(chaine)

El método ejecutar un objeto RegExp hace una colección de objetos de tipo match. Este objeto tiene una propiedad valor que es el elemento de cadena correspondiente al modelo. Si hemos escrito modele.global=truepuede haber varias coincidencias. Por ello, el resultado de la ejecutar es una colección de correspondencias.

  • el número de coincidencias viene dado por correspondances.count. Si este número es 0, el modelo no se ha encontrado en ninguna parte. El valor de la coincidencia nº i viene dado por coincidencias(i).valor. Si el modelo contiene submodelos entre paréntesis, los elementos de coincidencias(i) correspondiente al paréntesis j en el modelo es coincidencias(i).subcomparaciones(j).

Todo esto se muestra en el siguiente ejemplo:

Programa
' expresión regular

' queremos comprobar que una cadena contiene una fecha en formato dd/mm/aa

Option Explicit
Dim modele

' definimos el modelo
Set modele=new regexp
modele.pattern="\b(\d\d)/(\d\d)/(\d\d)\b"  ' una fecha en cualquier lugar de la cadena
modele.global=true                      ' buscaremos el modelo varias veces en la cadena

' el usuario proporciona la cadena en la que buscar el modelo
Dim chaine, correspondances, i

chaine=""
' bucle mientras cadena<>"fin"
Do While true
    ' se pide al usuario que escriba un texto
    wscript.stdout.writeLine "Tapez un texte contenant des dates au format jj/mm/aa et fin pour arrêter : "
    chaine=wscript.stdin.readLine
    ' terminado si cadena=terminado
    If chaine="fin" Then Exit Do
    ' la cadena leída se compara con la plantilla de fecha
    Set correspondances=modele.execute(chaine)
    ' se encontró una coincidencia
    If correspondances.count<>0 Then
        ' tenemos al menos una coincidencia
        For i=0 To correspondances.count-1
            ' mostramos la correspondencia i
            wscript.echo "J'ai trouvé la date " & correspondances(i).value
            ' recuperamos los subelementos de la coincidencia 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 hay correspondencia
        wscript.echo "Je n'ai pas trouvé de date au format jj/mm/aa dans votre texte"
    End If
Loop

' acabado
wscript.quit 0
Resultados
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

Utilizando expresiones regulares, el programa que comprueba si una entrada del teclado es un número entero positivo podría escribirse de la siguiente manera:

Programa
' leer los datos hasta que se reconozcan como un número

Option Explicit

Dim fini, nombre

' definimos el modelo de un número entero positivo (que puede ser cero)
Dim modele
Set modele=new regexp
modele.pattern="^\s*\d+\s*$"

' bucle hasta que los datos introducidos sean correctos
' el bucle está controlado por un booleano finito, puesto a false al principio (= no es finito)

fini=false
Do While Not fini
    ' pedimos el número
    wscript.stdout.write "Tapez un nombre entier >0: "
    ' lo leemos
    nombre=wscript.stdin.readLine
    ' comprobamos el formato de los datos leídos
    Dim correspondances
    Set correspondances=modele.execute(nombre)
    ' ¿Se ha comprobado el modelo?
    If correspondances.count<>0 Then
        ' es un número entero, pero ¿es >0?
        nombre=cint(nombre)
        If nombre>0 Then
            fini=true
        End If
    End If
    ' posible mensaje de error
    If Not fini Then wscript.echo "Erreur, vous n'avez pas tapé un nombre entier >0. Recommencez svp..."
Loop

' confirmación
wscript.echo "Merci pour le nombre entier >0 : " & nombre

' y fin
wscript.quit 0
Resultados
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

Encontrar la expresión regular que nos permita comprobar que una cadena corresponde a un determinado modelo es a veces un verdadero reto. El siguiente programa te da la oportunidad de practicar. Pide un patrón y una cadena y luego indica si la cadena coincide o no con el patrón.

Programa
' expresión regular

' queremos comprobar que una cadena corresponde a un modelo

Option Explicit

' definimos el modelo
Dim modele
Set modele=new regexp
modele.global=true                      ' buscaremos el modelo varias veces en la cadena

' el usuario proporciona la cadena en la que buscar el modelo
Dim chaine, correspondances, i

Do While true
    ' se pide al usuario que escriba un modelo
    wscript.stdout.write "Tapez le modèle à tester et fin pour arrêter : "
    modele.pattern=wscript.stdin.readLine
    ' ¿Terminaste?
    If modele.pattern="fin" Then Exit Do
        ' se pide al usuario las cadenas para compararlas con el modelo
        Do While true
            ' se pide al usuario que escriba un modelo
            wscript.stdout.writeLine "Tapez la chaîne à tester avec le modèle [" & modele.pattern & "] et fin pour arrêter : "
            chaine=wscript.stdin.readLine
            ' ¿Terminaste?
            If chaine="fin" Then Exit Do
            ' la cadena leída se compara con la plantilla de fecha
            Set correspondances=modele.execute(chaine)
            ' se encontró una coincidencia
            If correspondances.count<>0 Then
                ' tenemos al menos una coincidencia
                For i=0 To correspondances.count-1
                    ' mostramos la correspondencia i
                    wscript.echo "J'ai trouvé la correspondance " & correspondances(i).value
                Next
            Else
                ' no hay correspondencia
                wscript.echo "Je n'ai pas trouvé de correspondance"
            End If
    Loop
Loop

' terminado
wscript.quit 0
Resultados
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. Interceptar errores de ejecución

Otra forma de tratar los errores en tiempo de ejecución es dejar que se produzcan, ser advertido de ellos y luego tratarlos. Normalmente, cuando se produce un error en tiempo de ejecución, WSH muestra un mensaje de error y el programa se detiene. Dos instrucciones nos permiten cambiar esto:

on error resume next

Esta instrucción indica al sistema (WSH) que nosotros mismos manejaremos los errores. Después de esta instrucción, cualquier error es simplemente ignorado por el sistema.

on error goto 0

Esta instrucción nos devuelve a la gestión normal de errores.

Cuando el en error reanudar siguiente está activo, tenemos que ocuparnos nosotros mismos de cualquier error. El objeto Err nos ayuda a ello. Este objeto tiene varias propiedades y métodos, de los cuales mencionaremos los dos siguientes:

  • número un número entero del último error que se ha producido. 0 significa "ningún error"
  • descripción el mensaje de error que el sistema habría mostrado si la instrucción en error reanudar siguiente

Veamos el siguiente ejemplo:

Programa
Resultados
1
2
3
4
5
6
7
' error no controlado

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'

Ahora vamos a tratar el error:

Programa
Resultados
' error gestionado

Option Explicit
Dim nombre

' nosotros mismos nos ocupamos de los errores
On Error Resume Next
nombre=cdbl("abcd")
' ¿hubo un error?
If Err.number<>0 Then
    wscript.echo "L'erreur [" & err.description & "] s'est produite"
    On Error GoTo 0
    wscript.quit 1
End If
' no hay error - vuelve al funcionamiento normal
On Error GoTo 0
wscript.echo "nombre=" & nombre
wscript.quit 0
L'erreur [Type incompatible] s'est produite

Reescribamos el programa para introducir un entero >0 utilizando este nuevo método:

Programa
' leer los datos hasta que se reconozcan como un número

Option Explicit

Dim fini, nombre

' bucle hasta que los datos introducidos sean correctos
' el bucle está controlado por un booleano finito, puesto a false al principio (= no es finito)

fini=false
Do While Not fini
  ' pedimos el número
  wscript.stdout.write "Tapez un nombre entier >0: "
  ' lo leemos
  nombre=wscript.stdin.readLine
  ' comprobamos el formato de los datos leídos
  On Error Resume Next
  nombre=cdbl(nombre)
  If err.number=0 Then
    ' no hay error es un número
    ' volvemos al modo normal de gestión de errores
    On Error GoTo 0
    ' es un número entero >0
    If (nombre-int(nombre))=0 And nombre>0 Then
      fini=true
    End If
  End If
  ' volvemos al modo normal de gestión de errores
  On Error GoTo 0
  ' posible mensaje de error
  If Not fini Then wscript.echo "Erreur, vous n'avez pas tapé un nombre entier >0. Recommencez svp..."
Loop

' confirmación
wscript.echo "Merci pour le nombre entier >0 : " & nombre

' y fin
wscript.quit 0
Resultados
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

Comentarios :

  • Este método es a veces el único que puede utilizarse. En este caso, no olvide volver al modo normal de tratamiento de errores en cuanto haya finalizado la secuencia de instrucciones susceptible de generar el error.

4.4. Aplicación al programa de cálculo de impuestos

Volvemos al programa de cálculo de impuestos que ya hemos escrito, esta vez para comprobar la validez de los argumentos pasados al programa:

Programa
' cálculo de la deuda tributaria del contribuyente
' el programa debe llamarse con tres parámetros: salario de los hijos casados
' casado: carácter Y si está casado, N si no lo está
' hijos: número de hijos
' salario: salario anual sin céntimos

' no se realiza ninguna verificación de la validez de los datos, pero sí
' compruebe que son tres

' declaración obligatoria de 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)"

' comprobamos que hay 3 argumentos
  Dim nbArguments
  nbArguments=wscript.arguments.count
  If nbArguments<>3 Then
    ' mensaje de error
    wscript.echo syntaxe & vbCRLF & vbCRLF & "erreur : nombre d'arguments incorrect"
    ' parada con código de error 1
    wscript.quit 1
  End If

' recuperar los argumentos y comprobar su validez
' un argumento se pasa al programa sin espacios delante y detrás de él
' se utilizarán expresiones regulares para comprobar la validez de los datos
  Dim modele, correspondances
  Set modele=new regexp

  ' el estado civil debe ser uno de los caracteres 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"
    ' nos vamos
    wscript.quit 2
  End If
  ' el valor
  Dim marie
  If lcase(wscript.arguments(0)) = "o"Then
    marie=true
  Else
    marie=false
  End If

  ' children debe ser un entero >=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"
    ' nos vamos
    wscript.quit 3
  End If
  ' el valor
  Dim enfants
  enfants=cint(wscript.arguments(1))

  ' el salario debe ser un número entero >=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"
    ' nos vamos
    wscript.quit 4
  End If
  ' el valor
  Dim salaire
  salaire=clng(wscript.arguments(2))

  ' definimos los datos necesarios para calcular el impuesto en 3 tablas
  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)

  ' se calcula el número de acciones
  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

  ' calculamos la cuota familiar y la base imponible
  Dim revenu, qf
  revenu=0.72*salaire
  qf=revenu/nbParts

  ' se calcula el impuesto
  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))

  ' se muestra el resultado
  wscript.echo "impôt=" & impot

  ' salimos sin error
  wscript.quit 0
Resultados
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