5. As funções e procedimentos
5.1. As funções predefinidas do VBScript
A riqueza de uma linguagem deriva, em grande parte, da sua biblioteca de funções, podendo estas ser encapsuladas em objetos sob o nome de métodos. Nesta perspetiva, pode considerar-se que o VBScript é bastante limitado.
A tabela seguinte define as funções do VBScript fora dos objetos. Não as iremos detalhar. O seu nome é, geralmente, uma indicação da sua função. O leitor deverá consultar a documentação para obter detalhes sobre uma função específica.
Abs | Array | Asc | Atn |
CBool | CByte | CCur | CDate |
CDbl | Chr | CInt | CLng |
Conversões | Cos | CreateObject | CSng |
Data | DateAdd | DateDiff | DatePart |
DateSerial | DateValue | Dia | Matemática derivada |
Avaliação | Exp | Filtro | FormatCurrency |
FormatDateTime | FormatNumber | FormatPercent | GetLocale |
GetObject | GetRef | Hex | Hora |
InputBox | InStr | InStrRev | Int, Fixs |
IsArray | IsDate | IsEmpty | IsNull |
IsNumeric | IsObject | Juntar | LBound |
LCase | Esquerda | Len | LoadPicture |
Log | LTrim; RTrim; e acabamentos | Matemática | Meio |
Minuto | Mês | MonthName | MsgBox |
Agora | Out | Substituir | RGB |
Direita | Rnd | Redondo | ScriptEngine |
ScriptEngineBuildVersion | ScriptEngineMajorVersion | ScriptEngineMinorVersion | Segundo |
SetLocale | Assinatura | Sin | Espaço |
Split | Sqr | StrComp | String |
Castanho-claro | Time | Temporizador | TimeSerial |
TimeValue | TypeName | UBound | UCase |
VarType | Dia da semana | WeekdayName | Ano |
5.2. Programação modular
Descrever a solução programada de um problema significa descrever a sequência de ações elementares que podem ser executadas pelo computador e que são capazes de resolver o problema. Dependendo das linguagens, estas operações elementares são mais ou menos sofisticadas. Encontram-se, por exemplo:
- ler um dado proveniente do teclado ou do disco
- gravar dados no ecrã, numa impressora, num disco, etc.
- calcular expressões
- navegar num ficheiro
- ...
Descrever um problema complexo pode exigir vários milhares destas instruções elementares e até mais. Torna-se, então, muito difícil para a mente humana ter uma visão global de um programa. Perante esta dificuldade em compreender o problema na sua totalidade, este é então decomposto em subproblemas mais simples de resolver. Consideremos o seguinte problema: ordenar uma lista de valores numéricos introduzidos pelo teclado e apresentar a lista ordenada no ecrã.
Em primeiro lugar, podemos descrever a solução da seguinte forma:
début
lire les valeurs et les mettre dans un tableau T
trier le tableau T
écrire les valeurs triées du tableau T à l'écran
fin
O problema foi dividido em três subproblemas, mais simples de resolver. A escrita algorítmica é frequentemente mais formalizada do que a anterior e o algoritmo será escrito da seguinte forma:
onde T representa uma matriz. As operações
são operações não elementares que, por sua vez, têm de ser descritas por operações elementares. Isto é feito no que se denomina módulos. O dado T é designado por parâmetro do módulo. Trata-se de uma informação que o programa chamador passa ao módulo chamado (parâmetro de entrada) ou recebe do módulo chamado (parâmetro de saída). Os parâmetros de um módulo são, portanto, as informações que são trocadas entre o programa chamador e o módulo chamado.
módulo lire_tableau(T) | ![]() |
módulo trier_tableau(T) | ![]() |
módulo écrire_tableau(T) | ![]() |
O módulo lire_tableau(T) poderia ser descrito da seguinte forma:
début
écrire "Tapez la suite de valeurs à trier sous la forme val1 val2 ... : "
lire valeurs
construire tableau T à partir de la chaîne valeurs
fin
Aqui, descrevemos de forma exaustiva o módulo lire_tableau. Com efeito, as três ações necessárias têm uma tradução imediata para VBScript. A última exigirá a utilização da função split. Se o VBScript não dispusesse desta função, a ação 3 teria, por sua vez, de ser decomposta em ações elementares com um equivalente imediato em VBScript.
O módulo écrire_tableau(T) poderia ser descrito da seguinte forma:
début
construire chaîne texte "valeur1,valeur2,...." à partir du tableau T
écrire texte
fin
O módulo écrire_tableau(T) poderia ser descrito da seguinte forma (supondo que os índices dos elementos de T começam em 0):
début
N<-- indice dernier élément du tableau T
pour IFIN variant de N à 1
faire
//procura-se o índice IMAX do maior elemento de T
// IFIN é o índice do último elemento de T
chercher_max(T, IFIN, IMAX)
// troca-se o maior elemento de T pelo último elemento de T
échanger (T, IMAX, IFIN)
finfaire
FIN
Aqui, o algoritmo volta a utilizar ações não elementares:
. chercher_max(T, IFIN, IMAX)
. échanger(T, IMAX, IFIN)
chercher_max(T, IFIN, IMAX) define o índice IMAX do elemento maior da tabela T, cujo índice do último elemento é IFIN.
![]() |
trocar(T, IMAX, IFIN) troca dois elementos da matriz T, os de índice IMAX e IFIN.
![]() |
É, portanto, necessário descrever as novas operações não elementares.
módulo chercher_max(A, IFIN, IMAX) | |
módulo de troca (T IMAX, IFIN) |
O problema inicial foi descrito na íntegra utilizando operações elementares do VBScript, podendo agora ser traduzido para esta linguagem. Note-se que as ações elementares podem diferir de uma linguagem para outra e que, por isso, a análise de um problema deve, a certa altura, ter em conta a linguagem de programação utilizada. Um objeto que existe numa linguagem pode não existir noutra, o que altera o algoritmo utilizado. Assim, se uma linguagem tivesse uma função de ordenação, seria absurdo não a utilizar neste caso.
O princípio aqui aplicado é o chamado da análise descendente. Se representarmos a estrutura da solução, temos o seguinte:
![]() |
Temos uma estrutura em árvore.
5.3. As funções e procedimentos do VBScript
Uma vez realizada a análise modular, o programador pode traduzir os módulos do seu algoritmo para VBScript, como fonctions ou procédures. Tanto o fonctions como o procédures aceitam parâmetros de entrada/saída, mas o fonction devolve um resultado que permite a sua utilização em expressões, enquanto o procédure não o faz.
5.3.1. Declaração de funções e procedimentos VBScript
A declaração de um procedimento VBScript é a seguinte
e a de uma função
Para devolver o seu resultado, a função deve incluir uma instrução de atribuição do resultado a uma variável com o nome da função:
nomeDaFunção=resultado
A execução de uma função ou procedimento termina de duas formas:
- ao encontrar a instrução de fim de função (end function) ou fim de procedimento (end sub)
- ao encontrar a instrução de saída da função (exit function) ou do procedimento (exit sub)
No caso da função, é importante lembrar que o resultado deve ter sido atribuído a uma variável com o nome da função antes de esta terminar com um «end function» ou «exit function».
5.3.2. Modos de passagem de parâmetros de uma função ou procedimento
Na declaração dos parâmetros de entrada e saída de uma função ou procedimento, especifica-se o modo (byRef, byVal) de transmissão do parâmetro do programa chamador para o programa chamado:
sub nomProcédure([Byref/Byval] param1, [Byref/Byval] param2, ...)
function nomFonction([Byref/Byval] param1, [Byref/Byval] param2, ...)
Quando o modo de transmissão byRef ou byVal não é especificado, é utilizado o modo byRef.
Parâmetros efetivos, parâmetros formais
Seja uma função VBScript definida por
Os parâmetros parmamFormi utilizados na definição da função ou do procedimento são designados por parâmetros formais. A função anterior poderá ser utilizada a partir do programa principal ou de outro módulo através de uma instrução do tipo:
Os parâmetros parmamEffi utilizados na chamada à função ou ao procedimento são denominados parâmetros efetivos. Quando a execução da função nomFonction começa, os parâmetros formais recebem os valores dos parâmetros efetivos correspondentes. As palavras-chave byRef e byVal definem o modo de transmissão desses valores.
Modo de transmissão por valor (byVal)
Quando um parâmetro formal especifica este modo de transmissão, o parâmetro formal e o parâmetro efetivo são, então, duas variáveis diferentes. O valor do parâmetro efetivo é copiado para o parâmetro formal antes da execução da função ou procedimento. Se esta alterar o valor do parâmetro formal durante a sua execução, tal não altera de forma alguma o valor do parâmetro efetivo correspondente. Este modo de transmissão é adequado para os parâmetros de entrada da função ou procedimento.
![]() |
Modo de transmissão por referência (byRef)
Este modo de transmissão é o modo predefinido caso não seja indicado qualquer modo de transmissão do parâmetro. Quando um parâmetro formal especifica este modo de transmissão, o parâmetro formal e o parâmetro efetivo correspondente são uma única e mesma variável. Assim, se a função alterar o parâmetro formal, o parâmetro efetivo é igualmente alterado. Este modo de transmissão é adequado para:
- aos parâmetros de saída, uma vez que o valor destes deve ser transmitido ao programa chamador
- aos parâmetros de entrada cuja cópia é dispendiosa, como as tabelas
![]() |
O programa seguinte apresenta exemplos de passagem de parâmetros:
Programa |
|
Resultados |
Comentários
- Num script VBScript, não existe um local específico para as funções e os procedimentos. Podem estar em qualquer parte do texto-fonte. Em geral, agrupam-se no início ou no final e procura-se que o programa principal constitua um bloco contínuo.
5.3.3. Sintaxe de chamada de funções e procedimentos
Seja um procedimento p que aceita parâmetros formais pf1, pf2, ...
- a chamada ao procedimento p é feita da seguinte forma
sem parênteses à volta dos parâmetros
- se o procedimento p não aceitar nenhum parâmetro, pode-se utilizar indistintamente a chamada p ou p() e a declaração sub p ou sub p()
Seja uma função f que admite parâmetros formais pf1, pf2, ...
- a chamada à função f é feita na forma
Os parênteses em torno dos parâmetros são obrigatórios. Se a função f não aceitar nenhum parâmetro, pode-se utilizar indistintamente a chamada f ou f() e a declaração function f ou function f().
- O resultado da função f pode ser ignorado pelo programa chamador. A função f é então considerada um procedimento e segue as regras de chamada dos procedimentos. Escreve-se então f pe1, pe2, ... (sem parênteses) para chamar a função f.
Se a função ou procedimento for um método de objeto, parece que as regras são um pouco diferentes e não homogéneas.
- Assim, pode escrever-se MyFile.WriteLine «Isto é um teste.» ou MyFile.WriteLine(«Isto é um teste.»)
- mas, embora se possa escrever wscript.echo 4, não se pode escrever wscript.echo(4).
Seguiremos as seguintes regras:
- não utilizar parênteses em torno dos parâmetros de um procedimento ou de uma função utilizada como procedimento
- parênteses em torno dos parâmetros de uma função
5.3.4. Alguns exemplos de funções
A seguir, apresentam-se alguns exemplos de definições e utilizações de funções:
Programa |
|
Resultados |
Comentários
- A função rendUnTableau demonstra que uma função pode devolver vários resultados e não apenas um. Basta que os coloque numa variável de tipo tabela e que devolva essa variável como resultado.
- Por outro lado, a função argumentsVariables mostra que é possível escrever uma função que aceite um número variável de argumentos. Basta, também neste caso, colocá-los numa variante de tabela e definir essa variante como um parâmetro da função.
5.3.5. Parâmetro de saída ou resultado de uma função
Suponhamos que a análise de uma aplicação tenha revelado a necessidade de um módulo M com parâmetros de entrada Ei e parâmetros de saída Sj. Recorde-se que os parâmetros de entrada são informações que o programa chamador fornece ao programa chamado e que, inversamente, os parâmetros de saída são informações que o programa chamado fornece ao programa chamador. Em VBScript, existem várias soluções para os parâmetros de saída:
- se houver apenas um parâmetro de saída, pode-se torná-lo o resultado de uma função. Nesse caso, deixa de haver um parâmetro de saída, passando a ser simplesmente um resultado de função.
- Se houver n parâmetros de saída, um deles pode servir como resultado de uma função, sendo que os n-1 restantes continuam a ser parâmetros de saída. Também é possível não utilizar uma função, mas sim um procedimento com n parâmetros de saída. Além disso, pode-se utilizar uma função que devolva um array no qual tenham sido colocados os n valores a devolver ao programa chamador. Recorde-se que o programa chamado devolve os seus resultados ao programa chamador por cópia de valores. Esta cópia é evitada no caso de parâmetros de saída passados por referência. Existe, portanto, nesta última solução, uma poupança de tempo.
5.4. O programa VBScript de ordenação de valores
Começámos a discussão sobre a programação modular com o estudo algorítmico de uma ordenação de valores numéricos introduzidos pelo teclado. Eis a tradução VBScript que poderia ser feita:
Comentários:
- o módulo échanger, que tinha sido identificado no algoritmo inicial, não foi aqui objeto de um módulo em VBScript, pois foi considerado demasiado simples para ser objeto de um módulo específico.
5.5. O programa IMPOTS na forma modular
Retomamos o programa de cálculo do imposto, desta vez escrito em formato modular
Comentários
- A função getArguments permite recuperar as informações (cônjuge, filhos, salário) do contribuinte. Aqui, essas informações são passadas como argumentos para o programa VBScript. Se isso viesse a mudar, por exemplo, se esses argumentos proviessem de uma interface gráfica, apenas o procedimento getArguments teria de ser reescrito e não os outros.
- A função getArguments consegue detetar erros nos argumentos. Quando isso acontece, poderia ter-se decidido interromper a execução do programa na função getArguments através de uma instrução wscript.quit. Isto nunca deve ser feito numa função ou procedimento. Se uma função ou procedimento detetar um erro, deve comunicá-lo de alguma forma ao programa chamador. Cabe a este último decidir se interrompe ou não a execução, e não ao procedimento. No nosso exemplo, o programa chamador poderia decidir pedir novamente ao utilizador que voltasse a introduzir o dado errado através do teclado, em vez de interromper a execução.
- Aqui, a função getArguments devolve uma variante de tipo tabela, em que o primeiro elemento é um código de erro (0 se não houver erro) e o segundo é uma mensagem de erro, caso tenha ocorrido algum erro. Ao testar o resultado obtido, o programa chamador pode saber se ocorreu ou não um erro.
- O procedimento getData permite obter os dados necessários para o cálculo do imposto. Aqui, esses dados são definidos diretamente no procedimento getData. Se esses dados tivessem de provir de outra fonte, como um ficheiro ou uma base de dados, por exemplo, apenas o procedimento getData teria de ser reescrito, e não os outros.
- A função calculerImpot permite calcular o imposto assim que todos os dados tiverem sido obtidos, independentemente da forma como foram obtidos.
- Note-se, portanto, que uma programação modular permite a (re)utilização de determinados módulos em diferentes contextos. Este conceito foi fortemente desenvolvido nos últimos vinte anos no âmbito da programação orientada a objetos.







