vba - dei.isep.ipp.ptdei.isep.ipp.pt/~asilva/page14/page16/assets/excel pratica aula 6.pdf · excel...

9
Excel Aula Prática n o 6 VBA 1. Inicie o Microsoft Excel e abra o ficheiro "Excel_6" que se encontra no directório APROG. 2. Na folha "Aposta" deve ser criada uma tabela contendo os números de uma aposta no Totoloto conforme exemplo da Figura 1. Para tal, deverá usar uma subrotina criada para o efeito a que poderá dar o nome de Totoloto e que produza um conjunto de 6 números inteiros aleatórios entre 1 e 49. Por sua vez, essa subrotina deverá usar os serviços de uma função a criar, chamada NumAleatorio, capaz de produzir um número aleatório inteiro entre dois limites que lhe são passados como argumentos. Figura 1: Aposta do Totoloto Vamos então criar essa função e, em seguida, a rotina Totoloto que a vai usar: (a) A função NumAleatorio deve utilizar a função VBA standard Rnd() que produz um número real aleatório entre 0 e 1. Terá, portanto, que se converter esse valor real para inteiro (usando a função VBA int() ) e multiplicá-lo por um factor de escala apropriado. (b) A função receberá como parâmetros de entrada a informação de qual os limites inferior e superior da gama de valores a produzir e deverá devolver à saída um número aleatório inteiro entre esses limites. (c) O código de tal função poderá ser o seguinte: 1 Function NumAleatorio( inf As Integer , sup As Integer ) 2 NumAleatorio = int (inf + Rnd () * ( sup - inf)) 3 End Function Para criar a função, deverá arrancar com o Ambiente de Desenvolvimento Integrado do VBA (mediante a combinação de teclas ALT-F11) e invocar o Menu "Insert/Pro- cedure". Na janela que aparecerá deverá seleccionar a opção "Function" e preencher o campo do nome.

Upload: trinhthu

Post on 25-Nov-2018

240 views

Category:

Documents


0 download

TRANSCRIPT

Excel

Aula Prática no 6VBA

1. Inicie o Microsoft Excel e abra o ficheiro "Excel_6" que se encontra no directórioAPROG.

2. Na folha "Aposta" deve ser criada uma tabela contendo os números de uma aposta noTotoloto conforme exemplo da Figura 1. Para tal, deverá usar uma subrotina criadapara o efeito a que poderá dar o nome de Totoloto e que produza um conjunto de 6números inteiros aleatórios entre 1 e 49. Por sua vez, essa subrotina deverá usar osserviços de uma função a criar, chamada NumAleatorio, capaz de produzir um númeroaleatório inteiro entre dois limites que lhe são passados como argumentos.

Figura 1: Aposta do Totoloto

Vamos então criar essa função e, em seguida, a rotina Totoloto que a vai usar:

(a) A função NumAleatorio deve utilizar a função VBA standard Rnd() que produz umnúmero real aleatório entre 0 e 1. Terá, portanto, que se converter esse valor realpara inteiro (usando a função VBA int()) e multiplicá-lo por um factor de escalaapropriado.

(b) A função receberá como parâmetros de entrada a informação de qual os limitesinferior e superior da gama de valores a produzir e deverá devolver à saída umnúmero aleatório inteiro entre esses limites.

(c) O código de tal função poderá ser o seguinte:

1 Function NumAleatorio ( i n f As Integer , sup As Integer )2 NumAleatorio = int ( i n f + Rnd( )∗ ( sup − i n f ) )3 End Function

Para criar a função, deverá arrancar com o Ambiente de Desenvolvimento Integradodo VBA (mediante a combinação de teclas ALT-F11) e invocar o Menu "Insert/Pro-cedure". Na janela que aparecerá deverá seleccionar a opção "Function" e preenchero campo do nome.

Aula Prática no 6 - VBA

(d) A subrotina Totoloto deverá seleccionar uma gama de células pré-determinada(neste exemplo, a gama D9:D14) e em cada uma dessas células deve colocar umnúmero aleatório entre 1 e 49. Para tal necessitará de:1. Inicializar o gerador de números aleatórios, usando a instrução Randomize2. Seleccionar a gama de células aplicando o método Select ao objecto Range

pretendido3. Usando um ciclo For...Each, atribuir a cada uma das células o resultado da

chamada da função NumAleatorio.

(e) Um código possível para esta sub-rotina é o seguinte:1 Public Sub Totoloto ( )2 Dim Ce l l As Range3 Randomize45 Range ( "D9" , "D14" ) . Select6 For Each Ce l l In S e l e c t i o n7 Ce l l . Value = NumAleatorio (1 , 49)8 Next9 End Sub

A variável Cell vai representar cada uma das células da gama D9:D14. A instruçãoRange("D9", "D14").Select selecciona a gama pretendida. O ciclo For...Each vaipercorrer cada uma das células seleccionadas, atribuindo à sua propriedade Valueo resultado fornecido pela função NumAleatorio. Repare-se que a esta função sãopassados os limites inferior e superior da gama de valores possíveis a gerar.

(f) Esta sub-rotina apresenta, no entanto, um problema: não garante que não sejamproduzidos números repetidos, o que seria algo a evitar. Vamos, no entanto, esque-cer esse detalhe.

3. Seleccione a folha "Datas". Nela vai encontrar um conjunto de células contendo umasérie de datas que se supõe constituirem o período compreendido entre o início e o fim dasaulas. Vamos supor que não existem nem férias nem feriados a "complicar" os cálculos.Pretende-se preencher a coluna ao lado da que contem as datas com a informação do diada semana a que cada uma dessas datas corresponde.

O Excel já possui a função standard WEEKDAY que indica qual o dia da semana quecorresponde a uma determinada data mas apenas sob a forma de um número inteiroentre 1 e 7. Neste caso, pretende-se que essa informação seja apresentada em Português,conforme se pode ver na Figura 2 na próxima página. Vai, portanto, ser necessárioconstruir uma função específica para obter esse resultado.

(a) Construa a função DiaSemana que receba uma data e forneça o dia da semanarespectivo. Para tal, use o Menu "Insert/Procedure", escolha a opção "Function"e dê-lhe o nome DiaSemana.

(b) Essa função vai utilizar a função VBA Weekday() que tem uma utilidade semelhantea da função Excel WEEKDAY referida acima. O valor numérico por ela fornecido

Page 2

Aula Prática no 6 - VBA

Figura 2: Tabela com dias da semana (excerto)

vai ser usado nas condições das estruturas condicionais IF...Then...Else imbricadasque transformarão esse valor numérico no seu equivalente em português.

(c) O código da função DiaSemana é o seguinte:

1 Public Function DiaSemana (Data As Date)2 Dim Dia As Integer34 Dia = Weekday(Data )5 I f Dia = 1 Then6 DiaSemana = "Domingo"7 ElseIf Dia = 2 Then8 DiaSemana = "2a␣Fe i ra "9 ElseIf Dia = 3 Then10 DiaSemana = "3a␣Fe i ra "11 ElseIf Dia = 4 Then12 DiaSemana = "4a␣Fe i ra "13 ElseIf Dia = 5 Then14 DiaSemana = "5a␣Fe i ra "15 ElseIf Dia = 6 Then16 DiaSemana = "6a␣Fe i ra "17 Else18 DiaSemana = "Sabado"19 End I f20 End Function

Relembrando o que foi aprendido sobre o funcionamento das funções, repare-se naforma pela qual a função DiaSemana devolve o resultado do seu trabalho: fá-loatravés do seu próprio nome, de tal forma que, quando termina a sua execução,deixa em seu lugar, na fórmula em que foi invocada, o resultado produzido.

Page 3

Aula Prática no 6 - VBA

(d) Insira fórmulas usando esta função na coluna ao lado da que contem as datas.

4. Pretende-se agora criar uma sub-rotina que forneça o número de dias utilizáveis nesseperíodo, ou seja, todos menos os sábados e os domingos, e coloque essa informação numadada célula. Para tal, poderemos utilizar a função DiaSemana acabada de criar 1 paraindicar se uma determinada data é sábado ou domingo.

(a) A sub-rotina começará por calcular o número de datas que compõem o período emcausa. Para tal vamos usar a método Count aplicado ao objecto Selection (instru-ção 7). Este objecto refere-se ao conjunto de células seleccionadas no momento.Vamos partir do princípio que esta sub-rotina se aplicará ao conjunto de datas quese encontrem em células previamente seleccionadas pelo utilizador. Dessa forma,poder-se-á utilizar apenas no período de dias que interessar (na gama toda ou ape-nas em parte dela).

(b) Para cada célula seleccionada, o ciclo For...Each vai fazer o seguinte:

1. Copia para uma variável auxiliar o conteúdo da célula (uma data).2. Invoca a função DiaSemana para encontrar o dia da semana a que corresponde

essa data e armazena-o noutra variável.3. Verifica se esse dia é Sábado ou Domingo e, caso seja, decrementa o no total de

dias contido na variável n.

(c) Finalmente, é transferido o no total de dias utilizáveis para a célula D2 (instrução15)

(d) O código completo da sub-rotina encontra-se a seguir:

1 Public Sub DiasDi spon ive i s ( )2 Dim Ce l l As Range3 Dim d As Date4 Dim ds As String5 Dim n As Integer67 n = Se l e c t i o n .Count8 For Each Ce l l In S e l e c t i o n9 d = Ce l l . Value10 ds = DiaSemana (d)11 I f ds = "Domingo" Or ds = "Sabado" Then12 n = n − 113 End I f14 Next15 [D2 ] . Value = n16 End Sub

(e) Teste a sub-rotina, seleccionando a gama de células com as datas e invocando-ausando a janela de macros activada mediante a combinação de teclas ALT-F8. Se

1Poder-se-ia também utilizar a função Weekday().

Page 4

Aula Prática no 6 - VBA

tudo correr bem, deverá aparecer na célula G3 o número de dias utilizáveis naqueleperíodo.

5. Seleccione a folha "Produção", contendo uma tabela de Ordens de Fabrico (Figura 3).Usando funções de pesquisa como a VLookup é possível encontrar nesta tabela qualquerinformação respeitante a cada ordem de fabrico.

(a) Utilizando a função Excel VLookup, já dada na Aula Prática no3, construa umafórmula na célula H3 que permita saber qual a data de uma dada ordem de fabrico(especificada na célula H2). Recorde-se que esta função standard usa 4 argumentos2:

1. A célula em que se encontra o que se vai pesquisar2. A tabela em que essa pesquisa se vai realizar3. A coluna da tabela em que o resultado vai ser encontrado4. O valor zero caso a pesquisa seja exacta

(b) Esta função tem algumas limitações:

• Impõe que a pesquisa se faça pela 1a coluna da tabela• Só suporta a pesquisa por um único parâmetro

Pretende-se agora construir uma função de pesquisa mais lata, especificamente umaque permita fazer a pesquisa por dois parâmetros simultaneamente e sem limitaçõesquanto à coluna de pesquisa.Vamos chamar a esta nova função "DblVLookup" (VLookup duplo).

Figura 3: Tabela com Ordens de Fabrico

(c) Esta função irá necessitar de mais informações para trabalhar. O seu número deargumentos será assim maior. Ao contrário do VLookup clássico, receberá dois

2Sobre esta e outras funções de pesquisa pode consultar o texto "Técnicas de pesquisa em Excel" disponívelna página da cadeira, em www.dei.isep.ipp.pt/~asilva.

Page 5

Aula Prática no 6 - VBA

valores a pesquisar na tabela (v1 e v2 ) e, consequentemente, terá também quesaber em que duas colunas essa pesquisa se efectuará (col1 e col2 ). Como nãoé possível conhecer, à partida, o tipo de dados que vão ser pesquisados, vai serutilizado para os dois primeiros argumentos o tipo Variant3. O último argumento(result) especifica qual a coluna em que o resultado da pesquisa se encontrará.

(d) O trabalho da função é controlado por um ciclo Do...Until que, para cada linha4,compara v1 com o conteúdo da célula em col1 e v2 com o conteúdo da célulaem col2. A condição de funcionamento do ciclo deve ser construída de tal formaque, para uma dada linha, seja verdadeira só quando v1 for igual ao conteúdo dacélula em col1 e v2 igual ao conteúdo da célula em col2, simultaneamente, ou então,quando se chegar ao fim da tabela. O ciclo vai repetir apenas uma instrução deincremento da variável contadora i (instrução no 10).

(e) O código da função é o seguinte:

1 Public Function DblVLookup ( v1 As Variant , v2 As Variant , _2 tab l e As Range , co l 1 As Integer , c o l 2 As Integer , _3 r e s u l t As Integer )4 Dim i As Integer , n As Integer56 i = 07 n = tab l e . Rows .Count8 Do Unt i l ( t ab l e . Ce l l s ( i , c o l 1 ) = v1 And _9 tab l e . C e l l s ( i , c o l 2 ) = v2 ) Or i > n10 i = i + 111 Loop12 I f i > n Then13 DblVLookup1 = "N/A"14 Else15 DblVLookup1 = tab l e . Ce l l s ( i , r e s u l t )16 End I f17 End Function

O resultado a fornecer pela função dependerá do valor de i no fim do ciclo. Já seviu que este pode terminar, quer porque a pesquisa teve sucesso numa determinadalinha, quer porque atingiu o fim da tabela. Esta última situação corresponde a umvalor final de i igual a n + 1. Se for igual ou inferior a n é porque a pesquisa tevesucesso. É esta verificação que a estrutura If...Then...Else efectua. Dependendodo valor de i, assim é atribuído ao nome da função DblVLookup o valor "N/A"ou table.Cells(i, result), ou seja, o conteúdo da célula no cruzamento da linha emque a pesquisa teve sucesso (dada pelo valor de i) com a coluna especificada peloargumento result.

3Uma variável do tipo Variant pode receber qualquer tipo de dados. Se bem que seja menos eficiente e,por isso, em geral de evitar, é útil em situações como esta.

4O número de linhas da tabela é dado por Table.Rows.Count

Page 6

Aula Prática no 6 - VBA

(f) Teste esta função usando-a numa fórmula a inserir na célula C21 e que forneça aquantidade da ordem de fabrico correspondente ao produto cuja referência estivercontida na célula C19 e à data referida na célula C20.

6. Abra a folha "Vendas" (Figura 4), contendo uma tabela com informação sobre os pro-dutos vendidos por uma empresa. Pretende-se inserir na coluna mais à direita (gamaH3:H13) uma fórmula que apresente as mensagens "Margem Baixa" caso a margem sejainferior a 20% ou "Excelente!" caso seja superior a 40%.

Figura 4: Exemplo de aplicação da função MargemLucro()

(a) Para a construção dessa fórmula propõe-se a utilização duma função a criar chamadaMargemLucro que calcule a margem de lucro de um produto com base no seu custoe no seu preço de venda, de acordo com a seguinte fórmula:

MargemLucro = (custo− precoV enda)/precoV enda

(b) Crie essa função de forma a que ela receba como argumentos os valores do custo edo preço de venda e devolva um número real que corresponde à margem de lucro. Afunção deve ainda verificar se o custo é diferente de zero. Nessa caso, deve devolvera string "Erro".

(c) Construa a fórmula usando a função que acabou de criar e qualquer outra funçãoExcel que achar apropriada.

Figura 5: Critérios do filtro e resultado da filtragem

Page 7

Aula Prática no 6 - VBA

7. Volte a seleccionar a folha "Produção". Reentroduzimos aqui o tema das filtragens.Numa das aulas anteriores foi introduzida a técnica da filtragem automática. Vamosagora utilizar as filtragens avançadas que permitem aplicar filtros mais poderosos eflexíveis5.

(a) Para aplicar a filtragem avançada é necessário especificar os seus critérios usando,para o efeito, uma gama de células da folha de cálculo. Nas células de B23 a D25coloque os critérios descritos na Figura 5 na página precedente. Na 1a linha dessagama insira o nome das colunas em que os critérios serão aplicados. Tenha ematenção que essess nomes devem ser copiados com total exactidão. Os critériosinseridos devem permitir visualizar apenas as Ordens de Fabrico posteriores ao dia25-05-2008:

• do produto "V100" com quantidade superior a 15000, mais as• do produto "X11" com quantidade superior a 7500.

Repare que os critérios contidos na mesma linha devem ser aplicados em simultâneo,pelo que estamos aqui perante um "E" lógico. Os critérios inseridos em diferenteslinhas deverão ser considerados como unidos por um "Ou" lógico.

Figura 6: Janela de configuração do Filtro Avançado

(b) Seleccione uma célula qualquer dentro da tabela e accione o Menu "Data/Filter/Ad-vanced Filter". Aparecerá uma janela como a descrita na Figura 6. Repare quecom um Filtro Avançado temos uma possibilidade adicional de que não dispúnha-mos com o Filtro Automático: a de copiar as linhas da tabela que correspondemao critério para uma outra localização dentro da mesma folha de cálculo, mantendoassim a tabela original intocada. Neste caso vamos escolher esta opção.

(c) Preencha os campos da janela "Criteria Range" e "Copy to", indicando, respecti-vamente, a gama de células em que se encontram os critérios a aplicar e a célulasuperior esquerda da gama para onde vão ser copiadas as linhas resultantes dafiltragem. Pressione OK, devendo obter o resultado descrito na parte inferior daFigura 5 na página precedente.

5Sobre este assunto pode consultar o texto "Filtragem de informação em Tabelas" disponível na páginada cadeira.

Page 8

Aula Prática no 6 - VBA

8. Crie um macro capaz de realizar de forma automática as operações que acabou derealizar manualmente. Dê-lhe o nome "FiltrarTabela" e associe-o à combinação de teclas"Shift+Control+S". Execute-o e assegure-se que o resultado obtido é o correcto.

Page 9