Escolar Documentos
Profissional Documentos
Cultura Documentos
Programming in VBA V1a PDF
Programming in VBA V1a PDF
Texto Introdutório
António Silva
DEI-Isep
2009-10-28
1
.
Conteúdo
1 Introdução 8
2 Conceitos Básicos 8
2.1 O que é um Macro? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2 Técnicas de construção dum Macro . . . . . . . . . . . . . . . . . . . . . 9
2.3 Gravação de um Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.4 A escrita de um Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.5 O editor de VBA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.6 Criação de um Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3
5.2.3 Ciclos controlados por sentinela . . . . . . . . . . . . . . . . . . . 41
5.2.4 Estrutura de Controlo For..To..Next . . . . . . . . . . . . . . . . . 43
5.2.5 Estruturas de controlo repetitivo imbricadas . . . . . . . . . . . . 44
5.3 Variáveis indexadas - vectores e matrizes . . . . . . . . . . . . . . . . . . 46
5.3.1 Declaração de vectores . . . . . . . . . . . . . . . . . . . . . . . . 47
5.3.2 Processamento de vectores . . . . . . . . . . . . . . . . . . . . . . 48
6 Funções e Procedimentos 50
6.1 Exemplo de função criada pelo programador . . . . . . . . . . . . . . . . 51
6.2 Como aceder às funções standard do Excel . . . . . . . . . . . . . . . . . 52
9 Notas finais 63
4
Lista de Figuras
1 Janela de invocação do ambiente de Gravação de Macros . . . . . . . . . 9
2 Janela de Gestão de Macros . . . . . . . . . . . . . . . . . . . . . . . . . 10
3 Barra de Ferramentas de VBA . . . . . . . . . . . . . . . . . . . . . . . . 10
4 Editor integrado do VBA . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
5 Criação de novo Módulo . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
6 Diferentes tipos de dados e o seu armazenamento em memória . . . . . . 15
7 Como forçar a declaração explícita automaticamente . . . . . . . . . . . 16
8 Uma Form e vários Controlos . . . . . . . . . . . . . . . . . . . . . . . . 19
9 Janela de Propriedades . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
10 Lista de eventos disponíveis . . . . . . . . . . . . . . . . . . . . . . . . . 22
11 Objectos e Eventos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
12 Exemplo de MsgBox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
13 Exemplo de InputBox . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
14 Vários optionButton agrupados numa frame . . . . . . . . . . . . . . . . 30
15 Vários checkBox agrupadas numa frame . . . . . . . . . . . . . . . . . . 31
16 Uma Frame agrupando três botões de comando . . . . . . . . . . . . . . 31
17 Exemplo de listBox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
18 Estrutura de controlo condicional If...Then...Else . . . . . . . . . . . . . 34
19 Estrutura de controlo condicional If...Then . . . . . . . . . . . . . . . . 35
20 Estruturas de controlo condicional imbricadas . . . . . . . . . . . . . . . 37
21 Estrutura de controlo repetitivo Do...While . . . . . . . . . . . . . . . . 39
22 Estrutura de controlo repetitivo Do...Until . . . . . . . . . . . . . . . . 40
23 Ciclos controlados por contador . . . . . . . . . . . . . . . . . . . . . . . 41
24 Ciclos controlados por sentinela . . . . . . . . . . . . . . . . . . . . . . . 42
25 Exemplo de Ciclos Imbricados . . . . . . . . . . . . . . . . . . . . . . . . 45
26 Um vector é uma variável múltipla . . . . . . . . . . . . . . . . . . . . . 46
27 Um exemplo de vector de strings . . . . . . . . . . . . . . . . . . . . . . 47
28 Porquê usar ciclos para processar vectores? . . . . . . . . . . . . . . . . . 48
29 Funções como caixas pretas . . . . . . . . . . . . . . . . . . . . . . . . . 51
30 Utilização da função margemLucro numa fórmula . . . . . . . . . . . . . 52
31 Criação de uma Form no VBA . . . . . . . . . . . . . . . . . . . . . . . 57
32 A UserForm para Entrada Múltipla de Dados . . . . . . . . . . . . . . . 61
33 Objecto da classe Tabstrip . . . . . . . . . . . . . . . . . . . . . . . . . . 62
5
Lista de Tabelas
1 Tipos de dados suportados pelo VBA . . . . . . . . . . . . . . . . . . . . 17
2 Propriedades mais comuns dos objectos gráficos VBA . . . . . . . . . . . 20
3 Valores de configuração das características de uma Caixa de Mensagem . 26
4 Valores devolvidos por uma Caixa de Mensagem . . . . . . . . . . . . . . 27
6
Listings
1 VerificaValor - exemplo de função definida pelo utilizador . . . . . . . . . 12
2 verificaGama - exemplo de função definida pelo utilizador . . . . . . . . . 13
3 Exemplo de aplicação de If..Then..Else imbricados . . . . . . . . . . . . 38
4 FormataBordo - exemplo de sub-rotina usando For..Next . . . . . . . . . 44
5 Exemplo usando Ciclos Imbricados . . . . . . . . . . . . . . . . . . . . . 45
6 Exemplo de processamento de um vector . . . . . . . . . . . . . . . . . . 49
7 Outro exemplo de processamento de um vector . . . . . . . . . . . . . . . 49
8 Função margemLucro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
9 Sub-rotina InsereLinhas . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
10 Handler do objecto cmdFechar para o evento click . . . . . . . . . . . . 59
11 Exemplo de sub-rotina de invocação de uma UserForm . . . . . . . . . . 60
12 Exemplo de sub-rotina de inicialização de uma UserForm . . . . . . . . . 61
13 Handler do objecto cmdFechar para o evento Click . . . . . . . . . . . . 61
14 Sub-rotina de inicialização da UserForm . . . . . . . . . . . . . . . . . . 62
15 Handler associado ao objecto Tabstrip1 para o evento Change . . . . . . 63
7
1 Introdução
Este texto tem como objectivo apoiar o ensino das técnicas de programação de compu-
tadores, utilizando, como ambiente de aplicação, programas como o gestor de folhas de
cálculo Excel.
Destina-se assim aos alunos que já possuem alguns conhecimentos da utilização e
funcionamento desta aplicação. Concretamente, presume-se que estão já familiarizados
com os conceitos de folha de cálculo, de livro de trabalho, de fórmulas e funções standard.
A linguagem de programação que vai ser utilizada será o VBA (Visual Basic for
Applications). É uma linguagem que permite acrescentar capacidades adicionais a certo
tipo de aplicações informáticas, concretamente as pertencentes ao Microsoft Office, entre
as quais o Excel e o Word. Permite ainda automatizar a realização de muitas tarefas
rotineiras nessas aplicações.
Como o próprio nome indica, trata-se duma adaptação da linguagem genérica de
programação Visual Basic de modo a poder ser utilizada no ambiente específico das
aplicações Office.
2 Conceitos Básicos
O VBA constitui uma ferramenta poderosa nas mãos de programadores experimentados
mas pode, ao mesmo tempo, ser muito útil a qualquer utilizador, mesmo inexperiente.
De facto, no dia a dia da utilização destas aplicações, defrontamo-nos com a neces-
sidade de repetir a mesma tarefa várias vezes ao dia ou, de em certas ocasiões, ter que
repetir uma determinada tarefa uma série de vezes de seguida. Seja escrever ou formatar
um certo texto, seja executar uma série de comandos ou escolher opções de menus, seja
ainda realizar a formatação complexa de um documento, são inúmeras as ocasiões em
que dava jeito poder automatizar essas tarefas repetitivas.
É aqui que entra o VBA, permitindo a construção daquilo que se designa vulgarmente
por macros.
8
2.2 Técnicas de construção dum Macro
Se bem que um macro seja um programa em VBA, nem sempre é necessário escrevê-lo de
forma explícita, ou seja, escrevendo especificamente as instruções VBA que o compõem.
Sobretudo quando os macros são simples, é muitas vezes mais prático criá-los de forma
automática, gravando a sequência de passos que ele deverá executar na aplicação.
Esta forma de criar um macro corresponde a mostrar ao computador o que fazer
para conseguir obter o resultado pretendido. O utilizador indica ao programa que se
vai entrar num modo de gravação do macro e inicia a execução da sequência de acções
que normalmente teria que executar. Quando chega ao fim dessa sequência, indica ao
programa que a gravação terminou. Após ter atribuído a essa sequência uma combinação
de teclas especial, esse macro estará pronto a ser executado, substituindo assim o conjunto
de acções que anteriormente seriam necessárias. Tudo se passa como se estivéssemos a
ensinar a aplicação pelo exemplo.
Se se investigar, no entanto, o conteúdo desse macro, verificar-se-á que ele é composto
precisamente por instruções escritas em VBA, sendo que a cada acção ou comando da
aplicação corresponderá uma instrução (ou conjunto de instruções) específica do macro.
A forma alternativa de construir um macro será assim introduzir essas instruções num
editor de texto apropriado. É essa, de facto, a forma de criar um macro quando o seu
âmbito é algo não trivial.
9
Figura 2: Janela de Gestão de Macros
Após se premir a tecla OK, aparecerá uma pequena janela que permitirá controlar
o processo de gravação e dever-se-á dar início à execução das acções que o macro vai
substituir. Quando se tiver executado a última acção a incluir no macro, basta dar a
indicação de que a gravação terminou.
Uma vez tal realizado, esse macro passará a estar disponível mediante a invocação
da combinação de teclas especificada anteriormente (no caso da Figura 1 na página pre-
cedente, seria Ctrl+Shft+M) e realizará, de forma automática, exactamente a mesma
sequência de acções que tínhamos realizado manualmente.
Em alternativa, mediante a combinação de teclas ALT-F8, pode ser accionada a janela
de Gestão de Macros (Figura 2), onde, entre outras acções, pode ser escolhido o macro a
ser executado.
Para facilitar o acesso às facilidades de gravação e edição de macros, será conveniente
tornar visível de forma permanente a barra de ferramentas de Visual Basic (Figura 3).
No Excel, isto poderá fazer-se mediante a opção de Menu "View/Toolbars/Visual Basic".
10
escrito em VBA, porque não tratá-lo como tal e aceder ao seu código, alterando-o de
forma a melhorar a sua eficiência ou a corrigir problemas. E já agora, porque não criá-los
de raiz, aproveitando todo o poder duma linguagem como o VBA?
Do lado esquerdo na Figura 4 podem-se ver duas janelas, a primeira das quais é
designada por Explorador de Projectos e que serve para mostrar o conteúdo do projecto
VBA actual. Um projecto em VBA inclui um ficheiro duma aplicação Office (como, por
exemplo, uma folha de cálculo do Excel) e todos os ficheiros VBA associados, incluindo
os próprios macros e eventuais user forms (janelas de interface próprias utilizadas pelos
11
Figura 5: Criação de novo Módulo
macros1 ).
Para poder começar a escrever macros usando o VBA é necessário criar um módulo
que o possa albergar, o que é conseguido usando a opção de menu "Insert/Module".
Como consequência, para além do novo módulo aparecer referido na janela do Explora-
dor de Projectos, será criada uma janela nova onde será possível escrever o código que
constitui o novo macro. Se já existir algum módulo criado, bastará seleccionar o módulo
pretendido no explorador de projectos, posicionar o cursor na janela correspondente a
esse módulo, numa área fora de qualquer macro já existente, e seleccionar a opção de
menu "Insert/Procedure". Aparecerá uma janela própria (Figura 5) onde será possível
dar o nome ao novo procedimento (o conjunto de instruções que constituirá o macro),
especificar o tipo de macro que vai ser construído (função ou procedimento2 ) e qual o
âmbito da sua utilização (privada ou pública, ou seja, limitada ou não ao ficheiro actual).
12
Não nos vamos de momento preocupar com os detalhes do código que constitui o
macro. Basta verificar que, em 1o lugar, é constituído por uma linha de cabeçalho que
especifica o tipo de macro (neste caso, uma sub-rotina (Sub) ou procedimento) e o seu
nome (verificaValor). O corpo do macro é composto pela estrutura de controle condici-
onal (If...Then 3 ) que vai verificar se o conteúdo da célula B24 é ou não maior que o valor
200. Caso essa condição seja verdadeira, o macro apresentará uma mensagem no ecran
dizendo que o valor máximo foi excedido. Finalmente, o macro é terminado com uma
linha contendo "End Sub".
O que este simples macro faz, portanto, é verificar o conteúdo de uma célula específica
da folha de cálculo e avisar o utilizador caso o valor nela contido ultrapassar um valor
pré-determinado. Sempre que for necessário fazer esta verificação, bastará invocar a
combinação de teclas que tenha sido associada a este macro.
É verdade que sta verificação poderia ter sido realizada colocando numa célula uma
fórmula contendo a função standard do Excel IF. Mas suponhamos agora que se pretende
algo mais complicado, por exemplo, fazer essa verificação num conjunto de células e
apenas desencadear o alarme caso mais do que duas dessas células ultrapassem o limite
estabelecido. A sub-rotina modificada poderia ser algo como:
Listing 2: verificaGama - exemplo de função definida pelo utilizador
1 Public Sub v e r i f i c a G a m a ( )
2 Dim i As Integer , c As Integer
3 c = 0
4 For i = 1 To 5
5 I f C e l l s ( i , 3 ) > 100 Then
6 c = c + 1
7 End I f
8 Next
9 I f c > 2 Then
10 MsgBox c & "␣ v a l o r e s ␣ s u p e r i o r e s ␣ ao ␣ l i m i t e ! "
11 End I f
12 End Sub
13
Options na Janela de Gestão de Macros, invocada mediante ALT-F8.
O tipo da variável especifica qual o tipo de dados que pode conter. Uma variável de um
determinado tipo não está preparada para armazenar dados de um tipo diferente. A razão
para este facto é que o espaço necessário para armazenar diferentes tipos de dados não é
o mesmo. Enquanto um inteiro simples pode ser guardado em 2 bytes de memória 6 , para
guardar um número real podem ser necessários 8 bytes (ou mesmo mais, dependendo da
precisão requerida). A Figura 6 na página seguinte ilustra graficamente esta realidade.
14
Figura 6: Diferentes tipos de dados e o seu armazenamento em memória
declarações necessárias num bloco a colocar no início, para mais fácil manutenção do
programa.
Em VBA, existem duas formas de declaração de variáveis: explícita e implícita. A
declaração explícita exige a utilização da instrução específica
Dim ... As (Dimensionar ... Como).
Por exemplo, a instrução
Dim Preço As Integer
cria (declara) uma variável com o nome Preço e do tipo Integer, ou seja, dimensio-
nada para receber dados do tipo integer (inteiro simples7 ).
A declaração implícita resume-se a utilizar pela primeira vez uma variável sem qual-
quer declaração explícita prévia, dando-lhe um nome e atribuindo-lhe um valor. O VBA
criará automaticamente a variável do tipo pretendido.
Esta segunda forma de declarar variáveis tem, a despeito da sua simplicidade, um
problema grave: é possível, por distracção, criar uma variável nova indesejada, quando o
que se pretendia era apenas escrever o nome de uma variável já existente. Suponha, por
exemplo, que havia criado uma variável "Distancia" mediante a instrução8 :
7
A discussão dos vários tipos de dados suportados pelo VBA será feita na Secção 3.3 na próxima
página.
8
Como se verá na secção 3.4 na página 17, esta instrução guarda na variável "Distancia"o valor 1260
15
Distancia=1260
Como é a primeira vez que o VBA encontra esta palavra ("Distancia"), partirá do
princípio que se trata de uma variável ainda por declarar e tratará de a criar, substituindo-
se ao programador. Dar-lhe-á o nome "Distancia" e dimensiona-la-á de forma a poder
guardar inteiros simples, já que é essa a utilização sugerida na instrução.
Agora suponha que adiante no programa, por engano, escrevia "Distncia" ao referir-se
à variável em causa. O VBA não emitirá nenhum alerta, já que aceitou tranquilamente
"Distncia" como uma nova variável. A forma mais prudente de lidar com declarações de
variáveis é, pois, utilizar apenas declarações explícitas, e instruir o VBA para não aceitar
declarações implícitas, gerando uma mensagem de erro apropriada. Para tal, deverá ser
acrescentada a instrução Option Explicit no início do módulo contendo o macro.
16
Tipo Descrição
Integer Inteiro simples, usado para representar inteiros entre -32768 e 32767
Long Inteiro longo, ou seja, compreendido entre -2.147.483.648 e
2.147.483.647
Single Real representado com precisão simples, com valores negativos compre-
endidos entre cerca de -3,4E38 e -1,4E-45 e valores positivos entre cerca
de 1,4E-45 e 3,4E38
Double Real representado com precisão dupla, usado para representar números
reais muito maiores ou muito mais pequenos que com o tipo single
String Usado para representar texto (informação alfanumérica como letras,
algarismos e símbolos especiais); strings são representadas entre aspas
Boolean Usado para representar valores lógicos (True ou False)
Date Usado para representar datas ou valores de tempo; são representados
entre caracteres #
Object Serve para guardar referências a objectos
17
variável, substituirá o valor nela contido pelo novo valor. Convem, assim, lembrar que
nesta operação o fluxo da informação se faz sempre da direita para a esquerda e não o
contrário.
Há ainda que ter em atenção o facto de que não é normalmente aconselhável atribuir
um valor de um dado tipo a uma variável de tipo diferente. Os resultados podem ser a
perda de informação ou o mau funcionamento do programa. O VBA poderá gerar uma
mensagem de erro mas tal nem sempre acontece, podendo produzir-se comportamentos
anómalos difíceis de detectar e corrigir.
18
4 Como trabalhar com Objectos
Para que uma macro possa manipular o ambiente da aplicação, seja modificando a forma-
tação de um documento, modificando opções da aplicação ou introduzindo dados numa
gama de células, vai ser preciso interagir com Objectos. Genericamente, pode dizer-se que
um objecto é algo que pode ser visto, tocado, sentido. Em VBA, considera-se um objecto
tudo aquilo que pode ser visto e que pode ser manipulado de alguma forma.
Quer o documento, quer uma célula ou gama de células, quer a própria aplicação
são considerados, para os efeitos de programação em VBA, como sendo objectos. Mas
podem ainda existir outros objectos, nomeadamente aqueles que permitem construir uma
interface gráfica específica do macro. A esses objectos gráficos chamamos controlos e são
colocados em janelas especiais chamadas forms.
Na Figura 8 podem ser observados vários objectos instalados numa form: uma caixa
de texto, dois botões de comando, vários rótulos ou etiquetas e uma caixa de verificação.
Através deles é possível o macro interagir com o utilizador. Veremos em detalhe mais à
frente para que servem e como utilizar estes diferentes objectos.
19
• Os seus "métodos" especificam o que pode ser feito com ele: acelerar, travar, mudar
de direcção, etc;
• Os seus "eventos" são ocorrências que provocarão respostas automáticas por parte
do automóvel, como seja, um alarme que dispara (resposta) caso desliguemos o
carro com as luzes ligadas (evento).
4.1.1 Propriedades
As propriedades de um objecto são as suas características físicas. Como na vida real, cada
objecto possui características próprias ou propriedades, que podem ser quantificadas ou
especificadas, como sejam as suas dimensões ou o tipo de letra que usa. A cada objecto
está associada uma lista de propriedades a que é possível atribuir valores, determinando
a sua aparência, localização e outros detalhes. Pode-se então dizer que as propriedades
de um objecto definem a forma como ele se apresenta ou se comporta.
Diversos objectos podem partilhar a mesma propriedade. Essa propriedade, no en-
tanto, pode afectar esses objectos de forma diferente.
Já vimos que quer os elementos do Excel como folhas de cálculo ou próprio docu-
mento, quer elementos constituintes de interfaces gráficas que os macros possam utilizar,
são considerados objectos. Na Tabela 2 são descritas algumas das propriedades mais
importantes e que são comuns à maior parte dos objectos gráficos.
Os valores que as propriedades de um dado objecto tomam podem ser consultados ou
modificados usando a janela de propriedades (Figura 9 na página seguinte). Nessa janela
aparece a lista de propriedades do objecto que estiver nesse momento seleccionado . Nela
pode observar, entre outras, algumas das propriedades referidas na lista acima (Caption,
Height e Font) e os respectivos valores no momento.
20
Figura 9: Janela de Propriedades
4.1.2 Métodos
Os métodos traduzem acções que um macro pode realizar sobre os objectos. Por exem-
plo, aplicar o método Save ao objecto ActiveDocument implica desencadear o processo
de salvaguardar o conteúdo do documento activo num determinado ficheiro. Aplicar o
método Clear a um objecto da classe ListBox terá como consequência a eliminação de
todas as linhas nele contidas. A cada classe de objectos é possível aplicar um determinado
conjunto de métodos.
Para vermos como um método é aplicado a um objecto, vamos considerar o objecto
Worksheet, que representa uma folha de cálculo do Excel. Se pretendermos que o nosso
macro mova essa folha para uma nova posição dentro do Livro de Trabalho (Workbook ),
ele deverá aplicar o método Move a esse objecto, usando a seguinte sintaxe:
Worksheet.Move([Before][, After])
Exemplificando, se quisermos que o macro desloque a folha de cálculo "Dados 2009"para
a posição imediatamente a seguir à folha "Dados 2008", o comando a inserir no macro
será:
Worksheets("Dados 2009").Move Before:=Worksheets("Dados 2008")
Como veremos mais à frente, o objecto Worksheet é definido como um elemento do
conjunto de folhas de cálculo contidas no Livro de Trabalho. Este conjunto de folhas é
representado por Worksheets(). Assim sendo, Worksheets("Dados 2009") refere-se à folha
de cálculo com o nome "Dados 2009".
4.1.3 Eventos
Os eventos são acções que, uma vez exercidas sobre um objecto, implicam a possibilidade
de ocorrer uma resposta automática por parte dele. Basicamente, um evento é algo que
acontece a um objecto. Por exemplo, a abertura de uma folha de um livro de trabalho
(workbook ) em Excel é um evento. A inserção de uma nova folha no livro de trabalho é
21
outro exemplo de evento.
Para que um objecto possa reagir a um dado evento deverá existir, previamente pro-
gramado, um procedimento especial, chamado event handler, que vai especificar o que
fazer caso esse evento ocorra. Sem isso, o objecto detectará esse acontecimento mas não
saberá o que fazer. Nenhuma resposta será produzida.
22
Figura 11: Objectos e Eventos
associado a esse objecto (command1 ) um event handler adequado, o objecto será já capaz
de responder ao evento e produzir o resultado desejado. Neste caso, esse resultado deverá
ser efectuar os cálculos necessários para concluir se o número introduzido é ou não primo
e apresentar essa conclusão no rótulo lbl2.
23
Objecto.Propriedade
Se nos quisermos referir, por exemplo, à propriedade ActiveWindow do objecto Ap-
plication, procederemos do seguinte modo:
Application.ActiveWindow
A propriedade ActiveWindow refere-se à janela da aplicação com que estamos, de
momento, a trabalhar. No caso do Excel, podemos ainda referirmo-nos, por exemplo, à
propriedade ActiveSheet para designar a folha de cálculo em que se está a trabalhar ou a
ActiveCell para nos referirmos à célula actualmente seleccionada.
Se pretendermos, por exemplo, especificar o tipo de letra da célula activa, usaremos
a seguinte descrição de objecto:
Application.ActiveWindow.ActiveCell.Font.Name
Na prática, quando nos estamos a referir a uma propriedade da janela activa da
aplicação como seja a ActiveCell, não precisamos de referir que pertence à ActiveWindow
e à Application. Podemos omitir esses detalhes e apenas escrever:
ActiveCell.Font.Name
Se quisermos utilizar esta propriedade para mudar o tipo de letra da célula activa,
utilizaremos então uma instrução como a seguinte10 :
ActiveCell.Font.Name = "Helvetica"
Se, ao contrário, quisermos obter o valor de uma dada propriedade, a instrução a usar
será do tipo:
variavel = Objecto.Propriedade
Para obtermos, por exemplo, o conteúdo da célula activa da folha de cálculo, a ins-
trução correcta seria:
conteudo = ActiveCell.Value
Estaremos, assim, a usar a propriedade Value do objecto ActiveCell. Nessa proprie-
dade encontra-se armazenado o conteúdo da célula.
24
Worksheets("Leituras").Activate
Estamos aqui a aplicar o método Activate ao objecto Worksheets("Leituras"), o
que tem como consequência que essa folha de cálculo se tornará activa.
No entanto, muitas vezes, os métodos exigem informação adicional para poderem
executar o seu trabalho. Essa informação adicional será fornecida através de argumentos,
inseridos a seguir ao nome do método aplicado:
Objecto.Método (argumento1, argumento2. ...)
O seguinte exemplo abre um Livro de Trabalho pré-existente com o nome "Dados.xls":
Workbooks.Open("Dados.xls")
Muitas vezes, os argumentos que se podem fornecer a um método são opcionais. Por
exemplo, a instrução abaixo adiciona (insere) uma nova folha de cálculo imediatamente
antes da folha com o nome "Dados_Jan":
Worksheets.Add Before:=Worksheets("Dados_Jan")
No entanto, caso seja omitido o argumento Before, a nova folha será inserida antes da
folha de cálculo activa. É esse o comportamento por defeito do método Add.
4.3.1 MsgBox
A função MsgBox permite apresentar no ecran uma Caixa de Mensagem (Msg Box ).
Trata-se de uma pequena janela contendo um mensagem, pelo menos um botão de co-
mando e eventualmente um pequeno desenho (ícone) ilustrativo do tipo de mensagem.
Na Figura 12 encontra-se um exemplo de uma destas janelas.
25
Uma Caixa de Mensagem destina-se a apresentar ao utilizador uma mensagem com
informação relevante, sejam avisos, resultados, perguntas ou sugestões. Uma janela deste
tipo tem um comportamento peculiar: enquanto não for premido um botão, não será
possível qualquer outra interacção com o computador, já que essa janela tomou o controlo.
O utilizador é assim obrigado a atender à mensagem apresentada.
A sintaxe da função MsgBox é a seguinte:
MsgBox(Mensagem, Características, Título)
Em que os argumentos são:
Mensagem Texto a apresentar (máximo de 1024 caracteres)
Características Valor numérico que especifica o número de botões, o tipo do
ícone e o botão de defeito (com o “focus”), obtido pela soma
de três valores parciais.
Título Conteúdo da barra de título da janela (opcional)
O 2o argumento será calculado usando os valores da Tabela 3:
Assim, para obter a MsBox da Figura 12 na página anterior o valor a utilizar para
o parâmetro características seria obtido somando 3 valores, um de cada coluna da
Tabela 3, cada um deles especificando uma das características (Botões de Comando,
Ícone e qual o botão com o "focus"11 ):
1 + 16 + 0 = 17
A MsgBox serve então para apresentar uma mensagem ao utilizador. No entanto,
permite também recolher informação. Quando a caixa de mensagem apresenta mais
do que um botão, está-se a pedir ao utilizador que escolha uma de entre duas ou três
alternativas. Dependendo de qual o botão premido pelo utilizador, assim o valor numérico
devolvido pela função MsgBox será um de entre 7 valores possíveis, descritos na Tabela 4
na página seguinte.
De notar que caso a tecla ESC (Escape) seja premida o valor devolvido será 2, a que
corresponde o botão Cancel (o que indica que as duas acções são equivalentes).
Claro que quando se pretende aproveitar o valor devolvido pela função MsgBox será
necessário usá-la com a seguinte sintaxe:
11
O botão com o "focus" ou botão de defeito é aquele que será accionado automáticamente caso o
utilizador prima a tecla Enter ou Return.
26
Constante Valor Botão seleccionado
vbOK 1 OK
vbCancel 2 Cancel
vbAbort 3 Abort
vbRetry 4 Retry
vbIgnore 5 Ignore
vbYes 6 Yes
vbNo 7 No
4.3.2 InputBox
A função InputBox permite apresentar ao utilizador uma mensagem com uma questão,
recolhendo ao mesmo tempo uma string contendo a sua resposta. Assim, ao contrário
da função MsgBox (Secção 4.3.1 na página 25), esta função produz um resultado do tipo
string e não do tipo integer.
Como pode ser visto na Figura 13, esta função cria um objecto composto (uma Caixa
de Entrada) incluindo um caixa de texto, dois botões12 e um rótulo dentro de uma
pequena janela.
A sua sintaxe é
Variável = InputBox (mensagem, título, valor_de_defeito, xpos, ypos)
Em que os argumentos são:
12
Ao contrário da MsgBox, neste caso os dois botões são fixos. Por outro lado, a tecla ESC tem o
mesmo comportamento.
27
Mensagem Texto da mensagem a afixar na Caixa de Entrada (máximo
de 1024 caracteres)
Título Conteúdo da barra de título da janela (opcional)
valor_de_defeito Texto a colocar à partida na caixa de texto da Caixa de En-
trada (opcional)
xpos e ypos Coordenadas da “Input Box” relativamente aos bordos es-
querdo e superior do ecrã (opcionais)
4.3.3 Forms
Como vimos no início da Secção 4 na página 19, uma interface gráfica (em terminolo-
gia VBA, uma DialogBox ) é construída dispondo os objectos adequados (genericamente
designados por controlos) sobre uma janela especial, a form. Efectivamente uma form é
utilizada como um contentor para outros objectos gráficos. Um objecto da classe User-
Form pode ser criado no Editor do VBA através do Menu "Insert/User Form". Esse
processo será visto em detalhe na Secção 8 na página 56.
A seguir são apresentadas algumas das principais propriedades que podem ser confi-
guradas numa Form:
Nas próximas secções, referiremos com algum detalhe os controlos de uso mais comum
na construção de dialogBoxes em VBA. Estes são os objectos que mais frequentemente
são colocados numa form.
28
A instrução seguinte serve de exemplo de como alterar programaticamente o estado
de um botão de comando:
cmdArranque.Enabled = True
O que fizemos com a instrução acima foi atribuir o valor booleano (lógico) True à pro-
priedade Enabled 13 do botão de comando cmdArranque. Estamos, assim, a tratar uma
propriedade como sendo uma variável. De facto, uma propriedade pode ser considerada
como uma variável especial.
4.3.5 Rótulos
Os rótulos, também designados por etiquetas (label ) são usados para apresentar texto
na interface. Mais uma vez, a propriedade mais utilizada é a propriedade Caption, que
permite especificar o texto a apresentar. Este controlo é usado não só para apresentar
informação estática, que é escolhida na fase de concepção da interface, como também
informação dinâmica, como seja a apresentação de resultados:
lblResultado.Caption = "O valor total é 235 metros"
A instrução acima atribui à propriedade Caption do rótulo lblResultado a string "O
valor total é 235 metros", o que vai ter como consequência a sua afixação na interface.
Enquanto que os rótulos (Label ) são utilizados pelo programa para aparesentar infor-
mação ao utilizador, já as caixas de texto (Text Box ) são maioritáriamente usadas para
permitir a leitura de informação pelo programa.
13
Esta propriedade permite controlar o acesso do utilizador ao botão de comando.
29
Funções Val e Str
A linguagem Visual Basic dispõe de um grande número de funções pré-definidas.
Duas delas, relacionadas com "strings", são particularmente úteis para lidar com
objectos da classeTextBox :
Função Descrição
Val() Retorna como valor numérico um número contido dentro duma string
Str() Retorna uma string representando um número
Vamos supor que um macro precisa de calcular o peso total à custa de dois valo-
res introduzidos pelo utilizador através de duas TextBox. A tentação seria usar a
instrução:
pesoTotal = txt1.Text + txt2.Text
No entanto, o que a propriedade Text das TextBox contem é apenas texto, ainda
que contendo algarismos. Para extrair a informação numérica de dentro do texto,
haverá que utilizar a função Val():
pesoTotal = Val(txt1.Text) + Val(txt2.Text)
30
4.3.8 Caixas de Verificação
Estes objectos comportam-se de forma semelhante à dos botões de opção mas, neste caso,
é possível encontrar vários controlos deste tipo activados simultaneamente na mesma
form, visto que tais objectos funcionam de forma independente (isto é, não se encontram
relacionados entre si).
Possuem também uma propriedade Value que, neste caso, pode apresentar os seguintes
valores:
0 não activada
1 activada
2 não disponível
O texto a inserir junto de cada caixa de verificação deve ser especificado mediante a
propriedade Caption.
31
Uma vez inserido um objecto dentro do quadro, esse quadro passa a constituir o
“contentor” desse objecto. Quer isto dizer que a sua localização passa a ser definida não
em relação à form mas em relação ao quadro que o contem.
Outra utilidade dos quadros é servir de “moldura” a um dado conjunto de controlos, de
modo a melhorar a aparência e a organização da form em que estão inseridos, agrupando
os diversos controlos de acordo com as suas funcionalidades.
32
ListCount permite conhecer em qualquer momento o número de elemen-
tos contidos na lista
Sorted permite especificar se a lista é ou não apresentada de maneira
ordenada
ColumnCount especifica qual o número de colunas em que a lista é apresen-
tada
ColumnHeads controla os cabeçalhos das colunas
MultiSelect permite controlar a forma de selecção de elementos na lista:
0 - só é possível seleccionar um elemento
1 - é possível seleccionar vários elementos simultaneamente,
pressionando cada elemento
2 - é possível seleccionar vários elementos simultaneamente,
usando a tecla Ctrl
ListIndex fornece ou especifica qual o índice do item actualmente selec-
cionado (ou –1 caso nenhum esteja). Sintaxe:
objecto.ListIndex [= indice]
List permite aceder aos elementos duma lista, quer para os ler,
quer para os modificar. Sintaxe:
objecto.List(indice) [= string]
Text permite obter o elemento actualmente seleccionado. Sintaxe:
variavel = objecto.Text
RowSource no Excel, especifica qual a gama de células onde estará a in-
formação a incluir na lista, ou seja, a fonte dos dados a apre-
sentar.
Na especificação de sintaxe, os parêntesis rectos indicam que o seu conteúdo é opcional.
No caso das propriedades ListIndex e List descritas acima, a versão curta destina-se a ser
usada do lado direito de uma operação de atribuição, enquanto que na versão completa
o que se pretende é atribuir um valor à propriedade.
Existe uma variante da ListBox, chamada ComboBox, que combina uma TextBox com
uma ListBox. O utilizador pode introduzir um item na TextBox ou seleccioná-lo na lista
que, estando normalmente escondida, só aparecerá quando se clica num ícone próprio. É
normalmente utilizado quando se pretende dar a possibilidade de escolher um elemento
de uma lista mas sem ocupar muito espaço na form.
33
5 Estruturas de controlo do programa
Um macro é um programa escrito na linguagem VBA. Vamos agora começar a analizar
mais em detalhe a estrutura de um programa. Um programa é composto por um conjunto
de instruções, cada uma delas executando uma tarefa específica. A sequência de instruções
levará à solução do problema que o programa se propõe resolver. Mas essa sequência não
tem que ser necessariamente linear, i.e., composta por uma lista de instruções que serão
realizadas uma após outra, de forma imutável. Isso tornaria o programa inflexível, incapaz
de se adaptar às circunstâncias ou aos diferentes desejos do utilizador.
Já foi introduzida na Secção 3.4 na página 17 a noção de operação de atribuição. Com
essa operação podemos criar instruções simples, mediante as quais é possível copiar valores
entre variáveis, ou armazenar resultados do cálculo de expressões. Mas um programa
flexível não poderá ser construído apenas com instruções desse tipo. É preciso dispor
de instruções que permitam alterar o fluxo do programa. Para tal vamos introduzir
estruturas de controlo que possibilitam a alteração desse fluxo.
5.1.1 If...Then...Else
34
A Figura 18 na página 34 descreve a estrutura condicional If...Then...Else. Como o
seu nome sugere, esta estrutura está baseada no teste de uma condição. Se essa condição
fôr verdadeira, desencadeará a execução das instruções representadas na figura por Bloco
de Instruções1. Em caso contrário, será executada o Bloco de Instruções 2.
A sintaxe desta estrutura é:
1 I f c o n d i c a o Then
2 [ instrucoes ]
3 Else
4 [ instrucoes alternativas ]
5 End I f
Quando a condição é verdadeira serão executadas as instruções delimitadas por Then
e Else. Em caso contrário, será executado o bloco alternativo de instruções.
A condição pode consistir numa comparação ou outra operação lógica, ou ainda em
qualquer expressão de que resulte um valor numérico: um valor não nulo será interpretado
como Verdadeiro, enquanto um valor nulo será considerado como Falso.
A condição é, portanto, uma expressão booleana (lógica). Uma expressão booleana
representa um valor booleano, TRUE (verdadeiro) ou FALSE (falso) e pode ser cons-
tituída por uma variável, uma função ou uma combinação destas entidades através de
operadores.
5.1.2 If...Then
Quando numa estrutura condicional não existe qualquer acção a executar quando a
35
condição seja falsa, usa-se uma variante simplificada, a If...Then. O seu diagrama está
descrito na Figura 19 na página 35. A sua sintaxe será então:
1 I f c o n d i c a o Then
2 [ instrucoes ]
3 End I f
Nesta 2a variante, quando a acção a realizar no caso a condição ser verdadeira puder ser
executada com apenas uma instrução, é possível utilizar a seguinte sintaxe simplificada,
sem o delimitador End If :
If condicao Then instrucao
Expressões lógicas
As expressões lógicas, utilizadas nas condições das estruturas de controlo, são cons-
truídas utilizando operadores lógicos específicos. A linguagem VBA prevê os seguin-
tes operadores lógicos, utilizáveis em expressões:
Operador Descrição
> Maior que
< Menor que
= Igualdade
<= Menor ou igual
>= Maior ou igual
<> Desigualdade
And E
Or Ou
Not Negação
Dos primeiros seis operadores não haverá muito a dizer. Já do And e do Or haverá
alguns detalhes a esclarecer:
AND
Sintaxe: Expr1 And Expr2
• Basta que quer Expr1 quer Expr2 seja falsa, para a expressão ser falsa
OR
Sintaxe: Expr1 Or Expr2
• Basta que quer Expr1 quer Expr2 seja verdadeira, para a expressão ser ver-
dadeira
36
5.1.3 Estruturas condicionais embutidas
É possível imbricar estruturas condicionais dentro de outras estruturas condicionais, per-
mitindo, assim, a construção de estruturas de controlo mais complexas. Para inserir uma
estrutura condicional dentro de outra, é utilizada a palavra reservada ElseIf.
A sintaxe desta estrutura é:
1 I f c o n d i c a o 1 Then
2 Accao1
3 E l s e I f c o n d i c a o 2 Then
4 Accao2
5 E l s e I f c o n d i c a o 3 Then
6 ...
7 Else
8 AccaoN
9 EndIf
Esta estrutura condicional permite a selecção de uma entre várias alternativas mu-
tuamente exclusivas. As instruções que se seguem à palavra reservada Else (aqui re-
presentadas por "AcçãoN") serão executadas apenas se nenhuma das condições se tiver
verificado.
37
Chama-se a esta acção, a acção por defeito, ou seja, aquilo que se faz quando todo o resto
falha.
É muito importante que se compreenda que estamos aqui a tratar de verdadeiras alter-
nativas, i.e., mútuamente exclusivas. Cada vez que uma estrutura deste tipo é executada,
só uma das acções será efectuada.
O exemplo seguinte traduz uma situação em que o programa, confrontado com a
necessidade de classificar uma nota numérica, pode escolher uma de entre seis notas
qualitativas diferentes. Só uma estrutura condicional imbricada lhe permitirá resolver o
problema.
Listing 3: Exemplo de aplicação de If..Then..Else imbricados
1 I f ( nota < 0 ) Or ( nota > 20 ) Then
2 r e s u l t a d o = "Nota␣ I n v a l i d a ! "
3 E l s e I f nota < 6 Then
4 r e s u l t a d o = "Mau"
5 E l s e I f nota < 10 Then
6 r e s u l t a d o = " Mediocre "
7 E l s e I f nota < 14 Then
8 resultado = " Suficiente "
9 E l s e I f nota < 17 Then
10 r e s u l t a d o = "Bom"
11 Else
12 r e s u l t a d o = " Muito ␣Bom"
13 End I f
É possível imbricar um qualquer número de blocos ElseIf dentro de uma dada estru-
tura condicional.
38
grama da primeira encontra-se na Figura 21:
Analizando esse fluxograma, pode-se observar que tudo roda à volta do teste a uma
condição, descrita como condição de funcionamento. Se a condição for verdadeira
na altura em que o teste é realizado, as instruções que compõem o chamado corpo do
ciclo serão executadas, após o que novo teste à condição será efectuado. Enquanto a
condição se verificar ser verdadeira, o programa não sairá deste ciclo. Na 1a vez em que
a condição se mostrar falsa, o ciclo terminará e o programa poderá continuar com as
instruções seguintes.
Chama-se corpo do ciclo ao conjunto de instruções que serão executadas em cada
iteração (repetição) do ciclo. Esse conjunto pode incluir qualquer número de instruções
e de qualquer tipo, mesmo outras estruturas repetitivas. Neste último caso, etaremos
perante o que se designa por ciclos imbricados ou embutidos, que serão tratados em
detalhe na Secção 5.2.5 na página 44.
A sintaxe em VBA desta estrutura de controle é a seguinte:
1 Do While c o n d i c a o
2 [ instrucoes ]
3 Loop
A segunda variante é muito semelhante à primeira. A grande diferença diz respeito à
condição de controle. Neste caso, temos a chamada condição de termo (ou de fim) o
que faz com que o ciclo funcione enquanto a condição for falsa ou, por outras palavras,
até que a condição de termo seja verdadeira (Figura 22).
A sintaxe da variante Do...Until será então:
1 Do
2 [ instrucoes ]
3 Loop U n t i l c o n d i c a o
Como se pode deduzir do atrás dito, é possível transformar uma estrutura Do...While
numa Do...Until desde que se substitua a palavra While pela Until e se negue a condição
de controlo. Escolher uma ou outra estrutura de controlo depende, no fundo, do jeito
39
Figura 22: Estrutura de controlo repetitivo Do...Until
40
Figura 23: Ciclos controlados por contador
41
Exemplo
Se o utilizador estiver a introduzir os dados referentes a um conjunto de alunos
identificados pelos seus números de matrícula, a introdução de um número com
menos de 6 dígitos (no caso do ISEP) como, por exemplo, o valor 1, permitirá
indicar ao programa que a presente sequência de introdução de dados deve
terminar. Seria esse, neste caso, o valor sentinela escolhido.
42
corpo do ciclo, um em cada iteração. Essa leitura deverá, no entanto, ser feita no fim do
corpo do ciclo, após o processameento do valor anteriormente lido. Neste tipo de ciclos, a
leitura e o processamento de cada valor lido andam desfasados de uma iteração do ciclo.
No caso de se usar a estrutura Do..While, o ciclo funcionará enquanto o valor lido for
diferente do valor sentinela escolhido.
O exemplo apresentado acima, poderia ser codificado pelo segmento de programa
seguinte:
1 num = InputBox ( " D i g i t e ␣o␣numero" , "ISEP␣−␣ M a t r i c u l a s " )
2 Do While numero <> 1
3 I f numero <> 1 Then l s t b o x 1 . AddItem num
4 num = InputBox ( " D i g i t e ␣o␣numero" , "ISEP␣−␣ M a t r i c u l a s " )
5 Loop
Geralmente o valor sentinela é um valor preciso. Existem casos, porém, em que a
sentinela pode ser qualquer valor dentro de uma determinada gama, por exemplo, todos
os números negativos. Um exemplo de um ciclo controlado por uma sentinela com estas
características é apresentado na Secção 5.2.5 na próxima página.
43
1 For c o n t a d o r = v a l o r _ i n i c i a l To v a l o r _ f i n a l Step p a s s o
2 [ instrucoes ]
3 Next
A diferença está na utilização da palavra Step após a especificação do valor final. A
sua inclusão é opcional: caso se pretenda que o conteúdo da variável de controlo seja
incrementada uma unidade de cada vez, é desnecessário especificar o passo. Em caso
contrário, Step passo permitirá incrementar o valor de variável de um valor diferente da
unidade (positivo ou negativo).
Caso o valor de passo seja positivo a variável contadora será incrementada. Se pre-
tendermos, no entanto, efectuar um decremento, deverá ser utilizado um valor negativo
para passo. Obviamente, nesse caso, a condição implícita de funcionamento do ciclo
passará a ser contador >= fim.
Repara-se que nesta estrutura de controlo, ao contrário das estudadas anteriormente,
o incremento ou decremento da variável de controle do ciclo é automático. Outro aspecto
interessante é que a condição de funcionamento do ciclo é implícita. Ela existe e é
verificada mas não é especificada de forma explícita pelo programador, apenas de forma
indirecta ao fixarem-se os valores inicial e final da variável de contagem.
Existe ainda em VBA uma estrutura de controlo que é uma variante da For..To..Next
e que opera numa colecção de objectos. Uma colecção é um conjunto de objectos idênticos,
pertencentes à mesma classe, e que são referenciáveis mediante um índice. Por exemplo,
um Workbook é constituído por um conjunto de objectos da classe Worksheet 14 .
A sintaxe desta estrutura é a seguinte:
1 For Each elemento In C o l e c c a o
2 [ instrucoes ]
3 Next
O bloco de instruções será aplicada a cada elemento da colecção de objectos em causa.
A seguir é apresentado um exemplo de sub-rotina, utilizando esta estrutura de controlo:
Listing 4: FormataBordo - exemplo de sub-rotina usando For..Next
1 Public Sub FormataBordo ( )
2 Dim c e l l O b j e c t As Range
3 For Each c e l l O b j e c t In S e l e c t i o n
4 c e l l O b j e c t . BorderAround C o l o r I n d e x :=3 , Weight := x l T h i c k
5 Next
6 End Sub
É criada a variável cellObject para guardar um objecto do tipo Range (que representa
uma gama de células - assunto tratado na Secção 7.3). O ciclo For Each...Next aplica
o método BorderAround a cada uma das células contidas na gama representada por
cellObject. Com os argumentos fornecidos no exemplo, este método formata o bordo
dessas células a vermelho e uma linha grossa.
14
Por sua vez, um workbook é também um objecto. Um objecto pode assim ser ele próprio uma
colecção de objectos.
44
5.2.5 Estruturas de controlo repetitivo imbricadas
Foi dito anteriormente que o corpo de um ciclo era constituído pelo conjunto de instruções
que o ciclo irá executar repetidamente. Foi também dito que nesse conjunto de instruções
se poderia incluir qualquer tipo de instruções, mesmo constituindo outras estruturas de
controlo repetitivo. Destes ciclos se diz que se encontram imbricados um dentro do
outro.
Considere-se o problema de calcular uma série de factoriais de números inteiros. O
cálculo de um factorial é realizado efectuando uma sucessão de multiplicações. Será
necessário usar um ciclo para o efeito. Por sua vez, se pretendermos repetir esse cálculo
um certo número de vezes, teremos também que usar um ciclo. Teremos assim um
ciclo, chamemos-lhe exterior, que se encarrega de produzir uma sequência de factoriais
e cujo corpo inclui por sua vez um ciclo, dito interior, que é responsável pelo cálculo de
cada factorial. O diagrama de fluxo da Figura 25 na página precedente representa esta
realidade. O código necessário para traduzir esse diagrama é o seguinte:
Listing 5: Exemplo usando Ciclos Imbricados
1 num = InputBox ( " I n t r o d u z a ␣um␣ i n t e i r o ␣ p o s i t i v o " )
2 Do U n t i l num < 0
3 factorial = 1
4 contador = 1
5 Do U n t i l c o n t a d o r > num
6 f a c t o r i a l = f a c t o r i a l ∗ contador
7 c o n t a d o r = c o n t a d o r +1
8 Loop
9 num = InputBox ( " I n t r o d u z a ␣um␣ i n t e i r o ␣ p o s i t i v o " )
10 Loop
O ciclo exterior é controlado por uma sentinela, no caso qualquer valor inteiro não
positivo. É um exemplo de sentinela constituído não por um valor específico mas por
uma gama de valores possíveis. O ciclo interior é calaramente controlado por contador,
funcionando tantas vezes quantas o valor do inteiro cujo factorial se pretende calcular.
45
Figura 25: Exemplo de Ciclos Imbricados
Um vector é uma lista ordenada de variáveis simples do mesmo tipo. Pode também ser
visto como um conjunto de variáveis simples agrupadas. Todos as variáveis membros desse
vector partilham o mesmo nome (o nome do vector). São identificadas individualmente
mediante o valor dum índice, que determina qual a sua posição dentro do vector. É por
isso que estas variáveis são conhecidas por variáveis indexadas.
Os valores do índice devem obrigatoriamente ser do tipo Integer. O primeiro valor do
índice é zero15 .
Um elemento de um vector é identificado utilizando o nome do vector seguido do valor
do índice dentro de parêntesis
nome_vector(indice)
Exemplos:
var_Multipla(3) 4o elemento do vector ‘var_Multipla’
var_Multipla(7) 8o e último elemento do vector ‘var_Multipla’
notas(14) 15o elemento do vector ‘notas’
nomes(0) 1o elemento do vector ‘nomes’
15
É possível forçar que os índices dos vectores comecem do valor 1 usando a directiva Option Base 1.
46
Figura 26: Um vector é uma variável múltipla
Os elementos de um vector não têm que ser inteiros, nem sequer valores numéricos.
Na Figura 27 na página precedente é representado um vector contendo strings (texto).
Considerando o vector como armazenado os nomes dos membros de uma equipa de fu-
tebol, os sucessivos valores do índice podem ser vistos como os correspondentes números
das suas camisolas. Note-se que estamos, neste caso, a forçar os valores do índice a iniciar
em 1.
47
Dim notas(30) As Single
Dim nomes(100) As String
Nota: num_elementos não se refere ao valor máximo que a variável índice pode
assumir (7, no caso do vector var_Multipla) mas sim ao número de elementos do
vector (8, neste caso). Por este processo, a declaração do limite inferior faz-se de forma
implícita: por defeito assume-se como limite inferior do índice o valor zero (ou 1 se tal
for especificado mediante a instrução Option Base 1 ).
Uma forma alternativa de utilizar a instrução Dim para declarar vectores implica a
utilização da palavra reservada To, permitindo especificar o menor e o maior valor que o
índice pode assumir:
Dim nome_vector(menorIndice To maiorIndice) As Tipo
Exemplos:
Dim numeros(100 To 200) As Double
Dim valores(-100 to 100) As Single
48
Figura 28: Porquê usar ciclos para processar vectores?
4 Dim r e s As S i n g l e
5 l s t T a b e l a . Clear
6 For i = 0 To txtMaior
7 r e s = Sqr ( i )
8 vectorSqr ( i ) = res
9 l s t T a b e l a . AddItem Format( r e s , " 0 . 0 0 0 " )
10 Next i
11 End Sub
49
9 For i = txtMenor To txtMaior
10 r e s = Sqr ( i )
11 vector ( indice ) = res
12 l i n h a = Format( Str ( i ) , "##0" ) + "␣−␣" + _
13 Format( v e c t o r ( i n d i c e ) , " 0 0 0 . 0 0 0 " )
14 l s t T a b e l a . AddItem l i n h a
15 indice = indice + 1
16 Next i
17 End Sub
6 Funções e Procedimentos
As sub-rotinas descritas nos exemplos que têm sido apresentados destinam-se a executar
tarefas. Por exemplo, as rotinas descritas na Secção 2.6 na página 12 têm como objectivo
a monitorização dos valores contidos em determinadas células da folha de cálculo. Este
tipo de sub-rotinas é designado por procedimentos. Destinam-se a realizar tarefas e não
devolvem qualquer resultado.
No entanto, não é possível utilizar estes procedimentos em fórmulas duma folha de
cálculo, ao contrário do que acontece com as funções standard disponíveis no Excel, como
seja a função If referida atrás, ou a função Sum, que calcula a soma do conteúdo numérico
das várias células contidas numa dada gama. Isso acontece porque, para poderem ser
utilizadas em fórmulas, elas terão que ser estruturadas como funções, e comportarem-se
de maneira idêntica à das funções standard.
Uma função, seja ela pré-existente no Excel, ou criada pelo utilizador, deve poder
50
receber a informação de que necessita, e de conseguir devolver o resultado do seu trabalho,
de modo a esse resultado poder ser utilizado na fórmula ou expressão que a utilize. Para
tal, tem que possuir uma estrutura definida pela sintaxe seguinte:
1 Function Nome ( argumento1 , argumento2 , . . . )
2 ’ L i s t a de i n s t r u c o e s
3 Nome = r e s u l t a d o
4 End Function
Repare-se que para além das diferenças óbvias no cabeçalho e no delimitador final em
relação às sub-rotinas estudadas atrás, verifica-se o seguinte:
1. A seguir ao nome da função e entre parênteses encontra-se uma lista de argumen-
tos, através dos quais a função vai receber as informações essenciais à realização do seu
trabalho.
2. O resultado dos cálculos efectuados será entregue à fórmula ou expressão que
invocou a função, depositando-o no seu próprio nome, como se este fosse uma variável.
Atentemos na seguinte fórmula:
= 10 * sin(angulo)
Para calcular a fórmula, ir-se-á multiplicar por 10 o resultado fornecido pela função
standard sin. Esta, por sua vez, para poder fornecer o resultado deverá ter recebido a
informação de qual o ângulo (neste caso em radianos) de que se quer calcular o seno.
Quando a função termina o seu trabalho, deixará o resultado do seu cálculo no lugar que
ocupava na fórmula.
Para o utilizador da função, não interessa conhecer o seu funcionamento interno, mas
apenas qual a informação que lhe tem que fornecer e qual o tipo de resultado esperado.
Assim sendo, pode dizer-se que do ponto de vista do utilizador da função, ela se comporta
como uma caixa preta, à qual é fornecida informação e que, com base nela, produz um
resultado (Figura 29 na página anterior).
51
6.1 Exemplo de função criada pelo programador
Vamos agora criar uma função que permita calcular a margem de lucro percentual de um
determinado produto sabendo o seu custo e o seu preço de venda. Supõe-se que esses
dados se encontrarão previamente armazenados em duas células da folha de cálculo. Uma
solução possível será a seguinte:
Listing 8: Função margemLucro
1 Public Function margemLucro ( venda , c u s t o )
2 margemLucro = ( venda − c u s t o ) / venda
3 End Function
Observe-se que esta função possui dois parâmetros de entrada, venda e custo, através
dos quais receberá os dados correspondentes. Note-se ainda que o resultado da expressão
que calcula a margem de lucro é atribuído directamente ao próprio nome da função. É
esse o processo pelo qual uma função consegue fornecer o resultado do seu trabalho à
entidade que a invocou.
Esta função poderá ser utilizada em qualquer fórmula contida numa célula da folha de
cálculo, das mesma maneira que qualquer das funções pré-existentes o seria. Um exemplo
de uma fórmula utilizando esta função seria a descrita na Figura 30.
52
valor médio de uma gama de células (identificada pelo nome "Dados") poderia ser usada
a seguinte instrução:
med = Application.WorksheetFunction.Average(Range("Dados"))
Esta instrução permite aceder à função standard Average do Excel, à qual é fornecido
um objecto do tipo Range, representando a gama de células descritas sob o nome "Dados".
• Usando o objecto Workbooks que representa o conjunto dos ficheiros Excel abertos
naquele momento (Workbooks(Nome));
Exemplo:
Workbooks.Open "C : \Documentos\Excel\Dados.xls"
Os métodos Save e Close são utilizados de forma similar para salvaguardar o conteúdo
dum ficheiro e para o fechar, respectivamente.
53
Worksheets("Custos")
Workbook("Dados 2007").Worksheets("Custos").Activate
Sintaxe:
Worksheet.Copy [Position]
Exemplo:
Worksheets(2).Copy After:=Worksheets(3)
54
• Worksheet.Add - permite acrescentar uma nova folha de cálculo ao livro de trabalho.
Sintaxe:
Worksheet.Add [Position]
55
Na sintaxe acima, a entidadeObjecto pode ser um objecto Worksheet ou Range. A sua
omissão, leva o VBA a partir do princípio que se trata da folha de cálculo activa. Linha
e Coluna são valores numéricos indicando qual a linha e qual a coluna na intersecção das
quais a célula se encontra20 . Veja-se o seguinte exemplo:
1 For c o l u n a = 2 To 13
2 C e l l s ( 2 , Coluna ) . Value = "Mes␣" & c o l u n a − 1
3 Next
O exemplo acima usa um ciclo For...To para preencher todas as células da gama C2 a
C13 com o texto "Mês X" em que X é o no do mês. É usado o operador de concatenação
de strings & para efectuar a colagem.
Caso se pretenda identificar uma linha ou coluna completa, podem ser utilizados os
métodos Rows e Columns.
Sintaxe:
Objecto.Rows(Indice)
Objecto.Columns(Indice)
Para ilustrar a utilização do método Rows atente-se no seguinte exemplo de sub-
rotina21 :
Listing 9: Sub-rotina InsereLinhas
1 Sub I n s e r e L i n h a s ( gama As Range , num As Integer )
2 Dim num_linhas As Integer , u l t i m a _ l i n h a As Integer
3 Dim i As Integer
4 With gama
5 num_linhas = . Rows . Count
6 u l t i m a _ l i n h a = . Rows ( num_linhas ) . Row
7 For i = 1 To num
8 . Rows ( u l t i m a _ l i n h a + i ) . I n s e r t
9 Next
10 End With
11 End Sub
Esta sub-rotina recebe como argumentos uma gama de células (um objecto do tipo
Range) e um inteiro especificando o número de linhas a inserir abaixo da última linha
dessa gama. A estrutura With...End...With é muito prática porque permite executar
um conjunto de instruções sobre um determinado objecto, neste caso qualquer objecto
Range que a sub-rotina receba como argumento. Dentro da estrutura With...End...With
omite-se qualquer referência a esse objecto, usando-se apenas os seus métodos e propri-
edades. Assim, .Rows.Count refere-se ao número total de linhas da gama especificada
e .Rows(num_linhas).Row fornece-nos o índice da última linha dessa gama. O ciclo
For...To repete num vezes a aplicação do método Insert à ultima linha da gama.
Para testar a sub-rotina InsereLinhas, use-se a seguinte rotina de teste:
20
Se o objecto for do tipo Range, os argumentos Linha e Coluna referir-se-ão à linha e à coluna dentro
da gama de células especificada.
21
Adaptado de um exemplo contido em [1].
56
1 Sub i n s e r e T e s t e ( )
2 I n s e r e L i n h a s Worksheets ( 3 ) . Range ( "Dados" ) , 3
3 End Sub
Apresentamos outro exemplo, agora referido ao método Columns:
Columns(5).ColumnWidth = 15
Aplicando o método Columns ao objecto Columns(5) (a coluna de índice 5, ou seja,
a coluna E) o efeito obtido é a mudança da sua largura para 15.
57
Figura 31: Criação de uma Form no VBA
58
Conforme referido na Secção 4.3 na página 25 no ambiente de desenvolvimento do
VBA encontram-se disponíveis diversos tipos de controlos: botões de comando (Command
Buttons), etiquetas (Labels), caixas de texto (Text Boxes), quadros (Frames), botões de
opção (Option Buttons), caixas de verificação (Check Boxes) e caixas de listagem (List
Boxes), entre outros.
1. Visualização da Form
59
um botão de comando) presente na Form. Nesta instrução, a palavra Me indica ao VBA
que a Form a desactivar será aquela a que o Event Handler diz respeito.
Um exemplo de um Event Handler que termine uma Form pode ser:
Listing 10: Handler do objecto cmdFechar para o evento click
1 Private Sub cmdFechar_Click ( )
2 Dim op As Integer
3 op = MsgBox( " S a i r ? ( Yes/No) " , vbYesNo + vbQuestion )
4 I f op = vbYes Then
5 Unload Me
6 End I f
7 End Sub
Classe Conteúdo
CheckBox True ou False conforme esteja ou não activada
OptionButton True ou False conforme esteja ou não activada
ListBox A posição da linha seleccionada
TextBox O conteúdo da TextBox (pode-se também usar a propriedade Text)
TabStrip Um inteiro indicando qual a Tab que está activa
Note-se que nas List Boxes em VBA a 1a linha tem a posição 1, ao contrário do que
se passa em Visual Basic, em que começa na posição 0.
60
dos dados de um aluno (Nome, Número e Curso) sem necessidade de recorrer a três Input
Boxes separadas.
Esta UserForm conterá duas Text Boxes para inserção do Nome e Número do aluno e
uma Combo Box para selecção do seu Curso. Uma Combo Box é um controlo semelhante
a uma List Box em que a lista está normalmente invisível, só aparecendo quando o campo
superior é activado. Aplicam-se-lhe os mesmos métodos da classe ListBox.
Listing 11: Exemplo de sub-rotina de invocação de uma UserForm
1 Public Sub testUserFormInput ( )
2 usrFrmInput . Show
3 Set usrFrmInput = Nothing
4 End Sub
61
Esta sub-rotina especial, que é executada automaticamente quando a UserForm ar-
ranca, trata de inicializar a Combo Box "cmbCursos" com os nomes dos diferentes cursos
da escola.
Listing 13: Handler do objecto cmdFechar para o evento Click
1 Private Sub cmdFechar_Click ( )
2 With Worksheets ( 4 )
3 . [ H5 ] = txtNome . Value
4 . [ I 5 ] = txtNum . Value
5 . [ J5 ] = cmbCursos . Text
6 End With
7 Unload Me
8 End Sub
Este Event Handler está associado ao botão cmdFechar e é chamado quando sobre
ele ocorre o evento Click. Antes de fechar a UserForm usando Unload, copia o conteúdo
das duas Text Box e o da linha seleccionada da Combo Box para três células contíguas
da folha de cálculo.
Numa Tabstrip é usual inserirem-se outros controlos, um pouco como se faria numa
mini-Form ou num quadro. No exemplo da figura, encontram-se três TextBox.
Conforme referido na Secção 4.1, para que um controlo possa reagir a acções pro-
vocadas pelo utilizador, como o "clicar" do rato, é preciso que o programador crie sub-
62
programas especiais, chamados Event Handlers e que esses sub-programas sejam associ-
ados aos controlos respectivos.
Vamos apresentar dois exemplos de Event Handlers, sub-programas que permitem
especificar o comportamento de controlos em face de certos eventos. Em 1o lugar,
apresentar-se-á o Event Handler da form "UserForm2" para o evento Initialize, que ocorre
quando a form é criada após o arranque do programa:
Listing 14: Sub-rotina de inicialização da UserForm
1 Private Sub U s e r F o r m _ I n i t i a l i z e ( )
2 With TabStrip1
3 . Tabs ( 0 ) . Caption = " C i v i l "
4 . Tabs ( 1 ) . Caption = " I n f o r m a t i c a "
5 . Tabs .Add " E l e c t r o t e c n i a "
6 End With
7 With Worksheets ( 4 )
8 txtNumAlunos . Text = . [ D5 ]
9 txtPercAprov . Text = . [ D6 ] ∗ 100
10 txtMedia . Text = . [ D7 ]
11 End With
12 End Sub
Este procedimento vai inicializar os dois separadores do controlo Tabstrip1 com que
ele é criado por defeito, mudando-lhe os nomes para "Civil" e "Informática". De seguida,
acrescenta um terceiro separador e dá-lhe o nome "Electrotecnia". Por fim, são atribuídos
a cada uma das TextBox contidas na Tabstrip1 os conteúdos das três células da folha de
cálculo referentes ao curso referente ao 1o separador.
O próximo procedimento é o Event Handler do controlo Tabstrip1 para o evento
Change que ocorre sempre que alguma alteração ocorre nesse controlo, concretamente,
uma mudança de separador activo.
Listing 15: Handler associado ao objecto Tabstrip1 para o evento Change
1 Private Sub TabStrip1_Change ( )
2 Dim v As Integer
3 With Worksheets ( 4 )
4 v = TabStrip1 . Value
5 I f v = 0 Then
6 txtNumAlunos = . [ D5 ]
7 txtPercAprov = . [ D6 ] ∗ 100
8 txtMedia = . [ D7 ]
9 E l s e I f v = 1 Then
10 txtNumAlunos = . [ E5 ]
11 txtPercAprov = . [ E6 ] ∗ 100
12 txtMedia = . [ E7 ]
13 Else
14 txtNumAlunos = . [ F5 ]
15 txtPercAprov = . [ F6 ] ∗ 100
63
16 txtMedia = . [ F7 ]
17 End I f
18 End With
19 End Sub
A propriedade Value dos objectos Tabstrip contem um valor numérico inteiro que
traduz qual o separador que está activo. Em função do valor recolhido na variável v, a
estrutura condicional imbricada If...Then...Else irá escolher o conjunto de valores corres-
pondente.
9 Notas finais
Parte da estrutura e alguns dos exemplos apresentados foram inspirados no livro de Paul
McFreddies[1]. Foram ainda reutilizados e adaptados materiais contidos na Sebenta de
Introdução à Computação da minha autoria[2].
Referências
[1] Paul McFredies. VBA for the Microsoft Office System, QUE.
64