Usando On Error para tratar erros
Há vezes em que um erro imprevisto e não tratado acontece. Imagine que isso
aconteça com um usuário da planilha que não tem conhecimento nenhum de VBA:
uma mensagem de erro aparece, a janela do Editor VBA é aberta e todo o seu
código fica visível para ele, que olha atônito e sem saber o que fazer. Essa
cena não é nada agradável e certamente ele estará procurando onde você está
para se queixar do ocorrido.
Para evitar isso temos a instrução On Error, que ativa o manipulador
de erros. Assim você poderá lidar com o erro e evitar que o Excel mande uma
mensagem e abra o Editor VBA (e que o usuário pegue no seu pé). As formas de
usar são as seguintes:
– On Error GoTo [rótulo]: É a principal forma de uso. Assim que um
erro ocorrer, a execução do programa será desviada para um ponto indicado pelo
rótulo. É boa prática manter a área de tratamento de erros no final da
sub-rotina, bem como colocar um Exit Sub antes do rótulo, para que as
instruções do tratamento de erro não sejam executadas toda vez que passar pela
sub-rotina.
– On Error GoTo 0: Desativa o manipulador de erros. É necessário
desativar o que estiver vigente antes de iniciar um novo manipulador de
erros.
– On Error Resume Next: Ignora o erro atual e continua a
execução na instrução posterior à que deu erro. Nenhum tratamento de erro é
feito e o uso desta forma é altamente não recomendado, pois pode ocasionar
erros ainda piores.
A instrução Resume Next (sem On Error na frente) direciona a
execução à instrução seguinte à que deu erro. Ela deve ser utilizada na seção
de tratamento de erros para retornar à execução caso o erro tenha sido tratado
e seja possível continuar a execução. No caso do erro não ser tratável, o
melhor a fazer é exibir uma mensagem ao usuário e encerrar o processamento.
Nessa mensagem é bom escrever algo que amenize o impacto para o usuário e, se
possível, informações que você possa usar para encontrar e lidar com o
erro.
É possível desativar e reativar o manipulador de erros na própria seção de
tratamento de erros, apontando para a própria seção. Desta forma, você poderá
concentrar todo o tratamento de erros em um ponto da sub-rotina. Veja o
exemplo abaixo:
Sub TesteOnError()
Dim Calculo As Integer
On Error GoTo TratarErro
Calculo = “Texto”
Calculo = 5 / 0
Exit Sub
TratarErro:
Debug.Print “Erro número ” & Err.Number & ” – ” &
Err.Description
On Error GoTo 0
On Error GoTo TratarErro
Resume Next
End Sub
A instrução On Error foi colocada logo após a declaração de variável.
Logo em seguida há duas instruções que acionarão o manipulador de erros. Use o
depurador para acompanhar a execução desse código. Assim que passar pela
primeira instrução, a execução irá para o rótulo TratarErro. A área de
Verificação imediata irá exibir o número e a descrição do erro gerado.
Em seguida, o manipulador de erros será desativado e reiniciado. Por fim, a
execução irá para a linha seguinte à que gerou o erro. Esta linha também gera
erro e o processo se repete. A área de Verificação imediata deverá
exibir o seguinte texto:
Erro número 13 – Tipos incompatíveis
Erro número 11 – Divisão por zero
O erro 13 indica “tipos incompatíveis”, pois enviamos texto para uma variável
numérica. Já o erro 11 é bem autoexplicativo.
Observe que há um objeto Err na rotina de tratamento de erros, com
duas propriedades sendo utilizadas: Number e Description, cujas
finalidades estão bem claras no texto gerado. Há ainda dois métodos que
podemos utilizar: Clear e Raise.
Err.Clear, como o nome sugere, zera o código de erro, o que também é
feito pelo On Error GoTo 0. A diferença é que Err.Clear não
desativa o depurador de código, sendo possível continuar apontando novos erros
para a mesma rotina sem necessidade de colocar uma nova linha. Altere a seção
TratarErro para o seguinte código:
TratarErro:
Debug.Print “Erro número ” & Err.Number & ” – ” &
Err.Description
Err.Clear
Resume Next
Executando o código vemos que não foi necessário desativar e ativar novamente
o manipulador de erros. Podemos até comentar a linha com o
Err.Clear que irá funcionar. A instrução Resume Next também zera
o código de erro, portanto também não precisamos nem da instrução
Err.Clear neste exemplo. Porém, é importante conhecer a função dela
porque pode haver casos em que é preciso zerar o código de erro e não dar
sequência no processamento. Pelo mesmo motivo foram mostradas as diferentes
formas de On Error.
Com Err.Raise é possível gerar seus próprios códigos de erros. Isso
pode ser feito tanto para ajudar nos testes do código quanto para ajudar no
próprio tratamento de erros da planilha. Também é possível colocar uma
descrição, que pode ser usada como o texto a colocar em uma mensagem para o
usuário. Veja o exemplo de código abaixo em que o erro está sendo gerado em
uma sub-rotina diferente da que tem o tratamento de erro:
Sub TesteGerarErro()
On Error GoTo TratarErro
GerarErro (513)
GerarErro (842)
GerarErro (1059)
Exit Sub
TratarErro:
Debug.Print “Número: ” & Err.Number & ” – Descrição:
” & Err.Description
Resume Next
End Sub
Sub GerarErro(Erro As Long)
Err.Raise Number:=Erro, Description:=”Erro ” & Erro &
” gerado”
End Sub
Depure o código (tecla F8) para acompanhar a execução. Perceba que não
importe quantos erros estão sendo gerados, a rotina de tratamento de erro
exibe a mensagem com código e descrição e parte para a próxima linha de
código. Em um caso de uso mais realista, pode-se colocar um
Select Case para agir de acordo com a necessidade do erro, inclusive
chamando outras sub-rotinas para simplificar o entendimento do código.
Imagine que esteja processando uma tabela longa e em uma linha aparece algum
dado inválido. A sub-rotina que está lendo a linha pode efetuar uma
consistência dos dados e gerar um código de erro diferente de acordo com a
coluna onde estiver o dado. Por exemplo, se estiver na primeira coluna o
código gerado é 601, se estiver na segunda é 602 e assim sucessivamente.
Pode-se exibir uma mensagem diferente de acordo com o número do erro gerado,
além de selecionar a célula com erro para apontar para o usuário, encerrando o
processamento. Alternativamente, pode-se abrir um formulário mostrando os
dados da linha que está sendo processada, apontando o campo onde está o erro e
solicitar que o usuário coloque o valor correto para continuar o
processamento. Outra possibilidade é não processar as linhas que contiverem
erros e copiar seus valores para um arquivo de texto (ou CSV). Tudo depende da
necessidade do projeto e da habilidade do desenvolvedor.
O intervalo de números de erro entre 0 e 512 é reservado para erros de
sistema. Podemos utilizar os valores entre 513 e 65535 para erros específicos.
Como há muitas possibilidades de valores, podemos definir uso de faixas no
início do projeto, separando por exemplo de 1001 a 2000 para consistências de
dados. Sempre deixe faixas de valores para poder usar um Select Case enviando
faixas diferentes para tratar em rotinas diferentes.
Como pode-se perceber, é possível usar o manipulador de erros do VBA a seu
favor, ajudando a evitar erros de sistema e criando códigos novos para
direcionar o processamento de acordo com a necessidade. Combinando uma boa
consistência de dados preventiva e o devido tratamento em caso de erros, a
chance de algo dar errado torna-se bem próximo de zero. O usuário da sua
planilha provavelmente nunca verá uma janela de erro junto com o Editor de VBA
quando seu código estiver sendo executado.
Espero ter contribuído para melhorar o tratamento de erros de suas planilhas.
Comentários e sugestões são bem vindos.
Pedro Martins
artefinalista, eletrotécnico, programador de CLP (para máquinas
industriais) e analista de sistemas em sistema bancário, programando em
COBOL.
1980, quando teve um MSX e aprendeu a programar em BASIC. É a favor da
disseminação do conhecimento.