Capítulo 13: Interface Gráfica Corporativa: Construção de UserForms

🎯 Objetivo da Aula

Nesta aula, você dará um salto definitivo de qualidade visual em suas automações criando Formulários Gráficos Personalizados (UserForms) no VBA. Você aprenderá a desenhar janelas de diálogo com controles da Caixa de Ferramentas (Rótulos / Labels, Caixas de Texto / TextBoxes e Botões de Comando / CommandButtons), configurar a ordem de navegação pelo teclado (TabIndex), manipular os estados do formulário (.Show, Unload Me) e transferir os dados da janela diretamente para a base do Excel.

Ao final desta aula, você terá desenvolvido a tela gráfica oficial de triagem e pesagem da portaria da FastLog S.A.


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

Empresa: FastLog Transportes & Logística Integrada S.A.
Problema: Na guarita de entrada do Centro de Distribuição, os operadores de balança registravam os caminhões digitando diretamente nas células da planilha do Excel. Diariamente ocorriam incidentes graves: um operador com luvas de segurança esbarrava na tecla Delete e apagava o cabeçalho; outro digitava o peso da carreta na coluna errada, corrompendo a pesagem líquida. A diretoria de TI proibiu o acesso direto do operador às células da planilha.
Sua Missão: Desenvolver o formulário gráfico frmEntradaCargas, que surge centralizado na tela sobrepondo o Excel. O operador digita o manifesto, a placa e o peso nos campos gráficos; ao clicar no botão “Registrar Entrada”, o robô valida os dados, grava na primeira linha livre da planilha no plano de fundo e limpa a tela para o próximo caminhão com foco automático do cursor.


🧠 Fundamentos: A Teoria Traduzida

1. O que é um UserForm?

Um UserForm é uma janela gráfica padrão do Windows (caixa de diálogo modal) desenhada dentro do próprio VBE. Ele funciona como uma camada de proteção (Front-End), isolando o operador das planilhas (Back-End):

flowchart TD
    USER["👤 Operador da Guarita"] <--> FORM["🖥️ UserForm Gráfico (frmEntradaCargas)<br/>Campos de Texto + Botão Salvar"]
    FORM -- "Validações e Gravação Transacional" --> PLAN["📊 Planilha Excel (Base Oculta / Protegida)<br/>Nenhum toque manual direto nas células!"]

    style USER fill:#2c3e50,stroke:#fff,stroke-width:2px,color:#fff
    style FORM fill:#1a365d,stroke:#fff,stroke-width:2px,color:#fff
    style PLAN fill:#217346,stroke:#fff,stroke-width:2px,color:#fff

2. A Caixa de Ferramentas (Toolbox) e Seus Controles

ControleNome no VBAPrefixo RecomendadoFinalidade
RótuloLabellbl (ex: lblPlaca)Exibe textos informativos fixos e títulos na janela.
Caixa de TextoTextBoxtxt (ex: txtPlaca)Campo onde o operador digita texto ou números.
Botão de ComandoCommandButtoncmd ou btn (ex: cmdSalvar)Botão clicável que dispara procedimentos de código.
MolduraFramefra (ex: fraDados)Agrupa visualmente controles relacionados.

3. Ciclo de Vida do UserForm

  • UserForm.Show: Carrega e exibe o formulário na tela do computador.
  • UserForm.Hide: Oculta visualmente a janela, mantendo seus dados na memória RAM.
  • Unload Me: Fecha a janela e remove completamente o formulário da memória RAM.

📖 Exemplo Guiado: Passo a Passo no Laboratório

No Excel, abra o VBE com o atalho Alt + F11.

Passo 1: Inserção do Formulário Gráfico

  1. No menu superior do VBE, clique em Inserir ➔ UserForm.
  2. Uma janela cinza de desenho e uma paleta flutuante chamada Caixa de ferramentas (Toolbox) surgirão na tela!
  3. Na Janela de Propriedades (F4), configure as seguintes propriedades do formulário:
    • (Name): frmEntradaCargas
    • Caption: FastLog S.A. - Controle de Entrada na Balança
    • BackColor: &H00F0F0F0& (Cinza claro corporativo)
    • Width: 340
    • Height: 260

🛠️ Prática Obrigatória 1: Desenho e Configuração dos Controles

Agora você desenhará os campos de digitação na janela utilizando a Caixa de Ferramentas.

Passo a Passo no Computador:

  1. Inserção dos Rótulos (Labels):
    • Clique na ferramenta Rótulo (A) na Toolbox e desenhe 3 rótulos no formulário:
      • lbl1: Caption = "Placa do Veículo:" | Top: 20, Left: 20
      • lbl2: Caption = "Nome do Condutor:" | Top: 60, Left: 20
      • lbl3: Caption = "Peso de Entrada (Kg):" | Top: 100, Left: 20
  2. Inserção das Caixas de Texto (TextBoxes):
    • Clique na ferramenta Caixa de texto (ab|) e desenhe ao lado de cada rótulo:
      • Campo 1: (Name) = txtPlaca | Top: 18, Left: 140, Width: 150
      • Campo 2: (Name) = txtMotorista | Top: 58, Left: 140, Width: 150
      • Campo 3: (Name) = txtPeso | Top: 98, Left: 140, Width: 150
  3. Inserção dos Botões de Comando (CommandButtons):
    • Clique na ferramenta Botão de comando:
      • Botão 1: (Name) = cmdGravar | Caption = "💾 Gravar Entrada" | Top: 160, Left: 40, Width: 110, Height: 30
      • Botão 2: (Name) = cmdFechar | Caption = "❌ Sair" | Top: 160, Left: 180, Width: 110, Height: 30
  4. Configuração da Ordem do Teclado (TabIndex):
    • txtPlaca: TabIndex = 0
    • txtMotorista: TabIndex = 1
    • txtPeso: TabIndex = 2
    • cmdGravar: TabIndex = 3
    • cmdFechar: TabIndex = 4 (Ao teclar Tab, o cursor pulará suavemente de campo em campo!).

🛠️ Prática Obrigatória 2: Codificação dos Eventos e Persistência na Base

Agora programaremos os eventos de clique dos botões para gravar na base e fechar a janela.

Passo a Passo no Computador:

  1. Dê um duplo clique sobre o botão cmdFechar no formulário. O VBE abrirá a tela de código do UserForm.

  2. Digite a instrução de fechamento:

    1
    2
    3
    
    Private Sub cmdFechar_Click()
        Unload Me
    End Sub
  3. Volte ao desenho do formulário (duplo clique em frmEntradaCargas no Project Explorer) e dê um duplo clique sobre o botão cmdGravar.

  4. Digite o código de persistência transacional com validação:

     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
    
    Private Sub cmdGravar_Click()
        Dim ws As Worksheet
        Dim lngProximaLinha As Long
        Dim strPlaca As String
        Dim strMotorista As String
        Dim dblPeso As Double
    
        Set ws = ThisWorkbook.Worksheets(1)
    
        ' 1. Validação de Preenchimento Obrigatório
        If Trim(txtPlaca.Text) = "" Then
            MsgBox "Atenção: A placa do veículo é obrigatória!", vbExclamation, "Balança FastLog"
            txtPlaca.SetFocus
            Exit Sub
        End If
    
        If Trim(txtMotorista.Text) = "" Then
            MsgBox "Atenção: O nome do motorista é obrigatório!", vbExclamation, "Balança FastLog"
            txtMotorista.SetFocus
            Exit Sub
        End If
    
        If Not IsNumeric(txtPeso.Text) Or Val(txtPeso.Text) <= 0 Then
            MsgBox "Atenção: Digite um peso de balança válido maior que zero!", vbExclamation, "Balança FastLog"
            txtPeso.SetFocus
            Exit Sub
        End If
    
        ' 2. Higienização e Coleta
        strPlaca = UCase(Trim(Replace(txtPlaca.Text, "-", "")))
        strMotorista = UCase(Trim(txtMotorista.Text))
        dblPeso = CDbl(txtPeso.Text)
    
        ' 3. Localização da próxima linha livre
        lngProximaLinha = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row + 1
    
        ' 4. Gravação na Planilha
        ws.Cells(lngProximaLinha, 1).Value = lngProximaLinha - 1
        ws.Cells(lngProximaLinha, 2).Value = strPlaca
        ws.Cells(lngProximaLinha, 3).Value = strMotorista
        ws.Cells(lngProximaLinha, 4).Value = dblPeso
        ws.Cells(lngProximaLinha, 5).Value = Now
    
        ' Formatação
        ws.Cells(lngProximaLinha, 4).NumberFormat = "#,##0 'kg'"
        ws.Cells(lngProximaLinha, 5).NumberFormat = "dd/mm/yyyy hh:mm:ss"
        ws.Columns("A:E").AutoFit
    
        MsgBox "Carga registrada com sucesso na guarita!" & vbCrLf & _
               "Linha de registro: " & lngProximaLinha, vbInformation, "Triagem Concluída"
    
        ' 5. Limpa os campos para a próxima pesagem e reposiciona o foco
        txtPlaca.Text = ""
        txtMotorista.Text = ""
        txtPeso.Text = ""
        txtPlaca.SetFocus
    End Sub
  5. Criação da Macro de Abertura:

    • No menu superior, clique em Inserir ➔ Módulo.
    • Digite a macro pública de chamada:
      1
      2
      3
      
      Sub AbrirTelaBalanca()
          frmEntradaCargas.Show
      End Sub
  6. Teste Completo no Excel:

    • Alterne para o Excel. Crie os cabeçalhos na linha 1 da primeira aba:
      • A1: ID | B1: Placa | C1: Motorista | D1: Peso_Entrada | E1: Data_Hora_Balanca
    • Execute a macro AbrirTelaBalanca (Alt + F8).
    • A janela gráfica surgirá flutuando sobre o Excel!
    • Digite os dados de teste (ex: BRA-2E19, Carlos Eduardo, 24500) e clique em Gravar Entrada.
    • Veja os dados serem gravados na linha 2 da planilha e os campos ficarem limpos aguardando o próximo caminhão!

✅ Resultado Esperado (Prática 2):

A janela do UserForm opera como um software profissional independente, blindando a planilha contra cliques indevidos e garantindo agilidade ao operador.


📤 Instruções de Entrega (Microsoft Teams)

  1. Salve sua pasta de trabalho com macros (.xlsm).
  2. Nomeie o arquivo como: Atividade_13_VBA_SeuNome_SeuSobrenome.xlsm.
  3. Acesse a plataforma Microsoft Teams.
  4. Abra a tarefa: “VBA - Cap 13: Interfaces Gráficas com UserForms”.
  5. Anexe o arquivo e entregue.

💡 Checkpoint de Gestão & TI

No design de interfaces homem-máquina (UI/UX corporativo), o uso de formulários gráficos reduz drasticamente o índice de chamados ao suporte de TI. Quando o usuário digita diretamente em células da planilha, ele está exposto a apagar macros, deletar colunas ou desalinhar fórmulas. Ao encapsular o processo em um UserForm com validações no evento Click, a empresa garante governança estrita na entrada de dados.


🔥 Desafio de Fixação: Inicialização Automática e Bloqueio de Fechamento

Incremente o UserForm:

  1. No evento UserForm_Initialize, adicione o preenchimento automático da data no título da janela:
    1
    2
    3
    
    Private Sub UserForm_Initialize()
        Me.Caption = "FastLog Balança - Operação: " & Format(Date, "dd/mm/yyyy")
    End Sub
  2. Adicione formatação de borda plana moderna (SpecialEffect = fmSpecialEffectFlat) em todas as caixas de texto.

🔑 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 do Formulário (frmEntradaCargas):

 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
Option Explicit

Private Sub UserForm_Initialize()
    Me.Caption = "FastLog S.A. - Balança Operacional (" & Format(Date, "dd/mm/yyyy") & ")"
    txtPlaca.SetFocus
End Sub

Private Sub cmdFechar_Click()
    Unload Me
End Sub

Private Sub cmdGravar_Click()
    Dim ws As Worksheet
    Dim lngLinha As Long
    Dim strPlaca As String
    Dim strMotorista As String
    Dim dblPeso As Double
    
    Set ws = ThisWorkbook.Worksheets(1)
    
    ' Validações de Consistência
    If Trim(txtPlaca.Text) = "" Then
        MsgBox "A placa do veículo é obrigatória!", vbExclamation, "Validação"
        txtPlaca.SetFocus
        Exit Sub
    End If
    
    If Trim(txtMotorista.Text) = "" Then
        MsgBox "O nome do motorista é obrigatório!", vbExclamation, "Validação"
        txtMotorista.SetFocus
        Exit Sub
    End If
    
    If Not IsNumeric(txtPeso.Text) Or Val(txtPeso.Text) <= 0 Then
        MsgBox "Informe um peso válido!", vbExclamation, "Validação"
        txtPeso.SetFocus
        Exit Sub
    End If
    
    ' Higienização
    strPlaca = UCase(Trim(Replace(txtPlaca.Text, "-", "")))
    strMotorista = UCase(Trim(txtMotorista.Text))
    dblPeso = CDbl(txtPeso.Text)
    
    ' Gravação
    lngLinha = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row + 1
    ws.Cells(lngLinha, 1).Value = lngLinha - 1
    ws.Cells(lngLinha, 2).Value = strPlaca
    ws.Cells(lngLinha, 3).Value = strMotorista
    ws.Cells(lngLinha, 4).Value = dblPeso
    ws.Cells(lngLinha, 5).Value = Now
    
    ws.Cells(lngLinha, 4).NumberFormat = "#,##0 'kg'"
    ws.Cells(lngLinha, 5).NumberFormat = "dd/mm/yyyy hh:mm:ss"
    ws.Columns("A:E").AutoFit
    
    MsgBox "Registro gravado com sucesso!", vbInformation, "Triagem Homologada"
    
    ' Limpeza e Foco
    txtPlaca.Text = ""
    txtMotorista.Text = ""
    txtPeso.Text = ""
    txtPlaca.SetFocus
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. O que é um UserForm no VBA e por que ele é mais seguro do que permitir ao operador digitar diretamente nas células?
  2. Quais são os três controles visuais mais comuns da Caixa de Ferramentas (Toolbox) e qual é a utilidade de cada um?
  3. O que a propriedade TabIndex configura nos controles de um formulário gráfico?
  4. Qual é a diferença entre os comandos UserForm.Hide e Unload Me?
  5. Qual comando é utilizado no código para exibir uma janela de formulário na tela do Excel?
  6. O que o método .SetFocus faz e por que ele melhora a usabilidade para o operador de pesagem?
  7. Como a função IsNumeric() foi utilizada para impedir que o usuário digite letras no campo de peso da balança?
  8. Qual evento do UserForm é disparado automaticamente assim que a janela é carregada na memória RAM?
  9. Como associamos a exibição do UserForm a um botão retangular desenhado na planilha do Excel?
  10. O que significa a palavra-chave Me quando utilizada no código interno de um formulário?