Por que os controles do UserForm VBA do Word perdem valores ao reexibir após fechar
🔍 WiseChecker

Por que os controles do UserForm VBA do Word perdem valores ao reexibir após fechar

Você criou um UserForm VBA no Word. Preenche caixas de texto, seleciona itens de lista e clica em um botão que oculta o formulário. Na próxima vez que exibir o formulário, todos os controles estarão em branco novamente. Isso acontece porque o VBA não persiste os valores dos controles do UserForm entre instâncias. Cada vez que o formulário é fechado ou descarregado, sua memória é limpa. Este artigo explica por que os dados dos controles são perdidos e como preservar valores ao exibir o formulário várias vezes.

Principais conclusões: Preservando valores de controles do UserForm no VBA do Word

  • O evento Terminate do UserForm é executado ao fechar: Descarregar o formulário destrói todos os valores dos controles, pois o objeto do formulário é removido da memória
  • Método Hide vs instrução Unload: Usar UserForm.Hide mantém o formulário na memória e retém os valores; Unload os destrói
  • Variáveis em nível de módulo como armazenamento: Declare variáveis Public em um módulo padrão para armazenar os valores dos controles antes de fechar o formulário e depois os repopule no evento Initialize

ADVERTISEMENT

Por que os controles do UserForm VBA do Word são redefinidos após fechar

Um UserForm no VBA do Word é um objeto. Quando você fecha o formulário usando a instrução Unload ou o usuário clica no botão X, o objeto do formulário é removido da memória. Isso aciona o evento UserForm_Terminate. Todos os valores das propriedades dos controles no formulário — como TextBox.Text, ComboBox.ListIndex, CheckBox.Value — são perdidos porque o objeto não existe mais.

A causa raiz é a diferença entre Hide e Unload. UserForm1.Hide torna o formulário invisível, mas o mantém carregado na memória. Todos os valores dos controles permanecem intactos. Unload UserForm1 remove o formulário da memória, e na próxima vez que você chamar UserForm1.Show, o VBA cria uma nova instância do formulário. Essa nova instância começa com valores padrão — caixas de texto vazias, itens de lista não selecionados e caixas de seleção desmarcadas.

Valores padrão dos controles

Cada controle em um UserForm tem um valor padrão definido em tempo de design. Para uma TextBox, o padrão é uma string vazia. Para uma ComboBox, o ListIndex padrão é -1 (nenhuma seleção). Para uma CheckBox, o valor padrão é False. Quando uma nova instância do UserForm é criada, todos os controles revertem para esses valores padrão de design.

O evento UserForm_Initialize

O evento Initialize é executado uma vez quando o formulário é carregado pela primeira vez na memória. Se você descarregar e reexibir o formulário, o Initialize é executado novamente. Qualquer código de configuração que você colocou lá — como preencher uma ComboBox ou definir texto padrão — será executado novamente. Mas quaisquer valores em tempo de execução que o usuário inseriu desaparecem porque a instância anterior foi destruída.

Etapas para manter os valores dos controles do UserForm ao reexibir o formulário

Você tem três métodos confiáveis para reter os valores dos controles. Escolha o que melhor se adapta à estrutura do seu projeto.

Método 1: Usar o método Hide em vez de Unload

  1. Substitua Unload por Hide no código do botão de comando
    Em vez de Unload Me ou Unload UserForm1, escreva Me.Hide ou UserForm1.Hide. Isso mantém o formulário na memória.
  2. Exiba o formulário novamente sem criar uma nova instância
    Chame UserForm1.Show novamente. Como o formulário ainda está carregado, o VBA não cria uma nova instância. Todos os valores dos controles permanecem como o usuário os deixou.
  3. Lide com o evento QueryClose para evitar Unload acidental
    Adicione este código ao módulo do UserForm para interceptar o botão X:
    Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = 0 Then
    Cancel = True
    Me.Hide
    End If
    End Sub

Método 2: Armazenar valores em variáveis em nível de módulo

  1. Declare variáveis públicas em um módulo padrão
    Em um módulo .bas novo ou existente, escreva:
    Public strUserName As String
    Public lngDepartmentIndex As Long
    Public blnNotify As Boolean
  2. Salve os valores dos controles antes de descarregar o formulário
    No evento Click do botão de comando ou no evento UserForm_Terminate, atribua os valores dos controles às suas variáveis públicas:
    strUserName = Me.txtName.Text
    lngDepartmentIndex = Me.cboDepartment.ListIndex
    blnNotify = Me.chkNotify.Value
  3. Restaure os valores no evento UserForm_Initialize
    No módulo do UserForm, adicione:
    Private Sub UserForm_Initialize()
    Me.txtName.Text = strUserName
    Me.cboDepartment.ListIndex = lngDepartmentIndex
    Me.chkNotify.Value = blnNotify
    End Sub

Método 3: Usar uma classe personalizada para encapsular o UserForm

  1. Crie um módulo de classe para armazenar a referência do formulário
    Insira um módulo de classe chamado CFormManager e adicione:
    Public WithEvents frm As UserForm1
    Private Sub Class_Initialize()
    Set frm = New UserForm1
    End Sub
  2. Exiba e oculte o formulário através da classe
    No seu código principal, use:
    Dim mgr As New CFormManager
    mgr.frm.Show
    ' depois
    mgr.frm.Hide
    mgr.frm.Show
  3. Deixe a classe persistir o objeto do formulário
    Enquanto a variável mgr estiver no escopo, o formulário permanece na memória. Os valores dos controles sobrevivem aos ciclos de Hide e Show.

ADVERTISEMENT

Armadilhas comuns e casos extremos

Valores do UserForm são redefinidos quando o documento fecha

Se o documento ou modelo do Word que contém o projeto VBA for fechado, todas as instâncias do formulário são destruídas. Na próxima vez que o documento abrir e o formulário for exibido, uma nova instância será criada com valores padrão. Para persistir valores entre sessões do documento, salve os dados dos controles em variáveis do documento, partes XML personalizadas ou uma planilha oculta no documento.

Múltiplas instâncias do mesmo UserForm

Se você criar várias instâncias do mesmo UserForm usando Dim f As New UserForm1, cada instância terá seu próprio conjunto de valores de controle. Ocultar uma instância não afeta outra. Para compartilhar valores entre instâncias, use variáveis públicas ou um módulo de dados separado.

O evento Initialize é executado muito cedo

Se você definir variáveis públicas depois que o formulário já estiver carregado, o evento Initialize não as captará. Sempre atribua as variáveis públicas antes de chamar UserForm1.Show pela primeira vez, ou use um método personalizado como UserForm1.LoadValues que você chama após exibir o formulário.

Controles do UserForm perdem valores após um erro

Um erro de tempo de execução não tratado pode fazer com que o VBA redefina a instância do formulário. Coloque seu código de exibição do formulário em um manipulador de erros:
On Error GoTo ErrHandler
UserForm1.Show
Exit Sub
ErrHandler:
Resume Next

Hide vs Unload: Comparação de comportamento para persistência de valores de controle

Item Método Hide Instrução Unload
Formulário na memória após ação Sim Não
Valores dos controles preservados ao reexibir Sim Não
UserForm_Initialize é executado ao reexibir Não Sim
UserForm_Terminate é executado na ação Não Sim
Uso de memória ao longo do tempo Maior (formulário permanece carregado) Menor (formulário é liberado)
Melhor caso de uso Fluxo de trabalho de formulário único na mesma sessão Limpeza no final da sessão com vários formulários

Agora você pode decidir se mantém o formulário oculto ou armazena os valores externamente. Para a maioria dos cenários de formulário único, o método Hide é o mais simples. Para projetos complexos com vários formulários ou persistência entre sessões, use variáveis em nível de módulo ou armazenamento XML personalizado. Teste cada abordagem com o layout específico do seu formulário antes de implantar para os usuários.

ADVERTISEMENT