Programação Avançada com Excel

56
Introdução O objetivo desse material é apresentar os fundamentos de resolução de problemas empresariais através de programas de computador e as técnicas básicas de construção de programas. A apresentação prática de exemplos e exercícios é feita utilizando a linguagem Visual Basic para Aplicativos, inserida no pacote Microsoft Excel para Windows(c). Os capítulos do livro obedecem à sequência de aulas apresentadas na disciplina de Introdução à Computação. Assim, esperamos que o leitor que estude do primeiro ao último capítulo, resolvendo todos os exercícios e projetos propostos, termine sua leitura preparado para resolver os mais diferenciados problemas empresariais através da construção de programas e utilização avançada dos recursos do Microsoft Excel para Windows. No Capítulo 1 descrevemos de forma sucinta o funcionamento interno do computador e de programas em geral. No Capítulo 2 apresentamos o funcionamento de planilhas eletrônicas em geral e do pacote Microsoft Excel para Windows em particular. No Capítulo 3 iniciamos o estudo de programação propriamente dito, com a incorporação de funções pré-programadas nas planilhas. No Capítulo 4 apresentamos os comandos de seleção. No Capítulo 5 apresentamos o comando básico de iteração. No Capítulo 6 apresentamos os conceitos de subrotina e macro e mostramos como efetuar entrada e saída de dados sem necessariamente utilizar uma planilha de apoio. No Capítulo 7 tratamos de simulação de programas para teste. Nesse capítulo tratamos também de novos tipos de dados, especificamente dos dados ``booleanos''. No Capítulo 8 estudamos como transmitir dados entre planilhas e programas. No Capítulo 9 tratamos da subdivisão de programas em funções, macros e subrotinas. No Capítulo 10 apresentamos como trabalhar simultaneamente com várias planilhas. No Capítulo 11 estudamos como trabalhar com vetores e matrizes. No Capítulo 12 estudamos programas para ordenação de valores, que além de permitirem utilizar boa parte do que foi estudado até aquele capítulo constituem uma classe de programas muito utilizados como procedimentos em outros programas. Finalmente, no Capítulo 13 estudamos manipulação e edição de strings por programas.

Transcript of Programação Avançada com Excel

Page 1: Programação Avançada com Excel

Introdução

O objetivo desse material é apresentar os fundamentos de resolução de problemas empresariais através de programas de computador e as técnicas básicas de construção de programas. A apresentação prática de exemplos e exercícios é feita utilizando a linguagem Visual Basic para Aplicativos, inserida no pacote Microsoft Excel para Windows(c).

Os capítulos do livro obedecem à sequência de aulas apresentadas na disciplina de Introdução à Computação. Assim, esperamos que o leitor que estude do primeiro ao último capítulo, resolvendo todos os exercícios e projetos propostos, termine sua leitura preparado para resolver os mais diferenciados problemas empresariais através da construção de programas e utilização avançada dos recursos do Microsoft Excel para Windows.

No Capítulo 1 descrevemos de forma sucinta o funcionamento interno do computador e de programas em geral. No Capítulo 2 apresentamos o funcionamento de planilhas eletrônicas em geral e do pacote Microsoft Excel para Windows em particular. No Capítulo 3 iniciamos o estudo de programação propriamente dito, com a incorporação de funções pré-programadas nas planilhas.

No Capítulo 4 apresentamos os comandos de seleção. No Capítulo 5 apresentamos o comando básico de iteração. No Capítulo 6 apresentamos os conceitos de subrotina e macro e mostramos como efetuar entrada e saída de dados sem necessariamente utilizar uma planilha de apoio. No Capítulo 7 tratamos de simulação de programas para teste. Nesse capítulo tratamos também de novos tipos de dados, especificamente dos dados ``booleanos''. No Capítulo 8 estudamos como transmitir dados entre planilhas e programas. No Capítulo 9 tratamos da subdivisão de programas em funções, macros e subrotinas. No Capítulo 10 apresentamos como trabalhar simultaneamente com várias planilhas. No Capítulo 11 estudamos como trabalhar com vetores e matrizes. No Capítulo 12 estudamos programas para ordenação de valores, que além de permitirem utilizar boa parte do que foi estudado até aquele capítulo constituem uma classe de programas muito utilizados como procedimentos em outros programas. Finalmente, no Capítulo 13 estudamos manipulação e edição de strings por programas.

Page 2: Programação Avançada com Excel

O que É um Computador Os computadores que usamos hoje em dia têm uma composição e uma organização comum, que passamos a apresentar a seguir.

A Unidade Central de Processamento executa a função principal do computador, que é processar as instruções armazenadas na memória. ``Processar'' significa:

1. buscar a próxima instrução na memória, 2. executar a instrução, 3. voltar para 1.

As instruções ficam codificadas na memória do computador, em uma linguagem própria chamada de Linguagem de Máquina. Uma instrução, por exemplo, é a instrução 1001000101001100011. O resultado da execução dessa instrução varia de acordo com o tipo de computador utilizado: um Macintosh fará uma coisa, um computador da linha PC fará outra, etc. Cada instrução identifica uma alteração e/ou inspeção do valor de uma posição da memória do computador.

Construir um programa diretamente na linguagem de máquina pode ser muito tedioso e demorado. Além disso, como a linguagem de máquina muda de computador para computador, a mesma solução de um problema requer diferentes programas em linguagem de máquina para ser aproveitada em diferentes computadores. Para sanar esses dois problemas, foram desenvolvidas as Linguagens de Alto Nível, que são códigos intermediários - mais interessantes de se usar do ponto de vista do programador - para os quais foram desenvolvidos ``tradutores'' para as linguagens de máquina dos diversos computadores. Assim, uma mesma solução de um problema codificada em uma linguagem de alto nível pode ser ``traduzida'' e utilizada em diferentes computadores. Por exemplo, a linguagem Visual Basic para Aplicações é uma linguagem de alto nível para a qual foram desenvolvidos ``tradutores'' denominados de Interpretadores: o mesmo programa pode ser usado em um Macintosh ou em um PC, bastando para isso que o interpretador apropriado (no caso, a versão apropriada do Microsoft Excel para Windows) esteja instalada no computador em uso.

A Memória do computador é aonde ficam armazenados os dados e instruções. Ela é organizada em Endereços de Memória, identificados por um código numérico que possibilita a identificação e acesso ao conteúdo de cada endereço.

O conteúdo da memória se apaga cada vez que o computador é desligado. Para armazenar de forma mais perene dados e programas, é preciso utilizar Dispositivos de Armazenamento: discos rígidos, disquetes, CD's, discos de Zip Drives, mini disks, fitas DAT, etc.

A ligação da Unidade Central de Processamento com o mundo exterior (ou seja, você) é feita através dos Dispositivos de Entrada e Saída: a tela do computador, o teclado, impressoras, o mouse, auto-falantes, câmeras e microfones para programas multimídia, scanners, etc.

Page 3: Programação Avançada com Excel

A tradução das instruções de uma linguagem de alto nível para a linguagem de máquina pode ser feita de duas maneiras diferentes:

1. através de um interpretador, que traduz os comandos ``passo-a-passo'' e na medida da necessidade; 2. através de um compilador, que primeiro traduz todos os comandos encontrados e armazena a tradução na memória como um conjunto de instruções na linguagem de máquina, e só depois executa todas essas instruções.

A principal diferença entre um interpretador e um compilador é que o segundo possibilita armazenar as instruções na linguagem de máquina diretamente, na forma de um arquivo de programa executável.

Toda a atividade da Unidade Central de Processamento, incluindo o controle dos dispositivos de armazenamento e de entrada e saída, é efetuada através de um programa especial, denominado de Sistema Operacional. Existem diversos sistemas operacionais disponíveis no mercado, cada um com suas peculiaridades e possibilidade de uso em computadores específicos: MacOS (que só funciona em computadores da linha Macintosh), Windows95 (que só funciona em computadores da linha PC), Unix (que tem diferentes versões e funciona em computadores diversos), etc.

A sequência usual para se resolver um problema utilizando o computador é:

1. estudar e analisar o problema para entender a sua estrutura; 2. codificar a resolução do problema como uma sequência lógica e ordenada de operações; 3. traduzir essa sequência de operações como instruções em uma linguagem de alto nível; 4. executar as instruções através do interpretador ou compilador apropriado.

Nos próximos capítulos estudaremos as técnicas específicas para desenvolver essa sequência em diferentes situações práticas.

Exercícios

1. Inserir a seguinte planilha de gastos pessoais:

A B C D E F

1 Gastos Cinema Almoço Gasolina Cônjuge Teatro

2 285 10 20 35 200 20

2. Formatar a tabela de várias formas:

• Adicionar ``,00'' após os números de forma automática; • Colocar o símbolo ``R$'' diante dos valores monetários,

automaticamente; • Mudar a formatação dos cabeçalhos das colunas.

Page 4: Programação Avançada com Excel

3. Salvar o documento:

• no disco; • em disquete; • movendo o arquivo do disco para o disquete.

4. Abrir um documento salvo.

Page 5: Programação Avançada com Excel

Introdução à Manipulação de Planilhas Eletrônicas Planilhas Eletrônicas são tabelas usadas para comunicar informações de forma clara, precisa e sucinta. Além de permitirem a comunicação de informações, elas também permitem a manipulação automática dessas informações através de fórmulas.

Assim, os dados que podemos inserir numa planilha podem ser dos seguintes tipos:

1. texto; 2. valores numéricos; 3. fórmulas.

Cada posição de uma planilha é chamada de Célula. Para se inserir um texto ou um número em uma célula, basta selecionar a célula e digitar o que se deseja:

• a seleção da célula pode ser feita usando o mouse ou as setas do teclado; • uma vez selecionada a célula, podemos editar seu conteúdo diretamente na

planilha ou no campo de edição localizado no topo da planilha; • para alterar uma célula que já contém algo escrito, primeiro selecionamos a

célula e depois temos 3 alternativas:

1. um duplo clique com o mouse nesta célula, que aciona um cursor que indica que podemos editar o seu conteúdo; 2. a tecla F2 no teclado, que produz o mesmo efeito do duplo clique com o mouse; 3. um clique com o mouse sobre o campo de edição no topo da planilha, que aciona um cursor no campo de edição e permite editar o conteúdo da célula a partir do campo de edição.

As Fórmulas se distinguem das células de texto e de números por serem iniciadas pelo símbolo `='. Por exemplo, uma célula contendo a expressão =3 + 4 é uma fórmula, que se avaliada produz o resultado esperado (ou seja o valor numérico 7); já uma célula contendo apenas a expressão 3+4 (sem o símbolo `=') é sómente um texto composto por três caracteres: ``3'', ``+'' e ``4''.

Após o término da edição de uma fórmula, não obtemos a cadeia de caracteres que foi digitada, mas sim o valor computado a partir dela. Por exemplo, após digitarmos = 3 * 5 + (7 - 2)obtemos o valor 20. No entanto, a cadeia de caracteres que define a fórmula (ou seja, ``= 3 * 5 + (7 - 2)'') aparece no campo de edição no topo da planilha.

Cada célula na planilha possui um nome. O nome da célula é dado no formato ``batalha naval'': cada coluna da planilha é nomeada com uma letra, e cada linha é nomeada com um número. Por exemplo, a célula que se encontra terceira linha da coluna D é a célula D3.

Nas fórmulas, em qualquer lugar em que podemos inserir um número numa expressão aritmética podemos também inserir uma referência a uma célula. Por exemplo, suponha

Page 6: Programação Avançada com Excel

que queiramos que na terceira linha da planilha a terceira célula seja a soma da primeira com a segunda. Para isso, escrevemos:

A B C

1

2

3 7 3 =A3+B3

Neste caso, a célula C3 mostrará o valor 10.

Quando trabalhamos com tabelas, muitas vezes queremos repetir em todas as linhas uma mesma operação. Por exemplo, se tivermos uma tabela com quatro linhas e quisermos que a terceira coluna seja sempre a soma das duas primeiras, basta escrever a fórmula na primeira linha e copiá-la para as outras linhas.

A título de ilustração, vamos supor que temos uma tabela com valores de Capital Inicial ($) e Taxa de Juros Mensal (%) e desejamos calcular o Capital Final, a juros simples, no final de 6 meses. A fórmula para o Capital Final é Cf = Ci * (1 + n * i/100), onde Ci é dado na primeira coluna, i é dado na segunda coluna e n é sempre igual a 6. Começamos com a tabela:

A B C

1 Capital Inicial Ci Taxa de Juros i Capital Final Cf

2 100,00 2,00 =A2*(1+6*(B2/100))

3 100,00 3,00

4 200,00 2,50

5 200,00 3,50

Em seguida, copiamos a fórmula em C2 para as demais linhas. Isso é feito colocando o mouse sobre o canto inferior direito da célula (o cursor deve se transformar em um ``+''), clicando e arrastando o mouse sobre as linhas desejadas. O resultado é:

A B C

1 Capital Inicial Ci Taxa de Juros i Capital Final Cf

2 100,00 2,00 =A2*(1+6*(B2/100))

3 100,00 3,00 =A3*(1+6*(B3/100))

4 200,00 2,50 =A4*(1+6*(B4/100))

Page 7: Programação Avançada com Excel

5 200,00 3,50 =A5*(1+6*(B5/100))

Observe que a própria planilha modificou apropriadamente as referências às células das diferentes linhas. Caso isso não fosse desejado (se as cópias desejadas fossem sempre referenciando a célula B2, por exemplo), então a fórmula inicial deveria ser escrita

como . Isso significa que todas as fórmulas geradas usariam o valor da célula B2,

ao invés de como acima. O mesmo vale para cópias de fórmulas através de linhas da planilha.

Exercícios

1. Insira numa planilha a tabela de juros simples vista acima. 2. Crie uma outra planilha igual à primeira, só que desta vez usando juros compostos. A fórmula para juros compostos é Cf = Ci * (1 + i )n, onde:

• Cf: Capital final • Ci: Capital inicial • i: taxa de juros mensal • n: número de meses

3. Considere a seguinte tabela de importação:

Produto Valor (US$) Valor (R$)

Cranberry Sauce 1.74

Whisky Cardu 12 anos 18.89

Queijo Cheddar Maturado 5.89

Massa instantânea p/ panquecas 3.78

Custo total

Preencha a coluna de valor em R$, baseada na conversão de US$ 1,00 = R$ 1,95.

4. Considere a fórmula de conversão de temperatura entre graus Celsius e Farenheit:

C/5 = (F - 32)/ 9

Construa uma tabela com as informações:

Temperatura Farenheit Temperatura em Celsius

Page 8: Programação Avançada com Excel

Faça a primeira coluna variar a temperatura Farenheit de 0 a 100 em intervalos de 10. A segunda coluna deverá conter a temperatura correspondente em Celsius.

Page 9: Programação Avançada com Excel

Programação e Utilização de Funções Além de números e referências a células, as fórmulas em uma planilha podem conter Chamadas de Funções.

Uma chamada de função tem o formato Nome-da-Função( Lista-de-Parâmetros), onde Nome-da-Função é um nome qualquer iniciando com uma letra (de A a Z) e Lista-de-Parâmetros é um número fixo de parâmetros que precisam ser fornecidos na ordem correta. Os parâmetros no Microsoft Excel para Windows em português são separados por `;' e no Microsoft Excel para Windows em inglês por `,'. Os parâmetros podem ser:

1. números; 2. referências a células; 3. expressões aritméticas quaisquer.

No exemplo abaixo vemos uma função de nome JurosSimples com 3 parâmetros. Os dois primeiros parâmetros são referências a células e o último é um número. Neste caso, o primeiro parâmetro deve conter o Capital Inicial, o segundo a Taxa de Juros Mensal e o terceiro o Número de Meses. A função deve retornar o capital final calculado a juros simples:

A B C

1 1000 25 =JurosSimples(A1; B1; 6)

O Símbolo de `=' na frente da chamada de função indica que a chamada da função ocorre dentro de uma fórmula. Num exemplo um pouco mais sofisticado, temos expressões aritméticas passadas como parâmetros:

A B C

1 1000 25 =JurosSimples(A1/2; B1+10; 6)

Uma chamada a função pode ocorrer em uma fórmula exatamente nos mesmos lugares em que podem ocorrer números ou referências a células. Muitas vezes, como nos exemplos acima, a fórmula contém apenas a chamada da função. Suponhamos agora que nós temos a função de nome INT que recebe como parâmetro um número e retorna a parte inteira do número. Por exemplo, na situação abaixo a fórmula deve retornar o valor 5, resultado da soma da parte inteira de 2,5 com 3.

A B

1 2,5 =INT(A1)+3

Page 10: Programação Avançada com Excel

As funções no Excel são divididas em dois tipos:

1. funções pré-definidas: estas funções ``vêm dentro'' do Excel. A função INT do exemplo acima é uma função pré-definida. Há uma lista bastante grande destas funções, mas não nos ocuparemos dela agora. 2. funções programadas: estas funções não existem ``dentro'' do Excel e nós precisamos criá-las. Ou seja, precisamos programar a função para que depois possamos usá-la numa planilha (ou numa outra função). Por exemplo, a função JurosSimples acima não existe pré-definida e se quisermos usá-la precisaremos programá-la. Boa parte dos próximos capítulos será dedicada a ensinar como se programa uma função. Vamos agora começar a examinar os ingredientes necessários para a construção de uma função. O primeiro passo necessário para construir uma função é criar um Módulo. Toda função que definirmos deverá estar dentro de um módulo. Para criarmos um módulo no Excel basta ativarmos o menu Inserir|Macro|Módulo (nas versões mais recentes do Excel este procedimento pode ser diferente). Uma vez criado, o módulo passa a ser parte integrante do documento, da mesma forma que as várias planilhas que compõem o documento, e vai ser salvo e aberto junto com o documento.

Um módulo, tal como uma planilha, também possui um nome, que fica localizado na aba na parte inferior da janela do Excel. Dentro do módulo podemos definir uma ou mais funções. Todas as funções definidas nos módulos podem ser chamadas de qualquer planilha do mesmo documento.

A definição de uma função possui 3 partes:

1. o cabeçalho: informa que estamos definindo uma função, qual o seu nome, quais são seus parâmetros e que tipo de valor a função retorna. 2. o corpo da função: é a parte que define qual a computação que deverá ser processada quando a função for chamada. 3. o término da função: indica que terminou a definição da função.

Uma outra função poderá ser definida logo em seguida. O formato genérico de uma função é o seguinte:

Function NomeDaFunção( Param1 As Tipo, ..., ParamN As Tipo ) As Tipo Aqui vem o corpo da função NomeDaFunção = Valor de Retorno End Function

As palavras em negrito são palavras reservadas da linguagem e devem aparecer desta forma e nesta posição. A primeira linha é o cabeçalho; a última linha é o término. Tudo que fica entre o cabeçalho e o término é o corpo da função. Note que imediatamente antes do término da função colocamos a expressão de retorno da função. Vamos agora detalhar os elementos que aparecem na definição da função. O cabeçalho da função possui o formato genérico Function NomeDaFunção( Param1 As Tipo, ..., ParamN As

Page 11: Programação Avançada com Excel

Tipo ) As Tipo. Um exemplo de cabeçalho de função é o seguinte: Function JurosSimples( CapitalInicial As Double, Taxa As Double, NMeses As Integer ) As Double. Neste exemplo, vemos que o nome da função é JurosSimples, e que a função possui 3 parâmetros. Cada parâmetro é uma variável do programa, e está associado a um tipo de dados. No exemplo, temos dois tipos de dados sendo usado: o tipo Double, que indica que a variável deve ser tratada como um número real (com parte inteira e fracionária); e o tipo Integer, que indica que a variável deve ser tratada como um número inteiro. Os parâmetros são separados por meio de vírgulas. Note que a função como um todo também está associada a um tipo de retorno, que é o tipo de dado retornado pela função; no caso, o tipo Double. Note também que o cabeçalho foi dividido em várias linhas.

Cada comando do programa (inclusive o cabeçalho) deve ser colocado inteiramente numa linha. Quando isto não é possível, precisamos indicar que a próxima linha é, na realidade, continuação da linha anterior. Fazemos isso colocando o símbolo de sublinhado no final da linha.

Vejamos agora um programa completo que calcula juros simples:

Function JurosSimples( CapitalInicial As Double, Taxa As Double, NMeses As Integer ) As Double Dim CapitalAcrescido As Double CapitalAcrescido = CapitalInicial * (Taxa/100) * NMeses JurosSimples = CapitalInicial + CapitalAcrescido End Function

A primeira observação é que o programa é basicamente uma manipulação de variáveis. Neste programa, temos as seguintes variáveis: CapitalInicial, Taxa, NMeses, CapitalAcrescido, JurosSimples. Varíaveis são os elementos do programa que armazenam informações. A informação armazenada em uma variável é o seu conteúdo. O nome da variável (por exemplo CapitalInicial no exemplo acima) é fixo, mas o seu conteúdo pode mudar (daí o nome variável). Toda variável tem um tipo (Integer, Double, etc.). As variáveis que constam no cabeçalho da função têm seu tipo declarado no próprio cabeçalho. As variáveis internas devem ser declaradas com seus respectivos tipos. No exemplo acima, temos a declaração Dim CapitalAcrescido As Double que declara a variável interna CapitalAcrescido como sendo do tipo Double, ou seja, um número real calculado usando dupla precisão. Para alterarmos o valor de uma variável, usamos um comando de atribuição. Por exemplo, o comando CapitalAcrescido = CapitalInicial * (Taxa/100) * NMeses no exemplo acima, que atribui o resultado da expressão à variável CapitalAcrescido.

Observe que o comando de atribuição é diferente da igualdade algébrica com que estamos habituados: por exemplo, os comandos

X = 0

X = 1

apresentados nessa sequência são perfeitamente coerentes, atribuindo o valor 0 à variável X e posteriormente o valor 1 à mesma variável. Isso não é o mesmo que

Page 12: Programação Avançada com Excel

afirmar que 0 = 1. Como um outro exemplo, o comando X = X+1 soma 1 ao valor atual de X e atribui o resultado como novo valor de X. Obviamente, essa expressão não faria sentido se a interpretássemos como uma indicação de igualdade.

Até aqui já utilizamos dois tipos de dados: números inteiros (Integer) e reais (Double). Mais adiante também encontraremos o tipo String, que é o tipo de dados das variáveis que armazenam texto. Também encontraremos o tipo Boolean, que é um tipo de dados que possui apenas 2 dois valores: TRUE e FALSE.

Exercícios

1. Faça uma função CMparaPOL que recebe uma medida em centímetros e a devolve em polegadas, onde 1 polegada = 2,54 cm. Faça também a função inversa POLparaCM, que converte de polegadas para centímetros. 2.Considere um polinômio do segundo grau p(x) = a * x2 + b*x + c.

(a):Escreva uma função PDEX que recebe números reais (isto é, números do tipo DOUBLE) a, b, c e x e calcula o valor de um polinômio do segundo grau. Use uma variável interna que armazena o valor de x2. (b) :Crie uma planilha com três colunas, que avalia o polinômio p(x) = x2 - 7*x + 12 para valores de x de 0 a 10. A primeira coluna contém os valores de x, a segunda os de p(x) e a terceira escreve o texto ``Raiz'' caso p(x) seja 0; caso contrário não escreve nada.

3.Considere uma equação do segundo grau a * x2 + b*x + c = 0.

(a):Escreva uma função DELTA, que recebe como parâmetros os números reais a, b e c e retorna o valor do discriminante da equação, b2 -4ac. (b):Crie uma planilha de 5 colunas. As três primeiras contêm os coeficientes da equação do segundo grau. A quarta contém o valor do discriminante. A quinta contém o texto:

• ``Uma única raiz'', se o discriminante for nulo. • ``Nenhuma raiz real'', se o discriminate for negativo. • ``Duas raizes reais'', se o discriminante for positivo.

(c):Invente valores para as três primeiras colunas que gerem os três tipos de determinante. Insira uma sexta coluna que, no caso de discriminante nulo, calcula esta raiz única, que será igual a -b/2a.

Page 13: Programação Avançada com Excel

Comandos de Seleção (IF-THEN e IF-

THEN-ELSE) Os comandos IF-THEN e IF-THEN-ELSE permitem selecionar quais os comandos que serão executados dependendo de uma condição.

O comando IF-THEN tem o seguinte formato:

If Condição Then Comando 1

Comando N End If Comando N+1

O comportamento do comando IF-THEN é o seguinte: primeiramente a condição é avaliada, podendo resultar em dois valores: TRUE (verdadeiro) ou FALSE (falso). Se a condição for verdadeira, os comandos 1 até N serão executados e, em seguida, o comando N+1. Se a condição for falsa, nenhum dos comandos de 1 a N será executado e o programa irá diretamente para o comando N+1. Por outro lado, o comando IF-THEN-ELSE tem o seguinte formato:

If Condição Then Comando 1

Comando N Else Comando N+1

Comando N+M End If Comando N+M+1

O comportamento do comando IF-THEN-ELSE é o seguinte: A condição é avaliada; se ela for verdadeira, os comandos de 1 até N serão executados; se a condição for falsa, os comandos de N+1 a N+M serão executados. Em ambos os casos, o comando posterior a ser executado será o comando N+M+1.

Vejamos como exemplo o cálculo de juros progressivos em um investimento financeiro. Se a conta contém um saldo inferior a R$10.000,00, então o banco paga juros mensais de 2%. Para saldo superiores a R$10.000,00 o banco paga 3%. A função TaxaProgressiva1 calcula o saldo da conta no final de um mês.

Function TaxaProgressiva1 (Saldo As Double) As Double 'saldo ao fim de um mes 'com taxa progressiva

Page 14: Programação Avançada com Excel

'Declaracoes Dim Taxa As Double 'Descobre o valor da taxa If Saldo < 10000 Then Taxa = 0.02 Else Taxa = 0.03 End If 'Retorno da funcao TaxaProgressiva1 = Saldo * (1+ Taxa) End Function

Outra forma de se computar exatamente a mesma função:

Function TaxaProgressiva2 (Saldo As Double) As Double 'saldo ao fim de um mes 'com taxa progressiva 'Declaracoes Dim Taxa As Double Dim Acrescimo As Double 'Descobre o valor da taxa If Saldo < 10000 Then Taxa = 0.02 Acrescimo = Saldo * Taxa Else Taxa = 0.03 Acrescimo = Saldo * Taxa End If 'Retorno da funcao TaxaProgressiva2 = Saldo + Acrescimo End Function

Conforme vimos no exemplo acima, as expressões condicionais são formadas por comparadores (o símbolo < no exemplo acima).

Uma expressão condicional simples tem o formato Expressão Aritmética comparador Expressão Aritmética. Os comparadores lógicos podem ser:

• = (igual a) • < (menor que) • > (maior que) • <= (menor ou igual a) • >= (maior ou igual a) • <> (diferente)

Desta forma, podemos formar expressões condicionais como (X + 2 <= Y*Z).

Page 15: Programação Avançada com Excel

As expressões condicionais simples podem ser combinadas para formarem expressões condicionais compostas. Temos os seguintes combinadores lógicos:

• AND (conjunção) • OR (disjunção) • NOT (negação)

Por exemplos, uma expressão condicional que testa se uma variável X está entre os

valores MIN e MAX (inclusive) é

Se quisermos verificar se Y NÃO está entre MIN e MAX, podemos fazê-lo de duas

formas: ou . Retomando o exemplo dos juros progressivos, se a conta contiver um saldo inferior a R$10.000,00 então o banco pagará juros mensais de 2%. Para cada R$5.000,00 adicionais acima de R$10.000,00 o banco pagará 0,5% a mais, até atingir a taxa limite de 4%. A função TaxaProgressiva3 fica:

Function TaxaProgressiva3 (Saldo As Double) As Double 'saldo ao fim de um mes 'com taxa progressiva 'Declaracoes Dim Taxa As Double 'Descobre o valor da taxa If Saldo < 10000 Then Taxa = 0.02 ElseIf Saldo < 15000 Then Taxa = 0.025 ElseIf Saldo < 20000 Then Taxa = 0.03 ElseIf Saldo < 25000 Then Taxa = 0.035 Else Taxa = 0.04 End If 'Retorno da funcao TaxaProgressiva3 = Saldo * (1+ Taxa) End Function

Exercícios

1. Considere a seguinte classificação de consumidores, baseada na percentagem do salário gasto com itens da cesta básica:

Esbanjador até 25% (inclusive)

Gastador entre 25% e 53% (inclusive)

Page 16: Programação Avançada com Excel

Comedido entre 53% e 75% (inclusive)

Essencial entre 75% e 95% (inclusive)

(a) Fazer um programa ClassificaConsumo, que recebe um número de 0 a 100 (real), representando a percentagem do salário gasta por uma família com itens da cesta básica, e retorna uma cadeia (string), contendo a classificação correspondente. (b) Fazer uma planilha com duas colunas. Na primeira, a percentagem do salário gasta por uma família com itens da cesta básica, que deve ir variando de 0 a 100% em intervalos de 10%. A segunda coluna contém a classificação. (c) O que acontece com 100%?

2.Na vida real, as fronteiras de classificação são menos definidas. Suponha que nós tenhamos a seguinte classificação, ``com buracos'':

Esbanjador até 20%

Gastador entre 25% e 45%

Comedido entre 53% e 75%

Essencial entre 80% e 95%

(a) Fazer um programa ClassificaConsumo2 tal que, se algum percentagem for fornecida que não é coberta pelos intervalos acima, o programa deve fornecer a cadeia "INDEFINIDO". (b) Fazer uma planilha semelhante à do exercício anterior.

3.Considere uma equação do segundo grau (a * x2 + b*x + c = 0). Utilizando a função DELTA desenvolvida nos exercícicios do capítulo anterior, escreva um programa que calcula a(s) raíz(es) desta equação, tal que:

(a) Se não houver raízes (Delta < 0), o programa retorna -9999. (b) Se houver uma única raiz (Delta = 0), o programa retorna o valor da raiz única igual a -b/2a. (c) Se houver duas raízes (Delta 0) o programa calcula as duas raízes: (x1 = ( -b - SQRT(Delta) )/ (2*a)) e (x2 = ( -b + SQRT(Delta) )/ (2*a))onde SQRT(X) é uma função pré-definida que calcula a raiz quadrada. O programa deve retornar a maior das duas raízes.

Crie uma planilha de 4 colunas. As três primeiras contêm os coeficientes da equação do segundo grau. A quarta contém o valor da maior raiz.

Page 17: Programação Avançada com Excel

Comando de Iteração (DO WHILE-

LOOP) A idéia básica da iteração é fazer com que uma série de comandos seja repetida enquanto uma determinada condição for verdadeira; quando a condição se tornar falsa, a repetição termina.

O comando básico de iteração (embora não seja o único comando capaz de iterar) é o comando DO WHILE-LOOP. Este comando possui o seguinte formato:

Do While Condição Comando 1

Comando N Loop Comando N+1

A região entre o início do comando, em Do While, e seu fim, em Loop, é chamada de malha, laço, ciclo ou, no original em inglês, ``loop''.

O comportamento do comando DO WHILE-LOOP é o seguinte: inicialmente a condição é testada. Se for falsa, nenhum comando dentro da malha é executado, e a execução prossegue no comando N+1. Se a condição for verdadeira, o programa prossegue executando um a um os comandos de 1 a N. Ao terminar o comando N, ou seja, ao atingir a instrução Loop, o programa volta ao início da malha e testa a condição novamente. Se ela continuar verdadeira então novamente são executados os comandos de 1 a N; caso contrário, a iteração termina e o programa sai da malha e prossegue a partir do comando N+1.

Desta forma, a condição de entrada controla quantas vezes a iteração será repetida. Enquanto ela permanecer verdadeira, o interior da malha será repetido. Pode ser que ela nunca fique falsa; isso quer dizer que o programa não pára nunca, e é um programa defeituoso. Portanto, bastante cuidado com o uso da iteração.

Por exemplo, vejamos o programa elevadoa(X,Y) que calcula XY. A idéia básica é

multiplicar o número X por ele mesmo Y vezes, ou seja:

XY = 1 * X * ... * X onde X aparece Y vezes.

O valor 1 aparece como um valor inicial e, obviamente, não influencia o resultado final. Além disso, a presença do número 1 no cáculo garante que o resultado seja correto mesmo quando Y = 0, pois nesse caso X0 = 1:

Function elevadoa(Num As Integer, expoente As Integer) As Integer Dim cont As Integer Dim result As Integer 'Inicialização result = 1

Page 18: Programação Avançada com Excel

cont = 0 'Malha principal Do While cont < expoente result = result * Num cont = cont + 1 Loop 'Finalização elevadoa = result End Function

Vejamos agora como calcular o fatorial de um número inteiro N, normalmente representado por N!:

N! = N * N-1 * N-2 * ... * 2 * 1

Uma das formas possíveis para computarmos o fatorial de um número é procedermos da direita para a esquerda, ou seja, começamos com um contador com o número 1, vamos incrementado-o e armazenado o valor da multiplicação em um acumulador de resultados intermediários, da seguinte forma: a cada passo da iteração, incrementamos o contador e multiplicamos esse valor pelo acumulador, armazenando o resultado no próprio acumulador. O processo continua até que o contador alcance o valor de N. Nesse instante o acumulador terá o valor do fatorial desejado:

Function fatorial(Num As Integer) As Integer Dim cont As Integer 'contador do numero atual Dim result As Double 'acumulador do resultado parcial 'Inicialização result = 1 cont = 1 'Malha principal Do While cont <= Num result = result * cont cont = cont + 1 Loop 'Finalização fatorial = result End Function

Vamos estudar o caso agora de juros compostos com uma taxa de juros que varia progressivamente com o tempo, em incrementos fixos. Por exemplo, podemos ter uma taxa de juros inicial de 2% e incrementos de 0.1% mensais: no primeiro mês a taxa de juros será de 2%, no segundo será 2,1%, etc. até o décimo-primeiro mês, quando será de 3%. Um dado capital inicial deverá sofrer juros compostos (acumulados) onde a taxa mensal varia progressivamente. Uma função que calcula o capital acumulado ao final de vários meses é a seguinte:

Function JurosProgr(CapIni As Double,TaxaIni As Double,IncrTaxaMensal As Double,NMeses As Integer) As Double

Page 19: Programação Avançada com Excel

'Computa o capital final com juros progressivos: a taxa de juros 'vai sendo incrementada mensalmente pelo valor IncrTaxaMensal (que 'pode ser negativo!!!) Dim mes As Integer 'Número de meses desde o início do investimento Dim TaxaAtual As Double 'Taxa do mes corrente Dim CapAtual As Double 'Capital ao final do mes corrente 'Inicialização CapAtual = CapIni 'Capital no iníco do primeiro mês TaxaAtual = TaxaIni 'Taxa no início primeiro mês mes = 1 'Primeiro mes 'Malha principal Do While mes <= NMeses 'Calcula o capital no final do mês corrente CapAtual = CapAtual * (1 + TaxaAtual / 100) 'Próximo mês mes = mes + 1 'Calcula a taxa do próximo mês TaxaAtual = TaxaAtual + IncrTaxaMensal Loop 'Retorno da função JurosProgr = CapAtual 'Capital ao fim de NMeses End Function

Exercícios

1. Fazer um programa que calcule a soma dos N primeiros números inteiros: 1 + 2 + 3 + ... + N

Fazer uma planilha que testa este programa para valores de N= 1, 5, 10, 15, 25

2. Fazer uma função S(N) que calcule a seguinte soma para N termos:

Fazer uma planilha que testa este programa para valores de N= 1, 5, 10, 15, 25.

3. Dados dois inteiros positivos N e P, escreva uma função que calcula a combinação de N sobre P:

Page 20: Programação Avançada com Excel

Note que tanto o numerador quando o denominador possuem P fatores. A

combinação de N sobre P pode ser também expressa por . Computacionalmente, a primeira versão é a mais eficiente, voce sabe explicar por quê? (Dica: conte o número de iterações em cada caso). A função deve

retornar 1 se .

Fazer uma planilha para N=10 e P variando de 0 a 15.

4. (a) Fazer uma função PA(N,A1,R) que calcula o N-ésimo termo de uma progressão aritmética de termo inicial A1 e razão R. Lembre-se de que Ai = R + Ai-1. (b) Fazer uma função PG(N,A1,R) que calcula o N-ésimo termo de uma progressão geométrica de termo inicial A1 e razão R. Lembre-se de que Ai = R * Ai-1.

Page 21: Programação Avançada com Excel

Subrotinas, Macros, Entrada e Saída de dados Até agora vimos apenas programas no formato função. Funções possuem as seguintes propriedades:

• Para acioná-las, podemos inserir uma chamada dentro de uma fórmula de uma planilha. No entanto, não sabemos (ou não temos como) chamar uma função ``de fora'' da planilha.

• A única forma de passar dados para uma função é através dos parâmetros de entrada (veremos mais adiante que isso pode ser relaxado um pouco, mas, de qualquer forma, os dados obtidos por uma função vão sempre se originar da planilha).

• A única forma de uma função passar dados de volta para a planilha é através de um (único) valor ao final da computação.

Vamos agora ver uma forma de ativar programas de maneira independente de uma planilha, obter informações de ``fora'' da planilha e poder não retornar nenhum valor, e comunicar resultados ao usuário por meio de janelas.

A isso se dá o nome de subrotina ou procedimento. Uma subrotina possui o seguinte formato

Sub NomeSub( <Lista de Parâmetros> )

End Sub

Subrotinas diferem de funções por não retornarem um valor. Por isso, não associamos um tipo de dados às subrotinas. Tampouco podemos utilizar o nome da subrotina como variável.

Uma classe especial de subrotinas que nos é muito interessante é a classe de subrotinas em que a lista de parâmetros é vazia. Neste caso, a subrotina é chamada de macro e pode ser ativada de forma independente da planilha.

A ativação de macros é feita acionando-se o menu Ferramentas|Macros, que fará aparecer uma janela contendo uma lista de todas as macros existentes nos módulos do programa. Como não há passagem de parâmetros para macros, basta selecionar uma macro nesta lista, e acionar o botão Executar.

Mas se não há passagem de parâmetros nem retorno de valor, como passar e receber

dados de uma macro? Para isso, o código da macro precisa acionar comandos de entrada e saída, que gerarão janelas de comunicação através das quais se fará a passagem da informação. Se quisermos entrar com algum dado, deveremos inserir na subrotina uma chamada à função via InputBox, da seguinte maneira:

Texto = InputBox( ``Entre com um valor'' )

Page 22: Programação Avançada com Excel

Ao executarmos este comando, primeiramente aparecerá uma janela contendo:

• o texto ``Entre com um valor'' enviando uma mensagem ao usuário; • um campo em branco para ser preenchido; • e um botão de OK.

Deveremos preencher o campo em branco e então clicar no botão (ou apertar ENTER). O String digitado no campo será atribuído à variavel Texto, que deverá, portanto, ser do tipo String.

Se desejarmos ler um valor numérico ao invés de String, o valor inserido será convertido para o tipo apropriado. Para isso, utilizamos as duas funções pré-definidas CDbl(String) e CInt(String) que convertem o parâmetro String respectivamente em um valor equivalente do tipo Double ou Int.

Em geral, fazemos a chamada a InputBox e a conversão por CDbl ou CInt num mesmo comando, como mostra o exemplo abaixo:

Dim Nprods As Integer Dim Preco1 As Double Nprods = CInt( InputBox( ``Entre a quantidade de produtos:'' )) Preco1 = CDbl( InputBox( ``Preço do primeiro produto'' ))

que terá o efeito de primeiro mostrar uma janela de diálogo cujo valor preenchido deverá ser o número de produtos, e em seguida uma outra caixa de diálogo que deverá ser preenchida com o preço do primeiro produto.

Além de solicitar dados ao usuário, uma macro pode exibir alguma informação, por exemplo o resultado de alguma computação. Esta comunicação pode ser feita na forma de uma janela que mostra o texto ao usuário e um botão de OK que o usuário pode clicar ao terminar de ler a mensagem.

O comando que faz isso é o comando MsgBox(String), que mostra o conteúdo do String ao usuário em uma janela. Por exemplo, supondo que a variável MIN é do tipo Double e contém o valor 27,32,

MsgBox( ``O melhor preço é: '' & MIN )

faz aparecer uma janela com a mensagem:

O melhor preco é: 27,32

Se quisermos que a mensagem exibida seja quebrada em diversas linhas, devemos incluir nos pontos desejados o caracter que codifica o comando ``mude de linha''. Por exemplo,

MsgBox( ``Isto aqui é uma'' & Chr(13) & ``linha quebrada.'' )

produz como resultado:

Page 23: Programação Avançada com Excel

Isto aqui é uma linha quebrada.

Vejamos por exemplo a macro SomaNum que nos solicita 4 valores (representando por exemplo preços de vários produtos para um pedido de compra) e calcula a sua soma:

Sub SomaNum() Dim Soma As Double Dim Cont As Integer Dim Valor As Double 'Inicialização Soma = 0 Cont = 0 Valor = 0 '(Desnecessário, apenas ajuda a entender o programa) Do While Cont < 4 'Le novo valor, convertendo-o para Double Valor = CDbl(InputBox(``Entre com o valor '')) 'Atualiza a soma Soma = Soma + Valor 'Prepara a próxima iteração Cont = Cont + 1 Loop 'Apresenta resposta MsgBox (``A soma é: '' & Soma) End Sub

Esta macro pode ser ``embelezada'' de forma a não ficar presa a um número fixo de valores nos solicitando, no início da execução, qual o número desejado de valores. Também podemos ``embelezar'' a solicitação dos valores, indicando a posição na seqüência de cada valor. Desta forma, criamos SomaNum1:

Sub SomaNum1() Dim Soma As Double Dim Cont As Integer Dim Valor As Double Dim N As Integer 'Inicialização Soma = 0 Cont = 0 Valor = 0 'Desnecessário N = CInt(InputBox(``Número de valores a serem somados: '')) Do While Cont < N 'Le novo valor, convertendo-o para Double Valor = CDbl(InputBox(``Entre com o valor '' & (Cont + 1))) 'Atualiza a soma Soma = Soma + Valor 'Prepara a próxima iteração Cont = Cont + 1 Loop 'Apresenta resposta

Page 24: Programação Avançada com Excel

MsgBox (``A soma dos '' & N & `` valores é: '' & Soma) End Sub

Podemos sofisticar ainda mais este programa, nos liberando de dizer no início quantos valores iremos entrar. Podemos assumir que todos os valores são positivos e assim, ao entrarmos um número negativo, estaremos encerrando a seqüência de preços. Assim, criamos SomaNum2:

Sub SomaNum2() 'Calcula a soma até encontrar um número menor ou igual a 0. Dim Soma As Double Dim Valor As Double 'Inicialização Soma = 0 Valor = CDbl(InputBox(``Entre com um valor.'' & Chr(13) & ``[Valor negativo para terminar]'')) 'Chr(13) é o caracter para mudar de linha Do While Valor > 0 'Atualiza a soma Soma = Soma + Valor 'Prepara a próxima iteração 'Le novo valor, convertendo-o para Double Valor = CDbl(InputBox(``Entre com um valor.'' & Chr(13) & ``[Valor negativo para terminar]'')) Loop 'Apresenta resposta MsgBox (``A soma dos valores é: '' & Soma) End Sub

Para finalizar, mostramos um programa que solicita 4 preços do usuário e retorna o menor:

Sub MelhorPr() Dim Min As Double 'menor preço até o momento Dim Preco As Double 'valor do produto atual Dim Cont As Integer 'contador de produtos 'Inicialização Min = 9E+99 'Este eh um valor muito alto: 9*1099 Cont = 0 MsgBox (``Você deverá entrar com o preço de'' & Chr(13) & ``um produto para quatro fornecedores.'') Do While Cont < 4 'Lê o preço do produto, convertendo-o para Double Preco = CDbl(InputBox( ``Preço do produto do fornecedor '' & (Cont + 1) & ``:'' )) 'Verifica se preço é menor que o mínimo atual If Preco < Min Then Min = Preco 'Novo valor mínimo encontrado

Page 25: Programação Avançada com Excel

End If 'Prepara próxima iteração Cont = Cont + 1 Loop 'Fornece a resposta MsgBox (``O menor preço é: '' & Min) End Sub

Exercícios

1. Altere MelhorPr para aceitar um número qualquer de preços. 2. Fazer uma macro que lê N valores e apresenta a soma dos valores positivos apenas. 3. O Departamento de Contabilidade Forênsica da Universidade Municipal de Uauá (BA) estuda casos famosos de fraude bancária. O mundialmente famoso Teste de Uauá realiza o seguinte procedimento:

Dado um capital inicial, uma taxa mensal de juros e um capital final, determinar se é consistente que o capital final foi obtido ao longo do tempo a partir do capital inicial sob juros compostos. Fazer uma macro que realiza o Teste de Uauá. No caso de consistência detectada, indicar o número de meses necessários para gerar o capital final. No caso de inconsistência, apenas mostrar em uma janela a mensagem ``Fraude detectada''.

4. Fazer uma macro que, lê o número N de alunos matriculados em Introdução à Contabilidade Forênsica e suas notas na primeira prova, e calcula:

• A média da turma. • A maior nota. • A menor nota.

Page 26: Programação Avançada com Excel

Simulação de Programas Para simular um programa no computador você deverá proceder da seguinte maneira:

1. Ativar a barra de ferramentass de programas. Normalmete, a barra de ferramentas de programas é ativada quando criamos um módulo (é aquela janelinha, com botõezinhos de mãozinha, oculinhos, etc). Caso esta não esteja ativa, você deverá ativá-la através do menu ``Exibir|Barras de Ferramentas'', selecionando ``Programa''. 2. Marcar a parada no inicio do programa. Coloque o cursor em cima do cabeçalho da função ou procedimento que você deseja simular. Em seguida, com o mouse, acione na barra de ferramentas de programas o botão da mãozinha (que significa: pare). O cabeçlho deve ficar com fundo vermelho.

Neste ponto, já se pode acionar o programa, que deverá ativar uma janela de depuração e parar no início da função/procedimento marcado.

3. Selecionar variáveis que serão observadas na simulação. Para isso, marcar a variável (uma expressão também pode ser marcada e observada). Em seguida, na barra de programa, clicar no oculinhos e pedir para adicionar a variável. Selecionar a aba de ``Inspecionar'' para ver as variáveis selecionadas. 4. Simular. Para isso, os dois últimos botões da barra de programas podem ser usados (a diferença entre eles está na ativação de outras funções e procedimentos de dentro de um programa, como veremos mais adiante.

Na simulação, o comando (linha) selecionado será aquele ainda por executar. Após a execução de cada comando, o valor das variáveis inspecionadas pode mudar. No término do programa, a janela de depuração desaparece.

O Tipo de dados Boolean

O tipo de dados chamado de Booleano possui apenas dois valores: TRUE e FALSE. Uma variável pode ser declarada como booleana assim:

Dim Teste As Boolean

Esta variável pode receber um valor booleano:

Teste = True

Uma variável booleana pode aparecer em expressões nos lugares onde uma condição poderia aparecer. Por exemplo:

If Teste Then

Essa expressão equivale a:

If Teste = TRUE Then

Page 27: Programação Avançada com Excel

Vejamos por exemplo uma função que executa o Teste de Uauá (ver exercícios do capítulo anterior). Este teste recebe como parâmetros um capital inicial, uma taxa de juros e um capital final. O teste retorna um valor booleano: Verdadeiro se é possivel que o capital final foi alcançado por meio de juros compostos aplicados ao capital inicial na taxa indicada; Falso em caso contrário.

Function TesteUaua(CapIni As Double, Taxa As Double, CapFim As Double) As Boolean ' Testa se é plausível que CapFim tenha sido obtido ' a partir de CapIni sob juros compostos com Taxa mensal Dim CapAtual As Double 'Capital até o momento Dim NMeses As Integer 'Número de meses Dim Resultado As Boolean 'Inicialização CapAtual = CapIni NMeses = 1 Resultado = False 'Começa assumindo teste falso 'Principal Do While CapAtual <= CapFim 'Testa o sucesso do resultado If CapAtual = CapFim Then Resultado = True End If 'Prepara próxima iteração CapAtual = CapAtual * (1 + Taxa) NMeses = NMeses + 1 Loop 'Retorno TesteUaua = Resultado End Function

Podemos simular este programa no computador. Tente a seguinte chamada da planilha: =TesteUaua(1000;0,1;1331) e =TesteUaua(1000;0,1;1300).

Um segundo exemplo: vamos fazer uma macro que lê uma sequência de inteiros positivos e informa ao usuário se esta sequência está em ordem crescente. A seqüência é terminada por um número menor que zero.

Sub EmOrdem() ' Lê uma sequência de inteiros positivos e informa ao usuário ' se esta sequência está em ordem crescente Dim Atual As Integer Dim Velho As Integer Dim AindaEmOrdem As Boolean 'Inicializações AindaEmOrdem = True Atual = CInt(InputBox(``Entre com um inteiro:'')) Velho = Atual 'Velho inicia com o mesmo valor que atual 'Principal Do While Atual >= 0

Page 28: Programação Avançada com Excel

If AindaEmOrdem And (Atual < Velho) Then 'Teste falhou AindaEmOrdem = False End If 'Prepara a próxima iteração Velho = Atual Atual = CInt(InputBox(``Entre com mais um inteiro:'')) Loop If AindaEmOrdem Then MsgBox(``Seqüência em ordem.'') Else MsgBox(``Desordenado.'') End If End Sub

Teste esse programa para as seqüências 1, 3, 7, 22, -1 e 1, 7, 2, 4, -23.

Exercícios

1. Alterar o programa acima para parar e dar a resposta assim que descobrir que a seqüência não está em ordem. 2. Simular no computador as suas soluções para os exercícios 1 e 2 do capítulo 5, para os valores de N=5 e N=6. 3. O resto da divisão inteira de X por Y é calculada por X MOD Y. O número X é divisível por Y se X MOD Y = 0. Neste caso, também dizemos que X é um mútiplo de Y.

Pede-se construir uma função MaxMultiplo(MIN,MAX,DIV) que encontra o maior múltiplo de DIV entre MIN e MAX. Resolver este problema de duas maneiras:

• Ir testando todos os números a partir de MIN e armazenar o múltiplo mais recentemente encontrado, até testar todos os números entre MIN e MAX.

• Começar testando os números de maneira decrescente a partir de MAX. Ao encontar o primeiro múltiplo de DIVpodemos parar, pois este será o maior divisor no intervalo.

Simular para MaxDivisor(5,10,3) e MaxDivisor(10,20,4).

Fazer uma planilha para MaxDivisor(0,100, X) onde X varia de 11 a 31, de 2 em 2.

4. Numa conta bancária, as movimentações de débito são representadas por números negativos e as movimentações de crédito por números positivos. Fazer uma macro que lê as movimentações de uma conta em um dia e:

• calcula, separadamente, o total de créditos e débitos; • lê o saldo no início do dia e calcula o saldo no início do próximo dia.

Page 29: Programação Avançada com Excel

Você pode escolher entre solicitar, no início, o número de movimentações, ou usar algum valor especial (muito grande) como sinal de parada.

Simular para 5 valores, 2 de crédito e 3 de débito.

Page 30: Programação Avançada com Excel

Leitura e Escrita de Planilhas por Programas Até agora, a única forma de comunicação vista entre uma planilha e uma função é a passagem de parâmetros. No entanto, podemos querer que uma função leia um dado de uma planilha sem que tenhamos que explicitamente passar o valor para o programa. Por exemplo, se quisermos somar os valores positivos de uma coluna:

A B

1 Produto Quantidade em Estoque

2 Vassoura 125

3 Rodo -2

...

53 Esfregão 12

Neste caso, vamos pensar que a planilha é uma Matriz de dimensão 2x2. A posição (I,J) da matriz corresponde à linha I e à coluna J. Por exemplo, na planilha acima, a posição (2,1) contém o valor ``Vassoura'' de tipo String e a posição (53,2) possui o valor 12 de tipo inteiro (ou double).

De maneira geral o valor da planilha que fica na posição de interseção da linha I com a coluna J pode ser lido através do comando Valor = Cells( I, J ).

Um programa que lê a soma dos itens em estoque (só os itens positivos, pois os itens negativos indicam falta de produto) pode ser o seguinte:

Function ItensEmEstoque() As Integer 'Este é um programa que conta o número de itens em 'estoque conforme armazenado na segunda coluna da Planilha. Dim Soma As Integer 'Soma de itens em estoque Dim Valor As Integer 'Valor da linha atual Dim I As Integer 'Indice da linha 'Inicializacões Soma = 0 I = 2 'Começamos na segunda linha Valor = 0 'Principal Do While I <= 53 'Terminamos na linha 53 'Lê o valor da Planilha Valor = Cells( I, 2 ) 'Valor lido na linha I, coluna 2 'Atualiza soma If Valor > 0 Soma = Soma + valor

Page 31: Programação Avançada com Excel

End If 'Próxima linha I = I + 1 Loop 'Retorno ItensEmEstoque = Soma End Function

Suponhamos agora que não sabemos a priori qual a última linha da coluna de valores. Há uma forma de saber se uma posição está vazia numa planilha, usando a função IsEmpty() . Por exemplo, a condição IsEmpty( cells( I, J ) ) retorna True se a célula (I,J) está vazia e retorna False se algo estiver escrito nela.

O programa anterior pode ser reescrito, sem limite de linhas, como:

Function ItensEmEstoque1() As Integer 'Este é um programa que conta o número de itens em 'estoque conforme armazenado na segunda coluna da Planilha. Dim Soma As Integer 'Soma de itens em estoque Dim I As Integer 'Indice da linha 'Inicializacoes Soma = 0 I = 2 'Começamos na segunda linha Valor = 0 'Principal Do While Not IsEmpty(Cells(I,2)) 'Terminamos na linha vazia 'Atualiza soma If Cells( I, 2 ) > 0 Soma = Soma + Cells( I, 2 ) End If 'Próxima linha I = I + 1 Loop 'Retorno ItensEmEstoque = Soma End Function

Escrita de dados na planilha não pode ser feita a partir de funções, apenas a partir de subrotinas. Isto porque as funções não possuem autorização para mudar a planilha, apenas para lê-las e retornar um único valor.

Para escrever um valor na posição (I,J) da planilha, é preciso usar o comando cells( I, J ) = <valor>. Se quisermos simplesmente apagar um valor contido numa célula, podemos usar cells( I, J ) = Empty.

Para exemplificar este fato, uma planilha resumindo as movimentações bancárias de diversos clientes:

A B C D

Page 32: Programação Avançada com Excel

1 Nome Saldo Anterior Crédito Débito Saldo Atual

2 Aarão 132,45 12,12 4321,12

3 Abel -987,65 78,90 56,56

...

Vamos preencher a coluna de Saldo Atual = Saldo Anterior + Crédito - Débito.

Sub SaldoAtual() ' Saldo Anterior na coluna 2 ' Credito na coluna 3 ' Débito na coluna 4 ' Saldo atual na coluna 5 Dim Anterior As Double Dim Credito As Double Dim Debito As Double Dim Atual As Double Dim I As Integer 'Contador das linhas I = 2 'Primeira linha 'Não há necessidade de inicialização pois as ' variáveis internas são lidas no início de cada ciclo Do While Not IsEmpty( Cells(I,1) ) 'Lê dados da planilha Anterior = Cells( I, 2) Credito = Cells( I, 3) Debito = Cells( I, 4) Atual = Anterior + Credito - Debito 'Escreve dados na Planilha Cells(I, 5) = Atual 'Próxima Linha I = I + 1 Loop End Sub

Note que poderíamos dispensar todas as variáveis internas (exceto I), sendo que as 5 primeiras atribuições do loop ficariam comprimidas em um único (e quase incompreensível) comando:

Cells(I, 5) = Cells( I, 2 ) + Cells( I, 3 ) - Cells( I, 4 )

Exercícios

1. Considere uma planilha que descreve para cada produto, a quantidade em estoque, o estoque mínimo e o estado do estoque.

A B C D

1 Produto Quantidade em Estoque Estoque Mínimo Status

Page 33: Programação Avançada com Excel

2 Vassoura 125 100

3 Rodo 2 10

...

53 Esfregão 12 20

Fazer uma macro que escreve na coluna de Status escreve ``OK'' se o estoque existente for maior que o estoque mínimo, ou escreve ``ATENÇÃO!!!'' se o estoque estiver abaixo do mínimo. Resolver o problema em dois casos:

• Para 52 produtos, como mostra a figura. • Para um número indefinido de produtos, send que o último produto é

sinalizado por uma linha vazia.

Por exemplo, sua macro deve alterar a planilha acima para:

A B C D

1 Produto Quantidade em Estoque Estoque Mínimo Status

2 Vassoura 125 100 OK

3 Rodo 2 10 ATENÇÃO!!!

...

53 Esfregão 12 20 ATENÇÃO!!!

2. Fazer uma macro que copia uma coluna de um lugar para outro da planilha. Assumir que:

• a coluna origem e a coluna destino são requisitadas ao usuário via InputBox.

• As colunas são descritas por números inteiros, ex: 1=A, 2=B, etc • Os dados da coluna começam na linha 1 • Os dados da coluna terminam com uma linha vazia.

Fazer uma macro para cada um dos dois casos abaixo:

• a coluna de origem NÃO é apagada (Copiar). • a coluna de origem é apagada (Mover).

Por exemplo, no primeiro caso, se pedimos a cópia da coluna origem 1 para a coluna de destino 3, devemos transformar a planilha:

A B C

1 10 2

2 3 1

3 -7

Page 34: Programação Avançada com Excel

4

na planilha

A B C

1 10 2 10

2 3 3

3 -7 -7

4

Page 35: Programação Avançada com Excel

Utilizando Funções e Macros Auxiliares O objetivo desse capítulo é mostrar como resolver um problema computacional razoavelmente grande, dividindo-o em problemas menores: ao encarar um problema computacional, vamos utilizar funções e macros auxiliares que resolverão parte do problema. Em seguida, vamos criar outros programas que utilizam estas pequenas soluções para compor soluções maiores, e desta forma comporemos soluções progressivamente mais complexas.

Vamos supor que nós temos a seguinte planilha, que realiza o controle de estoque de uma empresa.

A B C D

PRODUTO Em Estoque Estoque Mínimo Pedido de Compra

1 Vassoura 12 100

2 Rodo 120 70

3 Esfregão 5 50

...

Cada produto em estoque está associado a um estoque mínimo. Vamos fazer um programa que, ao detectar um produto cuja quantidade em estoque está abaixo do mínimo, decide quantas unidades devem ser compradas para restabelecer o estoque mínimo.

Por onde começamos?

A idéia inicial é formular a solução do problema de forma esquemática, que servirá de guia para dividir este problema em problemas menores. Basicamente, o que o programa deve fazer é o seguinte:

0. Para cada linha da planilha: 1. Descobrir o quantidade de itens faltantes no estoque 2. Atualizar a coluna Pedido com o valor calculado

Esta descrição serve de ``esqueleto'' para o desenvolvimento. O item 2 nós sabemos fazer: é só usar cells(linha,coluna) = valor, onde o valor foi calculado no item 1. Então vamos supor que há uma função que, para uma dada linha, calcula o valor faltante no estoque. A nossa representação esquemática pode ser refinada para:

0. Para cada linha da planilha: 1. valor = RepoeEstoque( linha ) 2. cells( linha, ``coluna do Pedido de Compra'' ) = valor

Então vamos escrever a função RepoeEstoque que calcula a quantidade de estoque que precisa ser reposta.

Page 36: Programação Avançada com Excel

Const ColunaProd = 1 'cria um ``apelido'' (ColunaProd) para a Constante 1 Const ColunaEs = 2 Const ColunaMin = 3 Const ColunaPed = 4 Const ColunaUnit = 5 Const ColunaCusto = 6 Function RepoeEstoque(Linha As Integer) As Integer 'Este programa descobre qual a quantidade de produto ' necessária em um pedido de compra para que o estoque ' atual iguale o estoque mínimo na Linha da planilha Dim emEstoque As Integer Dim estoqueMin As Integer Dim faltando As Integer 'Inicializações emEstoque = Cells(Linha, ColunaEs) estoqueMin = Cells(Linha, ColunaMin) faltando = 0 'Assume inicialmente que estoque está OK 'Principal If emEstoque < estoqueMin Then faltando = estoqueMin - emEstoque End If RepoeEstoque = faltando End Function

Inicialmente, note as primeiras linhas na forma

Const <NOME> = <VALOR>

Este comando declara uma Constante, que pode ser usada em qualquer parte do módulo em lugar do número. E para que usar constantes? Em primeiro lugar, porque o programa fica mais claro (ColunaMin é muito mais expressivo que o número 3 para sabermos a que este número se refere). Em segundo lugar, se houver várias ocorrências da constante no programa, para mudar seu valor basta alterar o valor associado a ela na declaração Const. Sem usar Const, teríamos que sair ``caçando'' as ocorrênicas do número e alterá-la no corpo do programa. No exemplo, usamos Const para o número das colunas, uma mudança de ordem nas colunas da planilha necessita apenas uma mudança nas declarações Const. (Dê uma olhada no programa e imagine como seria fácil cometermos um erro se não usássemos Const).

A função RepoeEstoque recebe como único parâmetro o número da linha corrente, e retorna 0 se não há estoque a repor. Ela é uma função bastante ordinária, sem nada de especial.

Especial é o fato de podermos utilizá-la como função auxiliar para resolver o problema de atualização da coluna de Pedido de compra na planilha. O resultado final almejado é uma macro que transforme a planilha inicial na seguinte planilha

A B C D

PRODUTO Em Estoque Estoque Mínimo Pedido de Compra

Page 37: Programação Avançada com Excel

1 Vassoura 12 100 88

2 Rodo 120 70

3 Esfregão 5 50 45

...

A macro que faz esta transformação (usando RepoeEstoque) é a seguinte:

Sub PedidoCompra() 'Monta o pedido de compra para toda a planilha Dim compra As Integer Dim lin As Integer 'Inicialização lin = 2 'Primeira linha de dados 'Varre toda a planilha Do While Not IsEmpty(Cells(lin, ColunaProd)) 'Descobre qtdd a comprar para o produto corrente compra = RepoeEstoque(lin) If compra > 0 Then 'Insere pedido de compra na planilha Cells(lin, ColunaPed) = compra End If 'Próxima linha lin = lin + 1 Loop End Sub

Suponha agora que nós queremos não apenas saber quantas unidades comprar, mas também calcular o custo do pedido de compra. Para isso precisamos de duas novas colunas na planilha, uma delas com o preço unitário do produto e a outra com o custo da compra para cada produto. No final queremos também computar o custo total do pedido de compra.

A B C D E F

PRODUTO Em Estoque Estoque Pedido de Preço Custo

Mínimo Compra Unitário Compra

1 Vassoura 12 100 R$2,50

2 Rodo 120 70 R$3,00

3 Esfregão 5 50 R$1,25

O esquema geral da solução é o seguinte:

1. Monta Pedido de Compra 2. Calcula o Custo

Page 38: Programação Avançada com Excel

O Item 1 nós já sabemos fazer, basta usar a macro PedidoCompra. O Item 2 pode ser refinado em

0. Para cada linha da planilha 1. Calcula o preço da compra 2. Atualiza a planilha

O cálculo do item 1, pode, por exemplo, ser feito por uma função auxiliar CustoCompra.

Function CustoCompra(Linha As Integer) As Double Dim quant As Integer Dim precoUnit As Double quant = Cells(Linha, ColunaPed) precoUnit = Cells(Linha, ColunaUnit) CustoCompra = quant * precoUnit End Function

Em seguida, podemos fazer uma macro que compõe a coluna Custo Compra utilizando a função CustoCompra:

Sub CustoPedido() Dim custolin As Double Dim lin As Integer Dim total As Double 'custo total do pedido 'Inicia lin = 2 total = 0 Do While Not IsEmpty(Cells(lin, ColunaProd)) custolin = CustoCompra(lin) Cells(lin, ColunaCusto) = custolin total = total + custolin 'proxima linha lin = lin + 1 Loop 'Escreve custo total sob os custos Cells(lin, ColunaCusto) = "Custo total: " & total End Sub

O resultado da utilização consecutiva das macros MontaPedido e Custo Pedido é a seguinte planilha:

A B C D E F

PRODUTO

Em Estoque

Estoque Mínimo

Pedido de Compra

Preço Unitário

Custo Compra

1 Vassoura 12 100 88 R$2,50 220

2 Rodo 120 70 R$3,00

Page 39: Programação Avançada com Excel

3 Esfregão 5 50 45 R$1,25 56,25

CustoTotal: 276,25

Agora, ao invés de chamarmos consecutivamente as duas macros, podemos ter uma macro que faça exatamente isso:

Sub MontaPedido() PedidoCompra CustoPedido End Sub

Exercícios

Considere a seguinte planilha:

Aluno Média Provas Média EPs Média Final Resultado

Adalberto 7,0 9,0

Belinda 3,0 6,0

Clementino 4,5 9,0

Danusa 5,5 4,0

Eleutério 2,0 4,0

1. Fazer uma função auxiliar CalculaMédia que calcula a média final de acordo com a fórmula:

MF = (3 * MP + MEP)/4, se MP >= 4 e MEP >= 4

MF = min( MP, MEP), caso contrário.

Quantos parâmetros esta função deve receber?

2. Fazer uma função auxiliar Resultado que retorna um string de acordo com as médias, da seguinte maneira:

• Aprovado. Se a média final é maior ou igual a 5,0. • Reaval de Prova. Se a média final e a média de provas estão entre 3,0 e

5,0, e a média de EPs é maior ou igual a 5,0. • Reaval de EP. Se a média final e a média de EPs estão entre 3,0 e 5,0, e

a média de provass é maior ou igual a 5,0. • Reaval de Prova e EP. Se a média final e a média de provas e a média

de EPs estão entre 3,0 e 5,0. • Reprovado. Caso contrário.

Quais são os parâmetros passados para a função? 3. Fazer uma macro que, usando as funções auxiliares CalculaMedia e Resultado, preenche a planilha acima.

Page 40: Programação Avançada com Excel

Trabalhando com Várias Planilhas Cada planilha tem um nome. Este nome inicialmente é, na versão em português do Excel, Plan1, Plan2, etc. Mas este nome pode ser mudado, bastando para isso clicar duas vezes sobre a aba que contém um nome e editar este nome na caixa de edição que é ativada.

A importância do nome da planilha é que será através dele que poderemos nos referir aos dados quando trabalharmos com diversas planilhas.

Quando editamos fórmula em uma planilha, utilizamos referências relativas, como C4, ou referências absolutas, como $C$4. Ambas as referências dizem respeito à planilha em que as fórmulas ocorrem. No entanto podemos nos referir a células em outras planilhas.

Por exemplo, suponha que nós temos duas planilhas, Moedas e Importações. Suponha que numa fórmula em Importações queiramos nos referir à célula C4 em Moedas. Para isso, não podemos usar apenas C4 pois este se refere a célula situada na linha 4 e coluna 3 da planilha atual, ou seja, Importações. Em vez disso, usamos

Moedas!C4

para uma referência relativa. Para uma referência absoluta, usamos

Moedas!$C$4

Quando estamos lidando com várias planilhas em um programa, precisamos dizer qual a planilha na qual queremos ler e/ou escrever. Por exemplo, se queremos ler o valor da célula C4 na planilha Moedas, usamos o comando

<Var> = Worksheets(``Moedas'').Cells(4,3)

E se queremos escrever o resultado de uma expressão na célula E2 da planilha Importações, usamos

Worksheets(``Importações'').Cells(2,5) = <expr>

Por exemplo, vamos construir planilhas para lidar com importações de produtos. Uma planilha, chamada Moedas, contém a cotação de diversas moedas.

A B C

1 Moeda País Valor em Reais

2 Dolar EUA 1,19

3 Libra Reino Unido 2,2

4 Marco Alemanha 1,07

Page 41: Programação Avançada com Excel

5 Yen Japão 0,006993007

6 Lira Itália 0,001278772

7 Dracma Grécia 0,43

Uma segunda planilha contém bens importados dos Estados Unidos, e a ela damos o nome de ImportUS.

A B C

1 Produto Preço em US$ Preço em R$

2 Computador 2000 =B2 * Moedas!$C$2

3 Torradeira 70 =B3 * Moedas!$C$2

4 Chaleira 30 =B4 * Moedas!$C$2

5 Geladeira 500 =B5 * Moedas!$C$2

Finalmente, temos uma planilha ImportMundo que trata da importação de produtos de todo o mundo, e portanto deve tratar da conversão de diversas moedas para o Real.

A B C D

1 Produto Moeda Preço Original Preço em R$

2 Computador Dolar 2000

3 TV Yen 600

4 Whisky Libra 26

5 Camelo Dinar 400

O preenchimento desta tabela é consideravelmente mais complexo que o da tabela anterior, pois envolve uma busca da cotação de cada moeda na planilha Moedas para cada caso. Neste caso, podemos escrever uma macro (e um conjunto de programas auxiliares) que nos ajude a solucionar o problema.

Const ColMoeda = 1 Const ColCota = 3 Const LinInicial = 2 Const PLAN2 = "ImportMundo" Const ColProd = 1 Const ColTipo = 2 Const ColPreco = 3 Const ColReal = 4 Function BuscaCotação(moeda As String) As Double 'Encontra a cotação na planilha "Moedas" para ' uma dada moeda. Se a moeda não for encontrada,

Page 42: Programação Avançada com Excel

' retorna -1. Dim lin As Integer Dim cotação As Double 'Inicialização lin = LinInicial cotação = -1 'assume que cotação não foi encontrada ainda 'Realiza busca Do While (Not IsEmpty(Worksheets("Moedas").Cells(lin, ColMoeda)) And cotação = -1) 'Encontrou a moeda? If moeda = Worksheets("Moedas").Cells(lin, ColMoeda) Then cotação = Worksheets("Moedas").Cells(lin, ColCota) End If 'Próxima linha lin = lin + 1 Loop 'Retorno BuscaCotação = cotação End Function Sub PreencheMundo() 'Preenche o preço em Reais dos produtos ' na planilha ImportMundo Dim i As Integer i = LinInicial 'Varre a planilha Do While Not IsEmpty(Worksheets(PLAN2).Cells(i, ColProd)) Call preencheLinhaMundo(i) i = i + 1 Loop End Sub Sub preencheLinhaMundo(lin As Integer) Dim tipoMoeda As String Dim cotação As Double Dim precoOriginal As Double 'Descobre o tipo de moeda tipoMoeda = Worksheets(PLAN2).Cells(lin, ColTipo) 'Descobre a cotação da moeda cotação = BuscaCotação(tipoMoeda) 'Descobre preco original precoOriginal = Worksheets(PLAN2).Cells(lin, ColPreco) 'Escreve preco em reais na planilha If cotação >= 0 Then Worksheets(PLAN2).Cells(lin, ColReal) = precoOriginal * cotação Else Worksheets(PLAN2).Cells(lin, ColReal) = "??" End If End Sub

Page 43: Programação Avançada com Excel

Exercícios

1. Suponha uma planilha de 4 colunas. Fazer uma macro que copia esta planilha para uma outra planilha, só que na ordem inversa das linhas, ou seja, o programa deve copiar:

1 2 3 4

10 20 30 40

100 200 300 400

a b c d

para

a b c d

100 200 300 400

10 20 30 40

1 2 3 4

O programa deve funcionar para planilhas com qualquer número de linhas, teminadas por uma linha em branco.

Sugestão: criar uma função auxiliar que conta o número N de linha e usar esta informação para inverter. A inversão deve mapear as posições:

LINHA_INICIAL em N + LINHA_INICIAL - 1 [ = LINHA_FINAL ]

LINHA_INICIAL + 1 em N + LINHA_INICIAL - 2

...

LINHA_INICIAL + i em N + LINHA_INICIAL - i - 1

...

LINHA_FINAL em N + LINHA_INICIAL - N [ = LINHA_INICIAL ]

Como você alteraria o seu programa para tratar de um número qualquer de colunas (terminadas por uma célula vazia)?

2. Um importador de automóveis tem a seguinte planilha de previsão de vendas de unidades de cada modelo:

Modelo Total 1997 1o trimestre 98 2o tri 98 3o tri 98 4o tri

Ferrari TR 115

Ferrari Nera 15

Ferrari SL 215

Mazzerati A1 43

Mazzerati A1-i 122

Page 44: Programação Avançada com Excel

Zorro 16V 1223

Zorro 8V 130

Suponha que a previsão de vendas é a seguinte: no primeiro trimestre deverão ser vendidos 30% do total do ano. E nos outros trimestres espera-se um aumento de 5% sobre cada trimestre anterior.

Preencha esta planilha da forma que achar mais adequada (fórmulas ou macro). Lembre-se de arredondar os resultado para números inteiros.

Suponha agora que haja uma segunda planilha de ordem de compra com as colunas:

Modelo Compras 1o tri 2o tri 3o tri 4o tri

Fazer uma macro que preencha tal planilha de planejamento de importações dado que:

• Havia em estoque, no final do ano de 1997, 2 unidades de cada modelo. • Aqui você tem a possibilidade de escolher entre uma opção fácil e outra

nem tão fácil assim. o (+ Fácil) Suponha que, ao final de cada trimestre, deva haver 2

unidades de cada modelo no estoque. Isso quer dizer que basta somar 2 a cada valor da planilha inicial.

o (+ Interessante) O pedido de compra de cada modelo deve ser feito em lotes de tamanho igual a 40% do total das unidades vendidas do ano anterior. Neste caso pode haver sobra de carros em um período, e há de se decidir quantos lotes se deve comprar para suprir a demanda estimada: 0, 1, 2, ...

Page 45: Programação Avançada com Excel

Vetores Até agora todos os tipos de dados vistos (Integer, Double, String, Boolean, ) foram tipos de dados atômicos. O tipo de Dados Vetor é um tipo de dados composto por outros tipos de dados.

Basicamente, um vetor é uma seqûência de dados do mesmo tipo. Desta forma, podemos ter um vetor de inteiros, um vetor de strings, etc. O que caracteriza um vetor é o fato de possuir um tamanho, que é o conjunto de posições contidas no vetor, e o fato de estas posições de dados poderem ser acessadas através de um índice.

Uma declaração de um vetor de 20 posições de inteiros é feita da seguinte maneira:

Dim vet(20) as Integer

Em geral, costuma-se deixar o valor de um vetor representado na forma de uma constante:

Const TAM_VET = 20 Dim vet(TAM_VET) as Integer

A primeira posição do vetor é a posição 1. A última é a posição TAM_VET. As posições do vetor podem ser acessadas através de um índice inteiro. Eis aqui alguns exemplos de manipulação do vetor vet:

vet(1) = 22 i=2 vet(i) = 20 vet(i+1) = vet(i) - vet(i-1)

Acessos ao vetor com valores de índice fora do intervalo padrão 1..TAM_VET são considerados ilegais e causam erros de execução no programa. Podemos alterar os valores deste intervalo padrão na declaração, por exemplo:

Dim lucroAnual(1985 To 2010) as Double

faz com que os valores legais de índice para o vetor estejam no intervalo 1985..2010. Note que o tamanho do vetor lucroAnual é 26 = 2010 - 1985 + 1 (a mesma fórmula é usada no cálculo dos vetores no caso padrão: o tamanho de vet é 20 = 20 - 1 + 1; em geral tamanho = PosiçaoFinal - PosiçãoInicial + 1.)

Podemos ter vetores multidimensionais. Um vetor bidimensional é, em geral, chamado de matriz. A declaração dos vetores multidimensionais segue o mesmo padrão da declaração dos vetores unidimensionais:

Dim matriz(50, 10) as String 'Matriz de 50 linhas por 10 colunas Dim multiDimensional(5, 10, 2) as Double

Page 46: Programação Avançada com Excel

O acesso a uma matriz se dá através de dois índices; similarmente, um vetor de n dimensões é acessado através de níndices. Em geral, quando mencionamos vetores, temos em mente o caso unidimensional, e é a ele que vamos nos restringir nesta seção.

Com relação ao uso de vetores como parâmetros de funções e procedimentos:

• Vetores podem ser passados como parâmetros em funções e procedimentos. O tipo do vetor é declarado no cabeçalho da função, mas não o seu tamanho. Informação de tamanho de vetor deve ser passada em outro parâmetro.

• Funções não podem retornar vetores.

Como conseqüência deste último fato, a alteração de vetores dentro de uma função ou procedimento se dá por efeito colateral. Com isso queremos dizer que, se um vetor é passado para uma função e, no interior desta função este vetor é alterado, esta alteração será percebida na função ou procedimento que chamou a função.

Isto é o que ocorre na função ColVet() abaixo, que lê uma coluna e copia seus valores um um vetor. Esta função recebe um vetor como parâmetro e, ao retornar, além de retornar o número de posições lidas, o valor do vetor está alterado, contendo uma cópia dos valores contidos na coluna.

Vamos considerar um exemplo. Considere uma planilha que contém, em uma coluna, valores positivos e negativos. Queremos eliminar os valores negativos (pois supostamente representam valores ilegais) eliminar as células ocupadas por estes valores. Por exemplo, queremos transformar:

12,50 12,50

-4,00 5,20

5,20 em 7,00

-9,50

7,00

Para resolver este problema, vamos dividi-lo em uma série de funções e macros auxiliares, de acordo com a seguinte descrição geral da solução:

• 1. Copiar a coluna a ser manipulada num vetor • 2. Modificar, no vetor, todos os números negativos para 0 • 3. Compactar o vetor, eliminando todos os 0s • 4. Copiar o vetor compactado sobre a coluna original • 5. Apagar os valores restantes da coluna original (em número igual ao número

de valores negativos encontrados).

Antes de iniciar o detalhamento, vamos mostrar as constantes usadas no módulo.

Const TamVet = 20 Const LinhaInicial = 2 Const ColunaFoco = 1

Page 47: Programação Avançada com Excel

Começamos mostrando a macro principal, que invoca todas as outras funções e procedimentos , além de realizar a compactação do vetor no item 3.

Sub EliminaNeg() Dim i As Integer Dim tam1 As Integer 'Tamanho inicial do vetor Dim tam2 As Integer 'Tamanho do vetor compactado Dim iniVet(TAM_VET) As Double 'Vetor inicial Dim CompactVet(TAM_VET) As Double 'Vetor compactado 'Lê coluna sob Foco, no máximo TAM_VET posições tam1 = ColVet(ColunaFoco, iniVet(), LinhaInicial, TamVet) tam2 = 0 'Zera posições negativas Call ApagaNeg(iniVet(), tam1) i = 1 'Principal Do While i <= tam1 If iniVet(i) > 0 Then 'Copia de iniVet para CompactVet tam2 = tam2 + 1 CompactVet(tam2) = iniVet(i) End If i = i + 1 Loop 'Copia CompactVet para a coluna Call VetCol(ColunaFoco, compactVet(), LinhaInicial, tam2) 'Esvazia demais posições Call Esvazia(ColunaFoco, tam2 + LinhaInicial, tam1 + LinhaInicial - 1) End Sub

Em seguida mostramos o item 2, que é uma subrotina que altera um vetor, mudando todos os valores negativos para 0. Como parâmetro, recebe o vetor e o seu tamanho:

Sub ApagaNeg(vet() As Double, tam As Integer) Dim i As Integer i = 1 'Inicialização Do While i <= tam If vet(i) < 0 Then vet(i) = 0 End If i = i + 1 'Proxima linha Loop End Sub

Em seguida, o item 1 é feito pela função ColVet(), que recebe como parâmetros a coluna a ser copiada, o vetor a ser alterado, o valor da primeira linha a ser copiada e o número máximo de posições que o vetor suporta. A função retorna o número de posições realmente lidas, que pode ser menor que o tamanho máximo.

Page 48: Programação Avançada com Excel

Function ColVet(col As Integer, vet() As Double, iniLin As Integer, tamMax As Integer) Dim i As Integer Dim lin As Integer i = 1 lin = LinhaInicial Do While i <= tamMax And Not IsEmpty(Cells(lin, col)) 'Lê célula atual vet(i) = Cells(lin, col) 'Próxima linha i = i + 1 lin = lin + 1 Loop 'Retorno ColVet = i - 1 End Function

O item 4 é feito pelo procedimento VetCol(), o oposto de ColVet(), que copia um vetor para uma coluna da planilha. Os parâmetros são os mesmos e não há necessidade de retornar nenhum valor, uma vez que o tamanho do vetor já é conhecido.

Sub VetCol(col As Integer, vet() As Double, iniLin As Integer, tam As Integer) Dim i As Integer i = 1 Do While i <= tam Cells(i + iniLin - 1, col) = vet(i) i = i + 1 Loop End Sub

Por fim, o procedimento que apaga as linhas restantes.

Sub Esvazia(col As Integer, iniLin As Integer, fimLin As Integer) Dim lin As Integer lin = iniLin Do While lin <= fimLin Cells(lin, col) = Empty lin = lin + 1 Loop End Sub

Exercícios

Nota: Algumas versões do Excel podem vir com o padrão de indexação diferente daquele apresentado nesse cap'itulo. Para garantir que todos os vetores possuem a primeira posição indexada por 1 (e não por 0), basta adicionar no início do seu módulo (antes das declarações de Const) a seguinte instrução:

Page 49: Programação Avançada com Excel

Option Base 1 1. Fazer um programa que inverte uma coluna. Por exemplo, uma coluna que contem ``1, 2, 3, 4'' deverá ser transformada em ``4, 3, 2, 1''. O programa deve:

(a) solicitar ao usuário qual a coluna a ser invertida (ColVet); (b) copiar a coluna para um vetor; o tamanho da coluna já é sabido pois foi retornado por ColVet; (c) inverter o vetor (ver enunciado do Exercício 1 da Lista 10). Você deve usar um segundo vetor para isso; (d) copiar o vetor invertido por sobre a coluna inicial (VetCol). Não é necessário usar funções ou procedimentos auxiliares além de ColVet e VetCol.

2. Fazer uma macro que lê uma coluna em um vetor e mostra, numa janela, a linha e o valor da menor célula na coluna. A coluna em questão deve ser solicitada ao usuário, bem como a posição da primeira linha a ser considerada.

Você deve usar uma função auxiliar que recebe um vetor e retorna o índice da posição que contém o menor valor. Não se esqueça que este valor do índice não é o mesmo que o valor da linha que contém o menor valor, pois a linha inicial na coluna considerada não é necessariamente a primeira.

Page 50: Programação Avançada com Excel

Ordenação O objetivo deste capítulo é descrever um método de ordenação de dados. Estaremos ordenando um conjunto de dados em um vetor (que pode ter sido, por exemplo, copiado de uma coluna da planilha). Existem vários métodos de ordenação, e nós vamos nos concentrar no método de Ordenação por Bolhas.

Uma bolha nada mais é que um par de números ordenados, por exemplo, ( 2, 7 ) ou ( 7, 4 ). A primeira destas bolhas está ordenada crescentemente, enquanto a segunda não. Toda vez que encontrarmos uma bolha desordenada, vamos invertê-la, transformando ( 7, 4 ) em ( 4, 7 ).

As bolhas são assim chamadas pois ``sobem pela seqüência'' da mesma forma como bolhas de gas na água. Vamos explicar o método através de um exemplo. Suponhamos que nós queremos ordenar a seqüência 4,2,12,7,4,1 de 6 elementos. Um passo de ordenação pelo método de bolhas irá produzir as seguintes alterações nos dados:

(4 2) 12 7 4 1

2 (4 12) 7 4 1

2 4 (12 7) 4 1

2 4 7 (12 4) 1

2 4 7 4 (12 1)

2 4 7 4 1 12

O passo de ordenação faz uma bolha deslocar-se pelo vetor da esquerda para a direita, ordenando a bolha se esta estiver desordenada e, em seguinda, movendo a bolha para a direita. As bolhas acima aparecem entre parênteses e, quando estão desordenadas, também estão em negrito.

Note que o maior número da seqüência, 12, foi parar na posição mais à direita. Portanto, se realizarmos o passo de ordenação uma segunda vez, o segundo maior número, 7, irá parar na segunda posição à direita.

(2 4) 7 4 1 12

2 (4 7) 4 1 12

2 4 (7 4) 1 12

2 4 4 (7 1) 12

2 4 4 1 (7 12)

2 4 4 1 7 12

Se realizarmos este passo de ordenação N vezes, onde N é o número de elementos na seqüência, a seqüência estará ordenada.

Page 51: Programação Avançada com Excel

Para implementar a ordenação pelo método de bolhas, utilizaremos as rotinas ColVet e VetCol do capítulo anterior, para realizar a leitura de uma coluna da planilha para um vetor e para realizar a cópia do vetor ordenado de volta para a planilha.

Para que o programa possa rodar, precisaremos copiar ColVet e VetCol no mesmo módulo que a macro principal, chamada de OrdenaCol. A coluna a ordenar é solicitada ao usuário.

Const TamVet = 20 Const LinhaInicial = 2

Sub OrdenaCol() Dim colAOrdenar As Integer 'Coluna a ordenar Dim vetorColuna(TamVet) As Double 'vetor que abriga a coluna Dim tamCol As Integer 'numero de elementos a serem ordenados colAOrdenar = CInt(InputBox("Qual a coluna a ser ordenada?")) 'Lê a coluna tamCol = ColVet(colAOrdenar, vetorColuna(), LinhaInicial, TamVet) 'Ordena a coluna Call OrdenaPorBolhas(tamCol, vetorColuna()) 'Escreve a coluna ordenada Call VetCol(colAOrdenar, vetorColuna(), LinhaInicial, tamCol) End Sub

Em seguida, vamos detalhar a rotina OrdenaPorBolhas(tam, vetor()), que realiza a ordenação por bolhas. Na chamada da rotina o vetor não está ordenado mas, por efeitos colaterais, no seu término o vetor estará em ordem crescente.

Sub OrdenaPorBolhas(tam As Integer, vet() As Double) 'Ordena o vetor vet() de tam posições pelo ' método das bolhas. Ao final, vet() está ordenado Dim vez As Integer 'Número de vezes que se repete o passo de ordenação vez = 1 'Repete (tam - 1) vezes, pois vetor de tamanho 1 já está ordenado Do While vez <= tam - 1 Call PassoOrdenação(tam, vet()) vez = vez + 1 Loop End Sub

Para finalizar, basta detalhar o passo de ordenação, que também recebe como parâmetros o tamanho do vetor e o vetor. Esta rotina também funciona por efeito colateral, devolvendo o vetor alterado por um passo de ordenação por bolhas.

Note que a inversão da bolha necessita de uma variável auxiliar.

Sub PassoOrdenação(nPos As Integer, vet() As Double) 'Passo de Ordenação do vetor vet. ' Ao fim da execução da rotina, o maior valor

Page 52: Programação Avançada com Excel

' de vet está na posição de maior índice (nPos). Dim i As Integer 'Indice do vetor Dim aux As Double 'Auxiliar na inversão da bolha i = 1 'Primeira posição 'Repita a inversão da bolha (nPos -1) vezes Do While i <= nPos - 1 'Verifica se a bolha é inversível If vet(i) > vet(i + 1) Then 'Inverte a bolha aux = vet(i) vet(i) = vet(i + 1) vet(i + 1) = aux End If i = i + 1 'Próxima bolha Loop End Sub

Exercícios

1. Alterar o programa de ordenação acima para gerar a coluna em ordem decrescente. Note que para isso basta alterar uma linha do passo de ordenação. 2. O passo de ordenação do método de bolhas garante que o maior valor da seqüência estará à direita. Não há necessidade, portanto, de se considerar este valor no próximo passo de ordenação, uma vez que ele já está em sua posição definitiva.

No exemplo acima, o primeiro passo produziu:

2 4 7 4 1 12

onde 12 foi parar na posição final e definitiva. O segundo passo produziu

2 4 4 1 7 12

onde 7 foi parar na posição definitiva (e 12 permaneceu na mesma posição).

Altere o programa para, a cada passo, propagar a bolha até uma posição a menos que na vez anterior.

Dica: uma pequena alteração na rotina OrdenaPorBolhas() resolve o problema.

3. Muitas vezes o vetor já está ordenado antes da execução dos Npassos de ordenação. Por exemplo, se o vetor já está ordenado de início, não há motivos para continuar aplicando os passos de ordenação.

Altere seu programa para que este pare de aplicar o passo de ordenação assim que a aplicação do passo de aplicação não realizar nenhuma inversão de ordem. O programa pode parar pois, garantidamente neste caso, o vetor já está ordenado.

Page 53: Programação Avançada com Excel

Manipulação de Strings Já sabemos como construir uma cadeia de caracteres (String) a partir de outras usando concatenação, representada pelo operador &:

``Banana'' & ``Madura'' = ``BananaMadura''

Vamos agora tratar da operação inversa, ou seja, construir um String que é um ``pedaço'' de outro. Para isso, basta entender que os caracteres em um String podem ser indexados da mesma forma que as posições em um vetor (mas Strings não são apenas vetores de caracteres, pois não possuem tamanho fixo). Por exemplo, o String ``BananaMadura'' pode ser indexado como ilustrado abaixo:

B a n a n a M a d u r a

1 2 3 4 5 6 7 8 9 10 11 12

Para extrair um vetor de outro, usamos a função MID$:

Mid$( <String>, <Posiçao Inicial>, <Número de caracteres a extrair>).

Alguns exemplos:

str = ``BananaMadura''

str2_7 = Mid$( str, 2, 6 ) 'str1 recebe ``ananaM''

char10 = Mid$( str, 10, 1 ) 'char10 recebe ``u''

Uma importante função é aquela que nos dá o tamanho de um String, Len( <String> ) (do inglês, length = comprimento). Por exemplo:

n = Len(``BananaMadura'') 'n recebe 12 x = Len(``12 34'') 'x recebe 5

Outras vezes, gostaríamos de saber se um caracter extraído de um string representa um número ou não. Neste caso usamos a função IsNumeric. Por exemplo,

OK = IsNumeric(``1'') 'OK é verdadeiro OK = IsNumeric(``;'') 'OK é falso OK = IsNumeric(`` '') 'OK é falso OK = IsNumeric(``x'') 'OK é falso

Vamos ilustrar o uso das funçoes Mid$, Len e IsNumeric construindo uma função que, dado um String, filtra todos os caracteres que não são numéricos. Por exemplo, dado o CPF ``123.456.789-01'', retorna o string ``12345678901'', eliminando toda a pontuação.

Page 54: Programação Avançada com Excel

Function FiltraAlgarismo(strIn As String) As String

Dim pos As Integer 'posicao no string Dim tamStr As Integer 'tamanho do string Dim strOut As String 'string de saída Dim letraCorr As String 'Letra corrente em strIn pos = 1 tamStr = Len(strIn) strOut = "" Do While pos <= tamStr letraCorr = Mid$(strIn, pos, 1) If IsNumeric(letraCorr) Then strOut = strOut & letraCorr End If pos = pos + 1 'próxima posição Loop FiltraAlgarismo = strOut End Function

Esse exemplo transforma, por efeito colateral, um string num vetor de caracteres (com a ressalva que o vetor de caracteres tem que ter tamanho pelo menos igual ao do string).

Sub stringVet(str As String, vet() As Integer) 'Assumimos que o tamanho de vet é ' maior que Len(str) Dim pos As Integer Dim strAux As String strAux = FiltraAlgarismo(str) pos = 1 Do While pos <= Len(strAux) vet(pos) = CInt(Mid$(strAux, pos, 1)) pos = pos + 1 'próxima posição Loop End Sub

Outro exemplo é a normalização de datas. Neste caso, uma data (dada por um string) do tipo ``3/2/98'' é transformada em ``19980203'', ou seja, uma data do tipo ``Dia/Mes/Ano'' é transformada em Ano1Mes1Dia1, onde Ano1 está com 4 algarismos, Mes1 e Dia1 com dois.

Function FormataData(data As String) As String 'transforma uma data Dia/Mes/Ano em ' um string AnoMesDia onde Dim ano As String, mes As String, dia As String Dim pos As Integer Dim letraCorr As String 'Inicialização ano = "" mes = ""

Page 55: Programação Avançada com Excel

dia = "" pos = 1 'obtem o dia, procurando pela primeira '/' letraCorr = Mid$(data, pos, 1) Do While letraCorr <> "/" dia = dia & letraCorr pos = pos + 1 'próxima posição letraCorr = Mid$(data, pos, 1) Loop If Len(dia) = 1 Then dia = "0" & dia ElseIf Len(dia) > 2 Or Len(dia) < 1 Then dia = "00" End If 'obtem o mes, procurando pela segunda '/' pos = pos + 1 'vai para a próxima posição letraCorr = Mid$(data, pos, 1) Do While letraCorr <> "/" mes = mes & letraCorr pos = pos + 1 'próxima posição letraCorr = Mid$(data, pos, 1) Loop If Len(mes) = 1 Then mes = "0" & mes ElseIf Len(mes) > 2 Or Len(mes) < 1 Then mes = "00" End If 'obtem o ano, varrendo data até o fim pos = pos + 1 'vai para a próxima posição letraCorr = Mid$(data, pos, 1) Do While pos <= Len(data) ano = ano & letraCorr pos = pos + 1 'próxima posição letraCorr = Mid$(data, pos, 1) Loop If Len(ano) = 2 Then ano = "19" & ano ElseIf Len(ano) <> 4 Then ano = "0000" End If 'Retorno FormataData = ano & mes & dia End Function

Por fim, temos uma função que verifica se uma data é valida (com alguns errinhos: quais?) que usa FormataData.

Function DataLegal(data As String) As Boolean Dim ok As Boolean Dim ano As Integer

Page 56: Programação Avançada com Excel

Dim mes As Integer Dim dia As Integer Dim dataFormatada As String ok = True dataFormatada = FormataData(data) ano = CInt(Mid$(dataFormatada, 1, 4)) mes = CInt(Mid$(dataFormatada, 5, 2)) dia = CInt(Mid$(dataFormatada, 7, 2)) If ano < 1900 Or ano > 2050 Then ok = False End If If mes < 1 Or mes > 12 Then ok = False End If If dia < 1 Or mes > 31 Then ok = False End If 'Retorno DataLegal = ok End Function

Exercícios

1. Fazer uma função que recebe um string como parâmetro e retorna um string obtido ao se eliminar os espaços em branco no início e fim do string:

" Bom dia, senhor " deve ser transformado em "Bom dia,

senhor"

"Bom dia, senhor " deve ser transformado em "Bom dia,

senhor"

" Bom dia, senhor" deve ser transformado em "Bom dia,

senhor"

2. Fazer uma função que codifica um string pelo método ZENIT-POLAR:

Z E N I T

P O L A R

Ou seja, onde aparece um ``Z'' no string de entrada, aparecerá um ``P'' na saída; e, semelhantemente, onde aparece um ``P'' no string de entrada, aparecerá um ``Z'' na saída. Isto deve ocorrer para todos os pares em ZENIT-POLAR, maiúsculas e minúsculas. As outras letras não são alteradas

Por exemplo, o string ``Parabens a voce'' é codificado para ``Zitibols i veco''.

Ao se aplicar duas vezes a transformação, obtém-se o mesmo string, ou seja, a codificação de ``Zitibols i veco'' é ``Parabens a voce''.

3. Fazer uma função que inverte um string. ``Parabens a voce'' vira ``ecov a snebaraP''.