Como criar um questionário de múltipla escolha com VBA

Veja nessa dica como realizar um questionário de múltipla escolha em um UserForm (formulário de usuário) com o VBA Excel.

Introdução

Essa dica ensina a alterar as propriedades de uma planilha dinamicamente (por código) e utilizar as informações localizadas na folha. O pré-requisito é a compreensão dos blocos com With e/ou End With. O banco de dados (perguntas/respostas) para múltipla escolha já foi preparado para você, nesse arquivo (em francês) a ser baixado gratuitamente.

Modo de design

Para começar, crie um UserForm (formulário de usuário) com uma etiqueta, um Frame (quadro) contendo um OptionButton 3 (Botão opção 3) e um CommandButton (Botão de comando). Se você não estiver familiarizado com a caixa de ferramentas, dê uma olhada nesta dica.

Não altere nenhuma das propriedades (tamanho, nome, título, etc.) desses controles.
Limite-se a colocar e alinhar os três OptionButtons, e você obterá isto:

Agora, vamos ter que alternar para o modo de código, seja clicando duas vezes na parte inferior do UserForm, seja clicando com o botão direito no Código. Duas linhas aparecerão:

Private Sub UserForm_Click()

End Sub

As propriedades pelo código

No início do UserForm, quero obter a seguinte configuração inicial: ter um texto que indique ao usuário que, para começar, ele deverá clicar no botão, não ver os botões de opção aparecerem (já que a múltipla escolha ainda não começou) e obter um botão que diz para começar o teste.

Também será preciso ajustar para cada controle as margens esquerda e superior, a largura, a altura e o texto. Durante o 'tempo de vida' do nosso UserForm, talvez tenhamos que lembrar dessa configuração inicial dos controles. Assim, vamos criar um procedimento reservado para esse caso no nosso módulo de código do UserForm. Procedimento este que poderemos usar quando quisermos.

Copie e cole esse código no módulo de código do UserForm:

Private Sub Config_Inicial_Controles()
    'Se refere ao objeto0 : UserForm1
    With UserForm1
        .Width = 350        'largura
        .Caption = "QCM"    'título
        'se refere ao objeto Label1 do UserForm1
        With .Label1
            .Caption = "Para começar, clique no botão: COMECE O TESTE”  'texto a ser exibido
            .Left = 5       'margem esquerda em relação à borda esquerda do UserForm  
            .Top = 5        'margem superior em relação à borda superior do UserForm
            .Width = UserForm1.Width - 15   'largura
            .Height = 50                    'altura
        End With
        With .Frame1
            .Visible = False     'deixa invisível o frame E seu conteúdo
            .Caption = "Possíveis respostas: "
            .Left = 5       'margem esquerda em relação à borda esquerda do UserForm
            .Top = Label1.Top + Label1.Height + 5        'margem superior em relação à borda inferior da Etiqueta  
            .Width = UserForm1.Width - 15   'largura
            .Height = 90
            With .OptionButton1
                .Caption = ""
                .Left = 5       'margem esquerda em relação à borda do Frame
                .Top = 5       'margem superior em relação à borda superior do Frame 
                .Width = Frame1.Width - 15
                .Height = 20
            End With
            With .OptionButton2
                .Caption = ""
                .Left = 5       'margem esquerda em relação à borda esquerda do Frame
                .Top = OptionButton1.Top + OptionButton1.Height + 5        'margem superior em relação à borda inferior da OptionButton1
                .Width = Frame1.Width - 15
                .Height = 20
            End With
            With .OptionButton3
                .Caption = ""
                .Left = 5       'margem esquerda em relação à borda esquerda do Frame
                .Top = OptionButton2.Top + OptionButton2.Height + 5        'margem superior   em relação à borda inferior da OptionButton2
                .Width = Frame1.Width - 15
                .Height = 20
            End With
        End With
        With .CommandButton1
            .Caption = "COMECE O TESTE"
            .Left = 5
            .Top = Frame1.Top + Frame1.Height + 5       'margem superior em relação à borda inferior do Frame
            .Width = UserForm1.Width - 15
            .Height = 30
        End With
        .Height = .CommandButton1.Top + .CommandButton1.Height + 30       'altura do UserForm de acordo com a altura dos controles 
    End With
End Sub

Até aqui, nada de especial a ser explicado. As propriedades são indicadas nos comentários. Essa imagem mostra apenas o método de posicionamento dos controles, uns em relação aos outros:

Agora, vamos ter que usar esta Sub antes da exibição do UserForm (formulário de usuário). Para isso, podemos usar, a nosso critério, seja o evento Inicialize seja o evento Activate do UserForm. Aqui, vamos escolher o Inicialize. No menu Geral, escolha UserForm e no menu Eventos, escolha Inicialize. Você obterá estas linhas adicionais de código:

Private Sub UserForm_Click()
End Sub
Private Sub UserForm_Initialize()
End Sub

Observação: já que o evento “Clique” não é mais necessário, você poderá remover as linhas relacionadas a ele.

Para chamar um procedimento depois de outro, eu costumo usar o Call (Chamada). Isso não é obrigatório, mas acho que é mais explícito. Portanto, no nosso evento Inicialize, chamemos a nossa Sub Config_Inicial_Controles:

Private Sub UserForm_Initialize()
    Call Config_Initiale_Controles
End Sub

Você pode testar (F5), alterando a propriedade visível do quadro (True/False - Verdadeiro/falso) para ver o resultado.

Da Planilha para o UserForm

De acordo com a nossa escolha inicial, a etiqueta vai ter a pergunta e os botões de opção, as respostas, respectivamente:

OptionButton1: respostas da coluna B,
OptionButton2: respostas da coluna C,
OptionButton3: respostas da coluna D.

Já que nós conhecemos as colunas, agora teremos que procurar a informação, os números de linha. Para isso, vamos criar uma variável nível de módulo (cujo tempo de vida = duração da exibição do UserForm). No topo (no cabeçalho e antes de qualquer declaração de Sub), escreva:

Dim Linha As Byte

Agora, teremos que criar um procedimento para procurar a informação na célula: Linha, Coluna de OptionButton e incluir esta informação (resposta) na Caption (subtítulo) do OptionButton em questão. Sob o seu procedimento Config_Inicial_Controles (depois do seu End Sub), copie e cole o seguinte código:

Private Sub Perguntas_Respostas()
    With Sheets("Plan1")
    'Pergunta
        'modificamos a propriedade Caption da etiqueta
        'com o conteúdo da coluna A (Perguntas)
        Label1.Caption = .Range("A" & Linha).Value
    'respostas
        'verificamos que a opção esteja desmarcada 
        OptionButton1.Value = False
        'completamos sua propriedade Caption com o conteúdo da célula em questão 
        OptionButton1.Caption = .Range("B" & Linha).Value
        'Idem para as outras 2 
        OptionButton2.Value = False
        OptionButton2.Caption = .Range("C" & Linha).Value
        OptionButton3.Value = False
        OptionButton3.Caption = .Range("D" & Linha).Value
    End With
End Sub

As explicações necessárias são dadas nos comentários do código. Para testar, teremos de lidar com o evento Click () no CommandButton. Para isso, selecione CommandButton1 no menu Geral. Por padrão, o VBA te coloca no evento Click() por estas linhas:

Private Sub CommandButton1_Click()

End Sub

Veja abaixo, o comentário do código desse evento:

Private Sub CommandButton1_Click()
    'primeiro clique, no botão, consultamos sua propriedade Caption
    'se "COMECE O TESTE" então
    If CommandButton1.Caption = "COMECE O TESTE" Then
        'modificamos a propriedade Caption do botão para os próximos cliques
        CommandButton1.Caption = "VALIDAR"
        'a primeira pergunta sendo linha 2 na planilha:
        Linha = 2
        'chamamos o procedimento de exibição da pergunta
        Call Perguntas_Respostas
        'Exibição do Frame (que estava invisível até agora)
        Frame1.Visible = True
    Else
    'caso dos cliques seguintes (a partir do segundo)
        'passamos para a linha seguinte
        Linha = Linha + 1
        'chamamos o procedimento da pergunta
        Call Perguntas_Respostas
    End If
End Sub

Agora você pode testá-lo, o seu UserForm exibe corretamente as perguntas e respostas da sua tabela Plan1 em seus controles.

Conclusão

O objetivo dessa dica não é fazer uma múltipla escolha, mas entender como carregar informações da planilha para o UserForm. No entanto, o trabalho estando quase completo, seria uma pena não finalizá-lo.

A preocupação agora será a de contar os pontos, já que podemos pular uma pergunta sem responde-la. Para fazê-lo, vamos criar uma segunda variável de nível de módulo, marcando sob Dim Linha As Byte:

Dim Pontos As Byte

Em seguida, vamos criar uma Function (Função) para reenviar 1 se a resposta for correta, caso contrário, 0. Para isso, basta verificar qual opção foi escolhida e ver se a célula relativa está amarela (6) ou:

Private Function Correção() As Byte
    'Valor padrão 
    Correção = 0
    With Sheets("Plan1")
        'se a propriedade Value da optionbutton = true significa
        'que você desmarcou esta resposta
        'então verificamos, na planilha, se a célula coluna B está amarela na linha em questão
        If OptionButton1.Value = True And .Range("B" & Linha).Interior.ColorIndex = 6 Then
            Correção = 1 'se sim, correção retorna 1
        'Idem
        ElseIf OptionButton2.Value = True And .Range("C" & Linha).Interior.ColorIndex = 6 Then
            Correção = 1
        ElseIf OptionButton3.Value = True And .Range("D" & Linha).Interior.ColorIndex = 6 Then
        'Idem
            Correção = 1
        End If
    End With
End Function

Para terminar, vamos alterar o código do botão assim:

Private Sub CommandButton1_Click()
    'primeiro clique, no botão, consultamos sua propriedade  Caption
    'se "COMECE O TESTE" Então
    If CommandButton1.Caption = "COMECE O TESTE" Then
        'modificamos a propriedade Caption do botão para os próximos cliques 
        CommandButton1.Caption = "VALIDAR"
        'a primeira pergunta sendo a linha 2 na planilha:
        Linha = 2
        Pontos = 0
        'chamamos o procedimento de exibição da pergunta
        Call Perguntas_Respostas
        'Exibição do Frame (que estava invisível até agora)
        Frame1.Visible = True
    Else
    'caso dos cliques seguintes (a partir do segundo)
        'conte os pontos
        Pontos = Pontos + Correção
        'passamos para a linha seguinte 
        Linha = Linha + 1
        'teste se última pergunta 
        If Linha = 22 Then
            'exibição do número de pontos 
            MsgBox “você obteve: " & Pontos & " sobre 20."
            'Colocar em 0 da configuração => volta ao início
            Call Config_Inicial_Controles
            'fechamos o procedimento para não acionar o Call Perguntas_Respostas
            Exit Sub
        End If
        'chamamos o procedimento de exibição da pergunta 
        Call Perguntas_Respostas
    End If
End Sub

.

Agora temos um código funcional. Só falta testar o seu formulário de usuário e seus conhecimentos.

Código completo do UserForm

Só para verificar se tudo está correto:

Option Explicit

Private Linha As Byte
Private Pontos As Byte

Private Sub CommandButton1_Click()
    'primeiro clique, no botão, consultamos a sua propriedade Caption
    'se "COMENCE O TESTE" Então
    If CommandButton1.Caption = "COMECE O TESTE" Then
        'modificamos a propriedade Caption do botão para os próximos cliques 
        CommandButton1.Caption = "VALIDAR"
        'a primeira Pergunta estando na linha 2 da planilha:
        Linha = 2
        Pontos = 0
        'chamamos o procedimento de exibição da Pergunta
        Call Perguntas_Respostas
        'Exibição do Frame (que estava invisível até agora)
        Frame1.Visible = True
    Else
    'caso dos cliques seguintes (a partir do segundo)
        'conte os pontos
        Pontos = Pontos + Correção
        Passamos para a linha seguinte
        Linha = Linha + 1
        'teste se última  Pergunta
        If Linha = 22 Then
            'Exibição do número de pontos
            MsgBox "Você obteve: " & Pontos & " sobre 20."
            'Colocar em 0 da configuração => volta ao início 
            Call Config_Inicial_Controles
            'fechamos o  procedimento para não acionar o Call Perguntas_Respostas
            Exit Sub
        End If
        'chamamos o procedimento de exibição da pergunta
        Call Perguntas_Respostas
    End If
End Sub

Private Sub UserForm_Initialize()
    Call Config_Inicial_Controles
End Sub

Private Sub Config_Inicial_Controles()
    'Refere-se ao objeto: UserForm1
    With UserForm1
        .Width = 350        'largura
        .Caption = "QME"    'título
        'refere-se ao objeto Label1 do UserForm1
        With .Label1
            .Caption = "Para começar, clique no botão : COMECE O TESTE"  'texto a ser exibido
            .Left = 5       'margem esquerda em relação à borda esquerda do UserForm
            .Top = 5        'margem superior em relação à borda superior do UserForm
            .Width = UserForm1.Width - 15   'largura
            .Height = 50                    'altura
        End With
        With .Frame1
            .Visible = False     torna 'invisível o frame E seu conteúdo 
            .Caption = "Possíveis respostas: "
            .Left = 5       'margem esquerda em relação à borda esquerda do UserForm
            .Top = Label1.Top + Label1.Height + 5        'margem superior em relação à borda inferior da etiqueta  
            .Width = UserForm1.Width - 15   'largura
            .Height = 90
            With .OptionButton1
                .Caption = "...................."
                .Left = 5       'margem esquerda em relação à  borda esquerda do Frame
                .Top = 5        'margem superior em relação à borda superior do  Frame
                .Width = Frame1.Width - 15
                .Height = 20
            End With
            With .OptionButton2
                .Caption = "...................."
                .Left = 5       'margem esquerda em relação à borda esquerda do Frame
                .Top = OptionButton1.Top + OptionButton1.Height + 5        'margem superior em relação à borda inferior  da OptionButton1
                .Width = Frame1.Width - 15
                .Height = 20
            End With
            With .OptionButton3
                .Caption = "...................."
                .Left = 5       'margem esquerda em relação à borda esquerda do Frame
                .Top = OptionButton2.Top + OptionButton2.Height + 'margem superior em relação à borda inferior  da OptionButton2
                .Width = Frame1.Width - 15
                .Height = 20
            End With
        End With
        With .CommandButton1
            .Caption = "COMECE O TESTE"
            .Left = 5
            .Top = Frame1.Top + Frame1.Height + 5       'margem superior em relação à borda inferior do  Frame
            .Width = UserForm1.Width - 15
            .Height = 30
        End With
        .Height = .CommandButton1.Top + .CommandButton1.Height + 30 'altura do UserForm em função da altura dos controles
    End With
End Sub

Private Sub Perguntas_Respostas ()
    With Sheets("Feuil1")
    'Pergunta
        'modificamos a propriedade Caption da etiqueta
        'com o conteúdo da coluna A (Perguntas)
        Label1.Caption = .Range("A" & Linha).Value
    'respostas
        'verificamos se a opção está desmarcada 
        OptionButton1.Value = False
        'completamos sua propriedade Caption com o conteúdo da célula em questão  
        OptionButton1.Caption = .Range("B" & Linha).Value
        'Idem para as outras 2 
        OptionButton2.Value = False
        OptionButton2.Caption = .Range("C" & Linha).Value
        OptionButton3.Value = False
        OptionButton3.Caption = .Range("D" & Linha).Value
    End With
End Sub
Private Function Correção() As Byte
    'Valor padrão 
    Correção = 0
    With Sheets("Plan1")
        'se a propriedade Value do optionbutton = true significa
        'que você marcou esta respostaa
        'então verificamos, na folha, se a célula da coluna B está amarela na linha em questão
        If OptionButton1.Value = True And .Range("B" & Linha).Interior.ColorIndex = 6 Then
            Correção = 1 'se sim, correção retorna 1
        'Idem
        ElseIf OptionButton2.Value = True And .Range("C" & Linha).Interior.ColorIndex = 6 Then
            Correção = 1
        ElseIf OptionButton3.Value = True And .Range("D" & Linha).Interior.ColorIndex = 6 Then
        'Idem
            Correção = 1
        End If
    End With
End Function

Para finalizar, você pode fazer o download do arquivo completo aqui (em francês).

Foto: © Kelly Sikkema - Unsplash.

Nosso conteúdo é produzido em colaboração com especialistas em tecnologia da informação sob o comando de Jean-François Pillou, fundador do CCM.net. CCM é um site sobre tecnologia líder em nível internacional e está disponível em 11 idiomas.
Este documento, intitulado 'Como criar um questionário de múltipla escolha com VBA', está disponível sob a licença Creative Commons. Você pode copiar e/ou modificar o conteúdo desta página com base nas condições estipuladas pela licença. Não se esqueça de creditar o CCM (br.ccm.net) ao utilizar este artigo.

Assine nossa newsletter!

Assine nossa newsletter!
Junte-se à comunidade