4. Gestión de errores
En programación, hay una regla absoluta: un programa nunca debe «colgarse» de forma imprevista. Todos los errores que puedan producirse durante la ejecución del programa deben gestionarse y deben generarse mensajes de error significativos.
Si retomamos el ejemplo de los impuestos tratado anteriormente, ¿qué ocurre si el usuario introduce cualquier valor para el número de hijos? Veamos este ejemplo:
Esto es lo que se denomina un fallo imprevisto. Se ha producido un «fallo» en la instrucción hijos=cint(wscript.arguments(1)) porque arguments(1) contenía la cadena «xyzt».
Antes de utilizar una variante de la que no se conoce la naturaleza exacta, hay que verificar su subtipo exacto. Esto se puede hacer de diferentes maneras:
- 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 se ajusta a un determinado patrón
- dejar que se produzca el error, interceptarlo y gestionarlo
Analizamos estos diferentes métodos.
4.1. Conocer el tipo exacto de un dato
Recordemos que las funciones vartype o varname permiten conocer el tipo exacto de un dato. Esto no siempre nos resulta de gran ayuda. Por ejemplo, cuando leemos un dato introducido con el teclado, las funciones vartype y typename nos dirán que se trata de una cadena de caracteres, ya que así se considera cualquier dato introducido con el teclado. Esto no nos indica si dicha cadena puede, por ejemplo, considerarse un número válido. Por lo tanto, utilizamos otras funciones para acceder a este tipo de información:
isNumeric(expresión) | devuelve verdadero si la expresión puede utilizarse como un número |
isDate(expresión) | devuelve verdadero si la expresión puede utilizarse como una fecha |
isEmpty(var) | devuelve «verdadero» si la variable var no se ha inicializado |
isNull(var) | devuelve verdadero si la variable var contiene datos no válidos |
isArray(var) | devuelve verdadero si var es una matriz |
isObject(var) | devuelve verdadero si var es un objeto |
El siguiente ejemplo solicita que se introduzca un dato mediante el teclado hasta que este sea reconocido como un número:
Programa
' lectura de un dato hasta que se reconozca como un número
Option Explicit
Dim fini, nombre
' se repite el bucle mientras el dato introducido no sea correcto
' el bucle se controla mediante un valor booleano finito, establecido en falso al inicio (= no ha terminado)
fini=false
Do While Not fini
' se solicita el número
wscript.stdout.write "Tapez un nombre : "
' se lee
nombre=wscript.stdin.readLine
' el tipo es necesariamente cadena al leer
wscript.echo "Type de la donnée lue : " & typename(nombre) & "," & vartype(nombre)
' se comprueba el tipo real de los 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
La función isNumeric no nos indica si una expresión es un entero o no. Para obtener esta información, es necesario realizar pruebas adicionales. El siguiente ejemplo solicita un número entero >0:
Programa
' lectura de un dato hasta que este se reconozca como un número entero >0
Option Explicit
Dim fini, nombre
' se repite el bucle mientras el dato introducido no sea correcto
' el bucle se controla mediante un valor booleano finito, establecido en falso al inicio (= no ha terminado)
fini=false
Do While Not fini
' se solicita el número
wscript.stdout.write "Tapez un nombre entier >0: "
' se lee
nombre=wscript.stdin.readLine
' se comprueba el tipo real de los datos leídos
If isNumeric(nombre) Then
' ¿Es un entero (número igual a su parte entera) positivo?
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
Comentarios:
- int(nombre) devuelve la parte entera de un número. Un número igual a su parte entera es un entero.
- Cabe destacar, curiosamente, que ha sido necesario emplear la prueba If (número-int(número))=0 And número>0 porque la prueba If número=int(número) And número>0 no daba los resultados esperados. No detectaba los números enteros positivos. Dejamos al lector la tarea de descubrir por qué.
- La prueba If (número - int(número)) = 0 no es totalmente fiable. Veamos el siguiente ejemplo de ejecución:
Los números reales no se representan de forma exacta, sino aproximada. Y en este caso, la operación nombre-int(nombre) ha dado como resultado 0, con la precisión del ordenador.
4.2. Las expresiones regulares
Las expresiones regulares nos permiten comprobar el formato de una cadena de caracteres. Así, podemos verificar que una cadena que representa una fecha tiene el formato dd/mm/aa. Para ello, se utiliza un patrón y se compara la cadena con dicho patrón. Así, en este ejemplo, d, m y a deben ser dígitos. El patrón de un formato de fecha válido es entonces «\d\d/\d\d/\d\d», donde el símbolo \d designa un dígito. Los símbolos que se pueden utilizar en un patrón son los siguientes (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 carácter de nueva 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 o más veces. Así, «zo*» corresponde a «z» o a «zoo». |
+ | Corresponde al carácter anterior una o varias veces. Así, «zo+» corresponde a «zoo», pero no a «z». |
? | Coincide con el carácter anterior cero o una vez. Por ejemplo, «a?ve?» coincide con «ve» en «lever». |
. | Coincide con cualquier carácter único, excepto el carácter de nueva línea. |
(patrón) | Busca modèle y memoriza la coincidencia. La subcadena correspondiente se puede extraer de la colección Matches obtenida, utilizando Item [0]...[n]. Para encontrar coincidencias con caracteres entre paréntesis ( ), utilice "\(" o "\)". |
x|y | Coincide con x o con y. Por ejemplo, «z|foot» coincide con «z» o con «foot». «(z|f)oo» coincide con «zoo» o con «foo». |
{n} | n es un número entero no negativo. Corresponde exactamente a n multiplicado por el carácter. Por ejemplo, «o{2}» no corresponde a «o» en «Bob», sino a las dos primeras «o» en «fooooot». |
{n,} | n es un número entero no negativo. Corresponde al menos a n veces el carácter. Por ejemplo, «o{2,}» no coincide con la «o» de «Bob», sino con todas las «o» de «fooooot». «o{1,}» equivale a «o+» y «o{0,}» equivale a «o*». |
{n,m} | m y n son números enteros no negativos. Corresponde al menos a n y como máximo a m veces el carácter. Por ejemplo, «o{1,3}» corresponde a las tres primeras «o» de «foooooot» y «o{0,1}» equivale a «o?». |
[xyz] | Conjunto de caracteres. Corresponde a uno de los caracteres indicados. Por ejemplo, «[abc]» corresponde a «a» en «plat». |
[^xyz] | Conjunto de caracteres negativo. Corresponde a cualquier carácter no indicado. Por ejemplo, «[^abc]» corresponde a «p» en «plat». |
[a-z] | Rango de caracteres. Corresponde a cualquier carácter de la serie especificada. Por ejemplo, «[a-z]» corresponde a cualquier carácter alfabético minúsculo comprendido entre «a» y «z». |
[^m-z] | Rango de caracteres negativo. Corresponde a cualquier carácter que no se encuentre en la serie especificada. Por ejemplo, «[^m-z]» corresponde a cualquier carácter que no se encuentre entre «m» y «z». |
\b | Corresponde a un límite que representa una palabra, es decir, a la posición entre una palabra y un espacio. Por ejemplo, «er\b» corresponde a «er» en «lever», pero no a «er» en «verbe». |
\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 dígito. 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 carácter de nueva línea. |
\r | Corresponde a un carácter de retorno de carro. |
\s | Corresponde a cualquier espacio en blanco, incluyendo el espacio, la tabulación, el salto de página, etc. Equivale a «[ \f\n\r\t\v]». |
\S | Corresponde a cualquier carácter de espacio no blanco. Equivale a «[^ \f\n\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 num, donde num es un número entero positivo. Hace referencia a las coincidencias almacenadas. Por ejemplo, «(.)\1» corresponde a dos caracteres idénticos consecutivos. |
\n | Corresponde a n, donde n es un valor de escape octal. Los valores de escape octales deben tener 1, 2 o 3 dígitos. Por ejemplo, «\11» y «\011» corresponden ambos a un carácter de tabulación. «\0011» equivale a «\001» y «1». Los valores de escape octales no deben superar 256. Si fuera así, solo se tendrían en cuenta los dos primeros dígitos en la expresión. Permite utilizar los códigos ASCII en expresiones regulares. |
\xn | Corresponde a n, donde n es un valor de escape hexadecimal. Los valores de escape hexadecimales deben constar obligatoriamente de dos dígitos. Por ejemplo, «\x41» corresponde a «A». «\x041» equivale a «\x04» y «1». Permite utilizar los códigos ASCII en expresiones regulares. |
Un elemento de una plantilla puede aparecer una o varias veces. Veamos algunos ejemplos relacionados con el símbolo \d, que representa un dígito:
plantilla | significado |
\d | un dígito |
\d? | 0 o 1 dígito |
\d* | 0 o más dígitos |
\d+ | 1 o más dígitos |
\d{2} | 2 dígitos |
\d{3,} | al menos 3 dígitos |
\d{5,7} | entre 5 y 7 dígitos |
Imaginemos ahora el modelo capaz de describir el formato esperado para una cadena de caracteres:
cadena buscada | 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 número entero sin signo | \d+ |
una secuencia de espacios, que puede estar vacía | \s* |
un número entero sin signo que puede ir precedido o seguido de espacios | \s*\d+\s* |
un número entero que puede ser con signo y estar precedido o seguido de espacios | \s*[+|-]?\s*\d+\s* |
un número real sin signo que puede ir precedido o seguido de espacios | \s*\d+(.\d*)?\s* |
un número real que puede ser con signo y estar precedido o seguido de espacios | \s*[+|]?\s*\d+(.\d*)?\s* |
una cadena que contenga la palabra «justo» | \bjusto\b |
Se puede especificar dónde se busca el patrón en la cadena:
patrón | significado |
^patrón | el patrón comienza la cadena |
patrón$ | el patrón termina la cadena |
^patrón$ | el patrón comienza y termina la cadena |
patrón | el patrón se busca en toda la cadena, empezando por el principio de la misma. |
cadena buscada | patrón |
una cadena que termina con un signo de exclamación | !$ |
una cadena que termina en un punto | \.$ |
una cadena que comienza con la secuencia // | ^// |
una cadena que contiene solo una palabra, seguida o precedida opcionalmente de espacios | ^\s*\w+\s*$ |
una cadena que contenga dos palabras, opcionalmente precedidas o seguidas de espacios | ^\s*\w+\s*\w+\s*$ |
una cadena que contenga la palabra «secret» | \bsecret\b |
Los subconjuntos de un patrón pueden «extraerse». De este modo, no solo se puede comprobar si una cadena se ajusta a un patrón concreto, sino que también se pueden extraer de dicha cadena los elementos que corresponden a los subconjuntos del patrón que se han encerrado entre paréntesis. Así, si analizamos una cadena que contiene una fecha dd/mm/aa y queremos además extraer los elementos dd, mm y aa de esa fecha, utilizaremos el patrón (\d\d)/(\d\d)/(\d\d).
Veamos en este ejemplo cómo se opera con VBScript.
- En primer lugar, debemos crear un objeto RegExp (Expresión regular)
- A continuación, establecemos el patrón que queremos comprobar
- Es posible que no queramos distinguir entre mayúsculas y minúsculas (por defecto, sí se distingue). En este caso, no tiene importancia.
- Es posible que se desee buscar el patrón varias veces en la cadena (por defecto no se hace)
Una búsqueda global solo tiene sentido si el patrón utilizado no hace referencia al principio o al final de la cadena.
- Entonces se buscan todas las coincidencias del patrón en la cadena:
El método execute de un objeto RegExp devuelve una colección de objetos de tipo match. Este objeto tiene una propiedad value que es el elemento de chaine correspondiente al patrón. Si se ha escrito modele.global=true, puede haber varias coincidencias. Por eso, el resultado del método execute es una colección de coincidencias.
- El número de coincidencias viene dado por correspondances.count. Si este número es 0, significa que el modelo no se ha encontrado en ninguna parte. El valor de la coincidencia n.º i viene dado por correspondances(i).value. Si el patrón contiene subpatrones entre paréntesis, entonces el elemento de correspondances(i) correspondiente al paréntesis j del patrón es coincidencias(i).subcoincidencias(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
' se define el patrón
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
' es el usuario quien proporciona la cadena en la que se buscará el patrón
Dim chaine, correspondances, i
chaine=""
' se realiza un bucle mientras cadena <> "fin"
Do While true
' se le 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
' se termina si cadena = fin
If chaine="fin" Then Exit Do
' se compara la cadena leída con el patrón de la fecha
Set correspondances=modele.execute(chaine)
' ¿se ha encontrado una coincidencia?
If correspondances.count<>0 Then
' hay al menos una coincidencia
For i=0 To correspondances.count-1
' se muestra la coincidencia i
wscript.echo "J'ai trouvé la date " & correspondances(i).value
' se recuperan 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 coincidencia
wscript.echo "Je n'ai pas trouvé de date au format jj/mm/aa dans votre texte"
End If
Loop
' fin
wscript.quit 0
Resultados
Con expresiones regulares, el programa que comprueba que una entrada del teclado es un número entero positivo podría escribirse de la siguiente manera:
Programa
' lectura de un dato hasta que se reconozca como un número
Option Explicit
Dim fini, nombre
' se define el formato de un número entero positivo (que puede ser cero)
Dim modele
Set modele=new regexp
modele.pattern="^\s*\d+\s*$"
' se repite el bucle mientras el dato introducido no sea correcto
' el bucle se controla mediante un valor booleano finito, establecido en falso al inicio (= no ha terminado)
fini=false
Do While Not fini
' se solicita el número
wscript.stdout.write "Tapez un nombre entier >0: "
' se lee
nombre=wscript.stdin.readLine
' se comprueba el formato de los datos leídos
Dim correspondances
Set correspondances=modele.execute(nombre)
' ¿Se ha verificado el modelo?
If correspondances.count<>0 Then
' es un 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
Encontrar la expresión regular que nos permita verificar que una cadena se ajusta a un determinado patrón es, a veces, todo un reto. El siguiente programa permite practicar. Solicita un patrón y una cadena y, a continuación, indica si la cadena se ajusta o no al patrón.
Programa
' expresión regular
' queremos comprobar que una cadena se ajusta a un patrón
Option Explicit
' se define el patrón
Dim modele
Set modele=new regexp
modele.global=true ' on recherchera le modèle plusieurs fois dans la chaîne
' es el usuario quien proporciona la cadena en la que se buscará el patrón
Dim chaine, correspondances, i
Do While true
' se le pide al usuario que introduzca un patrón
wscript.stdout.write "Tapez le modèle à tester et fin pour arrêter : "
modele.pattern=wscript.stdin.readLine
' ¿Terminado?
If modele.pattern="fin" Then Exit Do
' se le pide al usuario las cadenas que se van a comparar con el patrón
Do While true
' se le pide al usuario que introduzca un patrón
wscript.stdout.writeLine "Tapez la chaîne à tester avec le modèle [" & modele.pattern & "] et fin pour arrêter : "
chaine=wscript.stdin.readLine
' ¿Terminado?
If chaine="fin" Then Exit Do
' se compara la cadena leída con el patrón de la fecha
Set correspondances=modele.execute(chaine)
' ¿se ha encontrado alguna coincidencia?
If correspondances.count<>0 Then
' hay al menos una coincidencia
For i=0 To correspondances.count-1
' se muestra la coincidencia i
wscript.echo "J'ai trouvé la correspondance " & correspondances(i).value
Next
Else
' no hay coincidencia
wscript.echo "Je n'ai pas trouvé de correspondance"
End If
Loop
Loop
' fin
wscript.quit 0
Resultados
4.3. Interceptar los errores de ejecución
Otro método para gestionar los errores de ejecución consiste en dejar que se produzcan, recibir una notificación y gestionarlos en ese momento. Normalmente, cuando se produce un error durante la ejecución, WSH muestra un mensaje de error y el programa se detiene. Hay dos instrucciones que nos permiten modificar este comportamiento:
Esta instrucción indica al sistema (WSH) que vamos a gestionar los errores nosotros mismos. Tras esta instrucción, el sistema simplemente ignora cualquier error.
Esta instrucción nos devuelve al funcionamiento normal de gestión de errores.
Cuando la instrucción «on error resume next» está activa, debemos gestionar nosotros mismos los errores que puedan surgir. El objeto Err nos ayuda en ello. Este objeto tiene diversas propiedades y métodos, de los cuales destacaremos los dos siguientes:
- number: un número entero que indica el número del último error que se ha producido. 0 significa «sin error»
- descripción: el mensaje de error que habría mostrado el sistema si no se hubiera emitido la instrucción on error resume next
Veamos el siguiente ejemplo:
Programa
' error no gestionado
Option Explicit
Dim nombre
nombre=cdbl("abcd")
wscript.echo "nombre=" & nombre
Resultados
Ahora gestionemos el error:
Programa
' error gestionado
Option Explicit
Dim nombre
' gestionamos los errores nosotros mismos
On Error Resume Next
nombre=cdbl("abcd")
' ¿Ha habido algún error?
If Err.number<>0 Then
wscript.echo "L'erreur [" & err.description & "] s'est produite"
On Error GoTo 0
wscript.quit 1
End If
' sin error: se vuelve al funcionamiento normal
On Error GoTo 0
wscript.echo "nombre=" & nombre
wscript.quit 0
Resultados
Reescribamos el programa de introducción de un entero >0 con este nuevo método:
Programa
' lectura de un dato hasta que se reconozca como un número
Option Explicit
Dim fini, nombre
' se repite el bucle hasta que el dato introducido sea correcto
' el bucle se controla mediante un booleano finito, establecido en falso al inicio (= no ha terminado)
fini=false
Do While Not fini
' se solicita el número
wscript.stdout.write "Tapez un nombre entier >0: "
' se lee
nombre=wscript.stdin.readLine
' se comprueba el formato de los datos leídos
On Error Resume Next
nombre=cdbl(nombre)
If err.number=0 Then
' sin errores, es un número
' se vuelve al modo normal de gestión de errores
On Error GoTo 0
' ¿Es un entero >0?
If (nombre-int(nombre))=0 And nombre>0 Then
fini=true
End If
End If
' se vuelve 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:
- En ocasiones, este es el único método que se puede utilizar. En ese caso, no hay que olvidar volver al modo normal de gestión de errores tan pronto como finalice la secuencia de instrucciones que pueda generar el error.
4.4. Aplicación al programa de cálculo de impuestos
Retomamos el programa de cálculo de impuestos ya escrito para, en esta ocasión, verificar la validez de los argumentos pasados al programa:
Programa
' cálculo del impuesto de un contribuyente
' el programa debe ejecutarse con tres parámetros: casado, hijos, salario
' casado: carácter O si está casado, N si no lo está
' hijos: número de hijos
' salario: salario anual sin céntimos
' no se comprueba la validez de los datos, pero
' se comprueba que haya tres
' declaración obligatoria de las 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)"
' se comprueba que haya 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"
' salida con código de error 1
wscript.quit 1
End If
' se recuperan los argumentos comprobando su validez
' se pasa un argumento al programa sin espacios delante ni detrás
' se utilizarán expresiones regulares para verificar la validez de los datos
Dim modele, correspondances
Set modele=new regexp
' el estado civil debe estar entre 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"
' salimos
wscript.quit 2
End If
' se recupera el valor
Dim marie
If lcase(wscript.arguments(0)) = "o"Then
marie=true
Else
marie=false
End If
' «hijos» debe ser un número 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"
' salimos
wscript.quit 3
End If
' se recupera el valor
Dim enfants
enfants=cint(wscript.arguments(1))
' el salario debe ser un 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"
' salir
wscript.quit 4
End If
' se recupera el valor
Dim salaire
salaire=clng(wscript.arguments(2))
' se definen los datos necesarios para el cálculo del 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 participaciones
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
' se calcula el coeficiente 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
' se sale sin errores
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