Select Menu



por Alessandro Trovato

» » » » » » » » VBA - Artigo 012 - Usando On Error para tratar erros
«
Proxima
Postagem mais recente
»
Anterior
Postagem mais antiga


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


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.

Autor Pedro Martins

Esta é uma breve descrição no bloco de autor sobre o autor. Você edita-lo, no html
«
Proxima
Postagem mais recente
»
Anterior
Postagem mais antiga

2 comentários

  1. Parabéns por mais esse ótimo artigo Pedro!

    ResponderExcluir
  2. Muito bom sua explicaçao, mas estou teno uma certa difuculdade em acertar meu codigo. Poderia me ajudar? Quando digito um codigo que não esta no banco de dados, na caixa de texto(Combobox) manda a mesnagem de depuração. Ja tentei alguns tratamentos e erro, mas sem exito. Poderia me ajudar? Me passa seu e-mail que mando o projeto e se puder verificar ficaria agradecido.

    ResponderExcluir