Você está na página 1de 61

Programar em Visual Basic

Antnio Ramires Fernandes Departamento de Informtica Universidade do Minho 2001

1/61

DEFINIES BSICAS ........................................................................................... 4

1.1 VARIVEIS ................................................................................................................. 4 1.1.1 DECLARAO DE VARIVEIS ................................................................................... 5 1.2 CONSTANTES ............................................................................................................. 5 1.2.1 DECLARAO DE CONSTANTES ................................................................................ 5 1.3 EXPRESSES .............................................................................................................. 5 1.3.1 EXPRESSES NUMRICAS ......................................................................................... 6 1.3.2 EXPRESSES BOOLEANAS ........................................................................................ 7 1.3.3 EXPRESSES DO TIPO STRING................................................................................. 10 2 PROGRAMAO.................................................................................................... 11 2.1 ATRIBUIES ........................................................................................................... 11 2.1.1 EXEMPLOS ............................................................................................................. 11 2.2 COMENTRIOS ......................................................................................................... 12 2.3 INSTRUES CONDICIONAIS ................................................................................... 13 2.3.1 INSTRUES IF ...................................................................................................... 13 2.3.2 INSTRUO SELECT CASE.................................................................................. 19 2.4 FUNES .................................................................................................................. 21 2.5 COLECES ............................................................................................................. 25 2.6 INSTRUES CCLICAS ............................................................................................ 26 2.6.1 CICLOS FOR EACH .............................................................................................. 26 2.6.2 CICLOS FOR .......................................................................................................... 30 2.6.3 CICLOS WHILE ..................................................................................................... 36 2.6.4 ANLISE COMPARATIVA DE INSTRUES CCLICAS ............................................... 42 3 APLICAO DO VISUAL BASIC EM EXCEL.................................................. 44 3.1 INTRODUO AOS CONCEITOS DO EXCEL .............................................................. 44 3.1.1 REFERNCIAS A CLULAS NA FOLHA DE CLCULO................................................ 46 3.1.2 REFERENCIA A CLULAS NOUTRAS FOLHAS DE CLCULO ....................................... 50 3.2 COLECES DE CLULAS........................................................................................ 53 3.3 EXEMPLOS DE APLICAO DO VB AO EXCEL ........................................................ 54 3.4 EXEMPLOS AVANADOS.......................................................................................... 58

2/61

3/61

1 Definies Bsicas
Programar consiste em definir uma sequencia de comandos para o computador executar. Tipos de dados simples tipos Boolean Integer Long Single Variant String valores possveis True, False nmeros inteiros de -32768 a 32767 nmeros inteiros de 2.147.483.648 a 2.147.483.647 nmeros reais com limites muito grandes qualquer valor texto de comprimento varivel

1.1 Variveis
identificadores definidos pelo programador para armazenar valores Uma varivel tem sempre associado, explicitamente ou implicitamente, um tipo de dados. Os valores armazenados nas variveis podem ser alterados durante o programa. Os identificadores das variveis podem ser compostos por letras e nmeros e alguns caracteres especiais. Os caracteres no permitidos so o espao, !,@,&,$ e #. Para alem disso todos identificadores de variveis devem comear por uma letra Exemplos de identificadores invlidos: A minha morada 1aluno a#2 Exemplo de identificadores vlidos: aMinhaMorada a_minha_morada um_aluno umAluno a_2 Para efeitos de legibilidade do programa os identificadores devem ser escolhidos de forma a indicar qual o significado dos valores armazenados nas variveis associadas. Por
4/61

utiliza espaos comea por um nmero utiliza o caracter #

exemplo ao definir uma varivel para armazenar um nmero de aluno, os seguintes identificadores tm sentido: numAluno num Ao usar um dos indicadores acima a legibilidade do programa aumenta. Por outro lado se utilizssemos identificadores como por exemplo a ou x12 a dificuldade de leitura do programa seria aumentada desnecessariamente.

1.1.1 Declarao de variveis


Por regra de boa programao deve-se sempre declarar as variveis no inicio da sequencia de instrues. Por exemplo caso se pretenda utilizar um texto no programa deve-se escrever: Dim oMeuTexto As String Para declarar uma varivel que contenha como valor um numero escreve-se Dim umNumero As Integer Sintaxe: Dim identificador As tipo em que tipo tem de representar um tipo de dados vlido. Dim e As so palavras reservadas do vocabulrio do Visual Basic.

1.2 Constantes
identificadores definidos pelo programador para armazenar valores fixos Uma constante no pode ser alterada durante a execuo do programa. A utilizao de constantes permite escrever programas mais legveis e mais fceis de alterar.

1.2.1 Declarao de constantes


A declarao de uma constante implica, para alm da indicao do identificador e do seu tipo, a atribuio de um valor. Sintaxe: Public Const identificador As tipo = valor Public, Const e As so palavras reservadas do vocabulrio do Visual Basic. Exemplos: Public Const maxAlunosPrticas As Integer = 40

1.3 Expresses
Em termos genricos uma expresso um conjunto de operaes ou simplesmente um valor. O tipo de uma expresso o tipo de dados do valor do seu resultado.
5/61

Note-se que os tipos de dados das variveis que integram a expresso no tm necessariamente de ter o mesmo tipo do resultado da expresso. Por exemplo uma expresso que calcule o comprimento de um texto devolve um resultado inteiro, sendo portanto do tipo Integer ou Long. No entanto a varivel presente na expresso, cujo valor o texto do qual se pretende saber o comprimento, do tipo de dados String.

1.3.1 Expresses numricas


Uma expresso pode ser simplesmente um valor: 12723 Uma expresso pode tambm representar uma operao b*2 O smbolo * representa o operador da multiplicao. Uma expresso pode conter varias operaes, por exemplo: b*2+c No exemplo acima apresentado o resultado ambguo. Por um lado pode-se interpretar a expresso como sendo o valor de c mais o dobro do valor de b ou ento o valor de b multiplicado pela soma de 2 e c As duas interpretaes podem levar a resultados diferentes. Por exemplo considerando que o valor de b 3 e o valor de c igual a 2 teramos como resultados 8 e 12 para a primeira e segunda interpretaes respectivamente. O Visual Basic, perante uma expresso com vrias operaes, executa as operaes pela ordem determinada pela precedncia dos operadores, a ordem em que as operaes so descritas irrelevante. Para o Visual Basic a multiplicao e diviso tem precedncia sobre a adio e subtraco, sendo assim a interpretao que o Visual Basic adopta na expresso acima a primeira: primeiro realiza a multiplicao e depois a adio. Pe-se agora a seguinte questo: e se a interpretao pretendida fosse a segunda? Nesse caso necessrio utilizar parntesis para definir a expresso: a = b * (2 + c) O Visual Basic interpreta os parntesis como tendo precedncia mxima, ou seja primeiro realiza as operaes definidas dentro dos parntesis. Outros operadores teis so o mdulo, mod, e a diviso inteira \. Estes operadores permitem realizar operaes sobre nmeros inteiros (caso sejam utilizados nmeros reais estes so arredondados automaticamente para efeitos de clculo). O operador \ realiza a diviso inteira entre dois nmero, por exemplo: 5\2 d como resultado 2
6/61

10 \ 6 d como resultado 1

O operador mod devolve como resultado da operao o resto da diviso inteira, por exemplo: 5 mod 2 10 mod 6 d como resultado 1 d como resultado 4

Tabela dos operadores aritmticos: operador + * / \ mod significado adio subtraco multiplicao diviso diviso inteira resto da diviso inteira

1.3.2 Expresses Booleanas


As expresses booleanas so extremamente utilizadas na programao. Estas expresses baseiam-se nos operadores de comparao e nos operadores booleanos. Os operadores booleanos mais relevantes so os seguintes: operador NOT AND OR XOR significado Negao Conjuno (e) Disjuno (ou) Disjuno Exclusiva

O operador NOT aplicvel a uma varivel ou expresso booleana. O seu resultado a negao do valor do seu argumento. NOT x NOT expresso booleana so expresses vlidas. O resultado ser True se o argumento for False, e vice-versa.

7/61

Em Portugus o correspondente seria a palavra NO. Ou seja, a frase "no fui ao cinema" falsa se de facto fui ao cinema, ou seja se o argumento "fui ao cinema" for verdadeiro. O operador AND um operador binrio, isto realiza uma operao com duas expresses booleanas. Supondo que x e y so variveis ou expresses booleanas a expresso x AND y uma expresso vlida. O resultado desta expresso depende do valor de x e y, s sendo True (Verdade) no caso em que ambos x e y sejam True. A tabela seguinte apresenta o resultado da expresso para os valores possveis de x e y. valor de y False valor de x False True False False True False True

Em Portugus o correspondente seria a palavra E. Ou seja a frase "A Maria comprou o casaco e o guarda-chuva" s verdade se de facto ambos o casaco e o guarda-chuva foram comprados. Sendo falsa se nada se comprou, ou se s um dos artigos foi comprado. O operador OR, semelhana do operador AND, tambm um operador binrio. O resultado desta operao True se pelo menos uma das expresses for True. A sua tabela de resultados x OR y valor de y False valor de x False True False True True True True

Em Portugus o correspondente mais prximo seria a palavra OU. A frase "o Joo vai ao cinema ou ao pub" ser verdade se o Joo for ao cinema ou se o Joo for ao pub. Note-se que no entanto que a interpretao relativamente ambgua no caso em que o Joo visitou ambos os locais, j que a frase pode implicitamente querer dizer que o Joo ir somente a um local. Por exemplo uma me pode dizer a um filho "levas o Homem Aranha ou o Power Ranger", querendo implicitamente dizer que ambos os brinquedos esto fora de questo mas que um deles est garantido. O significado da frase depende do
8/61

contexto em que ela proferida. No caso dos brinquedos, o operador apropriado em Visual Basic o XOR. O operador XOR tambm um operador binrio. O seu resultado True quando um e s um dos seus argumentos for True. Se ambos forem False, ou se ambos forem True o resultado False. A sua tabela de resultados a seguinte: x XOR y valor de y False valor de x False True False True True True False

Relativamente s precedncias a ordem a seguinte: 1. NOT 2. AND 3. OR 4. XOR Seguem-se alguns exemplos: Na expresso NOT b AND c primeiro calcula-se a negao de b (NOT), e seguidamente a conjuno(AND). Na expresso a OR b AND c primeiro calcula-se a conjuno (b AND c) e depois a disjuno (OR). 1.3.2.1 Operadores de Comparao Uma expresso booleana pode tambm ser construda custa de operadores de comparao. Alguns dos operadores de comparao definidos so os seguintes: operador < <= exemplo a<b a <= b resultado Verdade se a for menor que b Verdade se a for menor ou igual a b
9/61

> <= <> = Alguns exemplos: c*2>3 c <= a + b

a>b a >= b a <> b a=b

Verdade se a for maior que b Verdade se a for maior ou igual a b Verdade se a for diferente de b Verdade se a for igual a b

Note-se que os operadores aritmticos tm precedncia sobre todos os operadores de comparao. Ou seja primeiro efectuam-se os clculos e depois as comparaes. possvel combinar os operadores booleanos e de comparao numa expresso booleana. Por exemplo: c < b AND c < a a expresso acima s ser verdade se c for o menor dos trs valores: a, b e c. Exemplos: definir a expresso que dado uma varivel nota inteira do tipo Integer que representa uma nota devolva um resultado booleano que indique se a varivel maior ou igual a 10. nota > 10

1.3.3 Expresses do tipo String


Utilizando operadores, s existe um tipo de operao sobre Strings: concatenao. A concatenao consiste em juntar dois textos. "ol" & " mundo" tem como resultado "ol mundo" A concatenao pode tambm ser realizada com o operador "+".

10/61

2 Programao
Programar consiste em definir uma sequncia de instrues, ou comandos. As instrues so seguidas letra pelo computador por isso necessrio muito cuidado ao escrev-las. Dentro dos tipos de instrues existentes, os seguintes sero abordados nesta cadeira: Atribuies Condicionais Cclicas

2.1 Atribuies
Instruo que atribui a uma varivel o valor de uma expresso. O resultado da expresso tem de ser do mesmo tipo que a varivel. Sintaxe identificador = expresso As seguintes atribuies so vlidas
Dim Dim a = b = a As Integer b As Integer 3 a + 2

2.1.1 Exemplos
Definir a atribuio de forma a que a varivel a fique com o dobro do valor de b
Dim a As Integer Dim b As Integer a = 2 * b

Definir uma instruo que atribua varivel positiva o valor True se a varivel nota for superior a 9

Dim positiva As Boolean Dim nota As Integer positiva = nota > 9

Definir uma instruo que atribua varivel preoFinal a expresso que multiplica um determinado preo de custo, representado pela varivel preoCusto, por uma margem de lucro de 10%, e pelo IVA de 17%.

Dim preoFinal As Single preoFinal = preoCusto * 1.1 * 1.17

11/61

Por razes de clareza neste ltimo exemplo poderamos optar por uma soluo mais longa mas mais legvel:
Dim preoFinal As Single Public Const IVA As Single = 1.17 Public Const MargemLucro As Single = 1.1 preoFinal = preoCusto * Margem * IVA

Clculo da nota final de programao Informtica

Dim tp1, tp2, nt1, nt2 As Integer Dim notaFinal As Integer notaFinal = (tp1 + tp2 + nt1 + nt2) / 4

Nota: este clculo no corresponde completamente realidade da actual cadeira.

2.2 Comentrios
Os comentrios na programao so pequenas notas em linguagem corrente includas no texto do programa que facilitam a leitura do programa pelos programadores. A utilizao dos comentrios uma prtica que se recomenda vivamente. Os comentrios no fazem parte do programa propriamente dito, sendo inclusivamente ignorados pelo compilador ou interpretador. No entanto a sua utilizao fundamental para a boa programao. Para inserir um comentrio em Basic escreve-se o smbolo ' seguido do texto do comentrio. O Basic ao encontrar este smbolo ignora o texto dessa linha a partir do local onde o smbolo foi encontrado. Para escrever um comentrio com vrias linhas deve-se colocar o smbolo em todos as linhas. Exemplo:
' Isto um comentrio Dim a As Integer 'O meu segundo comentrio ' tem duas linhas a = 3

Atravs de comentrios possvel documentar o texto do programa de forma a facilitar a sua leitura. A titulo de exemplo vejamos o seguinte excerto de um programa sem comentrios: n = (t1+t2+p1+p2) / 4 em seguida apresentada a verso comentada:
' o nmero mdio de alunos na sala a mdia dos nmeros das aulas ' tericas e prticas para os dois turnos n = (t1+t2+p1+p2) / 4
12/61

2.3 Instrues Condicionais


Por vezes conveniente garantir que determinada sequencia de instrues s executada em determinadas circunstancias. Por exemplo, podemos dizer que os alunos que obtiveram uma nota terica superior a 18 merecem um bnus de 1 valor. Sendo assim a atribuio do bnus estaria condicionada pelo valor da nota terica.

2.3.1 Instrues IF
Em Visual Basic existe uma forma de definir instrues condicionais utilizando a instruo IF. A sintaxe desta instruo a seguinte: If expresso booleana Then ... sequencia de instrues End If Nesta instruo, a sequencia de instrues definida no seu interior s executada quando a expresso booleana for verdadeira. Assumindo que temos o valor da nota terica e prtica nas variveis teo e prat, respectivamente, podemos expressar a expresso booleana que traduz o facto "nota terica superior a 18" por teo > 18 O excerto de cdigo para realizar esta atribuio condicional poderia ser o seguinte: ...
nota = (teo + prat) / 2 If teo > 18 Then nota = nota + 1 End If

Note-se que no exemplo acima possvel obter uma nota incorrecta, se um aluno tiver 20 valores de nota final, com o bnus ficara com 21. Ao programar necessrio prever estes casos que potencialmente podem gerar erros e resolve-los atempadamente. Para um bom funcionamento de um programa crucial prever todas as situaes passveis de gerar erros. No exemplo acima poder-se-ia resolver o problema de duas formas: 1. atribuir o bnus aos alunos cuja nota terica seja superior a 18 obtendo assim a nota final bonificada. Caso esta nota seja superior a 20 valores ento o valor da nota bonificada seria reduzida para 20 valores garantindo assim que no final da operao a nota vlida. 2. atribuir o bnus aos alunos cuja nota terica fosse superior a 18, somente nos casos em que a nota final seja menor que 20 valores garantindo assim que a nota nunca assume valores incorrectos.
13/61

O cdigo correspondente soluo 1 o seguinte:


nota = (teo + prat) / 2 ' Primeiro atribui-se o bnus If teo > 18 Then nota = nota + 1 End If ' Depois verifica-se se a nota vlida If nota > 20 Then nota = 20 End If

O cdigo da soluo 2 de seguida apresentado:


nota = (teo + prat) / 2 ' Aqui s se altera a nota nos casos em que a alterao no conduz a ' uma nota invlida If (teo > 18) AND (nota < 20) Then nota = nota + 1 End If

Note-se que neste caso trivial definir o caso em que a atribuio de bnus leva a uma nota invlida, no entanto nem sempre assim. Por vezes a soluo preventiva (soluo 2) demasiado complexa, sendo prefervel a soluo "curativa" (soluo 1). Considere-se agora a expresso para clculo do preo de venda de um determinado produto. Anteriormente foi apresentada uma expresso da seguinte forma:
Dim preoFinal, preoCusto As Single Public Const IVA As Single = 1.17 Public Const MargemLucro As Single = 1.1 preoFinal = preoCusto * Margem * IVA

Assuma agora que o preo final pode ter um desconto de 5 ou 10 por cento, conforme o valor da varivel preoFinal seja inferior a 100.000$, caso em que o desconto de 5%, ou o preoFinal seja igual ou superior a 100.000$, caso em que o desconto de 10%. Pode-se reescrever o programa da seguinte forma utilizando instrues condicionais:
Dim preoFinal, preoCusto, desconto As Single Public Const IVA As Single = 1.17 Public Const MargemLucro As Single = 1.1 preoFinal = preoCusto * Margem * IVA ' Se o valor for igual ou superior a 100 contos o ' desconto de 10%
14/61

If (preoFinal >= 100000) Then desconto = 0.9 End If ' Se o valor for inferior a 100 contos o ' desconto de 5% If (preoFinal < 100000) Then desconto = 0.95 End If ' Clculo do preo final com desconto preoFinal = preoFinal * desconto

Note-se no entanto que a atribuio de descontos exclusiva, isto uma venda tem um desconto de 10% ou de 5%, mas nunca de ambos. A analise das condies de ambas as instrues condicionais reflecte este facto. Se uma das condies for True ento a outra ser False. A exclusividade no exemplo acima implicitamente definida pelas expresses condicionais utilizadas. Nestes casos, convm tornar a exclusividade explicita, ou seja em vez de escrever: se o preo for inferior a 100000 ento o desconto de 5% se o preo for superior ou igual a 100000 ento o desconto de 10% deve-se escrever: se o preo for inferior a 100000 ento o desconto de 5%, seno o desconto de 10% Em Visual Basic a ultima alternativa corresponde a escrever:
If (preoFinal < 100000) Then desconto = 0.95 Else desconto = 0.90 End If

A sintaxe geral a seguinte:


If expresso Then sequencia de instrues A Else sequencia de instrues B End If

A primeira sequencia de instrues, A, executada quando a expresso definida for verdadeira. A segunda sequencia de instrues, B, executada sempre que a expresso definida seja falsa.
15/61

Considere-se agora que as condies de atribuio de descontos eram as seguintes:


preo final desconto

< 100 contos >= 100 e < 1000 >= 1000

0 5% 10%

O excerto de cdigo para clculo do desconto poderia ser escrito da seguinte forma:
1 2 3 4 5 6 7 ' Sem desconto desconto = 1 ' Atribuio dos descontos para valores superiores a 100 contos If (preo >= 1000) Then desconto = 0.90 Else If (preo >= 100) Then desconto = 0.95 End If preoFinal = preo * desconto

Nota: os nmeros de linha no devem ser escritos no Visual Basic. Note-se que no exemplo acima a instruo Else tambm leva uma expresso booleana. Esta expresso traduz uma condio parcial para atribuio do desconto de 5%. Note-se que a expresso completa implicaria testar se o valor inferior a 1000 contos. No entanto a escrita da expresso completa desnecessria uma vez que a segunda condio (preo >= 100) s ser testada caso a expresso booleana definida na primeira condio (preo >= 1000) seja falsa. De seguida ir-se- simular o comportamento do Visual Basic ao executar o excerto de cdigo acima apresentado. Para tal define-se uma tabela com a seguinte estrutura: nmero de linha actual valor actual das variveis desconto e preoFinal aps a execuo da linha (um trao representa indefinido). observaes

Considera-se neste exemplo que o valor de preo 5000 contos.


num 1 2 desconto 1 1 preofinal obs. atribuio varivel desconto do valor 1 Teste se o valor de preo maior ou igual a 1000. Esta condio verdadeira., logo a linha seguinte a linha 3 atribuio varivel desconto do valor 0.9. Aps a execuo desta instruo terminou-se o bloco
16/61

0.9

de cdigo para a condio (preo >= 1000) a instruo If terminada e a linha seguinte a linha que contem End If 6 7 0.9 4500 atribuio varivel preoFinal

Neste caso o Visual Basic executaria as linhas 1,2,3,6 e 7. A excluso das restantes linhas deveu-se ao facto da a primeira condio da instruo If ser verdadeira. A tabela seguinte representa a simulao da execuo do Visual Basic no caso em que o preo de 300 contos.
num 1 2 desconto 1 1 preofinal obs. atribuio varivel desconto do valor 1 Teste se o valor de preo maior ou igual a 1000. Esta condio falsa., logo a linha seguinte a linha 4, onde se definiu a segunda condio. Esta condio verdadeira, 300 >= 100, logo o bloco de instrues associado vai ser executado atribuio varivel desconto do valor 0.95. Aps a execuo desta instruo terminou-se o bloco de cdigo para a condio (preo >= 1000) a instruo If terminada e a linha seguinte a linha que contem End If atribuio varivel preoFinal

4 5

1 0.95

6 7

0.95 0.95

285

Finalmente considere-se o caso em que o valor da varivel preo de 50 contos.


num 1 2 desconto 1 1 preofinal obs. atribuio varivel desconto do valor 1 Teste se o valor de preo maior ou igual a 1000. Esta condio falsa., logo a linha seguinte a linha 4, onde se definiu a segunda condio. Esta condio tambm falsa, uma vez que 50 < 100. Sendo assim, e por no estarem definidas mais condies a instruo If termina sem nunca executar nenhum dos blocos de instrues nela definidos. atribuio varivel preoFinal

6 7

1 1

50

Como se pode ver pelas trs simulaes acima apresentadas o percurso de execuo do Visual Basic depende da verificao de condies presentes em instrues If, podendo
17/61

executar um s bloco, ou nenhum no caso em que todas as expresses definidas sejam falsas.

booleanas

Retornando ao exerccio apresentado acima, uma outra alternativa para a escrita do cdigo seria:
If (preo >= 1000) Then desconto = 0.90 Else If (preo >= 100) Then desconto = 0.95 Else desconto = 1 End If

O ultimo Else no apresenta nenhuma condio. A sequencia de instrues associada (desconto = 1) executada sempre que todas as condies especificadas anteriormente (preo >= 1000 e preo >= 100 ) sejam falsas. No caso genrico a sintaxe da instruo If pode ser sumariada da seguinte forma:
If condio1 Then sequencia de instrues 1 Else If condio 2 Then sequencia de instrues 2 Else If condio 3 Then sequencia de instrues 3 ... Else If condio n Then sequencia de instrues n Else sequencia de instrues n+1 End If

sendo o ultimo Else opcional. Note-se que s o ultimo Else pode prescindir de expresso. No caso geral em que existe um Else sem ter expresso definida sempre executada uma e s uma sequencia de instrues. Caso o ultimo Else tambm tenha uma expresso ento possvel que nenhuma sequencia de instrues seja executada se todas as condies forem falsas. Finalmente convm referir que existe a possibilidade de construir instrues condicionais dentro de instrues condicionais. A titulo de exemplo vejamos uma outra forma de escrever a instruo If no caso dos descontos:
If (preo >= 1000) Then desconto = 0.90 Else ' Vamos agora calcular o desconto caso o preo seja inferior a 1000 If (preo >= 100) Then desconto = 0.95
18/61

Else End If

desconto = 1

End If

2.3.2 Instruo SELECT CASE


O exemplo seguinte apresenta um excerto de cdigo para determinar qual o nmero de dias de um determinado ms ignorando o caso dos anos bissextos. Assume-se que a varivel ms um inteiro cujo valor se situa entre 1 e 12 inclusive.
If (mes=1 OR mes=3 OR mes=5 OR mes=7 OR mes=8 OR mes=10 OR mes=12) Then dias = 31 Else If mes=4 OR mes=6 OR mes=9 OR mes=11 Then dias = 30 Else dias = 29 End If

Note-se que o exemplo acima no est escrito da forma mais eficiente. Como exerccio procure reescreve-lo de uma forma mais eficiente Neste caso a instruo If est dependente de uma varivel, ou seja todas as expresses se referem varivel ms. Nestes casos possvel utilizar uma outra instruo fornecida pelo Visual Basic de forma a obter um excerto de cdigo mais compacto e simultaneamente mais legvel.
1 2 3 4 5 Select Case (mes) Case 1, 3, 5, 7, 8, 10, 12: dias = 31 Case 4, 6, 9, 11: dias = 30 Case Else: dias = 29 End Select

A primeira linha define qual a varivel que ser utilizada nas expresses definidas dentro da instruo Select Case. As linhas 2 e 3 utilizam o valor desta varivel e comparam-no com os valores definidos nas listas. Se o valor da varivel ms for igual a um dos valores da lista a instruo correspondente executada e o programa termina a instruo Select Case. A ultima linha (Case Else) aplicada nos casos em que o valor da varivel mes no se encontra em nenhuma das listas apresentadas. agora apresentado uma simulao de execuo considerando que o ms Abril, ou seja 4.
num 1 2 3 dias 30 obs. Inicio da instruo Select Case O valor 4 no se encontra na enumerao desta linha logo passa-se linha seguinte. O valor 4 encontra-se presente nesta enumerao logo a instruo associada executada. Uma vez que o valor se encontra presente na enumerao aps a execuo da
19/61

instruo associada a instruo Select Case termina. 5 1 Fim da instruo Select Case

agora apresentado uma simulao de execuo considerando que o ms Fevereiro, ou seja 2.


num 1 2 3 4 dias 29 obs. Inicio da instruo Select Case O valor 4 no se encontra na enumerao desta linha logo passa-se linha seguinte. O valor 4 no se encontra na enumerao desta linha logo passa-se linha seguinte. Esta linha especifica a sequencia de instrues a ser executada caso todas as outras condies Case no sejam satisfeitas. Aps a execuo da instruo associada a instruo Select Case termina. Fim da instruo Select Case

A sintaxe deste comando permite um elevado nmero de variaes. Por exemplo, possvel definir um nmero entre 1 e 5 de duas formas: Enumerando os possveis valores Case 1,2,3,4,5: sequencia de instrues Definindo um intervalo Case 1 To 5: sequencia de instrues

A titulo de exemplo considere-se que se pretende traduzir um valor numrico, correspondente a uma nota, para um texto que atribui uma categoria classificao obtida:
1 2 3 4 5 6 7 Select Case (nota) Case 1 To 5: categoria = Case 6 To 9: categoria = Case 10 To 13: categoria Case 14 To 17: categoria Case 18 To 20: categoria End Select "Medocre" "Insuficiente" = "Suficiente" = "Bom" = "Muito Bom"

Considere-se o exemplo hipottico em que a nota era 21. Apresenta-se em seguida a simulao da execuo do Visual Basic para este caso.
num 1 categoria obs. Inicio da instruo Select Case
20/61

2 3 4 5 6 7

O valor 21 no se encontra no intervalo desta linha logo passa-se linha seguinte. O valor 21 no se encontra no intervalo desta linha logo passa-se linha seguinte. O valor 21 no se encontra no intervalo desta linha logo passa-se linha seguinte. O valor 21 no se encontra no intervalo desta linha logo passa-se linha seguinte. O valor 21 no se encontra no intervalo desta linha logo passa-se linha seguinte. Fim da instruo Select Case

Neste caso o valor de categoria permanece indefinido j que nenhuma das instrues definidas no interior da instruo Select Case foi executada. possvel misturar numa mesma expresso Select Case vrios tipos de condies: por enumerao e intervalo. O exemplo seguinte utiliza ambas as construes para reescrever o exemplo anterior.
Select Case (nota) Case 1 To 5 : categoria = "Medocre" Case 6 To 9: categoria = "Insuficiente" Case 10 To 13: categoria = "Suficiente" Case 14 To 17: categoria = "Bom" Case 18,19,20 : categoria = "Muito Bom" End Select

As vantagens desta instruo sobre a instruo If so evidentes neste caso. O cdigo necessrio utilizando instrues If seria muito mais longo e menos claro. A titulo de exerccio reescreva utilizando instrues If o cdigo acima apresentado.

2.4 Funes
At agora todos os exemplos apresentados continham expresses que trabalhavam somente com operadores. Embora o conjunto de operadores definidos seja significativo, a especificao de uma tarefa pode tornar-se longa e pouco clara. medida que os programas crescem, a sua legibilidade diminui forosamente. A estratgia para lidar com este tipo de situaes consiste em dividir o problema original em problemas mais pequenos, repetindo se necessrio o processo de diviso de forma a que no final cada um dos sub problemas identificados seja simples e fcil de implementar. Atravs desta estratgia consegue-se escrever programas para resolver problemas extremamente complicados. Devido diviso do problema original em sub problemas a legibilidade do programa aumenta consideravelmente permitindo assim que os erros de implementao sejam eliminados de uma forma mais fcil.
21/61

Outra situao que ocorre geralmente na implementao da soluo de problemas consiste na reutilizao de excertos de cdigo. Por exemplo um determinado excerto de cdigo pode ser utilizado diversas vezes no mesmo programa. desejvel que se possa escrever esse mesmo excerto uma s vez e reutiliza-lo sempre que necessrio. Quase todas as linguagens de programao oferecem um mecanismo que permite agrupar uma sequencia de instrues de forma a que esta possa ser utilizada durante o programa de forma simples e clara. Em Visual Basic um destes mecanismos so as funes. Atravs da utilizao de funes pode-se dividir o cdigo de um programa em fragmentos, sendo cada um deles idealmente de dimenso reduzida e portanto potencialmente de melhor legibilidade. A sintaxe geral da construo de funes a seguinte:
Function nome() sequencia de instrues End Function

Uma funo recebe um nmero de argumentos e devolve um e um s resultado. O exerccio do clculo da nota agora revisitado de forma a solucionar o mesmo incorporando funes. O objectivo dividir o problema original em sub problemas e utilizar uma funo para resolver cada um dos sub problemas identificados. Apresenta-se de seguida o cdigo utilizado anteriormente para resolver este problema.
If ( frequncia terica Else terica End If nota = (terica > exame ) Then = frequncia = exame + prtica) / 2

O problema original pode-se dividir em dois sub problemas: 1. clculo da nota terica: mximo da nota de frequncia e exame 2. clculo da nota final: mdia da nota terica e prtica. Sendo assim os dois sub problemas identificados so calcular o mximo de dois nmeros e calcular a mdia de dois nmeros. Considere-se a funo para calcular o mximo dos valores contidos em duas variveis. Neste caso os parmetros sero as variveis, o resultado ser o mximo dos valores aceites como parmetro. Function mximo(a, b) ' definir uma varivel para armazenar o valor pretendido Dim aux ' clculo do mximo de dois valores
If (a > b ) Then
22/61

Else End If

aux = a aux = b

' o resultado pretendido esta armazenado em aux ' para devolve-lo atribui-se ao nome da funo o valor de aux mximo = aux End Function

Como se pode ver no exemplo acima apresentado o Visual Basic utiliza o nome da funo dentro do cdigo com um objectivo particular: indicar qual o valor a ser devolvido. No esquecer que uma funo tem sempre um e um s resultado. A sintaxe para indicar qual o resultado da funo em Visual Basic consiste em atribuir ao nome da funo o valor pretendido. A funo para calcular a mdia de dois nmeros tambm tem dois argumentos. O cdigo apresentado a seguir:
Function mdia(a, b) mdia = (a + b) / 2 End function

agora apresentado o cdigo que utiliza as funes acima definidas para resolver o problema original:
terica = mximo(frequncia, exame) nota = mdia(terica, prtica)

Note-se que ao definir as funes mximo e mdia utilizou-se variveis com nomes distintos da sua utilizao. Ao definir uma funo, os nomes das variveis so da escolha do programador, no tendo relao nenhuma com os nomes que posteriormente se utilizam na sua invocao. Mesmo que se os nomes fossem iguais, para o Visual Basic seriam variveis distintas. O Visual Basic estabelece a relao necessria entre os argumentos da utilizao e parmetros da definio ao utilizar a funo. Por exemplo na primeira linha do ultimo excerto de cdigo apresentado o Visual Basic ir "invocar" a funo mximo com os argumentos frequncia e exame. Esta funo tem dois parmetros a e b. Neste caso o Visual Basic estabelece a relao entre frequncia e a, e entre exame e b. O ultimo excerto de cdigo apresentado poderia por sua vez ser tambm parte de uma funo:
Function nota( frequncia, exame, prtica) terica = mximo(frequncia, exame) nota = mdia(terica, prtica) End Function
23/61

Sendo assim de onde vem os valores das variveis argumento da funo? Talvez de outra funo que por sua vez utilize esta funo, ou ento de uma folha de clculo Excel. Embora existam outras alternativas, o seu estudo no ser realizado no mbito desta cadeira. A funo nota acima apresentada em cima, apresenta um grau de abstraco elevado para o problema original, o clculo de uma nota com base na frequncia, exame e prtica. Assumindo que os nomes atribudos s funes tem algum significado, ao ler a funo sabe-se que a nota terica o mximo entre a frequncia e o exame. Sabe-se tambm que a nota final a mdia da nota terica e prtica. Tudo isto sem entrar em pormenores de como calcular o mximo e a mdia. Ou seja a leitura da funo acima apresentada fornece tanta informao como a leitura do cdigo completo, apresentado de seguida, sem utilizar funes.
If ( frequncia terica Else terica End If nota = (terica > exame ) Then = frequncia = exame + prtica) / 2

Este um dos objectivos das funes: permitir a escrita de programas facilmente legveis. Outro objectivo tambm muito importante permitir a utilizao de um excerto de cdigo parametrizado (ou seja uma funo com parmetros) mltiplas vezes num programa sem reescrever o excerto utilizado. Para ilustrar este ponto ir-se- aumentar o exerccio do clculo da nota definido anteriormente. Considere que a nota de frequncia calculada com base nas frequncias de Fevereiro e Junho. assuma que as classificaes obtidas nas frequncias est armazenada nas variveis fev e jun para a primeira e segunda frequncia respectivamente. Considere ainda que a nota prtica a mdia dos dois trabalhos prticos, cujas classificaes esto armazenadas nas variveis tp1 e tp2. Sendo assim o seguinte excerto de cdigo sem funes resolve o problema:
prtica = (tp1 + tp2) / 2 frequncia = (fev + jun) / 2 If ( frequncia > exame ) Then terica = frequncia Else terica = exame End If nota = (terica + prtica) / 2

Utilizando as duas funes definidas acima, mdia e mximo, o cdigo resultante seria:
prtica = mdia (tp1,tp2) frequncia = mdia(fev, jun) terica = mximo(frequncia, exame) nota = mdia(terica, prtica)

24/61

O cdigo utilizando funes claramente mais legvel, aproximando a escrita em Visual Basic da nossa formulao do problema, e eliminando de uma primeira leitura pormenores desnecessrios. Caso subsistam duvidas sobre o clculo da nota pode-se sempre recorrer leitura do cdigo das funes utilizadas. No entanto se os nomes atribudos s funes reflectirem o seu funcionamento, este passo geralmente desnecessrio, salvo em caso de erro. Como ultima nota pretende-se salientar que os programas no se medem linha! A clareza de um determinado excerto de cdigo no tem relao directa com o nmero de linhas escritas. Para ilustrar este ponto apresenta-se a seguinte linha que produz exactamente o mesmo resultado que ambos os excertos apresentados acima: nota = mdia(mximo(mdia(fev, jun),exame),mdia(tp1,tp2)) Embora esta ultima verso seja decididamente mais curta, ela representa o pesadelo de um programador: de muito difcil leitura! Uma troca de parntesis e est tudo perdido...

2.5 Coleces
At agora os tipos de dados definidos permitiam armazenar um s valor. Em Visual Basic existe o conceito de coleco para permitir armazenar numa s varivel uma sequencia de valores. A sintaxe para definir uma coleco a seguinte: Dim x As New Collection Em Visual Basic, Collection na realidade um objecto e no um tipo de dados. A distino entre estes dois conceitos est fora do mbito desta cadeira. As diferenas na sua utilizao ao nvel sintctico sero no entanto apresentadas de forma a permitir a sua utilizao. Note-se que por x ser um objecto necessrio utilizar a palavra New na sua declarao para o inicializar. Para adicionar um elemento a uma coleco o Visual Basic fornece a funo Add que adiciona ao fim da coleco um determinado valor:
Dim x As New Collection x.Add(327) x.Add(425)

Note-se que para objectos, a invocao de uma funo precedida do nome do objecto sobre o qual se ir realizar a operao. Para consultar o valor do elemento na posio i de uma coleco utiliza-se a funo Item.
x.Item(i)

Exemplo: aps a execuo do seguinte excerto de cdigo o valor da varivel a 425.


Dim x As New Collection
25/61

x.Add(327) x.Add(425) a = x.Item(2)

Note-se que uma consulta a uma posio para alm dos nmero de elementos da coleco produz um erro em Visual Basic terminando a execuo do programa. Para determinar qual o nmero de elementos de uma coleco o Visual Basic fornece a funo Count. Exemplo: aps a execuo do seguinte excerto de cdigo o valor da varivel a 2.
Dim x As New Collection x.Add(327) x.Add(425) a = x.Count()

2.6 Instrues Cclicas


Para trabalhar com coleces necessrio um tipo de instruo que permita aplicar uma sequencia de instrues aos elementos de uma coleco. As instrues para este efeito denominam-se instrues cclicas. Dentro das instrues fornecidas pelo Visual Basic as mais relevantes sero de seguida apresentadas, terminando esta seco com uma anlise comparativa entre as instrues apresentadas.

2.6.1 Ciclos FOR EACH


A instruo FOR EACH permite percorrer completamente uma coleco realizando uma sequencia de operaes para cada elemento da mesma. A sintaxe para esta instruo a seguinte:
For Each elemento In coleco sequencia de instrues Next elemento

Um exemplo apropriado para esta instruo realizar a soma de todos os elementos de uma coleco. Para tal define-se uma funo que recebe como parmetro uma coleco. Este tipo de processos iterativos realiza-se por acumulao, ou seja, inicialmente o valor de soma zero, ou seja, antes de se iniciar a operao o total zero. Seguidamente queremos acumular no valor de soma o primeiro elemento da coleco. A operao repete-se at ao ultimo elemento da coleco, altura em que soma conter como valor o somatrio de todos os elementos. Para cada elemento da coleco, a instruo que realiza a acumulao do seu valor com a soma anterior : soma = soma + elemento Sendo assim a funo completa ficar:
26/61

1 2 3 4 5

Function total(coleco) soma = 0 For Each elem In coleco soma = soma + elem Next elem total = soma End Function

A instruo Next fornece-nos o prximo elemento da coleco caso ainda no se tenha atingido o fim da coleco, caso contrrio o resultado desta instruo a sada do ciclo. Note-se que o nome da varivel nesta instruo tem de coincidir com o nome utilizado na definio For Each. Para a simulao de execuo que se segue considere que a coleco fornecida como parmetro funo, tem os seguintes elementos: < 4, 3, 5, 2>.
num 1 2 3 4 3 4 3 4 3 4 elem 4 4 3 3 5 5 2 2 soma 0 0 0+4=4 4 4+3=7 7 7 + 5 = 12 12 12 + 2 = 14 14 obs. Inicialmente o valor de soma zero. elem toma o valor do primeiro elemento da coleco, 4. atribudo a soma a acumulao do seu valor prvio com o valor de elem. elem toma o valor do prximo elemento da coleco, neste caso o segundo. atribudo a soma a acumulao do seu valor prvio com o valor de elem. elem toma o valor do prximo elemento da coleco, neste caso o terceiro. atribudo a soma a acumulao do seu valor prvio com o valor de elem. elem toma o valor do prximo elemento da coleco, neste caso o quarto. atribudo a soma a acumulao do seu valor prvio com o valor de elem. No existem mais elementos na coleco, logo o ciclo termina. Note-se que o valor de elem indefinido aps esta instruo. instruo que define que o valor de soma o resultado da funo

14

De seguida apresentado um outro exemplo de utilizao do ciclo FOR EACH para clculo do valor mximo de uma coleco. O calculo do mximo de uma determinada coleco um processo iterativo em que se vai comparando os elementos da coleco com um valor mximo calculado at altura, ou seja, se o ciclo se encontrar no terceiro elemento, deve existir uma varivel que contenha
27/61

o mximo dos dois primeiros elementos. Essa varivel ento comparada com o terceiro elemento e caso seja inferior o seu valor actualizado para o valor do terceiro elemento. O processo continua iterativamente percorrendo os restantes elementos da coleco substituindo o valor da varivel que contem o valor mximo sempre que seja encontrado um valor superior.
1 2 3 4 5 6 Function mximo(coleco) mximo = 0 For Each elem In coleco If elem > mximo Then mximo = elem End If Next elem End Function

Para a simulao de execuo que se segue considere que a coleco fornecida como parmetro funo, tem os seguintes elementos: < 4, 3, 5, 2>.
num 1 2 3 elem 4 4 mximo 0 0 0 obs. Inicialmente o valor de mximo zero. elem toma o valor do primeiro elemento da coleco, 4. O valor de mximo inferior a elem, logo a condio da instruo If verdadeira e por conseguinte a instruo definida dentro do If ser executada. mximo toma o valor de elem. elem toma o valor do prximo elemento da coleco, neste caso o segundo. O valor de mximo superior a elem, logo a condio da instruo If falsa e por conseguinte a instruo definida dentro do If no ser executada. elem toma o valor do prximo elemento da coleco, neste caso o terceiro. O valor de mximo inferior a elem, logo a condio da instruo If verdadeira e por conseguinte a instruo definida dentro do If ser executada. mximo toma o valor de elem. elem toma o valor do prximo elemento da coleco, neste caso o quarto e ltimo. O valor de mximo superior a elem, logo a
28/61

4 5 6 3

4 4 3 3

4 4 4 4

5 6 3

3 5 5

4 4 4

4 5 6 3

5 5 2 2

5 5 5 5

condio da instruo If falsa e por conseguinte a instruo definida dentro do If no ser executada. 5 6 2 5 5 No existem mais elementos em coleco e por isso termina o ciclo.

Note-se que na linha 1 da funo acima definida atribui-se o valor 0 varivel mximo. O valor inicial desta varivel importante j que pode influenciar o resultado. A titulo de exemplo considere que na linha 1 da funo acima definida em vez de
1 mximo = 0

se tinha escrito
1 mximo = 10

Neste caso o valor da varivel mximo permaneceria inalterado durante todo o ciclo, sendo o seu valor final 10, o que claramente errado! A razo pela qual o valor de mximo permanece inalterado que a condio especificada na instruo IF, linha 3,
3 If elem > mximo Then

nunca se verifica e portanto nunca se executa a instruo da linha 4.


4 mximo = elem

Caso o valor inicial de mximo seja superior a todos os elementos da coleco ento o valor final da varivel mximo incorrecto. Sendo assim qual a regra para atribuir o valor inicial varivel mximo de forma a obter um resultado correcto no final do ciclo, i.e. o valor mximo presente na coleco? O valor inicial da varivel mximo deve ser tal que exista sempre pelo menos um valor na coleco superior ao valor inicial escolhido. Desta forma garante-se que a condio especificada na instruo If, linha 3, ser verificada para pelo menos um valor e portanto o valor final de mximo realmente o mximo da coleco e no um elemento maior que todos os elementos da coleco. Se considerarmos que a coleco contem preos, ento seguro dizer que o mximo zero, j que no existem preos inferiores a esse valor. Caso se trate de uma coleco que contenha ambos nmeros positivos e nmeros negativos ento a nica soluo seria inicializar a varivel mximo com o menor nmero possvel, no caso de nmeros inteiros o seu valor seria 32768. O problema inverso verifica-se com o clculo do valor mnimo. Neste caso o valor inicial da varivel que conter o valor mnimo da coleco deve ser inicializada com um valor superior ao mnimo actual da coleco. Como no caso geral no se conhece o valor
29/61

mnimo de uma coleco ento a forma segura de inicializar o valor mnimo e atribuir-lhe o maior valor possvel, no caso dos inteiros este valor 32767. Uma vez que o valor inicial destas variveis depende da coleco em causa, uma possvel soluo inicializar a varivel com o primeiro valor da coleco, ou seja, por exemplo mximo = A.item(1) ou mnimo = A.item(2)

2.6.2 Ciclos FOR


O segundo tipo de ciclos que aqui ser estudado so os ciclos FOR. Este tipo de ciclos mais poderoso que os ciclos FOR EACH uma vez que permite especificar a forma como uma coleco percorrida e quais os elementos a considerar. A sintaxe para este ciclo a seguinte:
For i = limite_inicial TO limite_final sequencia de instrues Next i

A instruo Next i corresponde a incrementar o valor de i por uma unidade e de seguida, caso o valor de i no seja superior a limite_final ento voltar de novo para dentro do ciclo. Considere de novo o exemplo do calculo da soma de todos os elementos de uma coleco. Neste caso o limite_inicial 1, ou seja o primeiro elemento, e o limite_final a posio do ultimo elemento, ou seja o nmero total de elementos. O Visual Basic fornece uma funo que determina o nmero total de elementos de uma coleco, count(), ver seco referente s coleces. O esqueleto da funo utilizando a funo count() ser:
1 2 3 4 5 Function total(coleco) soma = 0 For i = 1 To coleo.count() instruo para acumular o valor de soma Next i total = soma End Function

A instruo para acumular o valor da soma, linha 3 da funo acima apresentada, pode ser definida informalmente como:
soma = soma + valor do elemento que se encontra na posio i

Para determinar o valor de um elemento numa determinada posio i, utiliza-se a funo item(i), ver seco referente s coleces. A funo completa em seguida apresentada:
30/61

1 2 3 4 5

Function total(coleco) soma = 0 For i = 1 To coleo.count() soma = soma + coleo.item(i) Next i total = soma End Function

Para a simulao da execuo desta funo considere que a coleco tem os seguintes elementos < 2 4 3>.
num 1 2 3 i 1 1 soma 0 0 0+2=2 obs. Inicialmente o valor de soma zero. Atribui-se a i o valor do limite inicial do ciclo, ou seja 1. atribudo a soma a acumulao do seu valor prvio,0, com o valor do elemento da coleco na posio i, ou seja o primeiro elemento da coleco. i incrementado de uma unidade. Uma vez que i no superior ao limite final, coleo.count() a simulao prossegue na linha 3. atribudo a soma a acumulao do seu valor prvio com o valor do elemento da coleco na posio i, ou seja o segundo elemento da coleco. i incrementado de uma unidade. Uma vez que i no superior ao limite final, coleo.count() a simulao prossegue na linha 3. atribudo a soma a acumulao do seu valor prvio com o valor do elemento da coleco na posio i, ou seja o terceiro elemento da coleco. i incrementado de uma unidade. Uma vez que i superior ao limite final, coleo.count() o ciclo terminado e a simulao prossegue na linha 5. instruo que define que o valor de soma o resultado da funo

2+4=6

6+3=9

Pelo exemplo apresentado acima evidente que para percorrer completamente uma coleco a escrita de uma funo utilizando o ciclo FOR definitivamente mais complicada que a mesma funo utilizando o ciclo FOR EACH. De facto para percorrer completamente uma coleco os ciclos FOR EACH so os mais apropriados.
31/61

No entanto os ciclos FOR permitem realizar operaes que os ciclos FOR EACH no permitem como por exemplo percorrer somente os n primeiros elementos de uma coleco. Ou seja nos ciclos FOR existe a liberdade de seleccionar limites iniciais e limites finais diferentes de 1 e o numero total de elementos respectivamente. De facto o ciclo FOR EACH um caso particular dos ciclos FOR em que os limites inicias e finais so respectivamente o primeiro e ultimo elemento de uma coleco. Por exemplo a seguinte funo realiza a soma dos elementos que se encontram entre a quinta e a dcima posio numa coleco.
1 2 3 4 5 Function total(coleco) soma = 0 For i = 5 To 10 soma = soma + coleo.item(i) Next i total = soma End Function

Note-se que se a coleco no possuir pelo menos dez elementos a funo provoca um erro de "Index Out of Bounds", ou seja tentativa de acesso a um elemento numa posio fora da gama de posies da coleco. Considere agora um outro exemplo: a procura de um determinado valor numa coleco. Esta funo ter de ter dois parmetros: o elemento a encontrar, e a coleco onde se pretende procurar. Sendo assim o esqueleto da funo poder ser algo do gnero:
Function procura(elem, coleco) ... End Function

Basicamente o que se pretende determinar para cada elemento da coleco verificar se este igual ou diferente ao elemento que se pretende procurar. Caso seja igual o resultado final deve ser false, caso contrrio este resultado ser true. Apresenta-se agora uma primeira tentativa para a resoluo deste problema:
1 2 3 4 5 6 7 Function procura(elem, coleco) For i = 1 To coleo.count() If (elem = coleo.item(i)) Then procura = true Else procura = false End If Next i End Function

Considerando que a coleco <8,6,7,5> e sendo 6 o valor procurado procede-se de seguida a uma simulao de execuo para esta funo.
num i procura obs.
32/61

Atribui-se varivel i o valor do limite inicial do ciclo. A varivel procura, que tambm o resultado da funo permanece indefinido. Testa se elem = coleo.item(1), ou seja 8. A condio falsa logo a linha seguinte a executar a linha 5. Termina a instruo If i incrementado de uma unidade. Uma vez que i no superior ao limite final, coleo.count() a simulao prossegue na linha 3. Testa se elem = coleo.item(2), ou seja 6. A condio verdadeira logo a linha seguinte a executar a linha 4. atribudo a procura o valor true. Terminou o bloco de instrues para a condio verdadeira, logo a prxima instruo a executar encontra-se na linha 6 Termina a instruo If i incrementado de uma unidade. Uma vez que i no superior ao limite final, coleo.count() a simulao prossegue na linha 3. Testa se elem = coleo.item(3), ou seja 7. A condio falsa logo a linha seguinte a executar a linha 5. Termina a instruo If i incrementado de uma unidade. Uma vez que i no superior ao limite final, coleo.count() a simulao prossegue na linha 3. Testa se elem = coleo.item(4), ou seja 5. A condio falsa logo a linha seguinte a executar a linha 5. Termina a instruo If i incrementado de uma unidade. Uma vez que i superior ao limite final termina o ciclo FOR.

5 6 7

1 1 2

false false false

false

true

6 7

2 3

true true

true

5 6 7

3 3 4

false false false

false

5 6 7

4 4 5

false false false

33/61

O resultado desta funo false, no entanto o valor 6 encontra-se presente na coleco passada como parmetro. Podemos ento concluir que esta funo est mal construda j que o resultado correcto seria true. Exerccio: Existem dois casos particulares em que a funo acima apresentada dar um resultado correcto: d exemplos de parmetros para os quais a funo de resultados correctos, e identifique as razes que levam a funo a devolver resultados correctos. Analisando a simulao de execuo da funo pode-se concluir o seguinte: ao encontrar o elemento pretendido atribudo ao valor da varivel procura o valor true. No entanto, logo de seguida o valor da varivel procura passa a false mal a funo se depare com um elemento da coleco que no seja igual ao elemento procurado. O problema reside no facto de se alterar para todos os elementos o valor da varivel procura e aceitar o ultimo valor como sendo o resultado real. Esta funo deve ser reescrita da seguinte forma: 1. inicialmente define-se que o valor da varivel procura false, ou seja, antes de se procurar nada se pode encontrar! 2. seguidamente realiza-se o ciclo FOR tal com na funo anterior sendo a nica diferena o facto de s se alterar o valor da varivel procura case se encontre o elemento pretendido. Sendo assim o cdigo da funo fica:
1 2 3 4 5 6 Function procura(elem, coleco) procura = false For i = 1 To coleo.count() If (elem = coleo.item(i)) Then procura = true End If Next i End Function

Apresenta-se de seguida a simulao de execuo da funo.


num 1 2 i 1 procura false false Atribui-se varivel i o valor do limite inicial do ciclo. A varivel procura, que tambm o resultado da funo permanece indefinido. Testa se elem = coleo.item(1), ou seja 8. A condio falsa logo a linha seguinte a executar a linha 5. Termina a instruo If i incrementado de uma unidade. Uma vez que i no superior ao limite final, coleo.count() a simulao
34/61

obs.

false

5 6

1 2

false false

prossegue na linha 3. 3 2 false Testa se elem = coleo.item(2), ou seja 6. A condio verdadeira logo a linha seguinte a executar a linha 4. atribudo a procura o valor true. Terminou o bloco de instrues para a condio verdadeira, logo a prxima instruo a executar encontra-se na linha 6 Termina a Instruo If. i incrementado de uma unidade. Uma vez que i no superior ao limite final, coleo.count() a simulao prossegue na linha 3. Testa se elem = coleo.item(3), ou seja 7. A condio falsa logo a linha seguinte a executar a linha 5. Termina a instruo If i incrementado de uma unidade. Uma vez que i no superior ao limite final, coleo.count() a simulao prossegue na linha 3. Testa se elem = coleo.item(4), ou seja 5. A condio falsa logo a linha seguinte a executar a linha 5. Termina a instruo If i incrementado de uma unidade. Uma vez que i superior ao limite final termina o ciclo FOR.

true

5 6

2 3

True true

true

5 6

3 4

true true

true

5 6

4 5

true true

Esta funo devolve o resultado correcto. fcil ver que caso o elemento no pertena coleco o resultado ser sempre false. A titulo de exerccio construa uma simulao de execuo tomando como parmetros a coleco <9,8,7,6> e o elemento 5. O cdigo desta funo no muito inteligente. Considere a seguinte analogia para ilustrar a falta de eficincia desta funo. Um gestor de uma empresa pede ao seu assistente uma cpia de um relatrio sobre a situao financeira da empresa. Na secretria do assistente encontra-se uma pilha de relatrios na qual se deve encontrar o relatrio pretendido. O assistente comea a procura do relatrio pelo topo da pilha, e vai procurando at encontrar o dito relatrio. Quando encontra, suspira aliviado, posa o relatrio na beira da secretria, e... continua a sua operao de procura at chegar ao fim da pilha!? Porque continuar a procurar aps encontrar? Porque na funo acima definida no h maneira de especificar que a busca termina aps procura assumir o valor true. Os ciclos FOR s permitem especificar os limites inicial e final. Atingir o limite final a nica sada possvel do ciclo. Na analogia acima o assistente s poderia terminar a sua busca
35/61

aps procurar em toda a pilha de relatrios, mesmo que encontre o relatrio pretendido a meio do processo. Na seco seguinte vamos apresentar um novo tipo de ciclos que permite resolver este tipo de problemas de forma adequada.

2.6.3 Ciclos WHILE


Os ciclos que agora so apresentados, ciclos WHILE, so os mais versteis de todos. Como foi mencionado anteriormente, os ciclos FOR EACH so um caso particular dos ciclos FOR. Por sua vez os ciclos FOR so um caso particular dos ciclos WHILE. Os ciclos WHILE tem a seguinte sintaxe:
While condio sequencia de instrues Wend

Sendo condio uma expresso booleana que determina enquanto o ciclo deve prosseguir, ou seja o ciclo no termina enquanto a expresso for verdadeira. Considere de novo a funo soma. Neste caso pretende-se percorrer a coleco completa desde o primeiro elemento at ao ltimo. Ao definir o ciclos FOR para esta funo os limites eram especificados na prpria definio da instruo. Para os ciclos WHILE, a situao diferente. S possvel especificar uma condio de continuao do ciclo, ou seja, o ciclo ir ser executado enquanto a posio do elemento actual no exceder o total de elementos. Apresenta-se de seguida o cdigo desta funo:
1 2 3 4 5 6 Function soma(col) soma = 0 i = 1 While i <= col.count() soma = soma + col.item(i) i = i + 1 Wend End function

A varivel i utilizada para percorrer a coleco, indicando a posio do elemento actual. A condio do ciclo WHILE i <= col.count() indica que o ciclo ser executado enquanto a posio do elemento actual no exceder o total de elementos da coleco. Note-se que na definio do ciclo WHILE no existe referencia ao valor inicial da varivel i. Esta definio de valor inicial deve ser feita antes do ciclo comear. Ao terminar o ciclo necessrio explicitar que se pretende passar ao elemento seguinte, ou seja ao elemento que se encontra na posio i+1, dai a instruo i=i+1
36/61

Ao terminar um ciclo FOR com a instruo Next i, est-se de facto a realizar duas operaes: 1. incrementar o valor de i por uma unidade, ou seja i = i + 1 2. definir o fim da instruo FOR Como se pode inferir do exemplo anterior, nos ciclos WHILE necessrio realizar o incremento da varivel i explicitamente. Os ciclos WHILE so portanto mais complexos, no entanto essa complexidade permite realizar operaes de uma forma mais eficiente. Antes de se prosseguir para o prximo exemplo considere a seguinte simulao de execuo da funo soma assumindo que a coleco passada como parmetro tem os seguintes elementos:<2,4,3>.
num 1 2 3 i 1 1 soma 0 0 0 Uma vez que a condio verdadeira, ou seja o valor de i no superior a col.count() as instrues dentro do ciclo sero executadas. atribudo a soma a acumulao do seu valor prvio com o valor do elemento na posio i. a varivel i incrementada por uma unidade. a instruo Wend determina o fim da instruo WHILE e provoca um salto para a linha onde se encontra o inicio da definio desta instruo, ou seja a linha 3. Uma vez que a condio verdadeira, ou seja o valor de i no superior a col.count() as instrues dentro do ciclo sero executadas. atribudo a soma a acumulao do seu valor prvio com o valor do elemento na posio i. a varivel i incrementada por uma unidade. Salto para a linha onde se encontra o inicio da definio desta instruo, ou seja a linha 3. Uma vez que a condio verdadeira, ou seja o valor de i no superior a col.count() as instrues dentro do ciclo sero executadas. atribudo a soma a acumulao do seu valor prvio com o valor do elemento na posio i. a varivel i incrementada por uma unidade. Salto para a linha onde se encontra o inicio da definio desta instruo, ou seja a linha 3. A condio falsa, ou seja o valor de i superior a col.count() o ciclo termina e a prxima instruo ser a instruo imediatamente a seguir instruo Wend. Neste caso como no
37/61

obs. Inicialmente o valor de soma zero.

4 5 6

1 2 2

0+2 = 2 2 2

4 5 6 3

2 3 3 3

2+4 = 6 6 6 6

4 5 6 3

3 4 4 4

6+3 = 9 9 9 9

existem mais instrues a funo termina.

Considere agora o caso em que se pretende realizar uma procura de um determinado elemento numa coleco, sendo ambos os valores passados como parmetro. O esqueleto da funo equivalente ao definido anteriormente para os ciclos FOR, ou seja:
Function procura(elem, col) ... End Function

Apresenta-se de seguida uma verso da funo procura semelhante apresentada com ciclos FOR mas desta vez utilizando ciclos WHILE.
Function procura(elem, col) procura = false i = 1 While (i <= col.count()) If elem = col.Item(i) Then procura = true End If i = i + 1 Wend End Function

A funo acima apresentada sofre do mesmo problema que a sua homnima com ciclos FOR. No entanto com ciclos WHILE possvel resolver o problema da ineficincia presente na soluo com ciclos FOR. A essncia da questo definir quando sair do ciclo WHILE, ou por outras palavras, enquanto permanecer dentro do ciclo. A funo acima define como condio de permanncia no ciclo o facto de a varivel i referenciar uma posio dentro dos limites da coleco. No entanto a varivel procura completamente ignorada nesta condio. Ou seja traduzindo para Portugus corrente actualmente a condio especificada : Procurar at ao fim, ignorando o facto de se encontrar a meio Na realidade o que se pretende a conjuno das duas condies apresentadas a seguir: 1. Procurar at ao fim 2. Procurar at encontrar. A condio 1 j se encontra definida. Resta agora definir a condio 2. De acordo com o cdigo acima apresentado sabe-se que enquanto o elemento no for encontrado na coleco a varivel procura ser false. Sendo assim a segunda condio poder ser: procura = false O cdigo completo com a nova condio agora apresentado:
38/61

Function procura(elem, col) procura = false i = 1 While (i <= col.count()) AND (procura = false) Then If elem = col.Item(i) Then procura = true End If i = i + 1 Wend End Function

O cdigo acima pode ser reescrito de forma a simplificar o ciclo. Considere a seguinte funo como uma primeira tentativa para resolver o problema:
Function procura(elem, col) 1 i = 1 2 While (i <= col.count()) AND (elem <> col.Item(i)) Then 3 i = i + 1 4 Wend End Function

A condio desta ultima funo especifica que o ciclo ser executado enquanto: 1. a posio actual, varivel i, estiver dentro dos limites da coleco 2. o elemento for diferente do elemento actual A segunda condio garante que mal se encontre um elemento na coleco igual ao elemento passado como parmetro o ciclo terminado. A funo no est completa uma vez que nunca definido qual o resultado da funo, ou seja no existe nenhuma atribuio varivel procura (nome da funo). Duas simulaes de execuo so agora apresentadas, a primeira em que o elemento existe na coleco, a seguinte em que o elemento no se encontra na coleco. Simulao de execuo da ultima verso da funo procura com os seguintes parmetros: elem = 2, col = <3,2,4>
num 1 2 3 4 2 i 1 1 2 2 2 col.item(i) 3 3 2 2 2 Salto para a linha 3 A condio falsa porque elem = col.item(i). Salto para o fim da funo. Condio verdadeira. obs.

O valor de i 2, ou seja indica a posio em que elem se encontra na coleco. Considere agora que os parmetro eram: elem = 5, col = <3,2,4>.
39/61

num 1 2 3 4 2 3 4 2 3 4 2

i 1 1 2 2 2 3 3 3 4 4 4

col.item(i) 3 3 2 2 2 4 4 4 -

obs.

Condio verdadeira. Salto para a linha 3. Condio verdadeira. Salto para a linha 3. Condio verdadeira. Salto para a linha 3. A condio falsa porque 4 superior a col.count(), ou seja a posio actual, 4, est fora dos limites da coleco. Salto para o fim da funo.

Neste caso o valor da varivel i 4. Este valor indica que o elemento procurado no se encontra na coleco, uma vez que o processo de procura foi terminado por termos esgotado os elementos da coleco. Pode-se ento concluir que, ao terminar o ciclo, caso a varivel i esteja dentro dos limites da coleco ento o elemento existe na coleco, caso contrrio, ou seja se i for maior que o nmero de elementos da coleco, ento o elemento no existe na coleco. Sendo assim deve-se acrescentar as seguintes linhas a seguir ao ciclo:
If i <= col.count() Then procura = true Else procura = false End If

O cdigo completo :
Function procura(elem, col) i = 1 While (i <= col.count()) AND (elem <> col.Item(i)) Then i = i + 1 Wend If i <= col.count() Then procura = true Else procura = false End If End Function

40/61

Um ultimo pormenor de interesse nesta funo reside na ordem das condies do ciclo WHILE. Caso a ordem fosse inversa ou seja,
While (elem <> col.Item(i)) AND (i <= col.count()) Then

ento o Visual Basic terminaria a execuo em erro caso o elemento no existisse na coleco. O erro deve-se ao facto de o valor final de i ser superior ao nmero de elementos da coleco (porque o elemento no existe), logo col.Item(i) no se encontra definido. Na ordem original,
While (i <= col.count()) AND (elem <> col.Item(i)) Then

este problema no se levanta porque a primeira condio falsa, e ao realizar a conjuno de condies (AND), desde que uma das condies seja falsa a conjuno tambm falsa e logo no necessrio calcular as restantes condies. Ou seja, para o valor final de i, como a condio i <= col.count() falso o VB no calcula a outra condio, uma vez que a conjuno de uma condio falsa com outra condio sempre falsa, independentemente do valor da outra condio. Resumindo o VB s calcula o estritamente necessrio para obter um resultado. A esta estratgia d-se o nome de "lazy evaluation". Nas funes anteriores o resultado devolvido corresponde em Portugus a "encontrei" ou "no encontrei". No entanto esta resposta pode no ser a pretendida, muitas vezes pretende-se saber no s se o elemento existe na coleco mas tambm caso exista em que posio se encontra. A funo apresentada acima pode ser reescrita para devolver false caso o elemento no se encontre na coleco e a sua posio caso o elemento exista. Uma vez que a varivel i representa a posio do elemento caso este exista na coleco o cdigo final desta verso ser:
Function procura(elem, col) i = 1 While (i <= col.count()) AND (elem <> col.Item(i)) Then i = i + 1 Wend If i <= col.count() Then procura = i Else procura = false End If End Function

41/61

2.6.4 Anlise comparativa de instrues Cclicas


A analise realizada nesta seco vai incidir sobre duas vertentes distintas: simplicidade do cdigo, e versatilidade das instrues propriamente ditas. Considere a funo soma definida anteriormente para todos os ciclos.
FOR EACH
Function soma(col) soma = 0 For Each elem In col soma = soma + elem Next elem End function

FOR
Function soma(col) soma = 0 For i = 1 To col.count() soma = soma + col.item(i) Next i End function

WHILE
Function soma(col) soma = 0 i = 1 While i <= col.count() soma = soma + col.item(i) i = i + 1 Wend End function

A verso que utiliza o ciclo FOR EACH a mais simples, no necessrio especificar limites para o ciclo. A forma de se obter o elemento tambm mais simples utilizando a instruo FOR EACH, no sendo necessrio recorrer a ndices. A instruo FOR implica a definio dos limites, ou seja col.count(). A terceira verso implica a inicializao separada do limite inferior , assim como o incremento manual da varivel i. Em termos de simplicidade as trs instrues poderiam ser apresentadas pela seguinte ordem, da mais simples mais complexa: 1. FOR EACH 2. FOR 3. WHILE Em termos de versatilidade a ordem exactamente a inversa. Isto natural uma vez que a simplicidade advm do facto de se restringir a utilizao a casos concretos. A instruo FOR EACH s deve ser utilizada quando se pretende percorrer uma coleco do principio ao fim. A instruo FOR permite definir intervalos diferentes do inicial, 1, e final, count() sendo portanto mais verstil. Por sua vez a instruo WHILE permite especificar qualquer tipo de condio. A vantagem da utilizao dos ciclos WHILE evidente quando se realiza uma operao cujo critrio de sada do ciclo no depende de um limite fixo. Um exemplo deste tipo de operaes a procura de um determinado elemento em que no se sabe partida a sua posio na coleco. 2.6.4.1 Converso de instrues cclicas FOR EACH - FOR possvel realizar a converso de qualquer instruo cclica FOR EACH para uma instruo FOR. A regra para a converso a seguinte: Para o esqueleto da instruo a converso realizada tal como se apresenta na tabela em baixo:
FOR EACH elem in coleco ... Next elem FOR i = 1 to coleo.count() ... Next i
42/61

Para o corpo de instrues dentro dos ciclos as alteraes a realizar prendem-se com o facto de ser necessrio substituir as referencias a elem, no caso dos ciclos FOR EACH, por referencias a coleo.item(i), para os ciclos FOR. De seguida apresentam-se as funes completas para o caso da soma com as diferenas sublinhadas:
Function soma(col) soma = 0 For Each elem In col soma = soma + elem Next elem End function Function soma(col) soma = 0 For i = 1 To col.count() soma = soma + col.item(i) Next i End function

Note-se que a passagem de ciclos FOR para ciclos FOR EACH nem sempre possvel. S possvel converter um ciclo FOR num ciclo FOR EACH no caso em que os limites iniciais e finais correspondem ao inicio e fim da coleco. Para alem disso necessrio que as indexaes a elementos nos ciclos FOR sejam todas do tipo col.item(i) sendo i a varivel utilizada no ciclo. A titulo de exemplo apresenta-se agora um ciclo FOR que no pode ser convertido para um ciclo FOR EACH.
Function soma5a10(col) soma = 0 For i = 5 To 10 soma = soma + col.item(i) Next i End function

2.6.4.2 Converso de instrues cclicas FOR - WHILE Um ciclo FOR pode ser sempre convertido para um ciclo WHILE seguindo um processo automtico da seguinte forma:
Function xpto(col) soma = 0 For i = inicio To fim Function xpto(col) soma = 0 i = inicio While i <= fim instrues i = i + 1 Wend End function

instrues Next i End function

As instrues dentro do ciclo no sofrem qualquer alterao ao converter o ciclo de FOR para WHILE. A converso no sentido inverso nem sempre possvel. Por exemplo a funo soma pode ser escrita com um ciclo WHILE ou com um ciclo FOR, no entanto a funo procura escrita com um ciclo WHILE no tem traduo directa para um ciclo FOR uma vez que a conjuno de condies no pode ser especificada em ciclos FOR.
43/61

3 Aplicao do Visual Basic em Excel


Todos os conceitos apresentados anteriormente tem aplicao na folha de clculo Excel. Neste capitulo inicialmente feita uma introduo resumida aos conceitos relevantes do Excel, seguida da aplicao dos conceitos de Visual Basic ao Excel.

3.1 Introduo aos Conceitos do Excel


Basicamente uma folha de clculo uma grelha. Cada posio da grelha denominada por clula. Uma clula pode conter um valor introduzido manualmente ou ento um resultado de um clculo. A titulo de exemplo considere-se a seguinte folha de clculo onde foram introduzidos os valores de abertura e fecho das cotaes de algumas empresas cotadas na Bolsa de Valores de Lisboa para um determinado dia.

figura 3.1 - Exemplo de uma folha de clculo preenchida

O Excel permite introduzir formulas para clculo de valores a partir dos valores existentes na folha de clculo. Por exemplo poder-se-ia seleccionar a clula D2 e introduzir a formula para o clculo da variao diria.

figura 3.2 Introduo de uma formula numa clula

Para escrever uma formula em Excel necessrio digitar o smbolo "=" antes de escrever a formula propriamente dita. A formula da figura 3.2 realiza a subtraco entre os valores das clulas C2 e B2. Note-se que a conveno no Excel para definir uma clula consiste em especificar primeiro a coluna e depois a linha pretendida. Escrever a frmula "=C2-B2" implica que o Excel execute os seguintes passos: 1. calcule o valor dessa expresso 2. e que atribua o valor da expresso clula activa, neste caso D2. Para aplicar a formula s outras linhas basta copi-la para D3,D4,etc... O Excel automaticamente refaz as referencias s clulas dentro das frmulas, ou seja, ao copiar a formula da clula D2 para a clula D3, desceu-se uma linha, logo o Excel automaticamente altera todas as referencias da frmula de forma a que sejam referentes linha 3. A frmula resultante da cpia :
44/61

=C3-B3 Considere-se agora um outro exemplo: pretende-se calcular o preo com IVA de um conjunto de artigos, aplicando o IVA ao preo. Na folha de clculo, figura 3.3, acrescentou-se uma clula com o valor do IVA em vez de utilizar o valor directamente. Com esta estratgia pretende-se a reduo das alteraes necessrias caso a taxa do IVA seja modificada. Caso se utilizasse o valor do IVA directamente na frmula, =B2*1.17, seria necessrio alterar todas as frmulas quando a taxa fosse modificada, desta forma basta alterar o valor da clula E1. Como ilustrado na figura que se segue, a frmula correcta para o clculo do preo com IVA : = B2 * $E$1

figura 3.3 - Clculo do IVA em Excel

Os smbolos $ indicam que a referncia a esta clula no varia quando a frmula copiada, ou seja caso a frmula seja copiada para a clula C3, a frmula resultante ser: = B3 * E1 S a referncia clula B2 foi alterada para B3, a referncia a E1 manteve-se. Em Visual Basic pode-se definir a seguinte funo:
Function IVA(a, b) IVA = a * b End Function

Para invocar esta funo escreve-se = IVA(B2,$E$1) tal como ilustrado na figura que se segue.

45/61

figura 3.4 Invocao em Excel de uma funo definida em VB

Como se pode inferir do cdigo da funo acima os conceitos de Visual Basic apresentados anteriormente so directamente aplicveis ao Excel.

3.1.1 Referncias a Clulas na Folha de Clculo


No exemplo da seco anterior desnecessrio considerar como argumento a clula E1 uma vez que esta constante. Como j foi referido tambm no se pretende utilizar o valor do IVA directamente na frmula para facilitar a manuteno da folha de clculo caso o IVA seja alterado. Sendo assim a nossa funo em VB fica s com um argumento, o preo:
Function IVA(a) IVA = a.Value * valor da clula E1 End Function

Em VB o acesso a uma clula feito segundo regras diferentes das do Excel. Enquanto em Excel se referncia uma clula atravs da sua coluna e linha, em VB utiliza-se a funo Cells que tem dois argumentos, a linha e a coluna. Note-se que a ordem de referncia entre o Excel e o VB inversa, ou seja em Excel primeiro indica-se a coluna e depois a linha, enquanto que em VB especifica-se primeiro a linha e depois a coluna. Apresentam-se de seguida alguns exemplos: Excel A2 B1 E1 Visual Basic Cells(2,1) Cells(1,2) Cells(1,5)

46/61

Programao Informtica 1999/2000

Sendo assim a funo em VB fica com a seguinte forma:


Function IVA(a) IVA = a.Value * Cells(1,5) End Function

Note-se que ao alterar o valor da clula E1 o resultado desta funo no imediatamente alterado. Por omisso, o Excel s actualiza automaticamente as clulas com formulas que referenciam nos seus parmetros clulas que foram alteradas. A ultima verso da funo IVA no contem como parmetro a clula E1, logo no automaticamente actualizada. Para actualizar todos os resultados deve-se utilizar a opo "Calculate Full" disponvel no Excel 2000. Esta opo realiza as actualizaes pretendidas, ou seja, se a clula E1 for alterada, ento todas as clulas s quais a funo IVA foi aplicada tambm sero actualizadas embora no existe nenhuma referencia clula E1 no cabealho da funo IVA. Na ultima verso da formula reduziu-se o nmero de parmetros desta de 2 para 1. A questo que se pe qual a vantagem da reduo do nmero de parmetros de uma funo? No caso geral se um parmetro pode ser calculado custa de outro ento desnecessrio. A sua eliminao da lista de parmetros evita erros de invocao da funo como por exemplo: Preo(B2, E1) em vez de Preo(B2, $E$1) No entanto em Excel existe potencialmente uma desvantagem de eliminar parmetros que sejam referencias a clulas caso se altera a estrutura da folha de clculo. Ao utilizar o comando "Insert Column" do Excel este desloca todas as colunas desde o ponto de insero uma coluna para a direita. Sendo assim caso se utilizasse o comando "Insert Column" na coluna C, localizao da clula do IVA passaria a F1.

figura 3.5 Resultado da insero de uma coluna com o comando "Insert Column"

Como se pode ver na figura 3.5 a frmula utilizando dois parmetros automaticamente actualizada. O Excel refaz todas as referencias a clulas presentes em frmulas de forma a compensar a operao realizada, neste caso a insero de uma nova coluna. No caso da segunda verso, em que s existe um parmetro: a clula do preo, o Excel no actualiza o cdigo da funo onde a referencia realizada (Cells(1,5)). Para obter um resultado correcto aps a insero da coluna utilizando o comando "Insert Column" seria necessrio actualizar manualmente o cdigo da funo.

47/61

Programao Informtica 1999/2000

Resumindo: desde que se garante que a estrutura da folha de clculo no alterada vantajoso reduzir o nmero de parmetros de forma a evitar erros de invocao como exemplificado acima. No entanto se no se puder garantir que a estrutura no alterada ento necessrio considerar se convm introduzir todos os parmetros. Uma vez que o mbito desta seco referenciar clulas de uma folha de clculo em Visual Basic sero apresentados mais exemplos onde o nmero de parmetros reduzido ao mnimo possvel. No entanto ao realizar um trabalho em Excel necessrio ter em ateno as consideraes acima enunciadas sobre os prs e contras da reduo de parmetros e analisar caso a caso qual a melhor estratgia. Considere agora que na folha de clculo acima definida era acrescentada mais uma coluna com uma percentagem de desconto para cada item. Pretende-se definir uma funo em VB para o clculo do preo final de acordo com a seguinte expresso em Excel:

figura 3.6 - Exemplo em Excel

A funo em VB :
Function Preo(a, b) Preo = a * ((100 - b)/100) * Cells(1,5) End Function

Sendo a sua invocao feita da seguinte forma:

figura 3.7 - Invocao em VB

Por razes de clareza pode-se dividir a funo em vrias linhas, por exemplo:
Function Preo(a, b) IVA = Cells(1,5) Preo = a * ((100 - b)/100) * IVA End Function

Ou ainda

48/61

Programao Informtica 1999/2000

Function Preo(a, b) IVA = Cells(1,5) PercentagemPagar = (100 - b) / 100 Preo = a * PercentagemPagar * IVA End Function

Desta forma a leitura da funo fica facilitada. Uma leitura atenta desta ultima funo permite concluir que afinal s necessrio um parmetro. O segundo parmetro sempre a clula na coluna seguinte do primeiro argumento. Pode-se ento simplificar a invocao da frmula de forma a s ter um parmetro. Ou seja, a invocao seria = Preo(B2) necessrio modificar a funo em VB de forma a reflectir a alterao desejada. O cabealho da funo fica portanto alterado de modo a reflectir a reduo do nmero de parmetros para:
Function Preo(a)

.... O problema reside no facto de como referenciar a clula que se encontra na coluna a seguir coluna do primeiro argumento, sendo a linha comum. A funo Cells devolve uma referncia a uma clula. Por omisso o VB entende a referencia clula como o seu valor. No entanto uma clula representa um conjunto de propriedades que a definem e no s o seu valor, entre estas temos: valor (Value) no necessrio especificar, j que o VB por omisso assume que se pretende o valor da clula linha (Row) coluna (Column)

Sendo assim, assumindo que o parmetro da funo a, possvel saber a coluna da linha referenciada atravs da expresso: a.Column Analogamente para a linha: a.Row Sendo assim a referncia clula na coluna seguinte clula do primeiro argumento Cells(a.Row, a.Column+1) A funo em VB portanto:
Function Preo(a) Preo = a * ((100-Cells(a.Row, a.Column+1)) / 100) * Cells(1, 5) End Function

Ou, decompondo a funo em vrias linhas,


Function Preo(a) IVA = Cells(1, 5)

49/61

Programao Informtica 1999/2000

desconto = Cells(a.Row, a.Column + 1) PercentagemPagar = ((100 -desconto) / 100) Preo = a * PercentagemPagar * IVA End Function

Como pode verificar-se de mais fcil leitura esta ltima funo.

3.1.2 Referencia a clulas noutras folhas de clculo


Em Excel existe o conceito de "Livro", sendo um "Livro" constitudo por vrias folhas de clculo. Apresenta-se de seguida um exemplo que utiliza vrias folhas de clculo para guardar informao, ilustrando como escrever expresses que utilizem clulas em folhas de clculo distintas. No exemplo acima considerou-se que o desconto era atribudo artigo a artigo. Mais realisticamente poder-se-ia dizer que existem escales de descontos. Ou seja em vez de se atribuir ao artigo xpto um desconto de 15%, atribui-se ao artigo um desconto do escalo 1. Para associar os escales de desconto aos valores a descontar criou-se uma tabela noutra folha de clculo. Sendo assim necessrio alterar a folha de clculo inicial substituindo o valor do desconto pelo escalo de desconto.

figura 3.8 - Folha de Clculo Excel com os artigos e respectivos tipos de desconto

Para definir os escales de descontos utiliza-se uma nova folha de clculo cuja estrutura apresentada na figura seguinte. Nesta folha de clculo o escalo de desconto 1 apresentado na linha 1, o escalo 2 na linha 2, e assim sucessivamente.

figura 3.9 - Folha de clculo com os descontos por tipo de artigo

Nota: Os nomes das folhas de clculo de um "Livro" Excel so apresentados numa barra na parte inferior da aplicao.

50/61

Programao Informtica 1999/2000

figura 3.10 - Barra com os nomes das folhas de clculo de um "Livro" Excel

Os nomes apresentados so os atribudos por omisso pelo prprio Excel. Para facilitar a legibilidade das frmulas e /ou funes VB deve-se alterar esses nomes de forma a atribuir carga semntica.

figura 3.11 - Nomes atribudos para o nosso problema

Nota: Para alterar os nomes de uma folha de clculo faz-se um duplo clique no nome que pretende alterar e introduz-se o novo nome. Recapitulando: A folha de clculo da figura 3.8 a folha "artigos" e a folha da figura 3.9 a folha "escales". Qual o PVP do artigo "Camisa Riscas"? Sabe-se que o seu preo de 4750$00, o IVA 1.17, e o desconto a aplicar 25% (escalo 3). O desconto 25% porque se consultou a linha 3 da folha "escales", ou seja, os descontos esto na folha "escales", na coluna A e na linha indicada pela coluna "Escalo" na folha "artigos". Do ponto de vista da escrita da expresso do clculo do preo em Excel, este exemplo levanta um problema: Como referenciar em Excel a clula na folha de clculo "escales" na coluna A e na linha indicada na coluna C da folha "artigos"? Para resolver este problema necessrio ir por partes: 1. para referenciar uma clula noutra folha de clculo escreve-se o nome da folha, seguido de ! e da referncia clula. Por exemplo para referenciar a clula A1 da folha "escales" escreve-se: escales!A1 2. No nosso caso sabe-se que o desconto est na folha "escales", na coluna A, na linha indicada pela coluna "Escalo" da folha "artigos". Por exemplo, se se considerar o artigo "Camisa Riscas", sabe-se que a referncia clula que contm o desconto a aplicar : escales!A3 3. Infelizmente no se pode escrever algo do gnero: escales!A(valor de C3) 4. Pode-se no definir um texto que represente a referncia correcta. A parte fixa deste texto "escales!A", sendo a parte varivel o numero da linha, ou seja supondo que a frmula est a ser escrita para a segunda linha, o valor da clula C2. Se juntarmos estes dois valores ficamos com o texto "escales!A1" que representa a referncia pretendida.

51/61

Programao Informtica 1999/2000

5. Para juntar um texto a outro texto, ou a um valor, utiliza-se a funo CONCATENATE, ou seja a referncia textual clula que contm o desconto para o artigo na linha 2 da folha "artigos" : CONCATENATE("escales!A",C2) pois o valor de C2 indica a coluna onde se encontra o valor a descontar para o artigo da linha 2. 6. O problema agora resume-se a dada uma referncia em formato de texto obter a clula desejada. Para tal utiliza-se a funo INDIRECT, ou seja para obter o valor do desconto para o artigo na linha 2 temos de escrever algo do gnero: INDIRECT(CONCATENATE("escales!A",C2)) Podemos finalmente escrever a nossa expresso em Excel para o clculo do PVP como se ilustra na figura seguinte:

figura 3.12: Frmula para clculo do PVP com referncia a outra folha de clculo

Felizmente em VB as coisas so mais simples! Os conceitos j apresentados so quase suficientes para escrever a frmula, sendo s necessrio introduzir uma funo para acesso a uma clula noutra folha de clculo. Ao escrever Cells(linha, coluna) por omisso, a referencia a uma clula na folha de clculo activa. Para referenciar uma clula noutra folha de clculo escreve-se Worksheets(nome_da_folha_de_clculo).Cells(linha, coluna) Sendo assim a funo em VB fica
Function PVP(preo) IVA = Cells(1, 5) escalo = Cells(preo.Row, preo.Column + 1) desconto = Worksheets("escales").Cells(escalo, 1) PercentagemPagar = (100 - desconto) / 100 PVP = preo.Value * PercentagemPagar * IVA End Function

1 2 3 4 5

Apresenta-se de seguida a simulao de execuo desta funo assumindo que invocada com o parmetro B2, ou seja PVP(B2).
num 1 2 escalo 1 escalo 1 desconto percentagemPagar obs. IVA = valor da clula E1, ou seja 1.17 escalo = valor da clula C2,

52/61

Programao Informtica 1999/2000

ou seja a clula na coluna a seguir a B2. O valor 1. 3 1 1 15 desconto = valor da clula A1 (escalo = 1) da folha de clculo "Escales", ou seja, 15. 0.85 0.85 percentagemPagar = (100-15)/100 5 1 1 15 Como todos os dados agora calcula-se o PVP, ou seja PVP = 4500 * 0.85 * 1.17

15

Diferena entre esta verso da funo em VB e a anterior em que os descontos eram definidos artigo a artigo pequena, mas em Excel enorme!!! A formula em Excel de muito difcil leitura quando comparada com a funo em VB. Para tarefas com um grau de complexidade razovel o VB permite definir a soluo de forma mais clara e legvel.

3.2 Coleces de Clulas


Em Excel existe a noo de coleco de clulas ("range"). Em visual Basic possvel trabalhar com coleces de clulas da mesma forma que se trabalha com coleces de valores. Uma coleco de clulas em Excel tem a seguinte sintaxe clulaInicial:clulaFinal Por exemplo A1:A10 A3:D4 representa todas as clulas desde a A1 at a A10 representa as clulas A3,A4,B3,B4,C3,C4,D3,D4

O exemplo aqui apresentado a soma de uma coleco de clulas:

figura 3.13 Soma de uma coleco de clulas

A figura 3.13 apresenta uma folha de clculo onde se realiza a invocao de uma funo soma que recebe como parmetro uma coleco de clulas. O cdigo da funo exactamente igual ao definido para coleces de valores em 2.6.1:Ciclos FOR EACH.
Function total(coleco) soma = 0 For Each elem In coleco soma = soma + elem Next elem

53/61

Programao Informtica 1999/2000

total = soma End Function

3.3 Exemplos de Aplicao do VB ao Excel


Considere uma folha de clculo onde so armazenadas as cotaes dirias para empresas cotadas na Bolsa de Valores de Lisboa.

figura 3.14 Cotaes BVL

O primeiro exemplo aqui apresentado consiste em definir uma funo que determine em que coluna se encontram os dados de uma determinada empresa. O parmetro desta funo o nome da empresa. Para implementar esta funo deve-se percorrer a primeira linha da folha de clculo desde a segunda coluna at encontrar o nome da empresa ou at encontrar uma clula vazia (EMPTY).
Function procuraEmp(nome) col = 2 linha = 1 While (Cells(linha, col) <> Empty And Cells(linha, col) <> nome) col = col + 1 Wend If Cells(linha, col) = nome Then procuraEmp = col Else procuraEmp = "No Existe" End If End Function

Resultados desta funo sero: Invocao =procuraEmp("EDP") =procuraEmp("PT") =procuraEmp("EPT") Resultado 2 4 "No existe"

De seguida apresenta-se uma funo que dada uma coluna onde se encontram os dados de uma empresa devolve a ultima cotao disponvel. Para implementar esta funo define-se um ciclo que percorra a coluna passada como parmetro desde a segunda linha, primeira cotao, at encontrar uma clula vazia. O valor da clula na linha acima da linha onde se encontra a clula vazia o valor da ultima cotao.
Function ultimacot(coluna)

54/61

Programao Informtica 1999/2000

linha = 2 While Cells(linha, coluna) <> Empty linha = linha + 1 Wend ultimacot = Cells(linha - 1, coluna) End Function

Resultados desta funo sero: Invocao = ultimacot (2) = ultimacot (3) = ultimacot (4) Resultado 25.3 48.5 44.2

Seguidamente apresenta-se uma funo para determinar qual a linha onde se encontra uma determinada data. Esta funo semelhante apresentada para procurar uma empresa dado o seu nome, s que desta vez a procura realizada nas linhas e no nas colunas.
Function procuraData(data) col = 1 linha = 2 While (Cells(linha, col) <> Empty And Cells(linha, col) <> data) linha = linha + 1 Wend If Cells(linha, col) = data Then procuraData = linha Else procuraData = "No Existe" End If End Function

Finalmente apresenta-se uma funo que utilizando as funes acima definidas ir calcular a cotao de uma empresa numa determinada data. Para tal necessrio determinar em que coluna se encontra a empresa, seguidamente encontrar em que linha se encontra a data e finalmente devolver como resultado o valor da clula na linha e coluna encontradas.
Function cotao(emp, dia) col = procuraEmp(emp) linha = procuraData(dia) cotao = Cells(linha, col) End Function

Exemplo: escrever uma funo que tem como argumento um ndice de uma linha. O resultado desta funo o ndice da coluna que contem a primeira clula vazia.
Function procuraVazia(linha) i = 1 While (Cells(linha, i) <> Empty) i = i + 1

55/61

Programao Informtica 1999/2000

Wend procuraVazia = i End Function

Considerando a seguinte folha de clculo, o resultado da invocao procuraVazia(1) seria 5. A 1 2 2 B 3 1 C 2 2 D 4 3 E F 6 3 G 7 4 H

Caso se invocasse procuraVazia(2) Exerccio proposto: implemente uma funo para determinar a posio da ensima clula vazia. A funo dever receber como parmetro um ndice de uma linha. Exerccio: Escrever uma funo que some os elementos de uma linha desde o elemento a seguir primeira clula vazia at encontrar a segunda clula vazia.
Function soma2(linha) soma2 = 0 i = procuraVazia(linha) + 1 While (Cells(linha, i) <> Empty) soma2 = soma2 + Cells(linha, i) i = i + 1 Wend End Function

No caso da folha de clculo acima apresentada o resultado seria 6+7 = 13. Exerccio: Escreva uma funo que determine a soma dos elementos de uma coleco, considerando somente os elementos superiores mdia: Primeiro vamos calcular a mdia, e seguidamente realizaremos a soma.
Function mdia(A) soma = 0 For Each elem In A soma = soma + elem Next elem mdia = soma / A.Count() End Function

Esta primeira verso de uma funo para calcular a mdia contabiliza os elementos vazios no clculo da mdia. A verso seguinte no conta os elementos vazios.
Function mdia2(A) soma = 0 contador = 0

56/61

Programao Informtica 1999/2000

For Each elem In A soma = soma + elem If elem <> Empty Then contador = contador + 1 End If Next elem mdia2 = soma / contador End Function

A funo para realizar a soma


Function soma3(A) soma3 = 0 m = mdia(A) For Each elem In A If (elem > m) Then soma3 = soma3 + elem End If Next elem End Function

O resultado desta funo 17. Verifique! Exerccio proposto: faa uma simulao de execuo para as funes acima apresentadas.

57/61

Programao Informtica 1999/2000

3.4 Exemplos Avanados


Vamos agora imaginar uma funo mais complexa: Calcular a variao em escudos (ou juros) da cotao de uma determinada empresa desde um determinado dia at ltima data na folha de clculo. A funo implica os seguintes passos: 1. saber qual a coluna da empresa em questo 2. saber qual a ultima cotao da empresa 3. saber qual a cotao da empresa no dia pretendido 4. calcular a variao Para saber qual a coluna da empresa podemos utilizar a funo procura definida acima. Para saber a ltima cotao precisamos de saber a linha e a coluna. A coluna a coluna da empresa devolvida pela funo procura. Para saber qual a linha temos de construir uma funo que faa uma busca na primeira coluna, a das datas, procura da ultima casa preenchida, assume-se que no existem casas brancas entre duas datas.
Function procuraUltimaData() linha = 2 // primeira linha onde aparecem datas While (Cells(linha,1) <> Empty) linha = linha + 1 Wend procuraUltimaData = linha -1 End Function

Note-se que a varivel linha ao sair do ciclo indica a primeira linha no preenchida. O resultado da funo a linha anterior, ou seja a ltima linha preenchida. Para saber qual a cotao de um determinado dia precisamos tambm de saber qual a linha e coluna em que o valor se encontra. A coluna obtm-se como explicado anteriormente, para descobrir a linha temos de fazer uma procura de uma determinada data.
Function procuraData(d) linha = 2 // primeira linha onde aparecem datas While (Cells(linha,1) <> d) linha = linha + 1 Wend procuraData = linha End Function

Nesta funo assumimos que a data existe. Podemos agora construir a funo pretendida:
Function variao(empresa, data) emp = procura(1,2,empresa)

58/61

Programao Informtica 1999/2000

linhaUltimaData = procuraUltimaData() linhaData = procuraData(data) ultimaCotao = Cells(linhaUltimaData, emp) cotaoData = Cells(linhaData, emp) variao = ultimaCotao - cotaoData End Function

Um exemplo de invocao para determinar a variao da Brisa em escudos desde 6 de Janeiro de 99 seria:

figura 3.15 - Invocao da funo variao

Vejamos como seria a funo variao se no tivssemos decomposto o problema, ou seja se escrevssemos todo o cdigo numa s funo:
Function variao(empresa, data) emp = 2 While (Cells(1, emp) <> empresa) emp = emp + 1 Wend linhaUltimaData = 2 While (Cells(linhaUltimaData, 1) <> Empty) linhaUltimaData = linhaUltimaData + 1 Wend linhaUltimaData = linhaUltimaData - 1 linhaData = 2 While (Cells(linhaData, 1) <> data) linhaData = linhaData + 1 Wend ultimaCotao = Cells(linhaUltimaData, emp) cotaoData = Cells(linhaData, emp) variao = ultimaCotao - cotaoData End Function

Como podemos ver a leitura desta ltima funo bastante mais complicada, no entanto o resultado o mesmo, assim como a sua invocao. Ao decompor o problema nos sub problemas que o definem obtemos uma maior legibilidade. Podemos ainda complicar um pouco mais e pedir qual a coluna da empresa que registou a variao mxima em escudos. Ou seja uma funo para calcular o mximo das
59/61

Programao Informtica 1999/2000

variaes calculadas anteriormente. Esta funo s tem um parmetro, a data. A empresa no parmetro uma vez que todas as empresas vo ser testadas.
Function maxVar(data) col = 2

' col inicializado com a primeira coluna ' onde aparecem empresas

mximo = -99999

' o mximo colocado a um valor inferior ' a qualquer variao que se possa verificar

While (Cells(1, col) <> Empty)

' o ciclo termina quando no existirem mais empresas ' calculo da variao da empresa da coluna col ' para uma varivel auxiliar, var1

var1 = variao(Cells(1, col), data)

' se a variao for superior ao mximo at ento, ' alterar o mximo e a coluna da empresa ' que verificou a variao

If var1 > mximo Then mximo = var1 maxVar = col End If

' passar coluna seguinte

Wend End Function

col = col + 1

A invocao desta funo poderia ser

figura 3.16- Invocao da funo maxvar com a data 5 de Janeiro de 1999-01-23

Note-se que esta funo extremamente ineficiente j que ao invocar a funo variao para cada empresa estamos sempre a procurar a linha da data assim como da ultima data. Uma verso optimizada da funo poderia ser escrita reescrevendo a funo variao de modo a retirar as procuras nela existentes:
Function variao2(col_empresa, linhaData, linhaUltimaData) ultimaCotao = Cells(linhaUltimaData, col_empresa) cotaoData = Cells(linhaData, col_empresa) variao2 = ultimaCotao - cotaoData End Function

60/61

Programao Informtica 1999/2000

Nesta verso da funo variao temos como parmetros as linhas e a coluna em que se encontram os valores pretendidos, a funo s faz o clculo da diferena. A funo maxVar deve ento incluir as procuras necessrias para fornecer os parmetros funo variao
Function maxVar(data) col = 2 mximo = -99999 linhaData = procuraData(data) linhaUltimaData = procuraUltimaData() While (Cells(1, col) <> Empty) var1 = variao2(col, linhaData, linhaUltimaData) If var1 > mximo Then mximo = var1 maxVar = col End If col = col + 1 Wend End Function

A invocao exactamente igual da verso anterior, no entanto esta ltima funo mais eficiente pois s executa uma vez as funes procuraData e procuraUltimaData.

61/61

Você também pode gostar