Capítulo 16: Tratamento Robusto de Exceções e Auditoria de Erros

🎯 Objetivo da Aula

Nesta aula, você aprenderá as melhores práticas corporativas de Tratamento de Exceções (Error Handling) no VBA. Você compreenderá como blindar suas aplicações contra travamentos inesperados, eliminando a assustadora janela amarela de depuração que confunde os usuários finais e expõe o código-fonte da empresa. Você dominará as diretivas On Error GoTo, On Error Resume Next e On Error GoTo 0, inspecionará o objeto de sistema Err e construirá mecanismos de auditoria com gravação de logs técnicos de falhas.

Ao final desta aula, você terá desenvolvido o motor resiliente de importação e auditoria financeira da FastLog S.A.


🏢 Cenário Prático (FastLog S.A.)

Empresa: FastLog Transportes & Logística Integrada S.A.
Problema: Durante o fechamento contábil de fim de mês, o robô de liquidação de fretes processava mais de 8.000 lançamentos bancários. Em um dos lotes, um arquivo continha um registro com peso zero (provocando uma divisão por zero: Erro de tempo de execução 11) e outro registro continha uma data inexistente (ex: 31/02/2026). O VBA interrompeu a execução bruscamente com a janela padrão: “Erro de tempo de execução… [Fim] [Depurar]”. Um assistente assustado clicou em “Depurar”, desconfigurou o código-fonte no VBE e deixou a liquidação incompleta, gerando duplicidade de pagamentos de R$ 180.000,00 no dia seguinte.
Sua Missão: Blindar o procedimento LiquidarFretesResiliente, garantindo que nenhum erro derrube a aplicação. O robô deve capturar qualquer falha em tempo de execução, identificar o número e a descrição do erro pelo objeto Err, gravar o incidente em uma trilha de auditoria e exibir uma mensagem amigável e explicativa ao operador.


🧠 Fundamentos: A Teoria Traduzida

1. O Fluxo de Controle com On Error GoTo

Sem tratamento de erro, qualquer exceção interrompe o programa instantaneamente. Com o tratamento estruturado, o controle é desviado suavemente para uma rotina especializada no rodapé do procedimento:

flowchart TD
    START["Início da Macro"] --> TRT["On Error GoTo TratarErro"]
    TRT --> HAPPY["Execução Normal (Happy Path)<br/>Cálculos, leitura e gravações"]
    HAPPY --> CHK{"Ocorreu alguma exceção?<br/>(Divisão por zero, arquivo inexistente)"}
    CHK -- NÃO --> EXIT["Exit Sub (Saída limpa normal)"]
    CHK -- SIM --> HANDLER["TratarErro: (Tratador de Exceções)<br/>Objeto Err captura detalhes"]
    HANDLER --> LOG["Registra Falha no Log de Auditoria"]
    LOG --> MSG["MsgBox Amigável: 'Operação cancelada com segurança.'"]
    MSG --> FIM["End Sub"]

    style START fill:#1a365d,stroke:#fff,stroke-width:2px,color:#fff
    style TRT fill:#2c3e50,stroke:#fff,stroke-width:2px,color:#fff
    style HAPPY fill:#27ae60,stroke:#fff,stroke-width:2px,color:#fff
    style CHK fill:#f39c12,stroke:#fff,stroke-width:2px,color:#fff
    style EXIT fill:#2980b9,stroke:#fff,stroke-width:2px,color:#fff
    style HANDLER fill:#c0392b,stroke:#fff,stroke-width:2px,color:#fff
    style LOG fill:#8e44ad,stroke:#fff,stroke-width:2px,color:#fff
    style MSG fill:#d35400,stroke:#fff,stroke-width:2px,color:#fff
    style FIM fill:#7f8c8d,stroke:#fff,stroke-width:2px,color:#fff

2. O Quarteto de Diretivas de Erro do VBA

ComandoComportamentoQuando Usar?
On Error GoTo RótuloDesvia imediatamente o fluxo para uma seção identificada por um rótulo no rodapé.Padrão em rotinas corporativas de gravação, cálculo e conexão de banco de dados.
On Error Resume NextIgnora solenemente o erro e passa para a linha de código imediatamente seguinte.Apenas em checagens cirúrgicas (ex: testar se uma aba ou arquivo existe).
On Error GoTo 0Desativa o tratador personalizado e restaura o comportamento padrão do Excel.Logo após o trecho que usou Resume Next.
Exit SubEncerra o procedimento antes do rótulo de erro.Obrigatório antes do rótulo, evitando que a rotina de erro seja executada no fluxo normal!

3. O Objeto Err e Suas Propriedades

Quando uma falha ocorre, o VBA preenche automaticamente o objeto global Err:

  • Err.Number: Código numérico oficial do erro (ex: 11 = Divisão por zero; 13 = Tipos incompatíveis; 9 = Subscrito fora do intervalo).
  • Err.Description: Descrição textual da falha gerada pelo sistema operacional.
  • Err.Source: Nome do componente que originou o erro.
  • Err.Clear: Limpa os dados do objeto Err da memória.

📖 Exemplo Guiado: Passo a Passo no Laboratório

No computador do laboratório, acesse o VBE com Alt + F11.

Passo 1: Inserção do Módulo de Resiliência

  1. No menu superior, clique em Inserir ➔ Módulo.
  2. Na janela de propriedades (F4), renomeie o módulo para: modResilienciaErros.
  3. Confirme a presença de Option Explicit.

🛠️ Prática Obrigatória 1: Estruturação do Padrão Try/Catch Corporativo

Construiremos a rotina oficial de liquidação financeira com o padrão arquitetural clássico de blindagem de erros.

Passo a Passo no Computador:

  1. No módulo modResilienciaErros, digite o seguinte procedimento:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    
    Option Explicit
    
    Sub LiquidarFretesResiliente()
        ' 1. Habilitação da Blindagem de Erros
        On Error GoTo TratarErro
    
        Dim ws As Worksheet
        Dim lngLinha As Long
        Dim curValorTotal As Currency
        Dim dblPesoKg As Double
        Dim curPrecoPorKg As Currency
    
        Set ws = ThisWorkbook.Worksheets(1)
    
        ' Desativa tela para proteção
        Application.ScreenUpdating = False
    
        ' Leitura das células A2 e B2
        curValorTotal = CCur(ws.Range("A2").Value)
        dblPesoKg = CDbl(ws.Range("B2").Value)
    
        ' Operação de risco (se peso for 0, causará erro 11: Divisão por Zero)
        curPrecoPorKg = curValorTotal / dblPesoKg
    
        ' Gravação do resultado
        ws.Range("C2").Value = curPrecoPorKg
        ws.Range("C2").NumberFormat = "R$ #,##0.00"
        ws.Range("D2").Value = "LIQUIDADO COM SUCESSO"
        ws.Range("D2").Interior.Color = RGB(220, 255, 220)
    
        Application.ScreenUpdating = True
        MsgBox "Liquidação realizada com sucesso!", vbInformation, "FastLog Sucesso"
    
        ' SAÍDA LIMPA: Impede a execução acidental do tratador de erros abaixo!
        Exit Sub
    
    TratarErro:
        ' 2. ROTINA DE CONTINGÊNCIA (Executada apenas se houver falha!)
        Application.ScreenUpdating = True
    
        Dim strMensagem As String
        strMensagem = "FALHA OPERACIONAL DETECTADA:" & vbCrLf & vbCrLf & _
                      "• Código do Erro: " & Err.Number & vbCrLf & _
                      "• Descrição Oficial: " & Err.Description & vbCrLf & vbCrLf
    
        Select Case Err.Number
            Case 11 ' Divisão por zero
                strMensagem = strMensagem & "Causa: O peso da carga na célula B2 está zerado ou nulo!"
            Case 13 ' Type mismatch (Tipos incompatíveis)
                strMensagem = strMensagem & "Causa: Foi digitado texto onde o sistema esperava um valor numérico!"
            Case Else
                strMensagem = strMensagem & "Causa: Falha genérica não catalogada. Consulte o suporte de TI."
        End Select
    
        ' Grava status de erro na planilha
        ws.Range("D2").Value = "FALHA: ERRO " & Err.Number
        ws.Range("D2").Interior.Color = RGB(255, 200, 200)
    
        ' Emite notificação amigável e segura ao operador (sem janela de depuração!)
        MsgBox strMensagem, vbCritical, "FastLog - Segurança Transacional"
    End Sub
  2. Testes Práticos no Excel:

    • Alterne para a planilha. Na linha 1, crie os cabeçalhos:
      • A1: Valor_Frete | B1: Peso_Kg | C1: Preco_Por_Kg | D1: Status_Liquidacao
    • Cenário de Sucesso: Na célula A2, digite 10000 e na B2, digite 2500. Execute a macro (F5).
      • Resultado: R$ 4,00 por kg e status "LIQUIDADO COM SUCESSO".
    • Cenário de Falha Crítica 1 (Divisão por Zero): Altere B2 para 0. Execute a macro (F5).
      • Resultado: Em vez do travamento amarelo do VBA, surge o alerta corporativo vermelho explicando que o peso estava zerado!
    • Cenário de Falha Crítica 2 (Texto em Campo Numérico): Altere A2 para "DEZ MIL". Execute a macro.
      • Resultado: O sistema captura o Erro 13 (Type Mismatch) e orienta o operador de forma clara!

✅ Resultado Esperado (Prática 1):

A aplicação nunca quebra nem exibe o código-fonte ao usuário, respondendo de forma madura e resiliente a qualquer dado incorreto.


🛠️ Prática Obrigatória 2: Gravação da Trilha de Auditoria Técnica

Agora criaremos uma rotina utilitária que persiste as falhas ocorridas em uma aba de auditoria oculta (Auditoria_Erros), permitindo que a equipe de TI analise as ocorrências sem incomodar os operadores de campo.

Passo a Passo no Computador:

  1. No mesmo módulo, adicione a sub-rotina de auditoria e integre-a ao tratador de erro:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    
    Private Sub RegistrarTrilhaAuditoria(ByVal lngNumErro As Long, _
                                         ByVal strDescricao As String, _
                                         ByVal strProcedimento As String)
        Dim wsAudit As Worksheet
        Dim lngLinha As Long
    
        ' Desativa erro local para garantir a integridade do próprio gravador de log
        On Error Resume Next
        Set wsAudit = ThisWorkbook.Worksheets("Auditoria_Erros")
        On Error GoTo 0
    
        If wsAudit Is Nothing Then
            Set wsAudit = ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count))
            wsAudit.Name = "Auditoria_Erros"
            wsAudit.Tab.Color = RGB(192, 57, 43)
            wsAudit.Range("A1:E1").Value = Array("DATA_HORA", "USUARIO_WINDOWS", "PROCEDIMENTO", "NUM_ERRO", "DESCRICAO")
            wsAudit.Range("A1:E1").Font.Bold = True
            wsAudit.Range("A1:E1").Interior.Color = RGB(220, 220, 220)
        End If
    
        lngLinha = wsAudit.Cells(wsAudit.Rows.Count, "A").End(xlUp).Row + 1
    
        wsAudit.Cells(lngLinha, 1).Value = Now
        wsAudit.Cells(lngLinha, 2).Value = Environ("USERNAME") ' Captura o login de quem está usando o PC!
        wsAudit.Cells(lngLinha, 3).Value = strProcedimento
        wsAudit.Cells(lngLinha, 4).Value = lngNumErro
        wsAudit.Cells(lngLinha, 5).Value = strDescricao
    
        wsAudit.Columns("A:E").AutoFit
    End Sub
  2. Adicione a seguinte linha dentro do bloco TratarErro: da sua macro anterior:
    1
    
        Call RegistrarTrilhaAuditoria(Err.Number, Err.Description, "LiquidarFretesResiliente")
  3. Provoque novamente um erro de propósito e verifique a nova aba "Auditoria_Erros" criada automaticamente com o registro forense do erro, data, hora e o nome do usuário do Windows!

✅ Resultado Esperado (Prática 2):

Todas as exceções ocorridas na empresa são registradas silenciosamente com data, hora e login do Windows para fins de governança de TI.


📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_16_VBA_SeuNome_SeuSobrenome.xlsm.
  2. Acesse a plataforma Microsoft Teams.
  3. Abra a tarefa: “VBA - Cap 16: Tratamento de Exceções e Resiliência”.
  4. Anexe sua pasta de trabalho e entregue.

💡 Checkpoint de Gestão & TI

No padrão internacional de governança de software (como COBIT e ISO 27001), nenhum sistema corporativo pode expor telas de depuração aos operadores comuns. A exibição de código-fonte aberto permite a manipulação não autorizada de regras de faturamento e expõe senhas de conexão com bancos de dados. Um tratamento de erro profissional é o divisor de águas entre scripts amadores e sistemas de TI de padrão industrial.


🔥 Desafio de Fixação: Rollback de Transação Financeira

Implemente o conceito de Rollback (Desfazer Alterações):

  1. Antes de iniciar as alterações, armazene o valor antigo da célula em uma variável de backup (curBackupValor = ws.Range("C2").Value).
  2. Se a macro falhar no meio do processamento (dentro de TratarErro:), restaure o valor original da planilha a partir da variável de backup:
    1
    
    ws.Range("C2").Value = curBackupValor
  3. Isso garante o princípio ACID: ou a transação é 100% concluída ou o sistema volta ao estado original sem corrupção de dados!

🔑 Revelar Gabarito Oficial de Laboratório (Clique para expandir)
💡 Incentivo Pedagógico: Tente resolver as práticas e o desafio de fixação por conta própria antes de abrir o gabarito. Seus erros e tentativas durante o laboratório são a chave para a consolidação real do aprendizado!

Código Consolidado (modResilienciaErros):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
Option Explicit

Sub ProcessamentoFinanceiroBlindado()
    On Error GoTo TratarErro
    
    Dim ws As Worksheet
    Dim curValorTotal As Currency
    Dim dblPesoKg As Double
    Dim curPrecoPorKg As Currency
    Dim curBackup As Variant
    
    Set ws = ThisWorkbook.Worksheets(1)
    
    ' Armazena estado anterior para Rollback
    curBackup = ws.Range("C2").Value
    
    curValorTotal = CCur(ws.Range("A2").Value)
    dblPesoKg = CDbl(ws.Range("B2").Value)
    
    curPrecoPorKg = curValorTotal / dblPesoKg
    
    ws.Range("C2").Value = curPrecoPorKg
    ws.Range("C2").NumberFormat = "R$ #,##0.00"
    ws.Range("D2").Value = "PROCESSADO COM SUCESSO"
    ws.Range("D2").Interior.Color = RGB(220, 255, 220)
    
    Exit Sub

TratarErro:
    ' Executa Rollback dos dados (Desafio de Fixação)
    ws.Range("C2").Value = curBackup
    ws.Range("D2").Value = "CANCELADO: FALHA NA TRANSAÇÃO"
    ws.Range("D2").Interior.Color = RGB(255, 200, 200)
    
    ' Registro de Auditoria Forense
    Call RegistrarLogErro(Err.Number, Err.Description, "ProcessamentoFinanceiroBlindado")
    
    MsgBox "Ocorreu uma falha no cálculo financeiro." & vbCrLf & _
           "As alterações foram desfeitas com segurança (Rollback) e o erro foi registrado para a TI.", _
           vbExclamation, "FastLog Resiliência"
End Sub

Private Sub RegistrarLogErro(ByVal lngNum As Long, ByVal strDesc As String, ByVal strProc As String)
    Dim wsAudit As Worksheet
    Dim lngLinha As Long
    
    On Error Resume Next
    Set wsAudit = ThisWorkbook.Worksheets("Auditoria_Erros")
    On Error GoTo 0
    
    If wsAudit Is Nothing Then
        Set wsAudit = ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count))
        wsAudit.Name = "Auditoria_Erros"
        wsAudit.Tab.Color = RGB(192, 57, 43)
        wsAudit.Range("A1:E1").Value = Array("DATA_HORA", "USUARIO", "ROTINA", "COD_ERRO", "MENSAGEM")
        wsAudit.Range("A1:E1").Font.Bold = True
    End If
    
    lngLinha = wsAudit.Cells(wsAudit.Rows.Count, "A").End(xlUp).Row + 1
    wsAudit.Cells(lngLinha, 1).Value = Now
    wsAudit.Cells(lngLinha, 2).Value = Environ("USERNAME")
    wsAudit.Cells(lngLinha, 3).Value = strProc
    wsAudit.Cells(lngLinha, 4).Value = lngNum
    wsAudit.Cells(lngLinha, 5).Value = strDesc
    wsAudit.Columns("A:E").AutoFit
End Sub

📝 Atividade Extra: Questionário de Fixação (Caderno)

Instruções: Responda no caderno, de próprio punho, as 10 perguntas abaixo com base no que você estudou neste capítulo. Ao concluir, apresente o caderno ao professor para visto.

  1. Por que permitir que a janela de depuração amarela do VBA apareça para um usuário final é considerado uma falha grave de segurança e usabilidade?
  2. Como funciona a instrução On Error GoTo NomeDoRotulo?
  3. Qual é a função indispensável da instrução Exit Sub posicionada logo antes do rótulo de tratamento de erros?
  4. O que a instrução On Error Resume Next faz e por que devemos ter muito cuidado ao utilizá-la?
  5. Qual é a finalidade da instrução On Error GoTo 0?
  6. Quais informações cruciais o objeto de sistema Err fornece através das propriedades .Number e .Description?
  7. Cite dois códigos numéricos de erro comuns do VBA e explique o que eles significam.
  8. Como a função de sistema Environ("USERNAME") foi utilizada no registro forense de logs?
  9. O que significa o conceito transacional de Rollback e por que ele é crucial em fechamentos financeiros?
  10. Como a padronização de tratamento de erros colabora com auditorias de segurança da informação (ISO 27001)?