Ao executar código VBA no Word que responde a eventos de documento como Open, Close ou BeforeSave, você pode ver o erro 91: Variável de objeto ou variável With block não definida. Esse erro interrompe sua macro e pode ser confuso porque o código parece correto. A causa é quase sempre que uma referência de objeto, como um objeto Document, Range ou Application, não foi atribuída antes que o código tente usá-la. Este artigo explica os motivos específicos pelos quais esse erro ocorre em VBA orientado a eventos e fornece etapas claras para corrigir cada cenário.
Principais conclusões: Corrigindo o erro 91 em eventos de documento do VBA no Word
- Defina obj = Nothing antes de atribuir uma nova referência de objeto: Evita o erro ao reutilizar uma variável de nível de módulo em vários procedimentos de evento.
- Use a referência correta do objeto de documento por meio de Application.Documents(1) ou ThisDocument: Garante que o objeto exista antes que qualquer método ou propriedade seja chamado nele.
- Verifique se o objeto não é Nothing antes de usá-lo em uma instrução If: Evita o erro quando o objeto pode não ter sido criado devido a um caminho de código condicional.
Por que o VBA do Word gera o erro 91 em eventos de documento
O erro 91 ocorre quando seu código VBA tenta usar uma variável de objeto que não possui uma referência atribuída. No contexto de eventos de documento, isso geralmente acontece porque a variável de objeto foi declarada, mas nunca definida como um objeto válido. Cenários comuns incluem:
- Usar uma variável de nível de módulo que contém uma referência a um objeto Document, mas o documento foi fechado antes que o código do evento seja executado.
- Chamar um método em um objeto Range ou Selection que não é mais válido porque o conteúdo do documento mudou.
- Escrever código no módulo ThisDocument que assume que o ActiveDocument é o mesmo que o documento onde o evento está sendo disparado.
- Esquecer de usar a palavra-chave Set ao atribuir um objeto a uma variável.
A causa raiz é que o VBA não consegue acessar um objeto nulo. Quando um procedimento de evento é executado, o documento pode não estar totalmente inicializado ou pode ter sido destruído. Entender esses gatilhos ajuda você a escrever código defensivo que verifica a validade do objeto antes de usá-lo.
Como os eventos de documento disparam o erro
O Word dispara eventos de documento a partir do módulo de código ThisDocument. Por exemplo, o evento Document_Open é executado quando um documento é aberto. Se você declarar uma variável no nível do módulo como Dim doc As Document e depois tentar usar doc dentro de Document_Open sem antes atribuí-la, o VBA gera o erro 91. Da mesma forma, se você definir doc = ActiveDocument mas o documento ativo não for o que foi aberto, a referência pode ser inválida.
Outro gatilho comum é o evento Document_BeforeClose. Se seu código tentar acessar o conteúdo do documento após o início do fechamento, o objeto de documento pode já estar definido como Nothing. É por isso que verificar se é Nothing é essencial em todo procedimento de evento que usa variáveis de objeto.
Etapas para corrigir o erro ‘Variável de objeto não definida’
Os métodos a seguir abordam as causas mais comuns do erro 91 em eventos de documento. Aplique-os na ordem mostrada. Se o erro persistir após um método, passe para o próximo.
Método 1: Definir explicitamente variáveis de objeto dentro de cada procedimento de evento
- Abra o editor VBA
Pressione Alt+F11 no Word para abrir o editor do Visual Basic for Applications. No Project Explorer, clique duas vezes em ThisDocument para abrir sua janela de código. - Localize o procedimento de evento que dispara o erro
Por exemplo, se o erro ocorrer ao abrir o documento, encontre o procedimentoDocument_Open(). Se ele não existir, crie-o selecionando Document na lista suspensa Object e Open na lista suspensa Procedure. - Declare e defina a variável de objeto dentro do procedimento de evento
Em vez de usar uma variável de nível de módulo, declare uma variável local e atribua-a com Set. Por exemplo:Private Sub Document_Open()
Dim doc As Document
Set doc = ThisDocument
MsgBox doc.Name
End Sub
UsarThisDocumentgarante que você faça referência ao documento que contém o código, não a um documento ativo arbitrário. - Teste o código
Feche e reabra o documento para disparar o evento. Se o erro desaparecer, a correção está completa. Caso contrário, prossiga para o Método 2.
Método 2: Verificar se o objeto não é Nothing antes de usá-lo
- Identifique a linha que gera o erro 91
Quando o erro ocorrer, clique em Debug na caixa de diálogo de erro. O editor VBA destaca a linha problemática. Anote a variável de objeto que está sendo usada. - Adicione uma verificação condicional antes da linha
Insira uma instrução If que verifique se o objeto não é Nothing. Por exemplo, se a variável forrng, adicione:If Not rng Is Nothing Then
rng.Text = "Olá"
End If
Se o objeto puder ser Nothing, seu código ignora a operação em vez de travar. - Aplique a verificação a cada variável de objeto no procedimento de evento
Revise todo o procedimento e envolva cada uso de objeto em uma verificação semelhante. Para variáveis de nível de módulo que persistem entre eventos, verifique-as também no início de cada evento. - Teste o documento
Dispare o evento novamente. O erro não deve aparecer. Se ainda ocorrer, prossiga para o Método 3.
Método 3: Usar a coleção Application.Documents em vez de ActiveDocument
- Substitua referências a ActiveDocument
Em seu procedimento de evento, altere cada ocorrência deActiveDocumentparaThisDocumentou para um documento específico da coleçãoApplication.Documents. Por exemplo:Set doc = Application.Documents(1)
Isso é confiável quando você conhece o índice do documento. - Percorra todos os documentos abertos, se necessário
Se você precisar encontrar um documento pelo nome, use um loop For Each:Dim doc As Document
For Each doc In Application.Documents
If doc.Name = "Relatorio.docx" Then
' executar ações
End If
Next doc
Isso evita o erro quando o documento de destino não está ativo. - Teste a correção
Salve o documento, feche-o e reabra-o. O evento deve ser executado sem erro.
Se o VBA do Word ainda gerar o erro 91 após a correção principal
Erro ocorre apenas em Document_BeforeClose
O evento Document_BeforeClose é disparado enquanto o documento está sendo fechado. Nesse ponto, algumas referências de objeto podem já ser inválidas. Para corrigir isso, sempre use ThisDocument em vez de uma variável que pode ter sido definida anteriormente. Além disso, evite referenciar outros documentos abertos dentro de BeforeClose, a menos que você primeiro verifique se eles existem.
Erro ocorre ao executar código de um modelo
Se seu código de evento estiver em um modelo global (Normal.dotm ou um suplemento), o objeto ThisDocument se refere ao modelo, não ao documento. Use ActiveDocument quando o código precisar atuar no documento que está aberto no momento. No entanto, verifique se ActiveDocument não é Nothing antes de usá-lo. Adicione esta linha no início do seu procedimento de evento:If ActiveDocument Is Nothing Then Exit Sub
Erro ocorre intermitentemente em macros de longa duração
Quando uma macro é executada por muito tempo, o usuário pode fechar o documento enquanto a macro ainda está em execução. Isso faz com que as referências de objeto se tornem inválidas. Para evitar isso, use tratamento de erro que capture o erro 91 e saia normalmente. Adicione esta estrutura ao redor do seu código de evento:On Error Resume Next
Set doc = ThisDocument
If doc Is Nothing Then Exit Sub
On Error GoTo 0
Causas do erro 91 do VBA em eventos de documento vs código de módulo padrão
| Item | Código de evento de documento | Código de módulo padrão |
|---|---|---|
| Fonte da referência de objeto | ThisDocument, ActiveDocument ou Application.Documents | Qualquer objeto criado ou passado como parâmetro |
| Causa comum do erro 91 | Evento é disparado antes da inicialização completa do documento ou após sua destruição | Variável declarada, mas nunca atribuída com Set |
| Melhor prática para evitar o erro | Sempre usar ThisDocument dentro do procedimento de evento e verificar se não é Nothing | Definir a variável imediatamente após a declaração e validar antes do uso |
| Escopo da variável | Frequentemente no nível do módulo, causando referências obsoletas entre eventos | Geralmente local, reduzindo o risco de referências obsoletas |
| Dificuldade de depuração | Maior porque os eventos são disparados automaticamente e podem não ser repetíveis | Menor porque você controla quando o código é executado |
Ao entender essas diferenças, você pode escrever código de evento robusto contra erros de referência de objeto. O segredo é sempre atribuir variáveis de objeto dentro do procedimento de evento, nunca confiar em uma variável de nível de módulo que pode ter sido limpa, e sempre verificar se não é Nothing antes de usar qualquer objeto.