Variáveis e Constantes

Este artigo explica com detalhes o uso de variáveis e constantes no VBA.

Introdução

Leia a seção de procedimentos antes de continuar.

Variáveis são elementos nomeados e podem armazenar uma informação ou referência sobre um procedimento ou objeto. Normalmente, são empregadas para reduzir o tempo gasto no desenvolvimento de um programa, facilitar a leitura do código e/ou melhorar o desempenho na execução.

Basicamente, você primeiro dá um valor à variável e depois utiliza esse valor conforme sua necessidade. O termo técnico empregado para dar um valor a uma variável é atribuição.

Variáveis devem, obrigatoriamente, possuir um nome. As regras para dar nome a uma variável são as mesmas que se aplicam a um procedimento, que são:

  • Iniciar com uma letra;
  • Ter de 1 até um máximo de 255 caracteres;
  • Não ter espaços (no entanto, é permitido o uso de sublinhado, exemplo: Endereço_Comercial)
  • Não ter nome igual a uma das palavras chaves do VBA, como If, End, Next, String, etc.

Atribuição de Variáveis

O exemplo abaixo faz atribuição da variável Idade ao valor 20:

Sub Atribuição1()
  Idade = 20
 
  MsgBox "O valor da variável 'Idade' é " & Idade & "."
End Sub

O VBA utiliza o símbolo de igualdade para representar uma atribuição, o que pode confundir um pouco iniciantes. Nunca faça analogia de atribuições com equações matemáticas. Idealmente, uma representação adequada de atribuição no VBA seria, em minha opinião:

Tecnicamente, o VBE está avaliando a expressão à direita da igualdade e então aloca esse resultado à variável que está à esquerda da equação. Idade está recebendo o valor 20. Outro exemplo:

Idade = 8 + 12

O VBE avalia a expressão à direita e então atribui esse valor à variável Idade. Nesse caso, é semelhante em atribuir diretamente o valor 20.

Veja a linha de código abaixo:

Idade = Idade + 1

É um exemplo em que realmente não devemos interpretar atribuições como equações matemáticas. No exemplo acima, Idade passará a ter um novo valor, que será seu valor atual acrescido de um.

Você pode utilizar variáveis para fazer atribuição de outras variáveis:

Sub Atribuição2()
  SalárioBruto = 1250.57
  Impostos = 113.26
  
  SalárioLíquido = SalárioBruto - Impostos
  
  MsgBox "Salário líquido: " & SalárioLíquido
End Sub

Note que o separador decimal no VBA é vírgula, e não ponto. Isso acontece porque o VBA é baseado no sistema de unidades americano, e o separador decimal desse sistema é o ponto. Por outro lado, eles utilizam a vírgula como separador de milhares. Logo, 1.234.567,89 no Brasil escreve-se 1,234,567.89 nos Estados Unidos.

Você pode alterar o valor de variáveis várias vezes durante a execução de uma macro.

Por Que Usar Variáveis?

Considere o código abaixo, numa aplicação em Excel:

Sub Usar1()
  Range("A1").Value = Range("B2").Value
  Range("A3").Value = Range("B2").Value * 2
  Range("A4").Value = Range("B2").Value * 3
  Range("A6").Value = Range("B2").Value * 4
End Sub

Esse código atribui valores às células A1, A3, A4 e A6 para algum múltiplo do valor da célula B2, que poderia representar na prática uma taxa de juros.

A expressão Range("B2").Value aparece quatro vezes. Isso torna a leitura do código confusa para o programador, além de que escrevê-la dá trabalho, já que possui 17 caracteres.

Pode ser que não entenda esses detalhes agora, mas vale a pena expor: toda a vez que se faz referência a um objeto Range dessa forma, o VBA procura o endereço da célula B2 numa planilha, avalia o objeto e então avalia sua propriedade Value, aumentando o overhead do programa (overhead é um conjunto de instruções implícitas processadas pelo VBA que você não vê nas linhas de código do VBE). No exemplo acima, a expressão que obtém o valor da célula B2 é responsável por fazer essa maratona de processamentos acontecer quatro vezes.

Uma forma de melhorar o código é mostrada a seguir:

Sub Usar2()
  Juros = Range("B2").Value
    
  Range("A1").Value = Juros
  Range("A2").Value = Juros * 2
  Range("A3").Value = Juros * 3
  Range("B2").Value = Juros * 4
End Sub

Criamos uma variável chamada Juros e estamos atribuindo o valor Range("B2").Value a ela. Observe como a leitura do código ficou mais clara. Além disso, escrever Juros é bem mais fácil que escrever toda a expressão que retorna o valor da célula B2.

Em termos de desempenho, houve também melhoria. A expressão Range("B2").Value é avaliada apenas uma vez para passar seu valor à Juros, poupando overheads desnecessários e aumentando a velocidade de execução do programa. Claro que nesse pequeno exemplo a questão de desempenho quase não faz diferença, mas é importante se educar em relação a esses detalhes desde cedo, já que seus programas assumirão maior complexidade e tempo gasto para executar.

É importante ressaltar que nesse exemplo o valor da variável Juros não está vinculado ao valor da célula B2. Isto é, se você alterar o valor da célula B2, terá que atribuir novamente Juros a seu valor, no contrário, Juros manterá seu valor original.

Declaração de Variáveis

A declaração de uma variável tem a finalidade de avisar ao compilador a sua existência.

No VBA, a palavra chave para declarar uma variável é Dim. O código abaixo declara as variáveis FirstName, HouseNumber, MonthlyTax e BirthDate:

Sub Declaração()
  Dim FirstName
  Dim HouseNumber
  Dim MonthlyTax
  Dim BirthDate
    
  FirstName = "Felipe"
  Debug.Print FirstName
  
  HouseNumber = 12
  Debug.Print HouseNumber
 
  MonthlyTax = 1.15
  Debug.Print MonthlyTax
 
  BirthDate = "10/05/1983"
  Debug.Print BirthDate
End Sub 

Você deve declarar uma variável antes de utilizá-la. Boas práticas de programação sugerem que você faça todas as declarações de variáveis no início de um procedimento.

Não confunda a declaração de um procedimento com a declaração de variáveis. A declaração de um procedimento se encontra em sua primeira linha.

Você não pode declarar duas variáveis com o mesmo nome num procedimento. Se tentar fazer isso, obterá o erro de compilação a seguir:

Declaração de Variável Obrigatória

É possível que o VBE te obrigue a declarar as variáveis que usa num módulo procedimento. Isso é recomendado e possui vantagens. Para ilustrar uma delas, veja o simples código a seguir, que deve exibir sempre a mensagem de pontos referente ao apelido de Felipão:

Sub Obrigar()
    sApelido = "Benzadeus"
    
    Select Case sApelido
        Case "Benzadeus": PontosTabelaA = 28
        Case "Creuza": PontosTabelaA = 24
        Case "Doutor": PontosTabelaA = 7
    End Select
    MsgBox sApelido & " tem " & PotosTabelaA & " pontos!"
End Sub

Esse código compilará normalmente, mas não funcionará como esperado, mostrando a mensagem abaixo:

Se você observar bem, há um erro ortográfico na variável PontosTabela na expressão que exibe a caixa de mensagem. Esse tipo de erro é difícil e desgastante para um programador detectar. Se num código desse tamanho já é suficiente para nos fazer perder tempo, imagine quando o projeto possui centenas de linhas de código.

Option Explicit

Você pode digitar a instrução Option Explicit na Seção de Declaraçãoo módulo para obrigar a declarar todas as variáveis que utiliza nos procedimentos desse módulo.

Se você executar uma macro e o VBE notar que no procedimento a ser interpretado há uma ou mais variáveis que não foram declaradas, você obterá um erro de compilação. Ao tentar executar o código acima, será notificado que há uma variável não declarada e o VBE irá indica-la:

Agora, vamos declarar as variáveis que estamos utilizando (sApelido e PontosTabela) e tentar executar o código novamente. O VBE ainda nos notificará que existe uma variável não declarada:

É nesse momento em que o programador interpreta o erro e chega à conclusão que errou ao escrever o nome de uma das variáveis que vai usar em sua macro. Agora, basta corrigir PotosTabelaA para PontosTabelaA, executar o código normalmente e verificar o resultado esperado:

Requerer Declaração de Variável

É possível que o VBE insira automaticamente a instrução Option Explicit no início de todos os módulos que você criar. Para tal, vá no menu Ferramentas >> Opções:

Na aba Editor, habilite a caixa de seleção Requerer declaração de variável e então em OK:

Tipos de Dados

O VBA trabalha com vários tipos de dados, como números, textos e objetos. Para prosseguir o estudo de declaração de variáveis, é fundamental entender quais tipos de dados o VBA suporta e os limites de cada um. Leia a página a seguir:

Tipos de Dados

Declaração Sem Especificar o Tipo de Dados

Voltemos às declarações de variáveis já usadas nesta página:

Dim FirstName
Dim HouseNumber
Dim MonthlyTax
Dim BirthDate

FirstName, HouseNumber, MonthlyTax e BirthDate são variáveis declaradas que tem seu valor posteriormente atribuídos por tipos de dados de texto, numérico e data, respectivamente. Como o VBA não sabe qual tipo de dados cada variável irá assumir, ele atribui inicialmente um tipo de dados Variant a elas. Logo, a seção de declaração desse exemplo é equivalente às declarações mostradas abaixo:

Dim FirstName As Variant
Dim HouseNumber As Variant
Dim MonthlyTax as Variant
Dim BirthDate As Variant

As declarações acima estão qualificadas porque estamos informando ao VBA o tipo de dados de cada variável, no caso, todas Variant.

Pessoalmente, mesmo sabendo que explicitar o tipo de dados Variant é opcional, indico-o na declaração para melhor coesão na leitura das declarações.

A Atribuição Implícita do Tipo de Dados Variant

O exemplo abaixo ilustra melhor como as variáveis sofrem alterações em seu tipo de dados:

Sub Flexões()
  Dim FirstName As Variant
  Dim HouseNumber As Variant
  Dim MonthlyTax As Variant
  Dim BirthDate As Variant
    
  Debug.Print TypeName(FirstName) 'Empty
  FirstName = "Felipe"
  Debug.Print TypeName(FirstName) 'String
  
  Debug.Print TypeName(HouseNumber) 'Empty
  HouseNumber = 12
  Debug.Print TypeName(HouseNumber) 'Integer
 
  Debug.Print TypeName(MonthlyTax) 'Empty
  MonthlyTax = 1.15
  Debug.Print TypeName(MonthlyTax) 'Double
 
  Debug.Print TypeName(BirthDate) 'Empty
  BirthDate = "10/05/1983"
  Debug.Print TypeName(BirthDate) 'Date
End Sub

Veja como o tipo de dados Variant flexiona ao decorrer da macro. É interessante notar que ele define como padrão um tipo de dados Integer para números inteiros e Double para decimais. Claro, se você atribuísse um valor maior que o limite do tipo de dados Integer como 100.000, o VBA flexionaria o tipo de dados dessa variável a um Long. E se utilizasse um valor maior que Long, haveria conversão para um Double.

Como se não bastasse, uma variável Variant pode alterar seu tipo de dados várias vezes numa macro:

Sub VáriasFlexões()
  Dim var As Variant
    
  var = "Benzadeus"
  Debug.Print TypeName(var) 'String
  
  var = 125345647
  Debug.Print TypeName(var) 'Long
 
  var = 1.15
  Debug.Print TypeName(var) 'Double
 
  var = "10/05/1983"
  Debug.Print TypeName(var) 'Date
End Sub

O nome dessa capacidade do tipo de dados Variant é atribuição implícita de tipo de dados.

Declaração Especificando o Tipo de Dados

O código abaixo declara as variáveis FirstName como um tipo de dados de texto String, HouseNumber como número inteiro Long e, MonthlyTax como um número decimal Single e BirthDate como uma data Date:

Sub Qualificada()
  Dim FirstName As String
  Dim HouseNumber As Long
  Dim MonthlyTax As Single
  Dim BirthDate As Date
    
  FirstName = "Felipe"
  HouseNumber = 12
  MonthlyTax = 1.15
  BirthDate = "10/05/1983"
End Sub

Você poderia fazer a declaração no exemplo acima como mostrado a seguir também, caso quisesse:

  Dim FirstName As String, HouseNumber As Long, MonthlyTax As Single, BirthDate As Date

No entanto, pessoalmente prefiro declarar cada variável numa linha.

Quando você especifica o tipo de dados numa declaração, não pode atribuir tipos de dados diferentes dos quais seu tipo de dados aceita. Por exemplo, se você declarar uma variável como Long, mas atribuir um texto a ela, como mostrado abaixo:

Sub AtribuiçãoInválida()
  Dim MyVar As Long
    
  MyVar = "Benzadeus"
  MsgBox MyVar
End Sub

Ao executar o código a seguinte tela de erro será apresentada:

Evite, sempre que possível, declarar variáveis como Variant. Uma Variant aloca um espaço grande na memória no tempo de compilação e sua conversão implícita de tipo de dados durante a execução gera um overhead desnecessário na macro.

Se você utiliza macros que processam muitas vezes uma variável que é um número inteiro, declare como Long. Se for texto, String e números decimais, Single. Se for números decimais ou inteiros muito grandes, utilize Double. O tipo de dados Decimal é utilizado apenas em situações muito específicas.

Você pode restringir o tamanho de uma sequência de texto declarando uma variável como String, inserindo um sinal de multiplicação e o número de caracteres máximo que a variável armazenará:

Sub Limitado()
  Dim sNome As String * 15
  
  sNome = "Felipe Costa Gualberto"
  
  'Mostrará apenas os 15 primeiros caracteres, isto é Felipe Costa Gu
  Debug.Print sNome
End Sub

Nesse caso, se você fizer uma atribuição que seja maior que o espaço alocado pela variável, ela armazenará um valor truncado.

Cuidado ao Declarar mais de uma Variável numa Instrução

Fique atento porque o código a seguir:

  Dim lNumber1 As Long
  Dim lNumber2 As Long
  Dim lNumber3 As Long

É diferente de:

  Dim lNumber1, lNumber2, lNumber3 As Long

Neste último, apenas lNumber está declarado como tipo de dados Long. lNumber1 e lNumber2 estão sem o tipo de dados especificados, então assumem o tipo de dados Variant. Essa declaração é equivalente a:

  Dim lNumber1 As Variant, lNumber2 As Variant, lNumber3 As Long

Logo, numa declaração de mais de uma variável, você é obrigado a especificar o tipo de dados de cada variável declarada:

  Dim lNumber1 As Long, lNumber2 As Long, lNumber3 As Long

Padronização de Nomenclatura de Variáveis

Se você se deparar num extenso código com uma variável chamada MeuNome, sem ver sua declaração, poderá deduzir com baixas chances de errar que ela é um tipo de dados String. No entanto, se encontrar um chamado MeuValor, não saberá se é um número inteiro ou decimal; pior, não saberá nem se é um número.

Algumas práticas de programação sugerem que é interessante representar no nome da variável o tipo de dados ao qual ela se refere, na forma de sufixo. Então, a variável Nome, se é um tipo de dados String, deverá ser chamada de sNome (se o programador optou por usar três letras de prefixo) ou strNome (se o programador optou por usar o mínimo de letras de prefixo possíveis). A tabela abaixo exemplifica a como nomear variáveis com a regra de prefixos:

A seguir, a tabela para tipos de dados não numéricos:

Já utilizei essa técnica de nomenclatura extensivamente. No entanto, ultimamente tenho preferido dar nome às variáveis como DataNascimento (que obviamente é uma data), PrimeiroNome (que obviamente é um texto). Como este site é antigo, você verá várias notações diferentes, pois já mudei meus hábitos várias vezes.

Existe uma discussão interessante sobre esse assunto neste link/.

Declaração por Sufixos

Ao invés de escrever na forma literal o tipo de dados desejado, você pode declara-los por um sufixo. A tabela a seguir mostra as equivalências dos tipos de dados com seus respectivos símbolos:

As declarações a seguir são equivalentes:

Sub SufixosLiterais()
  Dim sNome As String
  Dim lIdade As Long
  Dim dPosição As Double
End Sub
 
Sub SufixosSímbolos()
  Dim sNome$
  Dim lIdade&
  Dim dPosição#
End Sub

Pessoalmente, faço uso da forma SufixosLiterais. É mais claro e não exige que decoremos símbolos desnecessariamente. Minha dica é: fuja de declarações por sufixo, elas são terríveis.

Escopo de Variáveis

Dependendo de como se declara uma variável, ela pode assumir escopo de nível de procedimento, de módulo ou global. Esse importante assunto é discutido na página a seguir:

Escopo de Variáveis

Vetores

Vetores são elementos nomeados ou expressões que podem armazenar mais de um dado. Clique no link a seguir para ler a página sobre vetores:

Vetores

Constantes

O valor de uma variável pode alterar durante a execução de um programa. No entanto, precisamos às vezes nos referir a valores que nunca alteram. Para essas entidades, damos o nome de constantes.

Usar constantes em seu programa ao invés de representar seu valor literal é uma boa ideia, já que se você precisar alterar o nome desse valor literal, fará isso somente uma vez.

Suponha que você tenha um programa que exiba centenas de caixas de mensagem distintas, e que o título de cada caixa seja o nome do seu programa. O código de uma das caixas de mensagem é mostrado abaixo:

  MsgBox "Erro durante a execução do programa", , "South Refining"

Se um dia você quiser criar um novo sistema para a empresa North Refining, terá que revisitar todo código de seu projeto e fazer as alterações de um nome por outro, com o risco de deixar algo para trás ou errar na substituição. Essa é uma ótima situação de se utilizar uma constante ao invés de expressar um valor literal.

No geral, se uma expressão literal aparece no meu código mais de uma vez, crio uma constante para usa-la em seu lugar.

Usar constantes é prático porque em sua declaração você já atribui seu valor. Assim como variáveis, a regra de escopo se aplica também em constantes: você pode trabalhar com constantes de nível de procedimento, módulo e globais.

O exemplo abaixo mostra a declaração de cada uma dessas constantes:

Public Const PI = 3.1415 'Global
Const MODULE_NAME = "AmbienteXL" 'Nível de módulo
 
Sub Main()
  Const PROGRAM_NAME = "North Refining" 'Nível de procedimento
  '...código...
End Sub

Você pode especificar o tipo de dados de uma constante, se quiser:

  Const PROGRAM_NAME As String = "North Refining"
Uma regra de nomenclatura comum a constantes é utilizar somente letras maiúsculas para elas e separar os espaços com o caractere underscore.

Se você tentar atribuir um valor a uma constante, obterá um erro de compilação:

Constantes Pré-Definidas

O VBA e os aplicativos Office disponibilizam muitas constantes pré-definidas, e você pode utiliza-las sem declarar nem precisar saber seu valor. O exemplo a seguir mostra uma caixa de mensagem com um ícone de informação:

MsgBox "Relatório gerado com sucesso!", vbInformation 

A constante vbInformation é passada ao argumento Buttons da caixa de mensagem, e quando esse argumento tem o valor de vbInformation (que na verdade é 64), MsgBox exibe o ícone de informação. A vantagem dessas constantes é que é bem mais fácil saber que vbInformation se relaciona com uma caixa de mensagem de informação, em detrimento do número solto 64.

Outra vantagem é o fato do VBE exibir, em tempo de desenvolvimento, as possíveis constantes numa janela suspensa chamada Intellisense:

Na verdade, vbInformation é o membro de uma enumeração, mais especificamente da enumeração vbMsgBoxStyle. Recomendo ler mais sobre enumerações na página a seguir:

Enumerações

 

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.