Skip to content

3. Noções básicas de programação VBSCRIPT

Depois de descrevermos os possíveis contextos de execução de um script VBScript, abordamos agora a própria linguagem. A partir daqui, partimos do seguinte pressuposto:

  1. o contêiner do script é WSH
  2. o script está num ficheiro com a extensão .vbs

Para apresentar um conceito, procedemos geralmente da seguinte forma:

  • introduzimos o conceito, se necessário
  • apresentamos um programa ilustrativo com os respetivos resultados
  • comentamos os resultados e o programa, se necessário

Os contêineres VBScript não distinguem entre maiúsculas e minúsculas no texto do script. Assim, pode-se escrever indistintamente wscript.echo «olá» ou WSCRIPT.ECHO «olá».

Os programas apresentados a seguir realizam muitas saídas no ecrã, pelo que iremos apresentar novamente os métodos de saída do objeto wscript.

3.1. Exibir informações

Já utilizámos o método echo do objeto wscript, mas este último possui outros métodos que permitem escrever no ecrã, como mostra o seguinte script:

Programa
Resultados
1
2
3
4
un
deuxtrois
quatre
cinq

É importante ter em conta os seguintes pontos:

  • Qualquer texto colocado após um apóstrofo é considerado um comentário do script e não é interpretado pelo WSH (linha 1).
  • O método echo escreve os seus argumentos e passa para a linha seguinte, tal como o método writeLine (linhas 2 e 6)
  • O método write escreve os seus argumentos e não passa para a linha seguinte (linha 3)
  • Um marcador de fim de linha é representado pela sequência de dois caracteres de código ASCII 13 e 10. Assim, a linha 4 é representada pela expressão chr(13) & chr(10), em que chr(i) é o carácter de código ASCII i e & é o operador de concatenação de cadeias. Assim, «chat» & «eau» resulta na cadeia «chateau».
  • O marcador de fim de linha pode ser representado mais facilmente pela constante vbCRLF (linha 5)

3.2. E a escrita de instruções num script VBScript

Por predefinição, escreve-se uma instrução por linha. No entanto, é possível escrever várias instruções por linha, separando-as pelo caractere :, como em inst1:inst2:inst3. Se uma linha for demasiado longa, pode ser dividida em partes. Nesse caso, as diferentes partes da instrução devem terminar com os dois caracteres (espaço)_. Retomamos o exemplo anterior, reescrevendo as instruções de forma diferente:

Programa
Resultados
1
2
3
4
un
deuxtrois
quatre
cinq

3.3. Escrever com a função msgBox

Embora neste documento utilizemos quase exclusivamente o objeto wscript para escrever no ecrã, existe uma função mais sofisticada para apresentar informações numa janela. Trata-se da função msgbox, que é geralmente utilizada com três parâmetros:

msgbox mensagem, ícones+botões, título

  • mensagem é o texto da mensagem a exibir
  • ícones+botões (opcional) é, na verdade, um número que indica o tipo de ícone e os botões a colocar na janela da mensagem. Este número é, na maioria das vezes, a soma de dois números: o primeiro determina o ícone, o segundo os botões
  • o título é o texto a colocar na barra de título da janela da mensagem

Os valores a utilizar para especificar o ícone e os botões da janela de exibição são os seguintes:

Constante
Valor
Descrição
vbOKOnly
   0
Apresenta apenas o botão OK.
vbOKCancel
   1
Exibe os botões OK e «Cancelar».
vbAbortRetryIgnore
   2
Exibe os botões «Desistir», «Tentar novamente» e «Ignorar».
vbYesNoCancel
   3
Exibe os botões «Sim», «Não» e «Cancelar».
vbYesNo
   4
Exibe os botões «Sim» e «Não».
vbRetryCancel
   5
Exibe os botões «Tentar novamente» e «Cancelar».
vbCritical
16
Exibe o ícone «Mensagem crítica».
vbQuestion
32
Exibe o ícone «Pedido de aviso».
vbExclamation
48
Exibe o ícone «Mensagem de aviso».
vbInformation
64
Exibe o ícone de mensagem informativa.
vbDefaultButton1
   0
O primeiro botão é o botão predefinido.
vbDefaultButton2
256
O segundo botão é o botão predefinido.
vbDefaultButton3
512
O terceiro botão é o botão predefinido.
vbDefaultButton4
768
O quarto botão é o botão predefinido.
vbApplicationModal
   0
Aplicação modal; o utilizador deve responder à mensagem antes de continuar a trabalhar na aplicação atual.
vbSystemModal
4096
Sistema modal; todas as aplicações ficam suspensas até que o utilizador responda à mensagem.

Eis alguns exemplos:

Programa
Resultados
  
   
   

Em alguns casos, é apresentada uma janela de informação que também funciona como janela de introdução de dados. Se for feita uma pergunta, pretende-se, por exemplo, saber se o utilizador clicou no botão oui ou no botão non. A função msgBox devolve um resultado que, no programa anterior, não utilizámos. Este resultado é um número inteiro que representa o botão utilizado pelo utilizador para fechar a janela de visualização:

Constante
Valor
Botão selecionado
vbOK
1
OK
vbCancel
2
Cancelar
vbAbort
3
Desistência
vbRetry
4
Tentar novamente
vbIgnore
5
Ignorar
vbYes
6
Sim
vbNo
7
Não

O programa seguinte mostra a utilização do resultado da função msgBox. É apresentada 4 vezes uma janela com os botões «sim», «não» e «cancelar». Responde-se da seguinte forma:

  1. clica-se em «Sim»
  2. clica-se em «Não»
  3. clica-se em «Cancelar»
  4. fecha-se a janela sem utilizar nenhum botão. O programa mostra que isto equivale a utilizar o botão «Cancelar».
Programa
Resultados

3.4. O fornece dados utilizáveis em VBScript

O VBscript reconhece apenas um tipo de dados: o variante. O valor de um «variant» pode ser um número (4, 10,2), uma cadeia de caracteres («olá»), um valor booleano (true/false), uma data (#01/01/2002#), o endereço de um objeto ou um conjunto de todos estes dados colocados numa estrutura denominada «matriz».

Analisemos o seguinte programa e os seus resultados:

Programa
Resultados
4
i=4
10,2
r1=10,2
0,014
r2=0,014
c1=bonjour
01/10/02
d1=01/10/02
10/01/02
d2=10/01/02
-1
b1=Vrai
0
b2=Faux
v=4
v=10,2
v=bonjour
v=01/10/02
v=Vrai

Comentários:

  • Algumas linguagens de programação (C, C++, Pascal, Java, C#, ...) exigem a declaração prévia de uma variável antes da sua utilização. Esta declaração consiste em indicar o nome da variável e o tipo de dados que esta pode conter (inteiro, real, cadeia de caracteres, data, booleano, ...). A declaração das variáveis permite várias coisas:
    • saber o espaço de memória necessário para a variável, uma vez que diferentes tipos de dados requerem diferentes espaços de memória
    • verificar a coerência do programa. Assim, se i for um inteiro e c uma cadeia de caracteres, multiplicar i por c não faz qualquer sentido. Se o tipo das variáveis i e c tiver sido declarado pelo programador, o programa encarregado de analisar o código antes da sua execução pode sinalizar tal incoerência.

Tal como a maioria das linguagens de script com um único tipo de dados (Perl, Python, JavaScript, etc.), o VBScript permite não declarar as variáveis. Foi isso que aconteceu no exemplo acima.

  • Repare-se na sintaxe de diferentes valores
    • 10,2 na linha 10 (ponto decimal e não vírgula). Note-se que, na visualização, é exibido o valor 10,2.
    • 1.4e-2 na linha 13 (notação científica). No ecrã, foi exibido o número 0,014
    • [#01/10/2002#] (linha 26) para representar a data de 10 de janeiro de 2002. É, portanto, o formato #mm/dd/aaaa# que o VBScript utiliza para representar a data jj do mês mm do ano aaaa
    • os valores booleanos true e false (verdadeiro/falso) nas linhas 31 e 34. Estes dois valores são representados, respetivamente, pelos números inteiros -1 e 0, tal como se pode ver na exibição das linhas 32 e 35. Quando um valor booleano é concatenado a uma cadeia de caracteres, estes valores tornam-se, respetivamente, as cadeias «Vrai» e «Faux», como mostram as linhas 33 e 36. Note-se, de passagem, que o operador de concatenação & pode ser utilizado para concatenar outros elementos além de cadeias de caracteres.
  • Uma variável v que não tenha um tipo atribuído pode, sucessivamente, conter valores de diferentes tipos.

3.5. O os subtipos do tipo variant

Eis o que diz a documentação oficial sobre os diferentes tipos de dados que um variant pode conter:

Para além da simples distinção entre número e cadeia de caracteres, um Variant pode distinguir diferentes tipos de informação numérica. Por exemplo, certas informações numéricas representam uma data ou uma hora. Quando estas informações são utilizadas com outros dados de data ou hora, o resultado é sempre expresso sob a forma de uma data ou de uma hora. Existem também outros tipos de informação numérica, desde valores booleanos até grandes números de ponto flutuante. Estas diferentes categorias de informação que podem estar contidas num Variant são subtipos. Na maioria dos casos, basta colocar os seus dados num Variant e este comporta-se da forma mais adequada em função desses dados.

A tabela seguinte apresenta os diferentes subtipos que podem estar contidos num Variant.

Subtipo
Descrição
Empty
O Variant não está inicializado. O seu valor é igual a zero para as variáveis numéricas e a uma cadeia de comprimento nulo ("") para as variáveis de cadeia.
Null
O Variant contém intencionalmente dados incorretos.
Boolean
Contém True (verdadeiro) ou False (falso).
Byte
Contém um número inteiro de 0 a 255.
Integer
Contém um número inteiro de -32 768 a 32 767.
Moeda
-922 337 203 685 477,5808 a 922 337 203 685 477,5807.
Long
Contém um número inteiro entre -2 147 483 648 e 2 147 483 647.
Single
Contém um número de ponto flutuante de precisão simples de -3,402823E38 a -1,401298E-45 para os valores negativos; de 1,401298E-45 a 3,402823E38 para os valores positivos.
Duplo
Contém um número de ponto flutuante com precisão dupla, de -1,79769313486232E308 a -4,94065645841247E-324 para os valores negativos; de 4,94065645841247E-324 a 1,79769313486232E308 para os valores positivos.
Data (Hora)
Contém um número que representa uma data entre 1 de janeiro de 100 e 31 de dezembro de 9999.
String
Contém uma cadeia de comprimento variável, limitada a cerca de 2 mil milhões de caracteres.
Objeto
Contém um objeto.
Error
Contém um número de erro.

3.6. C onhecer o tipo exato dos dados contidos num variante

Uma variável do tipo «variant» pode conter dados de vários tipos. Por vezes, precisamos de saber a natureza exata desses dados. Se, num programa, escrevermos produit=nombre1*nombre2, partimos do princípio de que nombre1 e nombre2 são dois dados numéricos. Por vezes, não temos a certeza, pois esses valores podem provir de uma introdução pelo teclado, de um ficheiro ou de qualquer fonte externa. Temos, então, de verificar a natureza dos dados contidos em nombre1 e nombre2. A função typename(var) permite-nos saber o tipo de dados contidos na variável var. Eis alguns exemplos:

Programa
Resultados
var=1,type=Integer
var=deux,type=String
var=Vrai,type=Boolean
var=4,5,type=Double
var=11/10/01,type=Date

Outra função possível é a vartype(var), que devolve um número que representa o tipo dos dados contidos na variável var:

Constante
Valor
Descrição
vbEmpty
0
Vazio (não inicializado)
vbNull
1
Nulo (sem dados válidos)
vbInteger
2
Número inteiro
vbLong
3
Inteiro longo
vbSingle
4
Número de ponto flutuante de precisão simples
vbDouble
5
Número de ponto flutuante de dupla precisão
vbCurrency
6
Monetário
vbDate
7
Data
vbString
8
Canal
vbObject
9
Objeto de automação
vbError
10
Erro
vbBoolean
11
Booleano
vbVariant
12
Variante (utilizada apenas com tabelas de variantes)
vbDataObject
13
Objeto não Automation
vbByte
17
Byte
vbArray
8192
Tabela

Nota: Estas constantes são especificadas por VBScript. Consequentemente, os nomes podem ser utilizados em qualquer parte do seu código em vez dos valores reais.

As informações acima provêm da documentação de VBscript. Esta documentação está, por vezes, incorreta, provavelmente devido a cópias e colagens feitas a partir da documentação de VB. A função vartype do VBScript realiza apenas uma parte do que foi anunciado acima.

O programa anterior, reescrito para o vartype, apresenta os seguintes resultados:

Programa
Resultados
var=1,type=2
var=deux,type=8
var=Vrai,type=11
var=4,5,type=5
var=11/10/01,type=7

3.7. D clarear as variáveis utilizadas pelo script

Já referimos que não é obrigatório declarar as variáveis utilizadas pelo script. Neste caso, se escrevermos:


1) somme=4
...
2) somme=smme+10

Com um erro de digitação «smme» em vez de «somme» na instrução 2, o VBScript não indicará qualquer erro. Presumirá que «smme» é uma nova variável. Criá-la-á e, no contexto da instrução 2, utilizá-la-á, inicializando-a com o valor 0.

Este tipo de erros pode ser muito difícil de detetar. Por isso, é aconselhável forçar a declaração das variáveis com a diretiva «option explicit» colocada no início do script. Depois, todas as variáveis devem ser declaradas com uma instrução «dim» antes da sua primeira utilização:


option explicit
...
dim somme
1) somme=4
...
2) somme=smme+10

Neste exemplo, o VBScript indicará que existe uma variável não declarada, tal como em 2), conforme ilustrado no exemplo seguinte:

Programa
Resultados
dim1.vbs(9, 1) Erreur d'exécution Microsoft
 VBScript: Variable non définie: 'smme'

Embora nos breves exemplos deste documento as variáveis, na maioria das vezes, não sejam declaradas, iremos obrigá-las a ser declaradas assim que escrevermos os primeiros scripts significativos. A diretiva Option explicit será então utilizada sistematicamente.

3.8. As funções de conversão do « »

O VBScript transforma os dados das variantes em cadeias de caracteres, números, valores booleanos, etc., consoante o contexto. Na maioria das vezes, isto funciona bem, mas por vezes pode dar origem a algumas surpresas, como veremos mais adiante. Por isso, pode ser necessário «forçar» o tipo de dados da variante. O VBscript possui funções de conversão que transformam uma expressão em vários tipos de dados. Aqui estão algumas delas:

Cint (expressão)
transforma a expressão num inteiro curto (integer)
Clng (expressão)
transforma a expressão num inteiro longo (long)
Cdbl (expressão)
converte a expressão num número real de precisão dupla (double)
Csng (expressão)
converte a expressão num número real simples (single)
Ccur (expressão)
converte a expressão num valor monetário (currency)

Eis alguns exemplos:

Programa
Resultados
var=4,code type=8,nom type=String
var=4,code type=2,nom type=Integer
var=1000000,code type=8,nom type=String
var=1000000,code type=3,nom type=Long
var=3,4e-5,code type=8,nom type=String
var=0,000034,code type=5,nom type=Double
var=3,4e-5,code type=8,nom type=String
var=0,000034,code type=4,nom type=Single
var=1000,45,code type=8,nom type=String
var=1000,45,code type=6,nom type=Currency
var=14,code type=2,nom type=Integer
var=14,code type=8,nom type=String
var=1000,45,code type=5,nom type=Double
var=1000,code type=2,nom type=Integer
var=1000,75,code type=5,nom type=Double
var=1001,code type=2,nom type=Integer

3.9. O e os dados digitados no teclado

O objeto wscript permite que um script recupere dados introduzidos pelo teclado. O método wscript.stdin.readLine permite ler uma linha de texto introduzida pelo teclado e validada com a tecla «Enter». Esta linha lida pode ser atribuída a uma variável.

Programa
Resultados

Tapez votre nom : st
Bonjour st

Comentários:

  • Na coluna dos resultados e na linha [Tapez votre nom : st], st é a linha introduzida pelo utilizador.

Mesmo que o texto digitado no teclado represente um número, é, ainda assim, considerado, antes de mais nada, como uma cadeia de caracteres, tal como mostra o exemplo abaixo:

Programa
Resultados
Tapez un nombre : 14
nombre lu=14,type=String

Se este número for utilizado numa operação aritmética, o VBscript converterá automaticamente a cadeia de caracteres num número, mas nem sempre. Vejamos o exemplo seguinte:

Programa
Resultados
1
2
3
4
5
6
nombre1 : 3
nombre2 : 4
3+4=34
3-4=-1
3x4=12
3/4=0,75

Nos resultados, vemos que a linha 8 do script não decorreu como esperado, isto porque (infelizmente) no VBScript o operador + tem dois significados: adição de dois números ou concatenação de duas cadeias de caracteres (as duas cadeias são unidas uma à outra). Vimos anteriormente que os números digitados no teclado eram lidos como cadeias de caracteres e que o VBScript as transformava em números conforme necessário. Fê-lo corretamente para as operações -, *, /, que só podem envolver números, mas não para o operador +, que também pode envolver cadeias de caracteres. O programa partiu do princípio de que se pretendia efetuar uma concatenação de cadeias de caracteres.

Uma solução simples para este problema consiste em converter as cadeias de caracteres em números logo que são lidas, tal como mostra a melhoria seguinte do programa anterior:

Programa
Resultados
nombre1 : 3
nombre1=3,type=String
nombre1=3,type=Long
nombre2 : 4
nombre2=4,type=String
nombre2=4,type=Long
3+4=7
3-4=-1
3x4=12
3/4=0,75

3.10. S nsir dados com a função inputbox

Pode ser necessário introduzir dados numa interface gráfica em vez de o fazer através do teclado. Nesse caso, utiliza-se a função inputBox. Esta função aceita vários parâmetros, dos quais apenas os dois primeiros são frequentemente utilizados:

resposta=inputBox(mensagem,título)

  • mensagem: a pergunta que faz ao utilizador
  • título (opcional): o título que atribui à janela de introdução de dados
  • resposta: o texto digitado pelo utilizador. Se este tiver fechado a janela sem responder, a resposta é a cadeia vazia.

Eis um exemplo em que se pede o nome e a idade de uma pessoa. Para o nome, introduzimos uma informação e clicamos em OK. Para a idade, também introduzimos uma informação, mas clicamos em Cancelar.

Programa
Resultados

3.11. U tilizar objetos estruturados

É possível criar, com VBScript, objetos com métodos e propriedades. Para não complicar as coisas, vamos apresentar aqui um objeto com propriedades, mas sem métodos. Consideremos uma pessoa. Ela tem muitas propriedades que a caracterizam: altura, peso, cor da pele, dos olhos, do cabelo, etc. Vamos ficar apenas com duas: o seu nome e a sua idade. Antes de podermos utilizar objetos, é necessário criar o molde que permitirá criá-los. No VBScript, isto faz-se através de uma classe. A classe personne poderia ser definida da seguinte forma:


class personne
    Dim nom,age
End class

É a instrução [Dim nom,age] que define as duas propriedades da classe personne. Para criar exemplares (chamados de instâncias) da classe personne, escreve-se:

set personne1=new personne
set personne2=new personne

Porque não escrever

personne1=new personne
personne2=new personne

Porque uma variante não pode conter um objeto. Pode apenas conter o endereço do mesmo. Ao escrever set pessoa1=new pessoa, ocorre a seguinte sequência de eventos:

  1. é criado um objeto personne. Isto significa que lhe é atribuída memória.
  2. o endereço desse objeto personne é atribuído à variável personne1

Temos então o seguinte esquema de memória para as variáveis personne1 e personne2:

Por conveniência, poder-se-á dizer que personne1 é um objeto personne. Pode-se aceitar esta expressão, se tivermos em conta que personne1 é, na verdade, o endereço de um objeto personne e não o próprio objeto personne.

Dissemos que um objeto personne tinha duas propriedades: nom e age. Como explorar essas propriedades? Através da notação objet.propriété, tal como foi explicado um pouco mais acima. Assim,

personne1.nom designa o nome da pessoa 1 e personne1.age a sua idade. Eis um pequeno programa ilustrativo:

Programa
Resultados
p1=(dupont,18)

O programa anterior poderia ser alterado da seguinte forma:

Programa
Resultados
nom=dupont
age=18

Utilizámos aqui a estrutura «with ... end with», que permite «fatorizar» nomes de objetos em expressões. A estrutura «with p1 ... end with» das linhas 9a 12 e das linhas 15 a 18 permite utilizar posteriormente a sintaxe .nom em vez de p1.nom e .age em vez de p1.age. Isto permite simplificar a escrita das instruções em que o mesmo nome de objeto é utilizado repetidamente.

3.12. Atribuir um valor a uma variável

Existem duas instruções para atribuir um valor a uma variável:

  1. variável=expressão
  2. definir variável=expressão

A forma 2 destina-se a expressões cujo resultado é uma referência a um objeto. Para todos os outros tipos de expressões, deve utilizar-se a forma 1. A diferença entre as duas formas é a seguinte:

  • na instrução variable=expression, a variável recebe um valor. Se v1 e v2 forem duas variáveis, escrever v1=v2 atribui o valor de v1 a v2. Assim, tem-se a duplicação de um valor em dois locais diferentes. Se, posteriormente, o valor de v2 for alterado, o de v1 não sofre qualquer alteração.
  • Na instrução «set variable=expression», a variável recebe como valor o endereço de um objeto. Se v1 e v2 forem duas variáveis e se v2 for o endereço de um objeto obj2, escrever «set v1=v2» atribui o valor de v1 a v2, ou seja, o endereço do objeto obj2. Quando o script manipula posteriormente v1 e v2, não são os «valores» de v1 e v2 que são manipulados, mas sim os objetos «apontados» por v1 e v2, ou seja, o mesmo objeto neste caso. Diz-se que v1 e v2 são duas referências ao mesmo objeto e que manipular este último através de v1 ou v2 não faz qualquer diferença. Por outras palavras, alterar o objeto referenciado por v2 altera o objeto referenciado por v1.

Eis um exemplo:

Programa
Resultados
i=4
j=4
i=4
j=5
p1.nom=dupont
p1.age=18
p1.nom=dupont
p1.age=19
p2.nom=dupont
p2.age=19

3.13. É avaliar expressões

Os principais operadores que permitem avaliar expressões são os seguintes:

Tipo de operadores
Operadores
Exemplo
Aritméticos
+,-,*,/
 
 
mod
 
\
 
^
   
Comparação
<, <=
>, >=
=,<>
a<>b é verdadeiro se a for diferente de b
a=b é verdadeiro se a for igual a b
a e b podem ser ambos números ou ambos cadeias de caracteres. Neste último caso, cadeia1<cadeia2 se, na ordem alfabética, cadeia1 vier antes de cadeia2. Na comparação de cadeias, as maiúsculas vêm antes das minúsculas na ordem alfabética.
 
is
   
Lógica
and, or, not, xor
Aqui, todos os operandos são booleanos.
bool1 or bool2 é verdadeiro se bool1 ou bool2 for verdadeiro
bool1 and bool2 é verdadeiro se bool1 e bool2 forem verdadeiros
not bool1 é verdadeiro se bool1 for falso e vice-versa
bool1 xor bool2 é verdadeiro se apenas um dos valores booleanos bool1 ou bool2 for verdadeiro
   
Concatenação
&, +
Não é aconselhável utilizar o operador + para concatenar duas cadeias de caracteres, devido à possível confusão com a soma de dois números. Por isso, deve utilizar-se exclusivamente o operador &.

3.14. C ontrolar a execução do programa

3.14.1. E xecutar ações de forma condicional

A instrução VBScript que permite realizar ações de acordo com o valor verdadeiro/falso de uma condição é a seguinte:


if expression then
    action-vrai-1
    action-vrai-2
    ..
else
    action-faux-1
    action-faux-2
    ...
end if
A expressão expression é avaliada em primeiro lugar. Esta expressão deve ter um valor booleano. Se tiver o valor verdadeiro, são executadas as ações do then; caso contrário, são executadas as do else, se este existir.

Segue-se um programa que apresenta diferentes variantes da estrutura «if-then-else»:

Programa
Resultados
1
2
3
4
5
3 est plus grand que 0
3 est plus grand que 2
i=4
4 est plus petit que 10
i=3

Comentários:

  • em VBScript, é possível escrever instrução1:instrução2:... : instruçãon em vez de escrever uma instrução por linha. Foi esta possibilidade que foi aproveitada na linha 10, por exemplo.

3.14.2. E xecutar ações de forma repetida

Ciclo com número conhecido de iterações
for i=idébut to ifin step ipas
    actions
next
  1. A variável i é aqui designada por variável de ciclo. Pode ter qualquer nome
  2. i assume o valor idebut
  3. o valor de i é comparado com ifin. Se i <= ifin, as ações situadas entre o for... next são executadas
  4. i é incrementado pelo valor de ipas (i = i + ipas)
  5. volta-se ao passo 3 anterior. Após um número finito de passos, o valor de i ultrapassará ifin. A execução do script prossegue com a instrução que se segue ao next
  6. se o incremento ipas for negativo, a condição da etapa 3 é alterada. As ações do for...next só são executadas se i >= ifin.
É possível sair de um ciclo «for» a qualquer momento com a instrução «exit for».
Loop com número de iterações desconhecido
do while condition
    actions
loop
  1. A expressão condicional é avaliada. Se for verdadeira, as ações do while...loop são executadas
  2. as ações executadas podem ter alterado o valor da condição. Repete-se a etapa 1 anterior.
  3. Quando a expressão condicional se torna falsa, o ciclo termina
É possível sair de um ciclo «do while» a qualquer momento com a instrução «exit do».

O programa abaixo ilustra estes pontos:

Programa
Resultados
i=0,tableau(i)=10,somme=10
i=1,tableau(i)=20,somme=30
i=2,tableau(i)=30,somme=60
i=3,tableau(i)=40,somme=100
i=0,tableau(i)=10,somme=10
i=1,tableau(i)=20,somme=30
i=2,tableau(i)=30,somme=60
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9
i=10
i=11
i=1
i=2
i=3
i=4
i=5
i=6

Nota: Na fase de desenvolvimento de um programa, não é raro que um programa entre num «loop», c.a.d, e nunca termine. Geralmente, o programa executa um loop cuja condição de saída não pode ser verificada, como, por exemplo, no exemplo seguinte:


' loop infinito
i=0
Do While 1=1
  i=i+1
  wscript.echo i
Loop

' outra do mesmo tipo
i=0
Do While true
  i=i+1
  wscript.echo i
Loop

Se executarmos o programa anterior, o primeiro ciclo nunca terminará por si próprio. É possível forçar a sua interrupção digitando CTRL-C no teclado (mantendo premidas as teclas CTRL e C ao mesmo tempo).

3.14.3. Terminar a execução do programa

A instrução wscript.quit n termina a execução do programa, devolvendo um código de erro igual a n. Em DOS, este código de erro pode ser verificado com a instrução if ERRORLEVEL n, que é verdadeira se o código de erro devolvido pelo último programa executado for >=n. Consideremos o seguinte programa e os seus resultados:

  
début

Imediatamente após a execução do programa, são emitidos os três comandos DOS seguintes:

1
2
3
4
5
6
7
C:\>if ERRORLEVEL 5 echo 5

C:\>if ERRORLEVEL 4 echo 4
4

C: >if ERRORLEVEL 3 echo 3
3

O comando DOS 1 verifica se o código de erro devolvido pelo programa é >=5. Se for, exibe (echo) 5; caso contrário, nada.

O comando DOS 3 verifica se o código de erro devolvido pelo programa é >=4. Se for, exibe 4; caso contrário, nada.

O comando DOS 5 verifica se o código de erro devolvido pelo programa é >=3. Se for o caso, exibe 3; caso contrário, não exibe nada.

A partir dos resultados apresentados, pode-se deduzir que o código de erro devolvido pelo programa foi 4.

3.15. ar tabelas de dados numa variante

xml-ph-0000@deepl.internala tabelas de dados numa variante Uma variante T pode conter uma lista de valores. Diz-se então que se trata de uma tabela. Uma tabela T possui várias propriedades:

  • Tem-se acesso ao elemento i da matriz T através da sintaxe T(i), em que i é um número inteiro denominado índice, compreendido entre 0 e n-1, se T tiver n elementos.
  • É possível determinar o índice do último elemento da matriz T através da expressão ubound(T). O número de elementos da matriz T é, então, ubound(T)+1. Este número é frequentemente designado por «tamanho da matriz».
  • Uma variável T pode ser inicializada com uma matriz vazia através da sintaxe T=array() ou com uma sequência de elementos através da sintaxe T=array(elemento0, elemento1, ...., elemento n)
  • É possível adicionar elementos a um tabuço T já criado. Para tal, utiliza-se a instrução redim preserve T(N), em que N é o novo índice do último elemento do tabuço T. A operação denomina-se redimensionamento (redim). A palavra-chave preserve indica que, durante este redimensionamento, o conteúdo atual do tabuço deve ser preservado. Na ausência desta palavra-chave, T é redimensionado e esvaziado dos seus elementos.
  • Um elemento T(i) da matriz T é do tipo variant e pode, portanto, conter qualquer valor e, em particular, uma matriz. Neste caso, a notação T(i)(j) designa o elemento j da matriz T(i).

Estas diversas propriedades das tabelas são ilustradas pelo programa que se segue:

Programa
Resultados
Le tableau t1 a 5 éléments
t1(0)=1
t1(1)=-4,5
t1(2)=deux
t1(3)=Vrai
t1(4)=10/01/02
t1=1:-4,5:deux:Vrai:10/01/02
t1(5)=10:20:30
t1(5)(1)=20
t1=1 ~ -4,5 ~ deux
t1=:::

Comentários

  • Aqui utilizou-se uma função chamada «join», explicada mais adiante.

3.16. as variáveis de matriz

No VBScript, existe outra forma de utilizar um tabuleiro: através de uma variável de tabuleiro. Ao contrário das variáveis escalares, esta variável tem de ser obrigatoriamente declarada através de uma instrução «dim». São possíveis várias declarações:

  • dim array(n) declara um array estático com n+1 elementos numerados de 0 a n. Este tipo de array não pode ser redimensionado
  • dim tabela() declara uma tabela dinâmica vazia. Esta terá de ser redimensionada para ser utilizada através da instrução redim, da mesma forma que para um variante que contenha uma tabela
  • dim tabela(n,m) declara uma tabela bidimensional com (n+1)*(m+1) elementos. O elemento (i,j) da tabela é denotado por tableau(i,j). Note-se a diferença em relação a um variant, onde o mesmo elemento teria sido denotado por tableau(i)(j).

Por que razão existem dois tipos de matrizes que, no fim de contas, são muito semelhantes? A documentação do VBScript não aborda este assunto nem indica se um é mais eficiente do que o outro. Posteriormente, utilizaremos quase exclusivamente a matriz dentro de uma variante nos nossos exemplos. Recorde-se, no entanto, que VBscript deriva da linguagem Visual Basic, que contém dados tipados (integer, double, boolean, ...). Neste caso, se for necessário utilizar uma matriz de números reais, por exemplo, a variável «matriz» terá melhor desempenho do que a variável «variant». Deverá, então, declarar algo como dim tabela(1000) as double para declarar uma tabela de números reais ou simplesmente dim tabela() as double se a tabela for dinâmica.

Eis um exemplo que ilustra a utilização de variáveis de tabela:

Programa
Resultados
Le tableau t1 a 5 éléments
t1(0)=1
t1(1)=-4,5
t1(2)=deux
t1(3)=Vrai
t1(4)=10/01/02
t1=1:-4,5:deux:Vrai:10/01/02
Le tableau t1 a 5 éléments
t2(0)=0
t2(1)(2)=30
t2=:::
t3(0,0)=0
t3(0,1)=1
t3(1,0)=10
t3(1,1)=11

3.17. L as funções split e join

As funções split e join permitem converter uma cadeia de caracteres numa matriz e vice-versa:

  • Se T for um array e car uma cadeia de caracteres, join(T,car) é uma cadeia de caracteres formada pela junção de todos os elementos do array T, cada um separado do seguinte pela cadeia car. Assim, join(array(1,2,3),"abcd") resultará na cadeia "1abcd2abcd3"
  • Se C for uma cadeia de caracteres formada por uma sequência de campos separados pela cadeia car, a função split(C,car) é um tabuço cujos elementos são os diferentes da cadeia C. Assim, split("1abcd2abcd3", "abcd") resultará no tabuço (1,2,3)

Eis um exemplo:

Programa
Resultados

' transformação de matriz em cadeia e vice-versa

' matriz --> cadeia
tableau=array("un",2,"trois")
chaine=join(tableau,",")
wscript.echo chaine

' cadeia de caracteres → matriz
tableau2=split(chaine,",")
For i=0 To ubound(tableau2)
  wscript.echo tableau2(i)
Next

un,2,trois
un
2
trois

3.18. Os dicionários

Tem-se acesso a um elemento de uma matriz T quando se conhece o seu número i. Este é então acessível através da notação T(i). Existem matrizes cujos elementos são acedidos, não por um número, mas por uma cadeia de caracteres. O exemplo típico deste tipo de matriz é o dicionário. Quando se procura o significado de uma palavra no «Larousse» ou no «Le petit Robert», acede-se a esse significado através da palavra. Poderíamos representar este dicionário por uma matriz com duas colunas:

palavra1
descrição1
palavra2
descrição2
palavra3
descrição3
....
 

Poderíamos então escrever coisas como:

dicionário("palavra1") = "descrição1"

dicionário("palavra2") = "descrição2"

...

Estamos, assim, próximos do funcionamento de um tabuleiro, com a diferença de que os índices do tabuleiro não são números inteiros, mas sim cadeias de caracteres. A este tipo de tabuleiro chama-se dicionário (ou tabuleiro associativo, hashtable) e aos índices, que são cadeias de caracteres, chamam-se chaves do dicionário (keys). A utilização de dicionários é extremamente frequente no mundo da informática. Todos nós temos um cartão da segurança social com um número. Esse número identifica-nos de forma única e dá acesso às informações que nos dizem respeito. No modelo dicionário("chave")="informações", "chave" seria, neste caso, o número da segurança social e "informações" todas as informações armazenadas sobre nós nos computadores da segurança social.

No Windows, existe um objeto ActiveX denominado «Scripting.Dictionary» que permite criar e gerir dicionários. Um objeto ActiveX é um componente de software que disponibiliza uma interface utilizável por programas que podem ser escritos em diferentes linguagens, desde que respeitem a norma de utilização dos objetos ActiveX. O objeto Scripting.dictionary pode, portanto, ser utilizado pelas linguagens de programação do Windows: JavaScript, Perl, Python, C, C++, VB, VBA... e não apenas pelo VBScript.

1
Um objeto Scripting.Dictionary é criado por uma instrução
set dico=wscript.CreateObject("Scripting.Dictionary")
ou simplesmente
set dico=CreateObject("Scripting.Dictionary")
CreateObject é um método do objeto WScript que permite criar instâncias de objetos ActiveX. A versão 2 mostra que o wscript pode ser um objeto implícito. Quando um método não pode ser «associado» a um objeto, o contentor WSH tentará associá-lo ao objeto wscript.
2
Depois de criado o dicionário, será possível adicionar-lhe elementos com o método add:
dico.add «chave»,valor
irá criar uma nova entrada no dicionário associada à chave «chave». O valor associado é um variant com qualquer dado.
3
Para recuperar o valor associado a uma determinada chave, utiliza-se o método item do dicionário:
var=dico.item("chave")
ou set var=dico.item("chave") se o valor associado à chave for um objeto.
4
O conjunto de chaves do dicionário pode ser recuperado numa matriz de variantes através do método `keys`:
chaves=dico.keys
chaves é um array cujos elementos podem ser percorridos.
5
O conjunto de valores do dicionário pode ser recuperado numa matriz variável através do método `items`:
valores = dic.items
items é um array cujos elementos podem ser percorridos.
6
A existência de uma chave pode ser verificada com o método `exists`:
dico.exists("chave") é verdadeiro se a chave "chave" existir no dicionário
7
É possível remover uma entrada do dicionário (chave+valor) com o método remove:
dico.remove("chave") remove a entrada do dicionário associada à chave "chave". dico.removeall remove todas as chaves; c.a.d esvazia o dicionário.

O programa seguinte utiliza estas diversas possibilidades:

Programa

' criação e utilização de um dicionário
Set dico=CreateObject("Scripting.Dictionary")

' preenchimento do dicionário
dico.add "clé1","valeur1"
dico.add "clé2","valeur2"
dico.add "clé3","valeur3"

' número de elementos
wscript.echo "Le dictionnaire a " & dico.count & " éléments"

' lista de chaves
wscript.echo "liste des clés"
cles=dico.keys
For i=0 To ubound(cles)
  wscript.echo cles(i)
Next

' lista de valores
wscript.echo "liste des valeurs"
valeurs=dico.items
For i=0 To ubound(valeurs)
  wscript.echo valeurs(i)
Next

' lista de chaves e valores
wscript.echo "liste des clés et valeurs"
cles=dico.keys
For i=0 To ubound(cles)
  wscript.echo "dico(" & cles(i) & ")=" & dico.item(cles(i))
Next

' pesquisa de elementos
' chave1
If dico.exists("clé1") Then
    wscript.echo "La clé clé1 existe dans le dictionnaire et la valeur associée est " & dico.item("clé1")
  Else
    wscript.echo "La clé clé1  n'existe pas dans le dictionnaire"
  End If
' chave 4  
If dico.exists("clé4") Then
    wscript.echo "La clé clé4 existe dans le dictionnaire et la valeur associée est " & dico.item("clé4")
  Else
    wscript.echo "La clé clé4  n'existe pas dans le dictionnaire"
  End If

' remover a chave 1
dico.remove("clé1")

' lista de chaves e valores
wscript.echo "liste des clés et valeurs après suppression de clé1"
cles=dico.keys
For i=0 To ubound(cles)
  wscript.echo "dico(" & cles(i) & ")=" & dico.item(cles(i))
Next

' elimina-se tudo
dico.removeall

' lista de chaves e valores
wscript.echo "liste des clés et valeurs après suppression de tous les éléments"
cles=dico.keys
For i=0 To ubound(cles)
  wscript.echo "dico(" & cles(i) & ")=" & dico.item(cles(i))
Next

' fim
wscript.quit 0
Resultados
Le dictionnaire a 3 éléments
liste des clés
clé1
clé2
clé3
liste des valeurs
valeur1
valeur2
valeur3
liste des clés et valeurs
dico(clé1)=valeur1
dico(clé2)=valeur2
dico(clé3)=valeur3
La clé clé1 existe dans le dictionnaire et la valeur associée est valeur1
La clé clé4  n'existe pas dans le dictionnaire
liste des clés et valeurs après suppression de clé1
dico(clé2)=valeur2
dico(clé3)=valeur3
liste des clés et valeurs après suppression de tous les éléments

3.19. Ordenar um array ou um dicionário

É comum querer ordenar uma matriz ou um dicionário por ordem crescente ou decrescente dos seus valores ou, no caso de um dicionário, das suas chaves. Embora na maioria das linguagens existam funções de ordenação, parece não haver nenhuma no VBScript. Trata-se de uma lacuna.

3.20. Os argumentos de um programa

É possível chamar um programa VBScript passando-lhe parâmetros, como no exemplo:

cscript prog1.vbs arg1 arg2 .... argn

Isto permite ao utilizador passar informações para o programa. Como é que este as recupera? Vejamos o seguinte programa:

Programa
Resultados
C:\>cscript arg1.vbs a b c

Il y a 3 arguments
a
b
c

Comentários

  • WScript.Arguments é a coleção de argumentos passados ao script
  • uma coleção C é um objeto que possui
    • uma propriedade count que corresponde ao número de elementos na coleção
    • um método C(i) que devolve o elemento i da coleção

3.21. Uma primeira aplicação: IMPOTS

Propomos escrever um programa que permita calcular o imposto de um contribuinte. Consideramos o caso simplificado de um contribuinte que tenha apenas o seu salário para declarar:

  • calcula-se o número de quotas do trabalhador nbParts = nbEnfants/2 + 1 se não for casado, nbEnfants/2+2 se for casado, em que nbEnfants é o número de filhos que tem.
  • calcula-se o seu rendimento tributável R = 0,72 * S, em que S é o seu salário anual
  • calcula-se o seu coeficiente familiar Q = R/N

calcula-se o seu imposto I com base nos seguintes dados

12620,0
0
0
13 190
0,05
631
15640
0,1
1290,5
24 740
0,15
2072,5
31 810
0,2
3309,5
39 970
0,25
4900
48 360
0,3
6898,5
55 790
0,35
9316,5
92 970
0,4
12106
127 860
0,45
16 754,5
151 250
0,50
23 147,5
172 040
0,55
30710
195 000
0,60
39312
0
0,65
49 062

Cada linha tem 3 campos. Para calcular o imposto I, procura-se a primeira linha em que QF <= campo1. Por exemplo, se QF = 30000, encontrar-se-á a linha

    24740        0.15        2072.5

O imposto I é, então, igual a 0,15*R - 2072,5*nbParts. Se QF for tal que a relação QF<=campo1 nunca for verificada, então são utilizados os coeficientes da última linha. Neste caso:

    0                0.65        49062

o que resulta no imposto I = 0,65 * R - 49062 * nbParts.

O programa é o seguinte:

Programa
' cálculo do imposto de um contribuinte
' o programa deve ser chamado com três parâmetros: casado, filhos, salário
' casado: caractere O se casado, N se solteiro
' filhos: número de filhos
' salário: salário anual sem os cêntimos

' não é efetuada qualquer verificação da validade dos dados, mas
' verifica-se se existem efetivamente três

' declaração obrigatória das variáveis
Option Explicit

' verifica-se se existem 3 argumentos
Dim nbArguments
nbArguments=wscript.arguments.count
If nbArguments<>3 Then
    wscript.echo "Syntaxe : pg marié enfants salaire"
    wscript.echo "marié : caractère O si marié, N si non marié"
    wscript.echo "enfants : nombre d'enfants"
    wscript.echo "salaire : salaire annuel sans les centimes"
     ' interrupção com código de erro 1
    wscript.quit 1
End If

' recuperam-se os argumentos sem verificar a sua validade
Dim marie, enfants, salaire
If wscript.arguments(0) = "O" Or wscript.arguments(0)="o" Then
    marie=true
Else
    marie=false
End If
' «children» é um número inteiro
enfants=cint(wscript.arguments(1))
' «salário» é um inteiro longo
salaire=clng(wscript.arguments(2))

' definem-se os dados necessários para o cálculo do imposto em 3 tabelas
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)

' calcula-se o número de quotas
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

' calcula-se o quociente familiar e o rendimento tributável
Dim revenu, qf
revenu=0.72*salaire
qf=revenu/nbParts

' calcula-se o imposto
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))

' exibe-se o resultado
wscript.echo "impôt=" & impot

' sai sem erros
wscript.quit 0
Resultados
C:\>cscript impots1.vbs o 2 200000

impôt=22504

C:\>cscript impots1.vbs o 2 20000

impôt=0

C:\>cscript impots1.vbs o 2 2000000

impôt=746064

C:\>cscript impots1.vbs n 2 200000

impôt=33388

C:\>cscript impots1.vbs n 3 200000

impôt=22504

C:\>cscript impots1.vbs

Syntaxe : pg marié enfants salaire
marié : caractère O si marié, N si non marié
enfants : nombre d'enfants
salaire : salaire annuel sans les centimes

Comentários:

  • o programa utiliza o que foi explicado anteriormente (declaração de variáveis, argumentos, mudanças de tipos, verificações, loops, tabela num variante)
  • não verifica a validade dos dados, o que seria anormal num programa real
  • Apenas o ciclo while apresenta uma dificuldade. Este procura determinar o índice i da tabela «limites» para o qual se tem «limites(i)>qf», e isto para i<ubound(limites) (c.a.d. Aqui, i<13), uma vez que o último elemento da tabela «limites» não é relevante. Foi adicionado apenas para que o teste [Do While i<ubound(limites) And qf>limites(i)] possa ser realizado para i=13. O teste é, então, 13<13 e qf>limites(13) e é necessário (em VBScript) que limites(13) exista. Ao sair do ciclo «while», o último valor de i calculado permite calcular o imposto: [impot=int(revenu*coeffr(i)-nbParts*coeffn(i))].