Usuário com melhor resposta
Planilha com log de erros

Pergunta
-
Olá pessoal.
Estou criando um sisteminha para uma empresa e gostaria de criar uma planilha que registrasse todos os erros durante a execução das macros, já que com On Error Resume Next o código não é interrompido. Assim eu poderia analisar de tempos em tempos para ver se etá tudo certo.
Seria interessante registrar o máximo de informações possíveis, como o nome do procedimento, a linha de código onde ocorreu o erro, o tipo de erro e etc.
Pesquisei bastante e não consegui algo que resolvesse o problema.
Precisava de algo do tipo:
On Error Call RegistraErro
Mas pelo jeito isto não é possível.
Se puderem me ajudar agradeço muito.
- Editado Apenas mais um segunda-feira, 8 de novembro de 2021 01:09
Respostas
-
Deixando registrado para alguém que tenha a mesma dúvida...
De acordo com as respostas dadas a uma pergunta que fiz em outro tópico, consegui escrever um código para realizar o que estava precisando. Segue abaixo um exemplo simplificado onde os 4 erros são armazenados na planilha 'LogErros'.Sub TesteDeErros() On Error GoTo ResgistraErro: x = 1 / 0 y = 1 / "s" Range("1A").Select Sheets("PlaninhaInexistente").Select Exit Sub RegistraErro: Ul = Range("A" & Rows.Count).End(xlUp).Row + 1 With Sheets("LogErros") .Range("A" & Ul) = Err.Number .Range("B" & Ul) = Err.Description .Range("C" & Ul) = Now End With Err.Clear Resume Next End Sub
- Marcado como Resposta Apenas mais um domingo, 27 de julho de 2014 18:39
- Editado Apenas mais um segunda-feira, 8 de novembro de 2021 01:12
Todas as Respostas
-
Michel,
você pode criar um procedimento que pegue o valor do erro e grave na sua planilha de log....
algo como
Public Sub prcEnviarErrorLog(strProcedimento As String, lngErrNumber As Long, strErrMessage As String, DataHora As String) 'Aqui você cria o procedimento de gravaçao na planilha 'enviando os dados strProcedimento , lngErrNumber e strErrMessage End Sub Sub RotinaTeste() On Error GoTo TrataErro 'Aqui terá seu procedimento normal, 'Caso haja erro o código dará um salto até TrataErro TrataErro: 'Aqui o programa chamará a procedure prcEnviarErroLog prcEnviarErrorLog "RotinaTeste", Err.Number, Err.Description, Format(Now, "dd/mm/yyyy hh:mm") End Sub
Espero ter ajudado!
-
Olá Natan. Muito obrigado pela resposta.
Eu havia começado a fazer algo neste sentido, mas tem um grande problema. Ao encontrar um erro existe este salto para o fim do código e não é isto que eu quero. Porque aí o restante do código não é executado.
Por isto seria interessante algo como uma função. Porque ao encontrar o erro a função de registro do erro seria executada e o código seguiria normalmente, podendo até encontrar outros possíveis erros.
Ou estou falando besteira?
Grato!
- Editado Apenas mais um segunda-feira, 8 de novembro de 2021 01:09
-
Michel,
existem muitos programadores que rejeitam eternamente o uso do On Error Resume Next, considerando como uma péssima prática.... na maioria dos casos eu até concordo.
Mas se em algum procedimento temos certeza que um possível erro não trará problemas ao projeto num todo, eu não vejo motivo de tanto desprezo.
Mas uma opção pra você é sempre verificar se houve um erro e gravar o log...
Coloca isso em um módulo e habilita a opção de Verificação Imediata, pressiona F5 dentro da prcTeste pra executar.... vê se te ajuda.
Sub prcTeste() On Error Resume Next Debug.Print "Primeiro Bloco de Comandos" prcVerificaErro Debug.Print "Segundo Bloco de Comandos" prcVerificaErro Debug.Print 1 / 0 prcVerificaErro Debug.Print "Terceiro Bloco de Comandos" prcVerificaErro Debug.Print 1 * "A" prcVerificaErro Debug.Print "Quarto Bloco de Comandos" prcVerificaErro End Sub Sub prcVerificaErro() If Err.Number <> 0 Then Debug.Print "Erro: " & Err.Number & " - " & Err.Description Err.Clear End If End Sub
-
Olá Natan. Agradeço novamente a resposta.
Também acho perigo este "On Error Resume Next" pelas possibilidade de ocultar erros durante a execução. Não costumo utilizar em projetos pessoais, mas em projetos para outras pessoas que não entendem muito de VBA é complicado. Muitas vezes existem códigos importantes no fim dos procedimentos como proteger a planilha, habilitar screen, habilitar eventos, habilitar cálculo automático e etc. E se não executarem o sistema pode ter problemas bem maiores.
Gostei bastante da sua solução. Não havia pensado em algo assim. Ajuda bastante, mas ainda não é a solução perfeita. O problema é esta ideia de "bloco de comandos". Qual seria o tamanho ideal de um bloco? O ideal seria chamar esta verificação de erro a cada linha de código, mas obviamente não é uma solução muito elegante.
Aproveitando... como eu poderia registrar o nome do módulo onde ocorreu o erro? E é possível registrar a linha também? Porque apenas com o número do erro e sua descrição fica muito difícil rastreá-lo e corrigi-lo.
Grato!
- Editado Apenas mais um segunda-feira, 8 de novembro de 2021 01:10
-
Michel,
não existe um tamanho ideal, realmente usar a verificação a cada linha fica muito deselegante sim....
Nesse caso o interessante é chamar a procedure após um trecho que é mais propenso a erro ou um trecho mais crítico.
Para você saber em que linha o erro foi gerado você pode "rotular" cada linha do seu código.... da um pouco de trabalho e eu realmente nunca utilizei....
- Editado 'Natan Silva quarta-feira, 16 de julho de 2014 17:37
- Sugerido como Resposta 'Natan Silva quarta-feira, 16 de julho de 2014 18:38
- Não Sugerido como Resposta 'Natan Silva terça-feira, 23 de setembro de 2014 14:17
-
Legal Natan.
Não conhecia esta possibilidade. Irei analisar.
Muito obrigado!
- Editado Apenas mais um segunda-feira, 8 de novembro de 2021 01:11
-
Deixando registrado para alguém que tenha a mesma dúvida...
De acordo com as respostas dadas a uma pergunta que fiz em outro tópico, consegui escrever um código para realizar o que estava precisando. Segue abaixo um exemplo simplificado onde os 4 erros são armazenados na planilha 'LogErros'.Sub TesteDeErros() On Error GoTo ResgistraErro: x = 1 / 0 y = 1 / "s" Range("1A").Select Sheets("PlaninhaInexistente").Select Exit Sub RegistraErro: Ul = Range("A" & Rows.Count).End(xlUp).Row + 1 With Sheets("LogErros") .Range("A" & Ul) = Err.Number .Range("B" & Ul) = Err.Description .Range("C" & Ul) = Now End With Err.Clear Resume Next End Sub
- Marcado como Resposta Apenas mais um domingo, 27 de julho de 2014 18:39
- Editado Apenas mais um segunda-feira, 8 de novembro de 2021 01:12
-