Criando uma barra de progresso em formulários
Em processamentos longos, é sempre bom colocar um indicador
de progresso para que o usuário tenha uma noção do que está acontecendo no
momento. Colocar uma mensagem com o progresso na barra de status é uma ótima ideia
e cumpre bem sua função, mas e se quisermos sofisticar um pouco mais?
Que tal abrir um pequeno formulário com uma barra indicando
o progresso? É um efeito visual mais legal e deve deixar o usuário
impressionado.
Crie um formulário e adicione um rótulo para colocar o texto
com a mensagem indicando o progresso, colocando um nome como lblMensagem, por exemplo.
Em seguida, adicione outro rótulo, nomeie como lblFundo, apague o conteúdo da Caption, altere a cor de fundo (BackColor) para branco e acrescente a
borda (BorderStyle = 1 -
fmBorderStyleSingle). Deixe a altura (Height)
em 20 e a largura (Width) em 104.
Por fim, faça uma cópia desse rótulo e batize como lblProgresso. Altere a cor para azul,
retire a borda, defina a altura em 16 e a largura em 100. Posicione dois pixels
abaixo e dois à direita da posição do lblFundo, colocando esse rótulo por cima.
Posicione os objetos no formulário, altere o tamanho do
formulário para algo mais apropriado e coloque um título. O resultado deve ser
algo assim:
Por fim, altere a largura de lblProgresso para 0, que será o valor inicial. A parte de desenho
está feita, agora só falta o código.
No seu código deverá haver uma estrutura de repetição onde
acontecerá a maior parte do processamento. É imediatamente acima dessa
estrutura que deverá ser feito o carregamento do formulário.
frmProcessamento.Show
For Iteracao = ValorInicial To ValorFinal
...
No começo dessa estrutura de repetição deve ser calculado o
percentual atual do processamento. A conta é simples: PosicaoAtual dividido por ValorFinal
multiplicado por 100, com ValorInicial valendo 1. É este valor que será associado à largura da barra de
processamento. Você pode associar diretamente, sem criar uma variável
intermediária.
frmProcessamento.Show
For PosicaoAtual = ValorInicial To ValorFinal
lblProgresso.Width = CInt(PosicaoAtual / ValorFinal * 100)
...
Não se esqueça de alterar o texto do rótulo de mensagem para
indicar o status do processamento.
lblMensagem.Caption = "Andamento: " & lblProgresso.Width
& "%"
Se você processar agora, verá que nada acontece e o
formulário permanece igual a quando carregou. É que está faltando pedir ao
Excel atualizar o formulário:
frmProcessamento.Repaint
Por fim, não se esqueça de remover o formulário quando
terminar o processo. Pode ser logo após o final da estrutura de repetição, mas prefiro
no final do processo.
Unload frmProcessamento
Agora está funcionando. O formulário deve abrir, exibir o
progresso enquanto está processando e, ao terminar, o formulário desaparece.
Se quiser colocar um atraso antes de fechar o formulário,
para que o usuário veja a barra exibindo os 100% completados, pode colocar este
comando:
Application.Wait (Now + TimeValue("00:00:01"))
Esse comando Wait
para todo o processamento até o horário especificado dentro dos parênteses. O
horário no comando acima é um segundo após o instante em que chegar nesse ponto
do processamento (Now).
Você ainda pode incrementar esse formulário com uma imagem e
outros elementos que ajudem a deixar o usuário impressionado. Deixe com uma
aparência bem profissional e de bom gosto.
Este artigo foi bem curto em comparação com os anteriores,
mas ainda assim acredito que tenha gostado bastante desta dica.
Pedro Martins
Formado em Tecnologia em Eletrônica Digital, já trabalhou como artefinalista, eletrotécnico, programador de CLP (para máquinas industriais) e analista de sistemas em sistema bancário, programando em COBOL.
Mexe com computadores e programação desde a segunda metade dos anos 1980, quando teve um MSX e aprendeu a programar em BASIC. É a favor da disseminação do conhecimento.
Mais uma vez um excelente artigo Pedro! Muito obrigado!
ResponderExcluirExcelente mesmo professor, como faço para entrar em contato com o Pedro Martins? gostaria de perguntar sobre com uma barra dupla de progresso. uma para cada estrutura de repetição e uma outra para a macro completa?
ExcluirOlá, Márcio, este espaço pode ser usado para dúvidas :)
ExcluirPelo que entendi no seu caso, você tem duas barras de progresso com várias estruturas de repetição e quer usar a primeira para a execução total da macro e a segunda para as estruturas de repetição.
A solução é simples, você usa a segunda barra para todas as estruturas de repetição, não se esquecendo de zerar o valor da barra antes de entrar no laço.
Para a barra do processo todo, você precisa fazer uma variável contadora da etapa do processo: a cada estrutura de repetição processada, incrementa um nesse contador e atualiza o formulário para mostrar. Segue um código para demonstrar a ideia:
lblProgressoLaco.Width = 0
For PosicaoAtual = ValorInicial To ValorFinal
lblProgressoLaco.Width = CInt(PosicaoAtual / ValorFinal * 100)
... ' Processamento
frmProcessamento.Repaint
Next
EtapasConcluidas = EtapasConcluidas + 1
lblProgressoMacro.Width = CInt(EtapasConcluidas / TotalDeEtapas * 100)
frmProcessamento.Repaint
É melhor colocar o trecho do incremento em uma sub-rotina à parte para evitar reescrever esse código após cada laço executado, bastando assim chamar essa sub-rotina.
Veja se essa solução resolve seu problema :)
Pedro Martins, como faço para inserir essa macro da barra de progresso em outra macro que tenho de configuração de pagina para impressão.A barra de progresso teria que revelar o status do processamento da macro. Poderia me ajudar?
ResponderExcluirEste comentário foi removido pelo autor.
ResponderExcluirDesculpe, sai com Desconhecido. Não sei muito mexer nestas coisas.
ResponderExcluirMas a pergunta foi minha. Acho que agora sai com meu perfil.
Olá, Prof. Pedro. Sei que já faz tempo que escreveu este artigo mas só agora descobri e estou estudando todos desde o primeiro. Mas neste artigo não consigo compreender. Não sei como iniciar as variáveis PosicaoAtual, ValorInicial e ValorFinal. Poderia me ajudar?
ResponderExcluirFiz uma estrutura de repetição simples associada a um botão na planilha (como sempre o Prof. Alessandro faz). A estrutura procura números pares em um conjuntos de células e copia para outra coluna os valores pares.
Fiz assim:
Do While W.Cells(Lin, 1).Value <> ""
Valor = W.Cells(Lin, 1).Value
If Valor Mod 2 = 0 Then
W.Cells(TransfLin, 3).Value = Valor
TransfLin = TransfLin + 1
End If
Lin = Lin + 1
Loop
Como faço para incluir a barra de progresso?
Obrigada.
Yara
Olá, Prof. Pedro.
ResponderExcluirEu consegui fazer. Depois de quebrar a cabeça, consegui entender. Tive que modificar um pouco a minha estrutura de repetição para identificar o valor final e tive que colocar tb um vbmodeless após o frmprocessamento.show, senão o código era interrompido.
Obrigada.
Não consegui entender e nem colocar em prática a execução desse código...
ResponderExcluir