4. Tratamento de erros
Na programação, existe uma regra absoluta: um programa nunca deve «travar» inesperadamente. Todos os erros que possam ocorrer durante a execução do programa devem ser tratados, e devem ser geradas mensagens de erro significativas.
Se voltarmos ao exemplo do imposto discutido anteriormente, o que acontece se o utilizador introduzir qualquer valor para o número de filhos? Vejamos este exemplo:
Isto é o que se designa por uma falha grave. A instrução enfants=cint(wscript.arguments(1)) provocou uma «falha» porque arguments(1) continha a cadeia de caracteres «xyzt».
Antes de utilizar uma variante cuja natureza exata é desconhecida, deve verificar o seu subtipo exato. Existem várias formas de o fazer:
- testar o tipo real dos dados contidos numa variante utilizando as funções vartype ou typename
- utilizar uma expressão regular para verificar se o conteúdo da variante corresponde a um padrão específico
- deixar que o erro ocorra, para depois o interceptar e tratar
Iremos examinar estes diferentes métodos.
4.1. Determinar o tipo exato de um item de dados
Lembre-se de que as funções vartype e varname permitem determinar o tipo exato de um dado. Isto nem sempre é muito útil. Por exemplo, quando lemos dados digitados no teclado, as funções vartype e typename dir-nos-ão que se trata de uma cadeia de caracteres, uma vez que todos os dados digitados no teclado são tratados como tal. Isto não nos diz se esta cadeia de caracteres pode, por exemplo, ser considerada um número válido. Por isso, utilizamos outras funções para aceder a este tipo de informação:
isNumeric(expressão) | retorna true se a expressão puder ser usada como um número |
isDate(expressão) | retorna true se a expressão puder ser usada como uma data |
isEmpty(var) | retorna true se a variável var não tiver sido inicializada |
isNull(var) | retorna true se a variável var contiver dados inválidos |
isArray(var) | retorna true se var for uma matriz |
isObject(var) | retorna true se var for um objeto |
O exemplo seguinte solicita ao utilizador que introduza dados através do teclado até que sejam reconhecidos como um número:
Programa
' 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
Resultados
A função isNumeric não nos diz se uma expressão é um número inteiro ou não. Para obter esta informação, são necessários testes adicionais. O exemplo seguinte solicita um número inteiro maior que 0:
Programa
' 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
Resultados
Comentários:
- int(número) devolve a parte inteira de um número. Um número igual à sua parte inteira é um número inteiro.
- É interessante notar que tivemos de utilizar o teste If (número - int(número)) = 0 And número > 0 porque o teste If número = int(número) And número > 0 não produziu os resultados esperados. Não detectou números inteiros positivos. Deixamos ao leitor a tarefa de descobrir porquê.
- O teste If (número - int(número)) = 0 não é totalmente fiável. Vejamos o seguinte exemplo:
Os números reais não são representados com exatidão, mas sim de forma aproximada. E, neste caso, a operação number-int(number) devolveu 0 com a precisão do computador.
4.2. Expressões regulares
As expressões regulares permitem-nos testar o formato de uma cadeia de caracteres. Desta forma, podemos verificar se uma cadeia de caracteres que representa uma data está no formato dd/mm/aa. Para tal, utilizamos um padrão e comparamos a cadeia de caracteres com esse padrão. Assim, neste exemplo, d, m e y devem ser dígitos. O padrão para um formato de data válido é, então, "\d\d/\d\d/\d\d", onde o símbolo \d denota um dígito. Os símbolos que podem ser utilizados num padrão são os seguintes (documentação da Microsoft):
Caractere | Descrição |
\ | Designa o caractere seguinte como um caractere especial ou literal. Por exemplo, «n» corresponde ao caractere «n». «\n» corresponde a um caractere de nova linha. A sequência «\\» corresponde a «\», enquanto «\» corresponde a «(». |
^ | Corresponde ao início da entrada. |
$ | Corresponde ao fim da entrada. |
* | Corresponde ao caractere anterior zero ou mais vezes. Assim, «zo*» corresponde a «z» ou «zoo». |
+ | Corresponde ao caractere anterior uma ou mais vezes. Assim, «zo+» corresponde a «zoo», mas não a «z». |
? | Corresponde ao caractere anterior zero ou uma vez. Por exemplo, "a?ve?" corresponde a "ve" em "lever". |
. | Corresponde a qualquer caractere único, exceto o caractere de nova linha. |
(padrão) | Procura o padrão e armazena a correspondência. A subcadeia correspondente pode ser recuperada da coleção Matches resultante utilizando Item [0]...[n]. Para encontrar correspondências com caracteres dentro de parênteses ( ), utilize "\(" ou "\)". |
x|y | Corresponde a x ou a y. Por exemplo, "z|foot" corresponde a "z" ou a "foot". "(z|f)oo" corresponde a "zoo" ou a "foo". |
{n} | n é um número inteiro não negativo. Corresponde exatamente a n ocorrências do caractere. Por exemplo, "o{2}" não corresponde a "o" em "Bob", mas corresponde aos dois primeiros "o"s em "fooooot". |
{n,} | n é um número inteiro não negativo. Corresponde a, pelo menos, n ocorrências do caractere. Por exemplo, "o{2,}" não corresponde ao "o" em "Bob", mas corresponde a todos os "o"s em "fooooot". "o{1,}" é equivalente a "o+" e "o{0,}" é equivalente a "o*". |
{n,m} | m e n são números inteiros não negativos. Corresponde a, no mínimo, n e, no máximo, m ocorrências do caractere. Por exemplo, "o{1,3}" corresponde aos primeiros três "o"s em "foooooot", e "o{0,1}" corresponde a "o?". |
[xyz] | Conjunto de caracteres. Corresponde a qualquer um dos caracteres especificados. Por exemplo, "[abc]" corresponde a "a" em "plat". |
[^xyz] | Conjunto de caracteres negativo. Corresponde a qualquer caractere não listado. Por exemplo, "[^abc]" corresponde a "p" em "plat". |
[a-z] | Intervalo de caracteres. Corresponde a qualquer caractere no intervalo especificado. Por exemplo, "[a-z]" corresponde a qualquer caractere alfabético minúsculo entre "a" e "z". |
[^m-z] | Intervalo de caracteres negativo. Corresponde a qualquer caractere que não esteja no intervalo especificado. Por exemplo, "[^m-z]" corresponde a qualquer caractere que não esteja entre "m" e "z". |
\b | Corresponde a um limite de palavra, ou seja, a posição entre uma palavra e um espaço. Por exemplo, "er\b" corresponde a "er" em "lever", mas não a "er" em "verb". |
\B | Corresponde a um limite que não representa uma palavra. "en*t\B" corresponde a "ent" em "bien entendu". |
\d | Corresponde a um caractere que representa um dígito. Equivalente a [0-9]. |
\D | Corresponde a um carácter que não seja um dígito. Equivalente a [^0-9]. |
\f | Corresponde a um caractere de quebra de linha. |
\n | Corresponde a um caractere de nova linha. |
\r | Equivalente a um caractere de retorno de carro. |
\s | Corresponde a qualquer espaço em branco, incluindo espaço, tabulação, quebra de página, etc. Equivalente a "[ \f\n\r\t\v]". |
\S | Corresponde a qualquer caractere que não seja um espaço em branco. Equivalente a "[^ \f\n\r\t\v]". |
\t | Corresponde a um caractere de tabulação. |
\v | Corresponde a um caractere de tabulação vertical. |
\w | Corresponde a qualquer caractere que represente uma palavra, incluindo o sublinhado. Equivalente a "[A-Za-z0-9_]". |
\W | Corresponde a qualquer caractere que não represente uma palavra. Equivalente a "[^A-Za-z0-9_]". |
\num | Corresponde a num, onde num é um número inteiro positivo. Refere-se a correspondências armazenadas. Por exemplo, "(.)\1" corresponde a dois caracteres idênticos consecutivos. |
\n | Corresponde a n, onde n é um valor de escape octal. Os valores de escape octais devem consistir em 1, 2 ou 3 dígitos. Por exemplo, "\11" e "\011" correspondem ambos a um caractere de tabulação. "\0011" é equivalente a "\001" e "1". Os valores de escape octais não devem exceder 256. Se excederem, apenas os dois primeiros dígitos são tidos em conta na expressão. Permite que os códigos ASCII sejam utilizados em expressões regulares. |
\xn | Corresponde a n, onde n é um valor de escape hexadecimal. Os valores de escape hexadecimais devem consistir em exatamente dois dígitos. Por exemplo, "\x41" corresponde a "A". "\x041" é equivalente a "\x04" e "1". Permite a utilização de códigos ASCII em expressões regulares. |
Um elemento num padrão pode aparecer uma ou várias vezes. Vejamos alguns exemplos envolvendo o símbolo \d, que representa um único dígito:
padrão | significado |
\d | um dígito |
\d? | 0 ou 1 dígito |
\d* | 0 ou mais dígitos |
\d+ | 1 ou mais dígitos |
\d{2} | 2 dígitos |
\d{3,} | pelo menos 3 dígitos |
\d{5,7} | entre 5 e 7 dígitos |
Agora, imaginemos um modelo capaz de descrever o formato esperado para uma cadeia de caracteres:
cadeia de caracteres alvo | padrão |
uma data no formato dd/mm/aa | \d{2}/\d{2}/\d{2} |
uma hora no formato hh:mm:ss | \d{2}:\d{2}:\d{2} |
um inteiro sem sinal | \d+ |
uma sequência de espaços, que pode estar vazia | \s* |
um inteiro sem sinal que pode ser precedido ou seguido por espaços | \s*\d+\s* |
um inteiro que pode ser assinado e precedido ou seguido por espaços | \s*[+|-]?\s*\d+\s* |
um número real sem sinal que pode ser precedido ou seguido por espaços | \s*\d+(.\d*)?\s* |
um número real que pode ser assinado e precedido ou seguido por espaços | \s*[+|]?\s*\d+(.\d*)?\s* |
uma cadeia de caracteres contendo a palavra «just» | \bjuste\b |
Pode especificar onde procurar o padrão na cadeia de caracteres:
padrão | significado |
^padrão | o padrão inicia a cadeia |
padrão$ | o padrão termina a cadeia |
^padrão$ | o padrão inicia e termina a cadeia |
padrão | o padrão é procurado em qualquer parte da cadeia, começando pelo início. |
cadeia de pesquisa | padrão |
uma cadeia que termine com um ponto de exclamação | !$ |
uma cadeia que termina com um ponto | \.$ |
uma sequência que começa com // | ^// |
uma cadeia composta por uma única palavra, opcionalmente precedida ou seguida por espaços | ^\s*\w+\s*$ |
uma cadeia composta por duas palavras, opcionalmente seguida ou precedida por espaços | ^\s*\w+\s*\w+\s*$ |
uma cadeia que contém a palavra secret | \bsecret\b |
Os subpadrões de um padrão podem ser «extraídos». Assim, não só podemos verificar se uma cadeia corresponde a um determinado padrão, como também podemos extrair dessa cadeia os elementos correspondentes aos subpadrões do padrão que foram colocados entre parênteses. Por exemplo, se estivermos a analisar uma cadeia de caracteres que contenha uma data no formato dd/mm/aa e quisermos extrair os componentes dd, mm e aa dessa data, usaríamos o padrão (\d\d)/(\d\d)/(\d\d).
Vejamos este exemplo para perceber como fazer isto com VBScript.
- Primeiro, precisamos de criar um objeto RegExp (Expressão Regular)
- Em seguida, definimos o padrão a ser testado
- Pode querer ignorar maiúsculas e minúsculas (por predefinição, distingue-se entre maiúsculas e minúsculas). Aqui, isso não importa.
- Pode querer procurar o padrão várias vezes na cadeia de caracteres (por predefinição, isto não é feito)
Uma pesquisa global só faz sentido se o padrão utilizado não se referir ao início ou ao fim da cadeia de caracteres.
- Em seguida, procuramos todas as ocorrências do padrão na cadeia de caracteres:
O método execute de um objeto RegExp devolve uma coleção de objetos match. Este objeto possui uma propriedade value que corresponde à sequência de caracteres que corresponde ao padrão. Se tiver definido pattern.global=true*, poderá haver várias correspondências. É por isso que o resultado do método execute* é uma coleção de objetos match.
- O número de correspondências é fornecido por `matches.count`. Se este número for 0, significa que o padrão não foi encontrado em nenhum lugar. O valor da correspondência #i é fornecido por `matches(i).value`. Se o padrão contiver subpadrões entre parênteses, então o elemento de `matches(i)` correspondente ao parêntese j no padrão é `matches(i).submatches(j)`.
Tudo isto é demonstrado no exemplo seguinte:
Programa
' 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
Resultados
Utilizando expressões regulares, o programa que verifica se uma entrada do teclado é de facto um número inteiro positivo poderia ser escrito da seguinte forma:
Programa
' 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
Resultados
Encontrar a expressão regular que nos permite verificar se uma cadeia de caracteres corresponde a um determinado padrão pode, por vezes, ser um verdadeiro desafio. O programa seguinte permite-lhe praticar. Pede-lhe um padrão e uma cadeia de caracteres e, em seguida, indica se a cadeia de caracteres corresponde ou não ao padrão.
Programa
' 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
Resultados
4.3. Tratamento de erros de tempo de execução
Outro método para lidar com erros de tempo de execução consiste em deixá-los ocorrer, ser notificado sobre eles e, em seguida, tratá-los. Normalmente, quando ocorre um erro em tempo de execução, o WSH exibe uma mensagem de erro e o programa pára. Duas instruções permitem-nos alterar este comportamento:
Esta instrução indica ao sistema (WSH) que iremos tratar os erros nós próprios. Após esta instrução, quaisquer erros são simplesmente ignorados pelo sistema.
Esta instrução faz-nos regressar ao tratamento normal de erros.
Quando a instrução on error resume next está ativa, temos de tratar nós próprios quaisquer erros que possam ocorrer. O objeto Err ajuda-nos a fazer isso. Este objeto tem várias propriedades e métodos, dos quais nos vamos concentrar nos dois seguintes:
- number: um inteiro que representa o número do último erro ocorrido. 0 significa «sem erro»
- description: a mensagem de erro que o sistema teria exibido se não tivéssemos emitido a instrução on error resume next
Vejamos o seguinte exemplo:
Programa
' unhandled error
Option Explicit
Dim nombre
nombre=cdbl("abcd")
wscript.echo "nombre=" & nombre
Resultados
Agora vamos tratar do erro:
Programa
' 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
Resultados
Vamos reescrever o programa para introduzir um número inteiro >0 utilizando este novo método:
Programa
' 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
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
Comentários:
- Este método é, por vezes, o único que pode ser utilizado. Nesse caso, não se esqueça de regressar ao modo normal de tratamento de erros assim que a sequência de instruções suscetível de gerar o erro estiver concluída.
4.4. Aplicação ao programa de cálculo de impostos
Vamos revisitar o programa de cálculo de impostos que escrevemos anteriormente para, desta vez, verificar a validade dos argumentos passados ao programa:
Programa
' 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
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