Sintaxe do VBA

Esta página explica a sintaxe do VBA de forma compreensiva, incluindo procedimentos, caixas de mensagem, variáveis, palavras chaves, expressões, instruções, comentários, operadores, laços e sua interação com o VBE.

Introdução

Assim como qualquer outra linguagem de programação, o VBA deve ser escrito na sintaxe correta para que os programas sejam compilados e executados. Um programa em VBA é formado por um conjunto de procedimentos. Um procedimento é composto por um conjunto de instruções, que podem conter expressões e/ou palavras chaves. Normalmente, utilizam-se operadores para avaliar expressões. Esses conceitos são tratados nesta página.

Não é possível falar da sintaxe do VBA antes de falar sobre alguns elementos básicos de programação. Se não estiver usando esta página como uma referência, siga o roteiro de estudo do site para ter introdução de alguns termos utilizados nesta página. Todos os conceitos definidos nesta seção são vistos com mais profundidade em outras páginas do site.

Para seguir adiante, você deverá criar um módulo no projeto de um documento, copiar os exemplos das seções e colar na Janela de Código do VBE do seu aplicativo.

Subprocedimentos

Subprocedimentos são blocos de código que executam instruções. Um subprocedimento inicia na linha Sub <nome_do_procedimento> e termina em End Sub. Veja um exemplo de um subprocedimento:

Sub MeuPrimeiroPrograma
  Debug.Print "Olá Mundo!"
  Debug.Print (25 + 10) / 7
End Sub

Para executar esse subprocedimento, copie o código acima, cole na Janela de Código de um módulo, posicione o cursor de inserção de texto entre a primeira e última linha do subprocedimento e pressione a tecla F5.

A instrução Debug.Print é uma forma simples de imprimir o resultado de um programa. Se quiser exibir um texto, coloque-o entre aspas duplas. Se quiser exibir um número ou o resultado de uma operação matemática, dispense as aspas. O resultado do programa é exibido na Janela de Verificação Imediata (pressione Ctrl+G para exibi-la):

Escrever somente Debug irá gerar um erro de compilação. Escreva sempre Debug.Print!
O termo imprimir um resultado não se refere à impressão numa folha de papel física apenas. Uma impressão pode ser também uma exibição na tela a um usuário.

Caixas de Mensagem

Alternativamente, você também pode imprimir resultados do seu programa numa caixa de mensagem, usando a instrução MsgBox:

Sub CaixaDeMensagem
  MsgBox "Olá Mundo!"
End Sub

A interface e título de caixas de mensagem podem ser modificadas. Sua sintaxe é MsgBox <mensagem>, <modificação>, <título>. Cada uma dessas expressões separadas por vírgulas para modificar a caixa de mensagem são chamadas de argumentos.

Você deve usar no argumento <modificação> valores especiais que no VBA chamamos de constantes pré-definidas. Alguns desses valores que você pode usar são vbInformation, vbCritical e vbExclamation.

<título> deve ser um texto, e se refere ao título da caixa de mensagem. Veja um exemplo de uma caixa de mensagem modificada:

Sub ExibirErro()
  MsgBox "Erro ao salvar informações do cliente.", vbCritical, "Cadastro de Clientes"
End Sub

Variáveis

Você pode armazenar um valor num elemento nomeado que chamamos de variável para depois utiliza-lo no VBA. O exemplo a seguir armazena numa variável chamada x o valor de uma operação matemática, e em y uma sequência de texto, depois exibe seus valores:

Sub ArmazenarUsarVariáveis()
  x = (25 - 15) * 4
  y = "Felipe Costa Gualberto."
  
  Debug.Print x
  Debug.Print y
End Sub

Caixas de Diálogo InputBox

O VBA pode solicitar ao usuário que seja entrado um valor numa caixa de diálogo e utilizar esse valor no programa. Para fazer isso, utilize a instrução InputBox:

Sub ObterMostrarNome()
  Nome = InputBox("Qual é o seu nome?")
  
  Debug.Print Nome
End Sub

Palavras Chave e Expressões

Palavras chave são palavras ou símbolos que fazem parte da linguagem de programação do VBA, como If, End, +, Sub, (, =, etc.

MsgBox, InputBox, etc. não são palavras chave do VBA, mas sim uma função de uma biblioteca que, infelizmente, também chama-se VBA.

Uma forma simples diferenciar membros da biblioteca do VBA de palavras chaves do VBA é usar o qualificador VBA. Por exemplo, VBA.MsgBox produz uma sintaxe válida, mas VBA.If, não. Dessa forma, chegamos à conclusão que MsgBox é um membro da biblioteca VBA e If é uma palavra chave do VBA.

Uma expressão é uma combinação de palavras-chave, operadores, variáveis e constantes que produz uma sequência de caracteres, número ou objeto. Uma expressão pode ser utilizada para efetuar um cálculo, manipular caracteres ou testar dados.

O VBA avalia expressões. Avaliar significa calcular e/ou processar uma expressão até reduzi-la num tipo de dados. 5 + 8 é uma expressão numérica porque ao ser avaliada, produz um número. "Felipe" & " " & "Costa" é uma expressão de sequência de texto porque ao ser avaliada, produz um texto (você entenderá essa expressão de texto logo em diante). ActiveDocument.Range.Style é uma expressão que ao ser avaliada produz um objeto do tipo Style, e assim por diante.

Teoricamente, uma expressão pode ser de qualquer tamanho, e pode-se ter uma expressão dentro de uma expressão. Assim como 5 + 8 é uma expressão numérica, os números 5 e 8, separadamente, também são expressões.

Numa terminologia mais técnica, diz-se que avaliar uma expressão retorna um tipo de dados, sendo que retorna, nesse caso, é sinônimo de resulta.

Instruções

O código VBA é interpretado através de instruções. Uma instrução pode conter palavras-chave, operadores, variáveis, constantes e expressões, desde que seja válida. Existem instruções de declaração, de atribuição e executáveis.

O exemplo abaixo mostra os três tipos de instrução, respectivamente:

Sub ExemploInstruções()
  Dim var 'Declaração
  
  var = "Olá Mundo!" 'Atribuição
  
  MsgBox var _
  , vbInformation _
  , "Tutorial Ambiente Office" 'Executável
End Sub

Embora a instrução executável que exibe a caixa de mensagem esteja quebrada fisicamente em três linhas, logicamente ainda conta somente como uma instrução.

Para quebrar uma instrução em mais de uma linha, dê um espaço onde deseja realizar a quebra e insira o símbolo _ (sublinhado). Tente dar valor estético ou lógico a quebras físicas. Veja que no exemplo que apresentei, decidi colocar cada argumento da caixa de mensagem numa linha física diferente.

Genericamente, dizemos que um bloco de código contém um conjunto de instruções.

Representar Mais de uma Instrução numa Linha

Você pode representar mais de uma instrução numa linha física se usar o sinal de : como separador de instruções:

Sub UmaLinha()
  Dim var:  var = "Felipe":  MsgBox var, vbInformation, "Tutorial Ambiente Office"
End Sub

Como pode perceber, separar instruções com o símbolo de : pode complicar a leitura humana do código.

Indentação

A indentação de um código melhora sua aparência estética baseado em recuos de margem. É uma prática que quase todos os programadores de VBA seguem. Pendente: vou colocar um link sobre indentação aqui.

Instruções de Declaração

As instruções de declaração nomeiam uma variável, constante ou procedimento e também podem especificar um tipo de dados:

  Dim var 'Declaração

O assunto desta seção é abordado com mais detalhes nas páginas a seguir:

Se estiver seguindo o roteiro de estudo do site, deixe para ler essas páginas depois de terminar esta.

Pendente: os links ainda não funcionam. Em breve estarão disponíveis.

Declaração de Procedimentos

Declaração de Variáveis e Constantes

Enumerações

Instruções de Atribuição

As instruções de atribuição atribuem um valor ou expressão a uma variável ou constante, e são feitas através do sinal de igualdade =

O exemplo a seguir atribui a variável Altura o valor da altura de uma pessoa:

Altura = 1.77

Para fazer uma atribuição a um tipo de dados de objeto (discutido com mais detalhes em outras páginas deste site), você deve obrigatoriamente utilizar a palavra chave Set. Veja um exemplo para o Word:

Set stl = ActiveDocument.Range(5, 10).Style

Instruções Executáveis

As instruções executáveis iniciam ações. Essas instruções podem executar um método ou função e podem executar laços ou desviar-se pelos blocos de código. É comum instruções executáveis conter operadores matemáticos ou condicionais.

O exemplo a seguir mostra três instruções: uma que inicia um laço do tipo For...Next, outra que imprime um resultado na Janela de Verificação Imediata e outra que desvia a execução do código para o início do laço:

Sub InstruçõesExecutáveis()
  For lng = 1 To 5
    Debug.Print "Teste " & lng
  Next lng
End Sub

Comentários

Comentários são textos que não são compilados nem executados pelo VBA.

A presença de comentários num código é opcional. Eles podem ser usados para explicar um bloco de código, prover documentação de um programa ou servir como anotações. Por padrão, expressões de texto comentadas são exibidas na Janela de Código na cor verde.

Para inserir um comentário, insira o caractere ' (aspas simples) e em seguida escreva o comentário desejado. Você pode inserir comentários no início de uma linha ou após uma instrução, como mostra o exemplo a seguir:

Sub ExemploComentários()
  'O código abaixo exibe uma caixa de texto:
  MsgBox "Olá!!"
  
  Debug.Print 33 'você pode também comentar ao final de uma linha de código válida.
End Sub

Se você possuir uma instrução que ocupe mais de uma linha física, basta adicionar o símbolo ' no início da linha em que a instrução começa para torna-la um comentário:

  'MsgBox var _
  , vbInformation _
  , "Tutorial Ambiente Office" 'Executável

Ganhe Tempo com Comentários

Você pode usar comentários para testar eficientemente seus programas. Por exemplo, suponha que você esteja testando um programa de cadastro como mostrado a seguir:

Sub ExemploPrograma()
  Nome = InputBox("Digite o nome completo do paciente:")
  Telefone = InputBox("Digite o telefone do paciente na forma (XX) XXXX-XXXX:")
  Idade = InputBox("Digite a idade do paciente:")
  
  '(...mais instruções do programa...)

Em seus testes, quando você coloca uma determinada combinação de nome, telefone e endereço de cadastro, obtém um erro. Então, após corrigir o erro, deverá executar o programa de novo para verificar se o erro está realmente corrigido.

Se você tiver que fazer vários testes desse tipo, gastará mais tempo inserindo informações caixas de diálogo que efetivamente corrigir problemas do programa. Nesse caso, sugiro comentar as instruções de entrada do programa e fazer atribuições diretas às variáveis:

Sub ExemploPrograma()
'  Nome = InputBox("Digite o nome completo do paciente:")
'  Telefone = InputBox("Digite o telefone do paciente na forma (XX) XXXX-XXXX:")
'  Idade = InputBox("Digite a idade do paciente:")
  
  Nome = "Felipe Costa Gualberto"
  Telefone = "(31) 9115-1234"
  Idade = 30
  
  '(...mais instruções do programa...)
Não se esqueça de comentar as atribuições diretas e remover os comentários das instruções corretas antes de distribuir seu programa.

Comentar ou Remover Comentários de Várias Linhas

Você não precisa adicionar o símbolo de aspas simples manualmente em várias linhas para comentar um bloco de código, nem mesmo removê-los um a um se quiser voltá-los ao normal.

O VBE oferece um comando disponível na barra de ferramentas para fazer essa operação. Para habilitá-lo, clique com o botão direito na barra de ferramentas do VBE >> controle Editar:

O grupo de controles Editar aparecerá em sua barra de ferramentas:

Para comentar várias linhas de uma vez, selecione o bloco de código desejado e clique no controle mostrado a seguir:

O resultado é mostra a seguir:

Para remover todos os comentários, basta selecionar o bloco de código desejado e clicar no controle mostrado abaixo:

Operadores Aritméticos

O VBA pode ser considerado uma calculadora muito eficiente, e consegue processar operações matemáticas em velocidades incríveis. O exemplo a seguir mostra todas as operações aritméticas que o VBA suporta:

Sub OperaçõesAritméticas()
  'Soma, subtração e parênteses:
  Debug.Print 30 - (25 - (8 + 3))
  
  'Multiplicação (*) e divisão (/):
  Debug.Print 0.5 * (12 / 2)
  'Note que separador decimal do VBA é um ponto, e não uma vírgula!
 
  'Potência:
  Debug.Print 5 ^ 3
  
  'Raiz enésima de um número. Exemplo: raiz quadrada de 25 e raiz cúbica de 8:
  Debug.Print 25 ^ (1 / 2) + 8 ^ (1 / 3)
 
  'Divisão arrendondando-se ao inteiro mais próximo:
  Debug.Print 20 \ 3
  'Note que foi utilizada a contrabarra ao invés da barra.
 
  'Mostrar resto de uma divisão:
  Debug.Print 33 Mod 10
End Sub

O VBA avalia operações matemáticas da mesma forma que a matemática nos ensina: primeiro as raízes e potências, depois as multiplicações e divisões e depois as somas e subtrações. Claro, essa ordem respeita a precedência dos parênteses. Em caso de dúvida na ordem de cálculo de operações aritméticas, coloque expressões que deseja avaliar primeiro entre parênteses.

O único operador aritmético que não é um símbolo é o Mod, mas seu comportamento e modo de usar é igual a qualquer outro operador aritmético.

O VBA suporta números hexadecimais e octadecimais. Para representa-los, basta inserir &H e &O antes de seus valores, respectivamente:

Sub HexadecimalOctadecimal()
  'Hexadecimal
  Debug.Print &H10
  
  'Octadecimal
  Debug.Print &O10
End Sub

O resultado desse programa será 16 e 8, já que 10 em hexadecimal representa 10 no sistema decimal e 10 no sistema octadecimal representa 8 no sistema decimal.

Você pode, inclusive, misturar bases decimais que o VBA avaliará todas as expressões para decimal:

Sub SomarMistura()
  'Equivalente a 10 + 8 + 16
  Debug.Print 10 + &O10 + &H10
End Sub

O VBA suporta a notação científica (base 10). Se você escrever a expressão Debug.Print 2.5E2 (equivalente a 2.5 * (10 ^ 2)) o VBE transformará o número automaticamente em 250. No entanto, se você especificar uma base maior que 14 (ou menor que -14), ele manterá a notação científica, como no caso de 3E-150. , que equivale a 3 * (10 ^ (-150)).

Operadores de Concatenação

Um operador de concatenação opera entre duas expressões e retorna uma expressão de texto que é uma sequência de texto que junta as duas expressões, na ordem que foram escritas. Sua forma é expressão1 & expressão2, e o símbolo & é chamado de operador de concatenação.

Veja alguns exemplos:

Sub Concatenação()
  'Retorna Olá mundo!
  Debug.Print "Olá mu" & "ndo!"
 
  Nome = "Felipe"
  Sobrenome = "Costa"
  'Retorna Felipe Costa.
  Debug.Print "Seu nome é " & Nome & " " & Sobrenome & "."
  
End Sub

Atente-se ao fato de que expressões literais de texto devem estar entre aspas duplas e variáveis fora das aspas duplas. Todos esses conjuntos são ligados através de operadores de concatenação. Na expressão "Seu nome é " & Nome & " " & Sobrenome & "." há 5 expressões concatenadas, a saber:

  • 1a. expressão: A expressão literal "Seu nome";
  • 2a. expressão: variável Nome;
  • 3a. expressão: A expressão literal "Seu nome";
  • 4a. expressão: A variável Sobrenome;
  • 5a. expressão: A expressão literal ".".
Não se esqueça de inserir espaços nas expressões literais ao criar as sequências de texto!

Você pode utilizar o operador de concatenação também em números, mas nesse caso, eles não vão somar, e sim concatenar. Veja o exemplo abaixo:

Sub ConcatenarNúmeros()
  'Retorna 2526
  Debug.Print 25 & 26
End Sub
O símbolo + pode ser usado também para concatenar um texto. No entanto, evite seu uso porque se o VBA avaliar as duas expressões a ser concatenadas como números, a operação que ele fará será uma soma, e não concatenação.

Operadores de Comparação

Um operador de comparação é usado para comparar expressões.

O resultado de uma operação de comparação resulta em True se a comparação for verdadeira ou False se for falsa. Existem vários tipos de operadores de comparação.

Operadores Comuns

Os operadores comuns são representados pelos símbolos <, <=, >, >=, = e <>, e sua função é comparar duas expressões na forma expressão1 <símbolo de comparação> expressão2. As expressões comparadas podem ser números ou texto.

Veja alguns exemplos a seguir:

Sub Comparações()
  Dim var As Variant
  
  'Retorna Falso
  Debug.Print 25 < 23
  
  'Retorna Falso, equivalente à expressão anterior
  Debug.Print 35 - 10 < 23
  
  var = "Felipe"
  'Retorna Verdadeiro
  Debug.Print var <> "Felipe"
End Sub

Se você misturar tipos de dados numéricos com textos, poderá obter um erro de execução:

Sub TiposDiferentes()
  Debug.Print "Benzadeus" = 1000
End Sub

No entanto, se o VBA conseguir avaliar uma expressão de texto num número, ele conseguirá fazer uma comparação:

Sub TiposDiferentes2()
  'Retorna Verdadeiro
  Debug.Print "0010" = 10
End Sub

O operador = retorna True se duas expressões de texto forem iguais e para o mesmo caso, o operador <> retorna False. Você pode usar também os operadores <, <=, > e >= para comparar texto. O VBA avalia quem é maior ou menor de acordo com a ordem alfabética das expressões:

Sub CompararTexto()
  'Retorna Verdadeiro, porque m está depois de b no alfabeto
  Debug.Print "maçã" > "banana"
End Sub

Na verdade, o VBA avalia o código do primeiro caractere para fazer a comparação. Se o primeiro caractere das expressões forem iguais, ele parte para o próximo caractere e assim por diante:

Para representar qualquer um dos caracteres acima pelo seu respectivo código, experimente digitar Alt+<código> utilizando números do seu teclado numérico.

Palavras menores tem preferência: por exemplo, "casa" < "casarão" retorna True.

Por padrão, o VBA diferencia letras maiúsculas de minúsculas ao fazer comparações:

Sub MaiúsculasEMinúsculas()
  'Retorna Falso
  Debug.Print "Banana" = "banana"
End Sub

Nesse caso, ele considera que letras maiúsculas vem antes de letras minúsculas, então a expressão "Banana" < "banana" retorna True.

Se você quiser que o VBA não diferencie maiúsculas de minúsculas, insira a instrução Option Compare Text na seção de declaração do seu módulo:

Option Compare Text
 
Sub MaiúsculasEMinúsculas()
  'Retorna Verdadeiro
  Debug.Print "Banana" = "banana"
End Sub

Por padrão, se você não especificar uma instrução de comparação de texto, o VBA considerará que a forma de comparação é binária, isto é, equivalente à declaração Option Compare Binary. A comparação é binária porque o código ASCII de uma letra maiúscula é diferente do seu equivalente maiúsculo (experimente digitar Alt+66 e Alt+98 usando números do seu teclado numérico).

Não confunda o símbolo de igualdade de atribuição com o de comparação! Infelizmente, o símbolo = pode ter uma função diferente do operador =, que é uma atribuição. Isso costuma confundir programadores iniciantes. Por exemplo, veja a expressão a seguir:

Sub Igualdade()
  Dim var As Variant
  
  var = 1 = 2
  Debug.Print var
End Sub

O sinal de igualdade da esquerda é de atribuição, e o da direita, de comparação. Uma atribuição é feita somente após toda expressão à direita da igualdade ser avaliada. A avaliação da expressão 1 = 2 resulta em False, e então a atribuição de False é feita a var, e o programa exibe False na janela de verificação imediata na próxima instrução. Um modo diferente de escrever essa instrução de uma forma mais clara seria var = (1 = 2).

Operador Is

Operadores Is se aplicam a objetos.

Enquanto os operadores da subseção anterior comparam valores de tipos de dados numéricos, o operador Is verifica se duas expressões se referem ao mesmo objeto na forma expressão1 Is expressão2 e retorna True ou False.

Um exemplo de objeto é uma planilha do Excel, que pode ser representada pela expressão Worksheets("Plan1"). O exemplo a seguir

Sub Objetos()
  Set obj1 = Worksheets("Plan1")
  Set obj2 = Worksheets("Plan1")
  
  'Retorna Verdadeiro
  Debug.Print obj1 Is Worksheets("Plan1")
  
  'Retorna Verdadeiro
  Debug.Print obj1 Is obj2
  
  'Retorna Falso
  Debug.Print obj1 Is Worksheets("Plan5")
  
End Sub

Se uma expressão não se referir a um objeto, então seu valor será igual à palavra chave Nothing. No exemplo a seguir, a variável obj é declarada como um tipo de dados de um objeto, mas como ela não se refere a nenhum objeto, a instrução Debug.Print obj Is Nothing retorna True:

Sub ExemploNothing()
  Dim obj As Object
  
  Debug.Print obj Is Nothing
End Sub

Operador Like

O operador Like compara duas sequências de caracteres na forma <texto> Like <padrão>. <texto> é a sequência de texto que você quer comparar, e <padrão> é sua referência, chamado também de padrão. Like aceita o uso dos caracteres curingas ?, * e #, além de aceitar listas de caracteres entre colchetes.

Um caractere curinga é utilizado para fazer correspondência a mais de um caractere diferente numa busca ou comparação.

Muitas vezes, ao preencher dados, as pessoas omitem algumas acentuações de palavras. Se você criar uma rotina que verifique todos os dados que possuam a palavra iluminação, poderá ter problemas se as entradas não estiverem validadas e você encontrar variações da palavra como Iluminacao, Iluminaçao e iluminacão.

Essa é uma situação em que o operador Like é útil porque ao utilizar o caractere ? nos caracteres duvidosos do padrão, ele considerará qualquer caractere:

Sub CaractereÚnico()
  'Retorna Verdadeiro
  Debug.Print "Iluminação" Like "Ilumina??o"
  
  'Retorna Verdadeiro
  Debug.Print "Iluminacão" Like "Ilumina??o"
  
  'Retorna Verdadeiro
  Debug.Print "Iluminaçao" Like "Ilumina??o"
  
  'Retorna Verdadeiro
  Debug.Print "Iluminacao" Like "Ilumina??o"
  
  'Retorna Falso
  Debug.Print "Decoração" Like "Ilumina??o"
End Sub

Como pôde perceber, o caractere curinga ? corresponde a exatamente um caractere qualquer. Fique atento porque ? deve representar obrigatoriamente um caractere, então "Felie" Like "Feli?e" retorna False porque o padrão exige que haja um caractere entre as letras i e e, nem que esse caractere seja um espaço, pontuação ou até mesmo outro e.

No entanto, como ? aceita qualquer caractere, ele irá considerar válido alguns absurdos também:

  'Retorna Verdadeiro
  Debug.Print "IluminaWHo" Like "Ilumina??o"

Para restringir os caracteres que correspondem ao padrão, coloque-os entre colchetes:

  'Retorna Verdadeiro
  Debug.Print "Iluminacao" Like "Ilumina[cç][aã]o"
  
  'Retorna Falso
  Debug.Print "IluminaXXo" Like "Ilumina[cç][aã]o"

Sobre a questão de diferenciação de letras maiúsculas de minúsculas, Like se comporta de acordo com a instrução Option Compare em seu módulo. Como por padrão é feita uma comparação binária, "iLuMiNaçãO" Like "Iluminação" retorna Falso. Para contornar essa situação, você tem duas opções:

Usar a função LCase na sequência de texto a ser comparada para transformar todos seus caracteres em minúsculos, e então escrever o padrão em letras minúsculas:

  'Retorna Verdadeiro
  Debug.Print LCase("iLuMiNaçãO") Like "iluminação"

Ou inserir a instrução Option Compare Text na seção de declaração do seu módulo:

Option Compare Text
 
Sub SeçãoDeclaração()
  'Retorna Verdadeiro
  Debug.Print "iLuMiNaçãO" Like "iluminação"
End Sub

Particularmente, prefiro utilizar a função LCase para tratar essa situação.

Poderão aparecer textos como Grupo Iluminação, Grupo de Iluminação nos seus registros. Nesse caso, utilize o caractere, utilize o caractere curinga * para tratar esses casos:

Sub Asterisco()
  'Retorna Falso
  Debug.Print "Grupo de Iluminação" Like "Iluminação"
 
  'Retorna Verdadeiro
  Debug.Print "Grupo de Iluminação" Like "*Iluminação"
 
  'Retorna Verdadeiro
  Debug.Print "Iluminação" Like "*Iluminação"
End Sub

O caractere * representa zero ou mais caracteres.

Pode ser também que você tenha textos como Grupo de Iluminação. (observe o ponto final ao fim da sequência de texto) ou então variações da palavra Iluminação com espaços extras desnecessários antes e depois da palavra. Nesse caso, represente o * antes e depois no padrão:

  'Retorna Verdadeiro
  Debug.Print "Grupo de Iluminação.  " Like "*Iluminação*"

Por fim, o padrão que eu recomendaria nesse exemplo da palavra Iluminação seria "*ilumina[cç][aã]o*", aplicando a função LCase no texto a ser comparado para transforma-la antes em letras minúsculas.

Você pode utilizar o caractere curinga # para verificar representar um número qualquer:

Sub Dígitos()
  'Retorna Verdadeiro
  Debug.Print "061.221.954-48" Like "###.###.###-##"
  
  'Retorna Falso
  Debug.Print "061.2Ab.954-48" Like "###.###.###-##"
End Sub

Se quiser permitir apenas um intervalo de caracteres, utiliza colchetes e separe o caractere inicial do final com um hífen:

Sub Faixa()
  'Retornam Verdadeiro
  Debug.Print "Setor A" Like "Setor [A-C]"
  Debug.Print "Setor B" Like "Setor [A-C]"
  Debug.Print "Setor C" Like "Setor [A-C]"
  
  'Retorna Falso
  Debug.Print "Setor D" Like "Setor [A-C]"
End Sub

Podemos chegar à conclusão que o caractere curinga # é equivalente ao padrão [0-9].

O padrão [a-cf-mv-z] corresponde caracteres de a até c, de f até m e de v até z. Se quiser corresponder apenas caracteres num texto, utilize o padrão [A-Za-z]. O padrão do exemplo abaixo verifica se alguns dos textos possuem palavras com 6 ou mais letras consecutivas:

Sub SeisLetras()
  'Retorna Falso
  Debug.Print "O rato roeu a roupa do rei de Roma." Like "*[A-Za-z][A-Za-z][A-Za-z][A-Za-z][A-Za-z][A-Za-z]*"
 
  'Retorna Verdadeiro
  Debug.Print "Felipe Costa Gualberto." Like "*[A-Za-z][A-Za-z][A-Za-z][A-Za-z][A-Za-z][A-Za-z]*"
End Sub

Não utilize [A-z] para corresponder uma letra, porque de acordo com a tabela de código de caracteres, de Z até a há vários caracteres que não são letras.

[A-Za-z] não corresponde espaços e sublinhado, por exemplo. Se quiser que sejam considerados, use [A-Za-z_ ] (note que há um espaço após o sublinhado).

Em relação à acentuações, se quiser considerar todos os caracteres de A a Z e suas variações acentuadas, use [A-Za-zÀ-ÅÈ-ÏÒ-ÖÙ-ÜÇà-åè-ïò-öù-üç]. Claro, se quiser fazer correspondência de três caracteres, por exemplo, você pode evitar escrever essa expressão três vezes e fazer algo como mostrado abaixo usando como auxílio da função Replace:

Sub LikeSubstituição()
  Letra = "[A-Za-zÀ-ÅÈ-ÏÒ-ÖÙ-ÜÇà-åè-ïò-öù-üç]"
 
  Padrão = "Iniciais: @@@#."
  'Substitui caractere @ por [A-Za-zÀ-ÅÈ-ÏÒ-ÖÙ-ÜÇà-åè-ïò-öù-üç]
  Padrão = Replace(Padrão, "@", Letra)
  
  'Retorna Verdadeiro
  Debug.Print "Iniciais: Fáb6." Like Padrão
End Sub

Se quiser corresponder os caracteres especiais [, ], ?, # ou *, basta coloca-los entre colchetes:

  'Retorna Verdadeiro
  Debug.Print "Ela disse [Como? Ela não estava lá!] que..." _
  Like "*[[]*[?]*[!][]]*"
Cuidado para não confundir-se com as correspondências [[] e []].

Like possui uma grande limitação. Não é possível usa-lo diretamente para comparações de quantidades variáveis de caracteres sem o uso do *, que generaliza muito a comparação. Por exemplo: você não pode corresponder nomes de 6 a 8 caracteres sem criar uma comparação com 6 caracteres, depois outra com 7 e depois outra com 8 e verificar se uma delas é verdadeira.

Existe uma ferramenta muito mais poderosa que o Like, conhecida como Expressões Regulares. Peça-me para disponibilizar o link que postarei aqui.

Operadores Lógicos

Operadores lógicos são usados normalmente para modificar a lógica de uma expressão e/ou adicionar mais condições em comparações. O VBA suporta os operadores lógicos And, Egv, Imp, Not, Or e Xor. Com exceção do Not, que se aplica apenas a uma expressão, todos os outros operadores lógicos comparam duas expressões.

Os operadores lógicos mais comuns são o And (E) e o Or (Ou):

Sub LógicosComuns()
  'Retorna Verdadeiro
  '2 é maior que 1 e as expressões de texto são iguais.
  Debug.Print 2 > 1 And "João" = "João"
 
  'Retorna Verdadeiro
  'Embora 10 seja maior que 20, 10 + 5 é igual a 15.
  Debug.Print 10 > 20 Or 10 + 5 = 15
End Sub

Você pode usar vários operadores lógicos numa expressão:

  Debug.Print exp1 = exp2 And exp3 = exp4 Or exp5 = exp6 And exp7 = exp8

No entanto, quando uso mais de um operador lógico numa expressão, adiciono parênteses para dar ênfase na precedência das operações para não haver qualquer ambiguidade:

  Debug.Print exp1 = exp2 And (exp3 = exp4 Or exp5 = exp6) And exp7 = exp8

Quando as expressões ficam muito grandes, quebro linhas fisicamente mantando o operador em questão na próxima linha:

  Debug.Print (ExpressãoDemasiadamenteGrande1 = ExpressãoDemasiadamenteGrande2 _
  And ExpressãoDemasiadamenteGrande3 = ExpressãoDemasiadamenteGrande4) _
  Or (ExpressãoDemasiadamenteGrande5 = ExpressãoDemasiadamenteGrande6 _
  And ExpressãoDemasiadamenteGrande7 = ExpressãoDemasiadamenteGrande8)

Use o operador Not para inverter o valor lógico de uma expressão:

Sub OperadorNot()
  'Retorna Falso
  Debug.Print Not 5 = 5
End Sub

Particularmente, gosto de adicionar parênteses para melhorar a leitura do código:

  Debug.Print Not (5 = 5)

Os outros operadores lógicos são empregados com pouca frequência. Se tiver dúvida, consulte a ajuda do VBA do seu aplicativo.

Blocos de Decisão

Um bloco de decisão é formado por uma instrução que desvia a execução de código para uma instrução ou bloco de instruções de acordo com uma condição (também chamado de teste condicional). No VBA, existem as estruturas If…Then…Else e Select Case…End Select.

If…Then…Else

A instrução If…Then…Else executa condicionalmente um grupo de instruções dependendo do valor de uma comparação.

Veja o exemplo a seguir:

Sub ValidarSenha()
  Senha = InputBox("Qual é a senha do projeto?")
  
  If Senha <> "benzadeus" Then Exit Sub
  
  '<instruções>...
End Sub
A instrução Exit Sub sai imediatamente de um procedimento.

Se a comparação Senha <> "benzadeus" for True, a instrução Exit Sub será executada. Caso contrário, o código prossegue normalmente.

Se você quiser executar mais de uma instrução, pode fazer algo como:

  If Senha <> "benzadeus" Then
    Debug.Print "Senha incorreta!"
    Exit Sub
  End If

No entanto, nesse caso, você terá que usar a instrução End If para delimitar o fim do bloco de instruções.

Obviamente, você poderia separar as instruções usando :, mas a legibilidade do código ficaria ruim:

  If Senha <> "benzadeus" Then Debug.Print "Senha incorreta!": Exit Sub

Você pode também executar um bloco de código específico se o teste condicional falhar:

  If Senha = "benzadeus" Then
    Debug.Print "Senha correta."
  Else
    Debug.Print "Senha incorreta!"
    Exit Sub
  End If
 
'<instruções>...

Numa linha só (mas não recomendado):

If Senha = "benzadeus" Then Debug.Print "Senha correta." Else Debug.Print "Senha incorreta!": Exit Sub

Você pode adicionar múltiplas condições se quiser, usando a instrução ElseIf...Then:

  If Senha = "benzadeus" Then
    Debug.Print "Senha correta."
  ElseIf Senha = "BENZADEUS" Then
    Debug.Print "Acho que você esqueceu o Caps Lock habilitado!"
    Exit Sub
  ElseIf Senha = "" Then
    Debug.Print "Você não especificou uma senha!"
    Exit Sub
  Else
    Debug.Print "Senha incorreta!"
    Exit Sub
  End If

Na prática, não costumo utilizar muito estruturas ElseIf, prefiro usar a instrução Select Case, mostrada na subseção a seguir.

Vale ressaltar que mesmo quando mais de uma comparação da estrutura de decisão for verdadeira, apenas a primeira delas será executada.

Select Case

O bloco de decisão Select Case é uma alternativa ao If...Then...Else. O bloco se inicia com a instrução Select Case <expressão> e termina com End Select. Entre essas instruções, você lista casos diferentes com suas respectivas instruções em sequência. No primeiro caso verdadeiro, uma .

Para números, ele é muito útil, como já foi mostrado no início desta página:

Sub Conceito()
  Nota = InputBox("Qual nota você tirou no semestre?")
  
  Select Case Nota
    Case Is < 50: Conceito = "F"
    Case Is < 60: Conceito = "E"
    Case Is < 70: Conceito = "D"
    Case Is < 80: Conceito = "C"
    Case Is < 90: Conceito = "B"
    Case 100: Conceito = "A"
    Case Else
      Debug.Print "Valor inválido!"
      Exit Sub
  End Select
  
  Debug.Print "Seu conceito foi " & Conceito & "."
End Sub
Esse é um típico exemplo em que utilizar o símbolo : para representar mais de uma instrução numa linha melhora a leitura do código.

Se nenhum caso for verdadeiro, sempre serão executadas as instruções do bloco Case Else, que é uma instrução opcional.

Outro exemplo: numa competição de natação, considere que há 9 nadadores disputando, cada um numa raia. Como é sabido, por alguns motivos físicos, as raias centrais são as preferidas pelos nadadores. Por consequência, quanto mais próxima da borda da piscina, pior a raia é. O exemplo a seguir diz respeito à raia escolhida por um nadador:

Sub Raia()
  Dim lRaia As Long
  Dim sMensagem As String
  
  lRaia = InputBox("Qual raia você quer escolher?")
  
  Select Case lRaia
    Case 1, 9
      sMensagem = "Péssima escolha de raias!"
    Case 2 To 4, 6 To 8
      sMensagem = "Escolha razoável de raia."
    Case 5
      sMensagem = "Você escolheu a melhor raia, parabéns!"
    Case Else
      sMensagem = "Número de raia inválido!"
  End Select
  
  MsgBox sMensagem
End Sub

Veja que você pode especificar múltiplos casos, separando-os por vírgula, e pode também varrer toda uma faixa como 6 To 8. O bloco Case Else é executado se nenhuma das condições forem satisfeitas, e esse bloco é opcional.

Veja um exemplo de Select Case com sequências de texto:

Sub Permissões()
  Select Case InputBox("Digite seu login:")
    Case "felipe.costa"
      Mensagem = "Você tem permissões de administrador"
      
    Case "joao.gualberto"
      Mensagem = "Você pode visualizar as tabelas do sistema."
      
    Case "daniel.pereira", "renata.costa"
      Mensagem = "Você está com problemas no cadastro. Contate o administrador."
      
    Case "rodrigo.jose", "maria.socorro", "jose.horacio"
      Mensagem = "Autorização padrão de acesso"
      
    Case Else
      Mensagem = "Usuário não autorizado."
  End Select
 
  Debug.Print Mensagem
End Sub
Repare que nesse exemplo não passei o valor da caixa de diálogo a uma variável para depois avaliar a variável na instrução Select Case, mas coloquei a função InputBox diretamente na instrução.

Você pode usar também a palavra chave To para considerar uma faixa de caracteres:

Sub ExemploCaractere()
 
 Caractere = InputBox("Digite um caractere:")
 'Verifica se o tamanho de Caractere é de um caractere:
 If Len(Caractere) <> 1 Then
 Debug.Print "Você não digitou um e somente um caractere!"
 Exit Sub
 End If
 
 Select Case Caractere
 Case "a" To "z", "A" To "Z"
 Mensagem = "Você digitou uma letra."
 
 Case "0" To "9"
 Mensagem = "Você digitou um número."
 
 Case ".", "!", "?", "..."
 Mensagem = "Você digitou um símbolo de pontuação."
 End Select
 
 If Mensagem <> "" Then Debug.Print Mensagem
End Sub

Nesse caso, as comparações de letras são feitas de acordo com as regras de comparação de texto.

Laços

Laço é uma instrução que repete um bloco de código um número específico de vezes. No VBA, os laços disponíveis são o For...Next, Do...Loop, While...Wend e ForEach...Next.

For…Next

O exemplo abaixo imprime na Janela de Verificação Imediata o texto Olá Mundo! 8 vezes:

Sub ForNext()
  For cont = 3 To 10
    Debug.Print "Olá mundo!"
    Debug.Print "Essa é a iteração número " & cont & "."
  Next cont
End Sub
Depure esse exemplo pressionando a tecla F8 ao invés de pressionar F5 para estudar como os desvios de execução ocorrem.

Um laço For...Next depende de uma variável de controle, que nesse exemplo é representado pela variável cont. A variável de controle inicia com o valor 3. Quando o programa chega em Next cont, incrementa-se cont em uma unidade e a execução desvia para a primeira instrução após For.

Chama-se de iteração cada passo de execução de um laço. Nesse exemplo, foram executadas (10 – 3 + 1) = 8 iterações, já que a execução do programa sai do laço quando o valor da variável de controle supera o valor final atribuído na instrução For.

A representação da variável de controle na instrução Next é opcional, isto é, você pode escrever Next ao invés de Next cont. No entanto, prefiro representar a variável de controle na instrução para melhorar a leitura do código, especialmente se eu aninhar dois laços:

Aninhamento é o nome que se dá quando usamos uma instrução dentro do bloco de instruções de outra instrução.
Sub ForNext()
  For cont1 = 1 To 3
    Debug.Print "Iniciando a iteração " & cont1 & " do laço externo."
    For cont2 = 1 To 3
      Debug.Print "Iteração interna " & cont2 & " do laço externo " & cont1 & "."
    Next cont2
  Next cont1
End Sub

O laço externo é o que inicia primeiro e termina por último, o laço interno é o que está dentro do laço externo.

Se você especificar um valor inicial para a variável de controle maior que o valor final do laço, a execução do código não executará nenhuma vez o bloco de instruções de laço, desviando o código para a instrução Next. Exemplo: For x = 100 To 50.

O incremento que a instrução Next <variável_de_controle> faz o incremento de uma unidade a cada execução. A esse incremento damos o nome de Passo. O valor padrão é de uma unidade, mas se quiser um valor diferente, inclua a palavra chave Step na instrução e em seguida o valor do passo. O exemplo a seguir mostra um For...Next com passo 10:

Sub PassoGrande()
  For cont = -50 To 50 Step 10
    Debug.Print cont
  Next cont
End Sub

O passo pode ser um decimal:

Sub PassoDecimal()
  For cont = 1 To 3 Step 0.5
    Debug.Print cont
  Next cont
End Sub

O passo também pode ser um número negativo. Esse tipo de laço é muito comum, e nesse caso, o laço finda quando o valor da variável de controle se torna menor que sua meta na instrução For:

Sub PassoNegativo()
  For cont = 6 To -9 Step -3
    Debug.Print cont
  Next cont
End Sub

Embora não seja recomendável, você pode alterar o valor da variável de controle durante o laço. Com isso, pode, inclusive, um valor de passo igual a 0:

Sub NãoRecomendado()
  For cont = 1 To 10 Step 0
    Debug.Print cont
    cont = cont + 2
  Next cont
End Sub

Use a instrução Exit For para sair de um laço imediatamente:

Sub SairImediatamente()
  'Descomente a instrução abaixo para ver o efeito do Exit For:
  'registro = "Felipe"
  
  For cont = 1 To 10
    If registro = "Felipe" Then Exit For
    Debug.Print "O registro atual não é do Felipe."
  Next cont
End Sub

Se você tiver laços aninhados, a instrução Exit For sai somente do nível em questão, subindo para o próximo nível.

Do…Loop

Do…Loop é um laço que repete um bloco de instruções enquanto uma condição seja verdadeira. Observe o exemplo a seguir:

Sub Laço1()
  i = 1
  Do While i <= 10
    Debug.Print i
    i = i + 1
  Loop
End Sub

Enquanto i for menor ou igual a 10, o laço se repetirá. Note que esse exemplo é equivalente à instrução For i = 1 to 10. Vale ressaltar que laços Do...Loop não possuem uma variável de controle que autoincrementa como no caso de For...Next. Nesse exemplo, foi utilizada a variável i como se ela fosse uma variável de controle do laço.

Pus a condição de saída do laço na instrução Do. Alternativamente, você poderia ter colocado na instrução Loop, ficando Loop While i <= 10, controlando, dessa forma, onde o teste de prosseguir no laço é realizado.

Além da palavra chave While (enquanto), você pode utilizar a palavra chave Until (até que) como um condição de saída do laço:

Sub ObterSenha()
  i = 0
  Do
    i = i + 1
    If i > 3 Then
      MsgBox "Desculpe, apenas três tentativas.", vbCritical
      Exit Sub
    End If
    Senha = InputBox("Digite a senha:")
  Loop Until Senha = "Benzadeus"
  
  MsgBox "Bem Vindo!", vbInformation
End Sub

Você não pode criar blocos Do...Loop com condições de saída tanto em Do como Loop: deve escolher em qual das extremidades colocará a condição de saída. Por outro lado, pode criar laços suprimindo condições de ambas extremidades. Quando isso é feito, normalmente se insere uma instrução de saída Exit Do para evitar laços infinitos:

Sub Laço2()
  Do
    i = i + 3
    If i >= 10 Then Exit Do
  Loop
End Sub
Cuidado com laços infinitos. Eles travam o VBA, de forma que você só conseguirá fechar o aplicativo no qual o VBA está hospedado utilizando o Gerenciador de Tarefas do Windows (Ctrl+Shift+Esc). Nesse caso, você perderá todas informações não salvas na aplicação. Essa é uma das situações em que a sequência Ctrl+Break não interrompe a execução da macro.

No caso do laço Do...Loop estar aninhado em outro laço Do...Loop, a instrução Exit Do sairá sairá apenas do nível do laço em que a instrução foi chamada.

While…Wend

A instrução While...Wend é antecessora de Do...Loop, e não recomendo utiliza-la. Ela ainda está presente no VBA apenas para garantir compatibilidade com código VBA antigo.

Em laços While...Wend, você é obrigado a especificar uma condição de saída, e essa condição só pode estar na instrução While. Além disso, não há uma instrução de saída do laço como o Exit Do do Do...Loop. Veja um exemplo a seguir:

Sub WhileWend()
  While i < 20
    i = i + 1
    Debug.Print i
  Wend
End Sub

Utilize Do...Loop ao invés de While...Wend.

For…Each

Laços For...Each percorrem uma coleção ou vetor. A variável de controle de um laço

O exemplo a seguir, para Word, povoa uma coleção e depois efetua um laço nos itens da coleção:

Sub Coleção()
  Set clc = New Collection
  
  clc.Add 8
  clc.Add ActiveDocument
  clc.Add "Felipe Costa Gualberto"
  clc.Add 0
  clc.Add 8
  
  For Each var In clc
    Debug.Print var
  Next var
End Sub

O exemplo abaixo, para PowerPoint, faz um laço em todos os slides e imprime o índice e a quantidade de autoformas cada slide possui:

Sub ColeçãoPowerPoint()
  For Each sld In ActivePresentation.Slides
    Debug.Print "Índice do slide: " & sld.SlideIndex
    Debug.Print "Quantidade de autoformas: " & sld.Shapes.Count
  Next sld
End Sub

O exemplo abaixo povoa os elementos de um vetor e depois mostra seus valores através de um laço For...Each:

Sub Vetor()
  Dim alValores(0 To 4) As Long
  
  alValores(0) = 8
  alValores(1) = 14
  alValores(2) = -5
  alValores(3) = 22
  alValores(4) = 9
  
  For Each var In alValores
    Debug.Print var
  Next var
End Sub

Quando aplicado em coleções, a variável de controle pode ser uma Variant, Object, ou um tipo de objeto específico de uma coleção (como é o caso do exemplo no PowerPoint). Para vetores, a variável de controle só pode ser do tipo Variant.

Coleções e vetores são discutidos em outras páginas deste site.

Interação do VBE com Sintaxe do Código

Você deve ter percebido que o VBE altera algumas palavras do seu código automaticamente. Por exemplo, se no exemplo abaixo você trocar uma variável Nome por nome e desviar o cursor de inserção de texto para outra instrução, o VBE irá alterar automaticamente todas variáveis Nome por nome:

Além disso, ele reconhece palavras chaves, nomes de procedimentos e membros de bibliotecas referenciadas, colorindo de azul palavras chaves e capitalizando palavras reconhecidas.

Essa verificação instantânea de sintaxe é feita quando se desvia o cursor de inserção de texto de uma instrução que foi criada, excluída ou editada.

Autoverificação de Sintaxe

O VBE detecta erros de sintaxe quando você escreve seu código. Por exemplo, Se você escrever a expressão abaixo na atribuição de lng e pressionar Enter, receberá o aviso indicado:

Alguns avisos são coerentes, mas outros não. Em alguns casos, mesmo se você clicar em Ajuda, não saberá por que há erro de sintaxe e terá que tentar reescrever o código até entender por que a sintaxe está incorreta.

Pode ser desagradável receber notificações de erro de sintaxe do VBE para cada instrução escrita. É possível remover esses avisos, no entanto, sugiro que faça isso somente quando que estiver dominando a sintaxe do VBA.

Para desabilitar essas notificações, vá na guia Ferramentas >> controle Opções >> guia Editor e desmarque Autoverificar sintaxe e clique em OK:

Mesmo com essa opção habilitada, se houver erro de sintaxe numa linha em que você escrever uma instrução com erro de sintaxe, o VBE a colorirá em vermelho (cor padrão para erros) para que você saiba que cometeu um erro de sintaxe.

Desabilite a autoverificação de sintaxe apenas se você já for um usuário experiente na sintaxe do VBA.

 

Sobre Felipe Gualberto

Microsoft Most Valuable Professional (MVP) de Excel.
Esta entrada foi publicada em Tutoriais e marcada com a tag , , , , , , , , , , , , , , , , , , , , , , , , , , , . Adicione o link permanente aos seus favoritos.
  • GABRIEL CARVALHO MONTEIRO

    Felipe muito bom os ensinamentos. Venho só atualizar algo que acho que você possa ter se equivocado. Sobre o tópico de select case, vimos o código que lê a entrada de um caractere! Por favor, corrija-me se estiver errado, mas o código correto não seria esse abaixo?

    —————————————————————————————————————-

    Sub Caractere()

    Dim Caractere As String

    Caractere = InputBox(“Digite um caractere:”)
    ‘Verifica se o tamanho de Caractere é de um caractere:
    If Len(Caractere) 1 Then
    Debug.Print “Você não digitou um e somente um caractere!”
    Else

    Select Case Caractere
    Case “a” To “z”, “A” To “Z”
    Mensagem = “Você digitou uma letra.”

    Case “0” To “9”
    Mensagem = “Você digitou um número.”

    Case “.”, “!”, “?”, “…”
    Mensagem = “Você digitou um símbolo de pontuação.”
    End Select
    End If
    If Mensagem “” Then Debug.Print Mensagem
    End Sub