Controle do Programa no Visual Basic

Os pequenos programas que você escreveu são extremamente simples: executam instruções seqüenciais, realizam tarefas sem grandes desvios e, via de regra, são relativamente descomplicados. Este capítulo introduz conceitos que lhe ajudarão a ter um controle adicional sobre como um programa é executado, permitindo-lhe criar mecanismos que possam tratar de várias condições, repetidamente e com ampla variedade de dados.

Fazendo Escolhas

Os programas escritos nos capítulos anteriores eram formados exclusivamente por instruções e expressões, o equivalente a frases imperativas da língua portuguesa. Porém, ninguém, nem mesmo o mais exaltado ditador vitalício, pode passar a vida inteira apenas dando ordens. Na vida real, as pessoas precisam fazer escolhas. A ferramenta principal do Visual Basic para tratamento de escolhas é a instrução If.

 

A Instrução If

Suponhamos que você esteja ensinando a um amigo como obedecer aos sinais de tráfego. Em particular, o que deve ser feito quando se encontra um sinal de Atenção. Você pode explicar o sinal de Atenção da seguinte forma: "Reduza a velocidade para 20 Km/hora. Caso não venha ninguém, continue o seu caminho; do contrário, pare e deixe o carro passar". Em Visual Basic, essas instruções poderiam ser transformadas em:

Figura 6.1

A forma clássica da instrução If especifica uma escolha entre duas opções. Na vida real, é costume escolher-se uma alternativa, deixando de lado a outra e suas possíveis conseqüências. Como programador, é necessário seguir todas as alternativas possíveis, até suas últimas conseqüências.

Como programador, você tem de orientar o computador. Como você não sabe exatamente quais condições o programa encontrará a cada momento quando estiver em processamento, torna-se necessário incluir instruções para tratamento de todos os casos. No exemplo do sinal de Atenção, você não sabe quando seu amigo encontrará ou não carros trafegando, assim forneça as instruções adequadas para as duas possibilidades. Na codificação de seu programa, aplique um mecanismo conhecido como desvio condicional, usando a instrução If.

Eis aqui a sintaxe da instrução If em Visual Basic:

If expressão booleana Then

[Instrução] ...

Else

[Instrução] ...

End If

A palavra-chave If é seguida por uma expressão booleana, que (como você se recorda do Capítulo 4) é uma expressão avaliada como Verdadeira (True) ou Falsa (False). Isso é um outro exemplo da representação do mundo em termos binários: True ou False, Desvio à esquerda ou à direita, If ou Else. Caso a expressão booleana seja True, todas as instruções que seguem a palavra Then até a palavra-chave Else serão executadas. (As reticências na descrição da sintaxe indicam que pode haver mais de uma instrução.) O programa então saltará as próximas instruções, continuando a sua execução após as palavras-chave End If. Se a expressão booleana for False, as instruções imediatamente após a palavra Then serão saltadas. Quando for encontrada a parte Else da instrução If, o programa continuará a executar as instruções. Os dois possíveis caminhos de execução são mostrados a seguir:

Figura 6.2

A instrução If é uma instrução composta - isto é, apesar de ser avaliada como um todo, ela contém várias instruções dentro de si. A maioria dos programadores costuma colocar essas instruções internas recuadas, para melhorar a sua visualização. Observe como seria difícil ler o primeiro exemplo se isso não fosse feito:

Figura 6.3

Se você examinar a definição da sintaxe da instrução If, poderá ver que a parte Else da instrução é opcional. Isso evita codificação desnecessária quando não houver instruções para serem colocadas para a cláusula Else. Assim, estes dois fragmentos de programa são equivalentes:

Figura 6.4

Múltiplas Escolhas

A instrução If permite ao seu programa tratar da escolha entre duas opções. Mas como o seu programa pode tratar uma escolha entre muitas opções? Vejamos como utilizar a instrução If para tratar múltiplas escolhas.

A título de exemplo, considere o problema de identificação de cada um dos Três Patetas. Obviamente, você tem três possibilidades de escolha. Neste caso, o tipo de cabelo pode ser usado como característica de identificação. Você pode construir um teste simples, como mostrado na Figura 6.5.

Figura 6.5

O uso da instrução If para construção de uma seleção múltipla pode trazer à lembrança o jogo das Vinte Questões, onde uma pessoa pensa em alguma coisa de um tipo previamente combinado e as outras pessoas tentam adivinhar de que se trata, fazendo perguntas que recebem sempre uma resposta do tipo "Sim" ou "Não". A cada resposta, certas características vão sendo eliminadas, e o processo de adivinhação se encaminha para uma certa direção.

A codificação a ser implementada em Visual Basic para fazer o teste dos Três Patetas, da Figura 6.5, é mostrada aqui; a segunda instrução If é uma instrução aninhada integralmente contida na primeira:

lf Cabelo = "Nenhum" Then

Pateta = "Curly"

Else

lf Cabelo = "Preto" Then

Pateta = "Moe"

Else

Pateta = "Larry"

End If

End If

Como o aninhamento de mais de duas ou três instruções If torna-se complexo, o Visual Basic oferece uma variante para a cláusula Else, chamada ElseIf. A cláusula ElseIf combina a cláusula Else com a funcionalidade de outra instrução If. Veja a seguir uma versão da codificação precedente, refeita para usar ElseIf. Ao lado, encontra-se a sintaxe completa para as instruções If do Visual Basic.

Figura 6.6

Conforme indicado pela sintaxe da instrução, a cláusula ElseIf pode ser repetida muitas vezes, eliminando a necessidade de colocação de múltiplas instruções If aninhadas.

O Aplicativo Caça-níqueis

Para explorar um pouco mais a instrução If, vamos construir uma simulação de um caça-níqueis. Com o botão de comando fazendo o papel de uma alavanca, o programa Caça-níqueis exibirá três ícones aleatoriamente toda vez que o botão de comando for acionado. Caso os três ícones sejam iguais, o usuário vence. O programa manterá um registro das vitórias do jogador.

Voltaremos a usar aqui os ícones Copas, Paus, Ouro e Espadas, encontrados, respectivamente, nos arquivos HEART.ICO, CLUB.ICO, DIAMOND.ICO e SPADE.ICO no diretório \PacoteVB\Icones\Misc do primeiro cd deste produto. O programa pegará aleatoriamente um desses ícones para cada uma das três janelas do visor. Cada jogada custará R$ 1, 00. Se os três ícones combinarem, o jogador ganhará R$ 10, 00. Se os três forem de Ouro, o jogador ganhará R$25,00.

Pensando a Respeito

Reveja com rigor todas as condições, quando estiver programando com instruções If. É preciso ser cuidadoso para não incluir acidentalmente opções inesperadas ou, inversamente, excluir condições que deveriam ser tratadas. Não seja precipitado em assumir que o seu primeiro impulso para escrever uma cláusula Else cubra somente as alternativas possíveis.

A codificação escrita para identificar os Três Patetas, por exemplo, assume que, se Curly e Moe foram eliminados, a única possibilidade que resta é Larry. Entretanto, como sabem os estudantes da arte cinematográfica, realmente há outras possibilidades, tais como Shemp ou Curly-Joe. (Para quem não está familiarizado com a arte cinematográfica, o trio Moe Howard, Larry Fine e Curly Howard protagonizou a maioria dos filmes dos Três Patetas. Entretanto, após Curly sofrer um acidente, os filmes posteriores foram feitos com outras pessoas no papel do terceiro Pateta.)

Para um exemplo semelhante desse tipo de erro, imagine o teste da cor de um elemento. Caso não seja branco ou vermelho, podemos assumir que seja azul. Isso funciona se você sabe que todos os elementos a serem testados pertencem à bandeira americana; do contrário, o seu teste poderá tornar-se inválido.

Para desenhar a interface do programa, crie um novo projeto. Inclua três controles de imagem na parte superior do form, que serão usados como o visor do caça-níqueis. Abaixo dos controles de imagem, coloque o botão de comando que servirá como alavanca da máquina. À esquerda, acrescente um campo de rótulo para exibir as vitórias do jogador; à direita, crie outro botão de comando que permitirá ao jogador sair do jogo. Finalmente, para acomodar os quatro ícones que serão usados, inclua mais quatro controles de imagem na parte inferior do form. O seu form deverá parecer-se com o mostrado na Figura 6.7.

Para configurar os quatro controles de imagem inferiores, inicie selecionando o mais à esquerda e configurando a sua propriedade Name para ImgCopas. A seguir, configure a propriedade Picture, selecionando Picture na lista de propriedades, e dê um clique no botão de reticências, ao lado da propriedade. Na caixa de diálogo Load Picture, escolha o arquivo HEART.ICO a partir do subdiretório \PacoteVB \ Icones\Misc no primeiro cd deste produto. Repita esse processo para os outros três controles de imagem, nomeando-os como lmgPaus, lmgOuros e lmgEspadas e configurando as suas propriedades Picture de forma a carregar os arquivos CLUB.ICO, DIAMOND.ICO e SPADE.ICO, nesta ordem.

Figura 6.7 O projeto inicial do form para o aplicativo Caça-nÍqueis.

Agora, configure as propriedades dos elementos de exibição, como mostrado na Figura 6.8. O seu form agora deve parecer-se com a Figura 6.9.

Figura 6.8 Configuração de propriedades para o aplicativo Caça-níquel.

Para iniciar a codificação do programa, dê um clique duplo no form, para

abrir a janela de código. Inclua as seguintes linhas de código na seção de declarações gerais:

Const COPAS% = 1

Const PAUS% = 2

Const OUROS% = 3

Const ESPADAS% = 4

Dim Vitórias As Currency

Os inteiros de 1 a 4 mapearão os números gerados aleatoriamente para os ícones apropriados. As declarações de constantes permitem-lhe usar os nomes COPAS, PAUS, OUROS e ESPADAS no programa, simplificando sua leitura e compreensão. A variável Vitórias, que também foi declarada neste ponto, será usada para armazenar as vitórias do jogador.

Figura 6.9 O desenho do form completo para o aplicativo Caça-níquel.

Agora, selecione Form na caixa Object da janela de código e selecione o procedimento Load na caixa de procedimentos. Inclua estas linhas de código, que serão executadas quando o form for carregado pela primeira vez (isto é, no início do programa):

Private Sub Form_Load ()

 

Randomize

Vitórias = 0

End Sub

A instrução Randomize avisa ao Visual Basic para alternar os números produzidos pelo gerador de números aleatórios; sem essa instrução, haveria uma repetição dos números gerados toda vez que o programa fosse executado. Uma vez que o jogador ainda não começou a jogar, você deve zerar a variável Vitórias

Veja a seguir o código para o botão Sair:

Private Sub btnSair_Click ()

End

End Sub

O procedimento para o botão Jogada é apresentado na Figura 6.10. Cada uma das variáveis locais P1, P2 e P3 armazenará o número aleatório que será usado para selecionar os ícones que aparecerão nos controles de imagem superiores (ImgVisor1, lmgVisor2 e ImgVisor3). A variável Pagar conterá o resultado de cada jogada (um giro do caça-níqueis).

Figura 6.10 O procedimento btnJogada_Click para o aplicativo Caça-níquel.

Em primeiro lugar, o programa abate R$1,00 do total de vitórias, ou seja, o custo de uma jogada. A seguir, são gerados três números aleatórios. A fórmula Int(n * Rnd + 1) usa a função interna do Visual Basic Rnd para recuperar um inteiro aleatório dentro da faixa de 1 a n.

Após isso, o programa examina o número inteiro gerado e armazenado em P1 e configura a propriedade Picture do controle ImgVisor1, para copiar a imagem de um dos ícones predefinidos na parte inferior do form. Esse processo repete-se para os outros dois visores, ImgVisor2 e lmgVisor3.

Uma vez configurado o visor do caça-níqueis, o programa verifica se ocorreu alguma combinação vencedora. Se os três número forem iguais, o jogador vence. Além disso, o programa verifica se a combinação vencedora é composta por ouros. A variável Pagar é então assinalada para 10 ou 25, de acordo com a combinação que ocorreu. Caso o jogador não tenha vencido, a variável Pagar é zerada.

Finalmente, o programa adiciona o valor contido na variável Pagar ao total acumulado do jogador e exibe o total apurado no rótulo. A função Format do Visual Basic assegura que o total seja apresentado em reais e centavos de reais.

Ao fechar a janela de código, você estará pronto para executar o aplicativo. Entretanto, antes de fazê-lo, redimensione o form para esconder os quatro ícones predefinidos, conforme mostrado na Figura 6.11. Eles continuarão a fazer parte de seu aplicativo, mas já não aparecerão na interação com o usuário.

Você se sente com sorte? Pressione F5 e faça algumas tentativas. Quando terminar o jogo, pode ser que você queira salvar esse aplicativo para retornar mais tarde a ele.

Figura 6.11 O form redimensionado para o aplicativo Caça-níquel.

Uma alternativa a ElseIf: Select Case

No aplicativo Caça-níquel, você fez uso da palavra ElseIf para criar testes de múltiplas possibilidades. Uma outra instrução do Visual Basic lhe serviria ao mesmo propósito e com maior riqueza de recursos e clareza. Trata-se da instrução Select Case.

A instrução Select Case é uma estrutura de tomada de decisão que obedece a sintaxe abaixo:

Select Case expressãodeteste

[Case listadeexpressões

[instruções]] ...

[Case Else

[instruçõeselse]]

End Select

Onde:

expressãodeteste é qualquer expressão a ser testada quanto ao seu valor.

listadeexpressões lista de uma ou mais expressões numa das seguintes formas de arranjo: expressão; expressão To expressão; Is operadordecomparação expressão. A palavra To especifica um intervalo de valores. Se você usa a palavra To, a expressão de menor valor deve vir antes do To. Use a palavra Is com operadores de comparação ( exceto Is e Like) para especificar um intervalo de valores. Se não for fornecida, a palavra Is é automaticamente inserida.

Instruções pode ser uma ou mais instruções executadas se o valor da expressão sendo testada conferir com o valor de alguma das expressões da lista de expressões na cláusula Case.

Instruçõeselse são opcionais. Representam uma ou mais instruções que serão executadas caso nenhuma das cláusulas Case contiver uma expressão cujo valor confira com o da expressão sendo testada.

Se quiser utilizar Select Case no aplicativo Caça-níquel, você pode, por exemplo, substituir os testes das variáveis P1, P2 e P3 pelo seguinte código:

Select Case P1

Case COPAS:

ImgVisor1.Picture = ImgCopas.Picture

Case PAUS:

ImgVisor1.Picture = ImgPAUS.Picture

Case OUROS:

ImgVisor1.Picture = ImgOUROS.Picture

Case ESPADAS:

ImgVisor1.Picture = ImgESPADAS.Picture

End Select

Select Case P2

Case COPAS:

ImgVisor2.Picture = ImgCopas.Picture

Case PAUS:

ImgVisor2.Picture = ImgPAUS.Picture

Case OUROS:

ImgVisor2.Picture = ImgOUROS.Picture

Case ESPADAS:

ImgVisor2.Picture = ImgESPADAS.Picture

End Select

Select Case P3

Case COPAS:

ImgVisor3.Picture = ImgCopas.Picture

Case PAUS:

ImgVisor3.Picture = ImgPAUS.Picture

Case OUROS:

ImgVisor3.Picture = ImgOUROS.Picture

Case ESPADAS:

ImgVisor3.Picture = ImgESPADAS.Picture

End Select

Tornando-se Repetitivo

A habilidade de escrever instruções de assinalamento, e fazer escolhas usando a instrução If teoricamente lhe dá as ferramentas necessárias para criar qualquer tipo de programa. Porém, muitas tarefas são mais fáceis em teoria do que na prática. Considere o problema de imprimir todos os números do intervalo de 1 a 1000. A solução óbvia, escrever um programa contendo 1000 instruções Print (Print 1, Print 2, Print 3 e assim por diante), seria extremamente fatigante. Felizmente, o Visual Basic oferece um meio melhor.

A instrução Do do Visual Basic pode processar repetidamente um conjunto de instruções. Eis a sintaxe mais simples para essa instrução:

Do

[instrução] ...

Loop

A palavra-chave Do marca o início de uma instrução composta, que inclui todos os comandos até a palavra-chave Loop. As instruções são executadas em ordem até que a palavra-chave Loop seja encontrada; nesse ponto, a execução começa novamente no inicio do bloco com a instrução Do.

O conjunto de instruções que se repete é chamado de laço. Quando um programa está executando repetidamente esse conjunto de instruções, costuma-se dizer que está em looping. O nome laço provém do diagrama circular de fluxo de programa mostrado na Figura 6.12

O laço mostrado na Figura 6.12 é um lago infinito, isto é, o Visual Basic executará a instrução composta para sempre. E claro que, normalmente, você desejará que o programa interrompa a estrutura de laço em algum ponto, passando a executar as instruções que existem após o laço. O Visual Basic permite-lhe implementar isso de várias formas.

Figura 6.12 Um diagrama de laço Do.

Você pode anexar uma cláusula While (enquanto) à instrução Do ou à instrução Loop. O exemplo de impressão dos números de 1 a 1000 é tratado mais facilmente com um laço Do While, como mostrado a seguir:

Contador = 1

Do While Contador <= 1000

Print Contador

Contador = Contador + 1

Loop

A variável Contador recebe o valor 1. Então, a instrução Do While, que é

executada "enquanto" o Contador for menor ou igual a 1000, envolve uma

instrução Print e uma instrução de assinalamento. Quando o laço se encerrar, a execução continuará com as instruções do programa que se seguem à palavra-chave Loop.

A palavra-chave While deve ser seguida por uma condição com o formato de uma expressão booleana. Caso a expressão seja False, as instruções que a seguem, até a palavra-chave Loop, serão saltadas e a execução do programa prosseguirá com as instruções que vêm após a instrução Loop. Neste exemplo, Contador é verificado no início de cada laço, inclusive no primeiro. (Se Contador tivesse sido inicializado com 5000, nenhuma das instruções dentro do laço seria executada.)

Observe que, se a instrução Contador = Contador + 1 não tivesse sido incluída, a expressão booleana seria sempre True (pois Contador permaneceria com o valor 1) e o laço seria eternamente executado. A criação de laços infinitos é um erro comum, mesmo entre os programadores mais experientes. Lembre-se de que, em Visual Basic, você pode sempre pressionar Ctrl-Break para interromper um programa que está sendo executado e sair do laço infinito.

A palavra-chave While também pode ser associada à instrução Loop, obtendo-se um efeito um pouco diferente, como mostrado neste código:

Do

Password = lnputBox ("Digite a senha")

Loop While Password <> "Mussum"

A colocação da cláusula While no final do laço assegura que as instruções contidas no laço sejam executadas pelo menos uma vez, pois o teste de terminação ocorre após a palavra-chave Loop. Neste exemplo, a caixa de diálogo solicitando ao usuário a digitação da senha será exibida repetidamente, até que o usuário introduza a palavra certa.

Finalmente, para melhorar a legibilidade de seu programa, você pode usar a palavra-chave Until (até que) em vez de While. O uso de Until inverte a lógica da condição. Compare os dois exemplos anteriores, usando cada uma das alternativas.

Exemplos usando While

Contador = 1

Do While Contador <= 1000

Print Contador

Contador = Contador + 1

Loop

Do

Password = lnputBox("Digite a Senha")

Loop While Password <> "Mussurn"

Exemplos usando Until

Contador = 1

Do Until Contador > 1000

Print Contador

Contador = Contador + 1

Loop

Do

Password = lnputBox("Digite a Senha")

Loop Until Password = "Mussum"

Eis a sintaxe completa para a instrução Do no Visual Basic:

 

Teste no início do laço

 

Do [While | Until] expressão

[Instrução]

Loop

Teste no final do laço

Do

[Instrução]

Loop [While I Until] expressão

O Aplicativo Banco

Vamos usar o conhecimento recém-adquirido para escrever um programa que servirá de banco privado, contendo alguma informação diferente. Quando o usuário introduzir em uma caixa combinada os montantes de todos os cheques emitidos durante um certo período, o programa avisará ao usuário sobre o valor médio por cheque. Para encontrar essa média, o programa irá acumular todos os valores e dividi-los pela quantidade de cheques - uma tarefa perfeita para um laço Do While.

Crie um novo projeto no Visual Basic. A interface do programa requer uma caixa combinada para armazenar o valor de todos os cheques, um botão de comando para calcular a média e um rótulo para exibir a média. Desenhe um form contendo esses objetos, configurando as suas propriedades de acordo com a Figura 6.13. O seu form deverá parecer-se com o mostrado na Figura 6.14.

Figura 6.13 Configuração de propriedades para o aplicativo Banco.

Figura 6.14 Projeto do form para o aplicativo Banco.

Agora, você deve modificar ligeiramente a caixa combinada. Normalmente, uma caixa combinada oferece uma lista de opções para o usuário. Neste caso, você irá usá-la para construir uma lista de entradas do usuário. Cada vez que o usuário introduzir um valor na parte de texto da caixa combinada, o programa adicionará o valor aos itens da parte de lista. Para fazer isso, será necessário usar um procedimento de evento que foi citado no Capítulo 5, aquele baseado no evento KeyPress.

O evento KeyPress ocorre toda vez que o usuário pressiona uma tecla. Dê um clique duplo na caixa combinada e selecione KeyPress a partir da caixa de procedimentos na janela de código. A declaração desse procedimento deverá ser a seguinte:

Private Sub cboEntrada_KeyPress (KeyAscii As Integer)

End Sub

 

A variável chamada de KeyAscii é definida dentro dos parênteses. Essa variável é um parâmetro. Os parâmetros funcionam como variáveis locais, exceto pelo fato de serem inicializados pelo procedimento chamador e não pelo procedimento que contém a sua declaração. (Parâmetros em procedimentos são abordados em maiores detalhes no Capitulo 7.) Por enquanto, basta saber que o evento KeyPress ocorre com uma variável predefinida chamada de KeyAscii. Quando a execução do procedimento é iniciada, o valor de KeyAscii é o código ASCII correspondente ao caractere digitado pelo usuário. Por exemplo, se o usuário pressionar a tecla A, o valor de KeyAscii será 65. A digitação de a gera o valor 97. Dar um clique na tecla 3 gera o valor 51.

A codificação do procedimento KeyPress pode modificar a variável KeyAscii. Caso isso venha a ser feito, o Visual Basic incluirá o novo caractere na caixa combinada, em vez daquele originalmente introduzido pelo usuário. Experimente essa característica. Defina o procedimento KeyPress como segue:

Private Sub cboEntrada_KeyPress (KeyAscii As Integer)

lf KeyAscii = 83 Or KeyAscii = 84 Then

KeyAscii = 42

End lf

End Sub

Pressione F5 para iniciar a execução do aplicativo e digite TESTANDO na parte de texto da caixa combinada. As letras S e T serão substituídas por asteriscos. (O código ASCII para um asterisco é 42.) Deixe o aplicativo e edite o procedimento

KeyPress novamente, como mostrado abaixo:

Private Sub cboEntrada_KeyPress (KeyAscii As Integer)

‘Se a tecla for Enter

lf KeyAscii = 13 Then

‘Inserir nova entrada

cboEntrada.AddItem cboEntrada.Text

‘Limpar a parte de texto

cboEntrada.Text = ""

‘Descartar a tecla pressionada

KeyAscii = 0

End lf

End Sub

Esse procedimento foi configurado para detectar o pressionamento de Enter (código ASCII13). Se a tecla pressionada pelo usuário não for Enter, o Visual Basic simplesmente inserirá o caractere digitado na parte de texto da caixa combinada. Entretanto, quando o programa detecta a tecla Enter, esse procedimento insere a parte de texto da caixa combinada como um novo item na parte de lista. Depois, apaga a entrada da parte de texto e configura KeyAscii para 0. Uma vez que 0 é o código ASCII para caracter nulo, o Visual Basic simplesmente ignorará esse caractere.

Calculando a Média

Após o usuário introduzir todos os valores, ele poderá dar um clique no botão Média para fazer com que o programa calcule o valor médio. Dê um clique duplo no botão de comando Média e introduza o seguinte código:

Figura 6.15

A instrução Dim define duas variáveis locais: Atual, para ser usada como indexador para os itens da caixa de lista ou caixa combinada; e Total, que armazena a somatória dos valores. Total é então inicializada como 0, e o indexador de itens é configurado para 0. (Os itens em uma caixa de lista ou caixa combinada são identificados por meio dos indexadores 0, 1, 2 e assim por diante.)

A instrução Do While direciona o Visual Basic para continuar o processamento enquanto o indexador for menor que a quantidade total de itens. (Não se pode esperar que o programa encontre o item 21 se apenas 7 itens tiverem sido incluídos.) A próxima instrução contém a expressão cboEntrada.List(Atual), que especifica um item da lista. Como os itens de caixas de lista e de caixas combinadas são armazenados como texto, a função Val do Visual Basic é usada para converter o texto para valor numérico. Analogamente, a função Str$ converte o valor da média calculada para uma string de texto antes do programa exibí-lo no rótulo.

Agora, você pode processar o programa Banco. Digite uma série de valores na parte de texto da caixa combinada, pressionando Enter a cada valor. Quando tiver introduzido a lista completa, dê um clique no botão Média. Seus resultados devem ser semelhantes aos mostrados na Figura 6.16.

Figura 6.16 Processando o aplicativo Banco.

 

Laços Que Contam

A instrução For é uma instrução especial em Visual Basic que trata de mecanismos de laços, fazendo contagem em ordem crescente ou decrescente. Ela tem a seguinte sintaxe:

For variável = primeiroValor To últimoValor [Step Incremento]

[Instrução] ...

Next variável

A instrução For cria um laço no qual a variável contadora é inicializada com o valor de primeiroValor, sendo então incrementada toda vez que o programa executa o laço pelo valor incremento até atingir o valor últimoValor. Se a cláusula Step for omitida, será assumido incremento 1. A menos que o valor do incremento seja negativo, primeiroValor deverá ser menor do que últimoValor. Caso seja usado incremento negativo, primeiroValor deverá ser maior do que últimoValor.

O laço For pode ser escrito por meio de uma instrução While (enquanto), porém é mais comum usar o laço For, por sua simplicidade. A sintaxe dos laços While equivalentes é mostrada aqui:

Figura 6.17

Repare que a expressão To no laço For é equivalente à comparação menor ou igual no laço While, com incremento positivo, e equivalente à comparação maior ou igual, quando o incremento é negativo. Isso significa que o valor da variável ao final da execução do laço poderá ser diferente de últimoValor. Como um exemplo, veja este laço e a saída que ele produz:

For Contador = 1 To 10 Step 4

Print Contador

Next Contador

Saída

1

5

9

Se desejar, você pode modificar a codificação do programa Banco para usar

o laço For. Compare as suas modificações com esta versão (que mostra as linhas

alteradas em destaque):

Figura 6.18

Ao escrever a sua versão da codificação, você configurou o valor final do laço For para cboEntrada.ListCount - 1? Essa mudança, apesar de importante, costuma ser esquecida com freqüência. Lembre-se de que o Visual Basic numera os itens de uma caixa combinada, começando pelo 0, isto é, três itens são numerados como 0, 1 e 2. A versão original do código usa um laço com uma comparação menor do que. O laço For usa menor ou igual.

Essas diferenças sutis podem conduzir a erros, fazendo com que o laço seja executado uma vez a mais ou a menos. Até mesmo os programadores mais experientes cometem esses tipos de engano; assim, preocupe-se em testar o seu programa cuidadosamente. Por exemplo, quando eu criei o programa Banco pela primeira vez, ele foi processado usando os valores 1, 2, 3 e 4. Entretanto, como sabia que a média deveria ser 2,5, eu percebi que alguma coisa estava errada. Quando um programa não produz nenhum resultado, imediatamente descobre-se que está errado. Entretanto, quando um programa gera um resultado, somos quase sempre tentados a assumir que ele esteja correto.

Espere o Inesperado

Ainda que um programa produza um resultado correto nos primeiros testes, não se pode assumir que estará sempre correto. Um exemplo disso é o programa Banco. Esse programa falhará se o usuário der um clique no botão Média sem introduzir algum valor na caixa combinada. Você pode achar que ninguém faria uma coisa dessas. Porém, parte de seu trabalho como programador é entender que tudo o que pode acontecer provavelmente acontecerá. E você deve antecipar-se a tais eventos da melhor maneira possível.

No programa Banco, o laço Do While (ou o laço For, se você fez as alterações) apresenta um problema no cálculo da média. Se não houver algum item na caixa combinada, a expressão Total/cboEntrada.ListCount causará uma divisão por zero. Nesse caso, o Visual Basic oferece um tratamento de erro, exibindo uma caixa de diálogo que diz Division by zero. Isso, porém, não serve de conforto para o usuário. Além disso, alguns sistemas (tais como o MS-DOS) simplesmente encerram a execução de um programa que tente fazer uma divisão por zero. Sem dúvida é melhor que você, como um bom programador, antecipe-se a esse erro, em vez de acreditar que o sistema irá tratá-lo de alguma forma (possivelmente indesejável).

Você pode melhorar o programa Banco de várias formas. Uma é inserir o seguinte código no início do procedimento btnMédia_Click:

If cboEntrada.ListCount = 0 Then

Exit Sub

End If

Esse código fará com que o programa simplesmente ignore o clique do mouse no botão Média quando inadequado, encerrando o procedimento. Dará a impressão de que o botão Média não está respondendo, o que pode confundir o usuário. Se estiver preocupado com essa possibilidade, você pode exibir uma caixa de diálogo, como o código mostrado abaixo:

If cboEntrada.ListCount = 0 Then

MsgBox "Não há entradas para Média"

Exit Sub

End If

Usando Matrizes

No programa Banco, você usou a variável cboEntrada.List, que é uma matriz. Variáveis matriz podem conter múltiplos valores. Isso pode parecer-se um pouco com os tipos definidos pelo usuário no Capítulo 3, porém não é a mesma coisa. Uma variável de tipo definido pelo usuário contém um número fixo de componentes, cada um dos quais com nomes e tipos de dados diferentes. Em uma matriz, todos os elementos têm o mesmo tipo e cada elemento individual é numerado seqüencialmente. Para fazer referência a um campo de um tipo definido pelo usuário, você usa o nome da variável do tipo seguido pelo nome do campo, tal como em Siegmund.Cor. Para se referir ao elemento de uma matriz, você usa o nome da variável matriz seguido pelo número do elemento colocado entre parênteses, tal como cboEntrada.List(3). O número que especifica um elemento de uma matriz é chamado de índice. Os valores de índices são sempre inteiros. O Visual Basic armazena o valor dos elementos de matrizes em memória, por ordem do índice, começando pelo elemento 0. A Figura 6.19 compara o armazenamento de memória para variáveis simples e tipos definidos pelo usuário com o armazenamento de memória para matrizes.

Figura 6.19 Alocação de memória para variáveis simples, registros e matrizes.

 

Reservando Memória para Matrizes

O Visual Basic permite-lhe criar matrizes para armazenar qualquer tipo de dado, incluindo tipos de dados definidos pelo usuário. O programa Banco usa uma matriz de strings (cboEntrada.List) que é uma propriedade predefinida de caixa combinada. Para criar uma matriz e reservar memória para ela, deve-se usar uma declaração de variável. A exemplo das outras variáveis, as matrizes são declaradas por meio da instrução Dim. Eis a sintaxe para uma declaração padrão de matriz:

{ Dim | Private | Public } name (tamáximo) [As tipo]

O valor entre parênteses (tamáximo) é chamado de dimensão da matriz; ele indica para o Visual Basic a quantidade de memória a ser reservada para a matriz. A declaração cria uma matriz com índices que vão de 0 a tamáximo - Por exemplo, a Instrução Dim X(3) As Integer declara uma matriz com tamáximo igual a 3, criando uma matriz com quatro elementos: X(0), X(1), X(2) e X(3).

Fazendo Experiências com Matrizes

Matrizes são incrivelmente úteis, permitindo-lhe escrever programas mais genéricos e menos dependentes de tipos específicos de dados. Para demonstrar, considere nossos amigos do Capítulo 3, as doninhas de topete da Floresta da Baviera.

Para avaliar sua capacidade como criador de doninhas, você decide calcular o tamanho médio das doninhas, para compará-lo com a média nacional. A expressão a ser usada para este cálculo é (Siegmund.Tamanho + Sieglinda.Tamanho + Siegfried.Tamanho ) / 3. Naturalmente, qualquer programa que incorpore essa expressão será válido apenas para doninhas especificas. Cada vez que a sua população de doninhas aumentar, será preciso modificar o programa. Você precisa de uma forma mais genérica para armazenar informações.

Em vez de armazenar as informações sobre cada doninha em uma variável separada, você pode alterar a descrição do tipo (definida anteriormente) para conter o nome da doninha. O novo tipo de dados DoninhaTFB é mostrado a seguir.

Type DoninhaTFB

Nome As String

Cor As String

Peso As Integer

Tamanho As Integer

Data_nascimento As Date

Cor_topete As String

Compr_topete As Integer

End Type

Agora, você pode armazenar todas as informações sobre as doninhas coletivamente em uma variável matriz Doninhas. Você pode declarar a variável matriz Doninhas com a instrução Dim Doninhas(20) As DoninhaTFB. Uma vez que essa matriz pode armazenar informações sobre diversas doninhas (21 para ser exato), você precisa declarar outra variável para conter a quantidade de doninhas que existe no momento: use a instrução Dim QtdDoninhas As Integer.

Depois de declarar as variáveis, você pode armazenar dados sobre doninhas, quase da mesma forma que foi usada para armazená-los em variáveis separadas. As instruções que se seguem mostram como alguns desses valores podem ser inicializados:

QtdDoninhas = 3

Doninhas(0).Nome = "Siegmund"

Doninhas(0).Cor = "Marrom"

Doninhas(0).Peso = 300

Doninhas(1).Nome = "Sieglinda"

Doninhas(1).Peso = 250

Doninhas(2).Nome = "Siegfried"

Doninhas(2).Peso = 150

Agora, assumindo que todas as informações sobre as doninhas; tenham sido armazenadas, você pode escrever um programa para calcular o tamanho médio, independentemente da quantidade de doninhas que você tenha. Como seria de se esperar, a codificação se parece com a usada no programa Banco:

Dim Atual As Integer, Total As Integer, Média As Single

Total = 0

For Atual = 0 To QtdDoninhas - 1

Total = Total + Doninhas(Atual).Tamanho

Next Atual

Média = Total / QtdDoninhas

Esse código continuará a ser útil também quando a população de doninhas se modificar. O fator-chave para ser bem-sucedido em programação é examinar o problema para determinar quando pode ou não ser generalizado e então escrever um programa para resolver casos mais gerais, em vez de um programa que tenha de ser constantemente modificado à medida que as condições se alterem.

Usando Laços com Matrizes

Confirmando o que os programas simples deste capítulo devem ter-lhe sugerido, matrizes e laços são tão complementares quanto mão e luva. Operações como cálculo de totais, de médias, achar valores máximos e mínimos prestam-se muito bem ao processamento matricial. Todas essas operações precisam examinar a matriz completa. Outras operações, como procura, examinam apenas alguns elementos de uma matriz.

Considere a matriz das doninhas. Agora que as informações vitais estão armazenadas anonimamente, você não pode usar uma variável como Siegmund para extrair dados de uma certa doninha. Para isso, é necessário pesquisar a matriz até encontrar a doninha cujo elemento Nome seja igual a Siegmund. Por exemplo, se você quiser imprimir o peso de Siegmund, o processo mais simples seria parecido com:

Figura 6.20

Infelizmente, esse programa terá de examinar cada um dos elementos da matriz, mesmo que Siegmund seja o primeiro elemento. Esse problema não é tão sério, enquanto a população de doninhas for pequena, mas a pesquisa poderá demandar um tempo significativo se você tiver algumas centenas de doninhas.

É necessário modificar a condição do laço para terminar quando a doninha desejada for achada. Você pode escrever esse laço de duas formas diferentes. A primeira é reformular o laço, tratando-o com uma instrução Do While na qual a condição de finalização leve em consideração tanto o final da matriz quanto o próprio fato de encontrar a doninha.

Figura 6.21

 

Convertendo o laço For para Do While, torna-se possível definir um teste de condição mais preciso. Esse laço será encerrado quando a variável W ultrapassar o valor máximo, ou então quando na variável Encontrado for armazenado um valor diferente de -1 (o que acontece quando for achado o elemento Siegmund).

O método alternativo consiste em manter o laço For, mas interromper o processamento quando o elemento desejado for encontrado. O Visual Basic oferece a instrução Exit com esta finalidade:

Figura 6.22

Ao atingir a instrução Exit, a execução será imediatamente transferida para a instrução seguinte à instrução Next W.

As duas alternativas são aceitáveis. A primeira tem a vantagem de estabelecer explicitamente as condições de encerramento do laço, simplificando a compreensão do código do programa. O segundo método é ligeiramente mais eficiente, pois o laço não tem de executar um teste adicional sobre o conteúdo da variável Encontrado a cada iteração do laço. Quando o elemento procurado é achado, o laço termina. Entretanto, a instrução Exit que termina o laço encontra-se "perdida" no meio das instruções, podendo passar despercebida para alguém que esteja lendo o programa. Minha preferência pessoal é pelo uso do método mais eficiente.

As três versões desse código contêm um problema comum: a instrução Print. A codificação assume que tenha sido encontrado o elemento procurado, mesmo que isso não tenha acontecido. A versão correta deveria substituir a instrução Print pelo seguinte código:

lf Encontrado = -1 Then

MsgBox "Não foi encontrado"

Else

Print Doninhas(Encontrado).Peso

End If

Determinando o Tamanho da Matriz em Tempo de

Execução

Ao escrever uma instrução Dim para declarar uma matriz, está-se efetivamente preestabelecendo o tamanho da matriz. Pode ser que você conheça exatamente de que tamanho deverá ser a matriz, ou talvez saiba seu tamanho máximo. (Por exemplo, você pode saber que trabalhar com mais de 21 doninhas é muito difícil.) Em tais casos, uma matriz de tamanho fixo é o ideal. O problema ocorre quando não se conhece o tamanho da matriz. Suponha, por exemplo, que você deseje vender o seu programa de tratamento de doninhas para outras pessoas. Como você deve dimensionar a matriz ?

Você pode simplesmente escolher um número arbitrariamente grande, achando que será suficiente, porém encontrará dois problemas com essa abordagem. Primeiro, é necessária muita memória; a instrução Dim reserva memória para a matriz completa, esteja ou não sendo usada. Em segundo lugar, você está correndo o risco de vender o programa para alguém que queira criar mais doninhas do que você acha praticável; o seu programa falhará e você terá um cliente insatisfeito.

Para resolver essa questão, o Visual Basic oferece a instrução ReDim, que redimensiona uma matriz. ReDim não é uma declaração, é uma instrução que pode ser executada várias vezes durante um processamento do programa. Para usar a instrução ReDim, você deve retirar a indicação da dimensão da matriz (tamáximo) de seu programa. Essa omissão avisará que se trata de uma matriz dinâmica (aquela cuja dimensão ou tamanho pode modificar-se). Examine esse fragmento de programa que serve apenas para ilustrar como ReDim funciona:

Dim Teste() As Integer 'Na seção de declarações gerais

'Em algum procedimento de evento

For Tamanho = 10 To 50 Step 10

' Redimensiona a matriz teste

ReDim Teste(Tamanho) As Integer

Next Tamanho

Como a declaração original da matriz Teste não contém o componente tamáximo, o Visual Basic irá reconhecê-la como uma matriz dinâmica. Em algum ponto, o laço For será executado. Na primeira passagem do laço, Teste é redimensionada como uma matriz de 11 elementos (com elementos numerados de 0 a 10). Na próxima passagem, Teste será redimensionada. como uma matriz de 21 elementos. Quando o laço estiver completo, Teste estará dimensionada como uma matriz de 51 elementos. Eis a sintaxe da instrução ReDim:

ReDim [Preserve] variável (tamáxímo) [As tipo]

A sintaxe se parece com a da instrução Dim, exceto pelo fato de a palavra reservada Preserve poder ser incluída, e o valor tamáximo poder ser qualquer expressão inteira. Quando ReDim é usada sem Preserve, qualquer cópia existente da matriz será desconsiderada, e uma matriz completamente nova será criada. Se você usar ReDim com Preserve, os valores armazenados na matriz antiga serão preservados na nova matriz. Caso a nova dimensão da matriz seja menor que a anterior, os valores com índices maiores do que a nova dimensão não serão preservados.

Usando Matrizes de Controles

Além das matrizes de valores de dados, o Visual Basic permite-lhe definir matrizes de objetos de controle, que são úteis quando você estiver trabalhando com vários controles que executem essencialmente a mesma ação. As matrizes de controles compartilham os mesmos procedimentos de eventos. Por exemplo, se você tiver uma matriz de três botões de comando, será chamado o mesmo procedimento Click quando qualquer um dos botões receber um clique.

O Visual Basic permite-lhe diferenciar os itens de uma matriz de controles dentro do procedimento de evento compartilhado mediante a passagem do valor do índice como um argumento para o procedimento. Vejamos como isso funciona. Em um form vazio, crie dois botões de comando. Configure a propriedade Name dos dois botões para btnTeste. Quando tentar configurar a propriedade Name do segundo botão, o Visual Basic apresentará uma caixa de diálogo que lhe pergunta se você deseja ou não criar uma matriz de controles:

Figura 6.23

Dê um clique em Yes na caixa de diálogo. Agora, abra a janela de código, dando um clique duplo em qualquer um dos dois botões. Você verá que foi incluído um parâmetro Index em cada procedimento de evento, conforme mostrado aqui:

Private Sub btnTeste_Click (Index As Integer)

End Sub

Esse procedimento de evento será chamado quando for dado um clique em qualquer um dos dois botões; a propriedade Index do botão que recebeu o clique é passada como um parâmetro inteiro, identificando o botão acionado.

Quando você cria uma matriz de controles, o Visual Basic assinala um índice para cada objeto. Usando a janela de propriedades, examine a propriedade Index para os dois botões de comando criados.

Figura 6.24

O primeiro botão tem a Propriedade Index igual a 0. O segundo tem o valor 1. Você pode modificar a propriedade Index em tempo de desenvolvimento para dar valores especiais para a propriedade Index desses botões. Essa propriedade não pode ser modificada enquanto o programa estiver sendo processado.

Você se refere a um elemento de uma matriz de controles, especificando o nome da matriz seguido pelo valor da propriedade Index, entre parênteses. Por exemplo, esse procedimento Click configura os títulos dos botões de comando no seu form, com o valor da hora em que for dado um clique neles.

Sub btnTeste_Click (Index As Integer)

btnTeste(Index).Caption = Format(Now, "hh:mm:ss")

End Sub

As matrizes de controles são particularmente úteis com botões de opção. Você pode definir todos os botões de opção dentro de uma moldura como uma matriz de controles e então usar a propriedade Index ou a propriedade Caption em instruções de assinalamento. Por exemplo, você poderia usar o procedimento Click com uma matriz de controles de botões de opção mostrada na Figura 6.25.

Private Sub OpcCor_Click (Index As Integer)

MinhaDoninha.Cor = OpcCor(Index).Caption

End Sub

Figura 6.25 Uma matriz de controle de botões de opção.

Uma simplificação interessante para a criação de matrizes de controles consiste na criação do primeiro objeto de controle e na configuração de suas propriedades. Depois, você pode copiar e colá-lo tantas vezes quanto necessário para criar controles adicionais que terão o mesmo tamanho e com configurações de propriedades idênticas.

Identificando melhor os controles

Numa matriz de controles, todos os controles são referenciados pelo índice na matriz. Esta não é uma forma de deixar claro para quem lê o código qual controle é qual. Uma forma de contornar isso é utilizando a propriedade Tag, comum a praticamente todos os controles. Tag pode ser configurada para qualquer valor de string que você queira. Usando Tag para dar nomes aos controles, seus testes de identificação dos controles dentro dos procedimentos de evento não seriam pelo índice, mas sim pelo valor da propriedade Tag. Exemplo:

Private Sub OpcCor_Click(Index As Integer)

Select Case OpcCor(Index).Tag

Case "Marrom"

instruções

Case "Preta"

instruções

Case "Cinza"

instruções

Case "Parda"

instruções

End Select

End Sub

 

RabJump ajusta seu código quando seus controles mudam de nome