VBA – DoEvents
Este tutorial abordará como usar o comando DoEvents no VBA.
O comando DoEvents do VBA pausa temporariamente uma macro em execução, dando ao Excel a chance de processar pressionamentos de teclas, cliques do mouse e outras mensagens do sistema operacional.
Em macros de longa duração, o Excel pode parecer travado e não responder, e pode ser impossível interromper a macro. Se o DoEvents for incluído no seu código, os usuários poderão ter certeza de que a macro ainda está em execução e ainda poderão interromper a execução, se necessário.
Exemplo de DoEvents do VBA
Considere o código a seguir:
Public Sub Teste()
Dim i As Long
For i = 1 To 20000
Range("A1").Value = i
Next i
End Sub
Ao experimentar esse código, você notará que não é possível interagir com a janela do Excel. Entretanto, como não exige muito do processador, a macro ainda pode ser interrompida pressionando-se ESC ou CTRL+BREAK.
Se muitas funções complexas e exigentes estivessem sendo executadas dentro desse loop, o Excel levaria mais tempo para registrar um evento de pressionamento de tecla – até vários minutos ou talvez nem isso, especialmente se o computador estiver executando outros programas ao mesmo tempo.
Agora, adicione uma única linha com DoEvents abaixo da atribuição de Range:
Range("A1").Value = i
DoEvents
Se você executar esse código novamente, verá que o Excel agora é responsivo – ele pode ser focalizado e trazido para o primeiro plano. DoEvents é chamado todas as vezes no loop, o que garante que a macro esteja sempre produzindo execução para que o Excel possa processar todas as mensagens enviadas a ele. Como essa macro é executada rapidamente, quase parece que está sendo executada em segundo plano (embora não esteja) – mais operações dentro do loop exporiam rapidamente essa ilusão.
Perigos do DoEvents
Porém, dê uma segunda olhada. Mais do que simplesmente permitir que o Excel seja focado, você pode realmente clicar dentro das células e até mesmo alternar entre guias enquanto a macro estiver em execução (experimente – você verá um comportamento engraçado). Isso mostra um dos perigos do DoEvents: ele pode causar consequências indesejadas se a macro não for codificada com cuidado.
Outro perigo é que o DoEvents pode servir como uma janela para outras macros serem executadas dentro dele. Tente o seguinte: coloque um CommandButton ActiveX na planilha, clique duas vezes nele e adicione o seguinte código dentro do evento CommandButton1_Click():
Dim c As Range
For Each c In Range("B3:E8")
c.Value = c.Value + 1
Next c
Desative o Modo Design no Excel e, em seguida, execute a macro Teste() que você adicionou anteriormente. Enquanto a macro Test estiver em execução, você pode clicar no CommandButton na planilha, e a macro associada será executada assim que DoEvents der uma pausa na macro Test().
O perigo aqui é se a macro CommandButton alterar os dados nos quais a macro Teste() estava trabalhando ou acionar a macro Teste() novamente. Você pode acabar com resultados extremamente confusos se não tomar cuidado.
Por fim, você deve estar ciente de que DoEvents fará com que sua macro sofra um impacto no desempenho quando for chamado. Dentro de um loop, esse impacto se acumulará rapidamente, a menos que você limite a frequência com que DoEvents é chamado. Com relação ao nosso exemplo Teste(), tente o seguinte:
If i Mod 1000 = 0 Then DoEvents
Isso reduz visivelmente a capacidade de resposta do Excel, mas o impacto no desempenho será menor.
Quando Usar DoEvents
Apesar desses perigos, DoEvents é uma função útil que ajuda nos testes e na depuração. Considere adicionar DoEvents a loops de longa duração.
Outro motivo para incluir DoEvents é permitir o feedback do usuário. Por exemplo, uma macro pode atualizar os rótulos de um UserForm com indicadores de progresso. Sem DoEvents, o Excel pode não receber as mensagens para repintar o UserForm, dando ao usuário a impressão de que a macro parou de funcionar – especialmente se você mudar para outro programa e depois tentar voltar para o Excel. No entanto, com DoEvents, o UserForm continuará a ser repintado e as atualizações do progresso da macro continuarão a aparecer.
Na maioria das vezes, DoEvents não é algo que você queira incluir muito em seu código e pode ser omitido. No entanto, se a capacidade de resposta for algo de que sua macro precisa, não o deixe de lado!