Introdução
Variáveis são elementos temporários num código que possui informação sobre uma aplicação, procedimento ou objeto.
A declaração de uma variável tem a finalidade de pré-avisar o compilador do VBA qual é o tipo de dado que será tratado.
No VBE, o comando para declarar uma variável é Dim:
Sub Ex01() Dim lng As Long lng = 5 Debug.Print lng End Sub
No exemplo acima, a variável lng é definida como um número inteiro longo. Obviamente, se tentarmos executar o código:
Sub Ex02() Dim lng As Long lng = "Benzadeus" Debug.Print lng End Sub
A seguinte tela de erro será apresentada:

Esse erro foi gerado porque como lng foi declarado como um longo, se tentarmos atribuir uma string a ele, uma incompatibilidade é detectada.
Além nos números longos, existem os decimais, os inteiros, os tipos de dados não numéricos também como string e data. Para saber mais sobre os tipos de dados do VBA, clique aqui.
Declarando-se a variável var1 conforme abaixo, os códigos abaixo não retornarão erro:
Sub Ex03() Dim var1 var1 = 8 Debug.Print var1 End Sub Sub Ex04() Dim var1 var1 = "Felipe" Debug.Print var1 End Sub
Declarar uma variável sem especificar seu tipo tem o mesmo efeito de omitir o comando Dim:
Sub Ex05() var1 = 8 Debug.Print var1 End Sub Sub Ex06() var1 = "Felipe" Debug.Print var1 End Sub
Para esses procedimentos que não foi especificado o tipo da declaração da variável ou que a declaração foi omitida, o VBA atribui automaticamente, em tempo de execução, o tipo da variável. Por exemplo, no instante que se tenta atribuir 8 à var1, o VBA convertevar1 numa variável do tipo inteiro.
Mas não pára por aí. Considere o exemplo abaixo:
Sub Ex07() Dim var1 Debug.Print TypeName(var1) var1 = 8 Debug.Print TypeName(var1) var1 = 75000 Debug.Print TypeName(var1) var1 = -8.54 Debug.Print TypeName(var1) var1 = "st" Debug.Print TypeName(var1) var1 = 4 Debug.Print TypeName(var1) End Sub
O comando TypeName(parâmetro) retorna qual é o tipo da variável (longo, inteiro, string, double). Observe que, ao executar o código acima, o VBA converterá a variável de acordo com a necessidade.
Isso é uma vantagem? Bem, sim e não. A vantagem é que você tem uma facilidade enorme para inserir e converter os tipos de variáveis em seu código, mas à medida que este vai ficando grande, as coisas podem começar a complicar:
Sub Ex08() strApelido = "Benzadeus" Select Case strApelido Case "Benzadeus": lngPontos = 28 Case "Creuza": lngPontos = 24 Case "Doutior": lngPontos = 7 End Select MsgBox _ Prompt:=strApelido & " tem " & lngPotos & " pontos!", _ Buttons:=vbInformation, _ Title:="Informação" End Sub
O simples código acima pode te deixar puto por algum tempo até você descobrir por que, ao executar o código, no MsgBox nunca aparece quantos pontos a porra do strApelido tem. Você observou que escrevi lngPotos ao invés de lngPontos? Pois é. Se num código desse tamanho já é suficiente para nos fazer perder tempo, imagina quando estamos falando de códigos de milhares de linhas. A seção a seguir explica como evitar esse tipo de equívoco.
Vale ressaltar que a omissão do tipo de dado na declaração de uma variável automaticamente a trata como uma Variant. Os códigos abaixo são semelhantes:
Sub Ex08B() Dim strMatriz End Sub 'é equivalente a: Sub Ex08C() Dim strMatriz As Variant End Sub
Regras para Declaração de Variável
Existem regras para a nomenclatura de variáveis no VBA:
-Variáveis devem começar obrigatoriamente com letras, ou seja, números não são permitidos;
-O nome de uma variável não pode ter mais que 250 caracteres;
-Uma variável não pode ter o mesmo nome de um dos objetos/classes das bibliotecas referenciadas no projeto. Por exemplo, se você estar no Word, não pode chamar uma variável de Document, pois esta já existe na biblioteca Microsoft Word 14.0 Object Library, por exemplo;
-Não pode haver espaço no nome da variável. Você pode, entretanto, usar hifens ou letras maiúsculas para organizar o nome delas, como por exemplo strPrimeiroNome ou str_Primeiro_Nome;
As boas práticas de programação sugerem que deve-se usar uma terminologia organizada para não se perder nos nomes das variáveis. O final da seçã a seguir explora um pouco mais esse assunto.
Declaração de Variável Obrigatória
No VBA, existe uma forma de restringir quais são as variáveis que podem aparecer no código. Considere o código abaixo, que nada mais é o procedimento Ex08 com o comando Option Explicit e as declarações das variáveis que devem existir no código. Observe que o comando Option Explicit deve preceder todos os procedimentos e funções de um módulo:
Option Explicit Sub Ex09() Dim strApelido As String Dim lngPontos As Long strApelido = "Benzadeus" Select Case strApelido Case "Benzadeus": lngPontos = 28 Case "Creuza": lngPontos = 24 Case "Doutior": lngPontos = 7 End Select MsgBox _ Prompt:=strApelido & " tem " & lngPotos & " pontos!", _ Buttons:=vbInformation, _ Title:="Informação" End Sub
Se tentarmos executar o código acima, o erro será gerado:
Instantaneamente, o usuário perceberá que no local onde o VBA automaticamente sublinha, cometeu um erro de digitação.
Para ativar obrigatória a declaração de variável, no VBE, vá em Ferramentas / Opções,
Cheque Requerer Declaração de variável:

Pronto, agora todos os módulos criados pela Aplicação trará, em sua primeira linha, o comando Option Explicit.
As boas práticas de programação defendem a declaração de variável obrigatória. Então, se você quiser desenvolver aplicações sérias em VBA, ative essa opção.
Declaração por Sufixos
Caso deseje definir uma variável através de um sufixo, utilize a tabela abaixo:

Ou seja, os procedimentos Ex10 e Ex11 exemplificados abaixo têm o mesmo efeito:
Sub Ex10() Dim strNome As String Dim lngIdade As Long Dim dblPosição As Double End Sub Sub Ex11() Dim strNome$ Dim lngIdade& Dim dblPosição# End Sub
Pessoalmente, faço uso da topologia do Ex10. Pra quê complicar, né?
Gostaria de chamar atenção para o nome das minhas variáveis. Observe que se for do tipo String, uso o prefixo str em seu nome para definí-la. Isso é considerada boa prática de programação.
Normalmente nomeio minhas variáveis de acordo com a tabela abaixo:

Por Que Usar Variáveis?
Considere o exemplo abaixo, código para uma aplicação em Excel:
Sub Ex12() Range("A1").Value = Range("B2").Value Range("A2").Value = Range("B2").Value * 2 Range("A3").Value = Range("B2").Value * 3 Range("B2").Value = Range("B2").Value * 4 End Sub
A expressão Range("B2").Value está repetindo várias vezes. Isso torna o código confuso para o depurador e, além disso, toda a vez que o objeto Range é chamado, o VBA invoca uma chamada à propriedade Value do objeto, diminuindo a velocidade de execução do programa. Uma forma de melhorar o código acima é dado no exemplo abaixo:
Sub Ex13() Dim lng As Long lng = Range("B2").Value Range("A1").Value = lng Range("A2").Value = lng * 2 Range("A3").Value = lng * 3 Range("B2").Value = lng * 4 End Sub
Primeiramente atribui-se um valor à lng. Posteriormente, basta fazer chamadas da variável.
Variáveis Locais e Variáveis Globais
Observe o código abaixo. Preste atenção que são colados códigos de dois módulos diferentes, chamados mdlLocaisGlobais emdlLocaisGlobais2:
'********MÓDULO MDLLOCAISGLOBAIS1******** Dim lMódulo As Long Public lGlobal As Long Sub PrincipalLocaisGlobais() Dim lProcedto As Long lProcedto = lProcedto + 1 lMódulo = lMódulo + 1 lGlobal = lGlobal + 1 Debug.Print "lProcedto: ", lProcedto Debug.Print "lMódulo: ", lMódulo Debug.Print "lGlobal: ", lGlobal End Sub Sub AuxiliarLocaisGlobais() 'A linha abaixo compila porque a variável é definida 'como Global (Public) Debug.Print "lGlobal: ", lGlobal 'A linha abaixo compila porque a variável é definida 'no nível do Módulo: Debug.Print "lMódulo: ", lMódulo 'A linhas abaixo geraria erro de compilação porque a variável 'lProcedto é no nível do Procedimento PrincipalLocaisGlobais 'Debug.Print "lProcedto: ", lProcedto End Sub '********FIM MÓDULO MDLLOCAISGLOBAIS1******** '********MÓDULO MDLLOCAISGLOBAIS2******** Sub OutroMódulo() 'A linha abaixo compila porque a variável lGlobal é definida 'como Global (Public): Debug.Print "lGlobal: ", lGlobal 'As linhas abaixo gerariam erro de compilação porque a variável 'lMódulo é definida no nível do módulo mdlLocaisGlobais1 e a 'Variável lProcedto é definida no nível do Procedimento PrincipalLocaisGlobais 'Debug.Print "lMódulo: ", lMódulo 'Debug.Print "lProcedto: ", lProcedto End Sub
'********FIM MÓDULO MDLLOCAISGLOBAIS2********
Nesse exemplo temos um total de três variáveis declaradas: são elas lProcedto, lMódulo e lGlobal.
lProcedto é o que se diz de uma variável declarada no nível do Procedimento (ou Função). Ou seja, apenas chamadas ou alterações da variável dentro do Procedimento a que ela se encontra (que é o PrinipalLocaisGlobais) são compiladas pelo VBA.
lMódulo é o que se diz de uma variável declarada no nível do Módulo. Logo, todos os procedimentos dentro do módulomdlLocaisGlobais1 podem ler ou alterar valores dessa variável. Ela está declarada no nível do módulo porque ela se encontra nas primeiras linhas do módulo, antes do cabeçalho do primeiro Procedimento, fora de qualquer Procedimento.
lGlobal é o que se diz de uma variável declarada no nível Global (ou Público). Qualquer Procedimento ou Função do projeto pode ler ou alterar seu valor. Ela está declarada no nível Global porque se encontra nas primeiras linhas do módulo, antes do cabeçalho do primeiro Procedimento, fora de qualquer Procedimento e possui, ao invés do prefixo Dim, o prefixo Public.
Observe que, ao executar a rotina PrincipalLocaisGlobais, a , a saída será:
lProcedto: 1 lMódulo: 1 lGlobal: 1
Caso seja executado o Procedimento AuxiliarLocaisGlobais, a saída será:
lGlobal: 1 lMódulo: 1
Se for executado o Procedimento OutroMódulo, presente no Módulo mdlLocaisGlobais2, a saída será:
lGlobal: 1
Com isso, torna-se claro como que os níveis de declaração das variáveis afetam as permissões de leitura e alteração que os Procedimentos tem sobre cada variável.
Valor de Algumas Variáveis é Preservado
Num primeiro momento, como mostrado acima, ao ser executada a rotina PrincipalLocaisGlobais, a saída foi:
lProcedto: 1 lMódulo: 1 lGlobal: 1
Vamos experimentar executar essa rotina novamente e ver qual será a saída:
lProcedto: 1 lMódulo: 2 lGlobal: 2
Rodando mais uma vez:
lProcedto: 1 lMódulo: 3 lGlobal: 3
Note que o valor das variáveis lMódulo e lGlobal incrementa, e o valor de lProcedto não. Isso ocorre porque variáveis declaradas no nível do módulo ou globais preservam seus valores na memória mesmo após o término da execução da rotina. Já, variáveis no nível do Procedimento são resetadas a cada vez que o Procedimento é chamado.
O programador pode ter problemas em suas rotinas caso ele deseje sempre que uma rotina inicie com todos os parâmetros limpos. Para contornar essa situação, uma das idéias é fazer como abaixo:
Sub PrincipalLocaisGlobais_Limpar() lMódulo = 0 lGlobal = 0 '...resto do código End Sub
O código acima deve estar no início da rotina do programa: as variáveis que retêm seus valores são zeradas manualmente.
Declarações Estáticas
Suponha que você queria manter o valor de uma variável toda vez que ela for executada. Podemos usar o prefixo de declaração Staticao invés de Dim. Observe o exemplo abaixo:
Sub Principal() Debug.Print "---Antes---" Estático Debug.Print "---Depois---" Estático End Sub Sub Estático() Dim lDinâmica As Long Static lEstática As Long lDinâmica = lDinâmica + 8 lEstática = lEstática + 8 Debug.Print "lEstática: " & lEstática Debug.Print "lDinâmica: " & lDinâmica End Sub
A rotina Estático é chamada duas vezes. Imprime-se a saída da rotina após ser executada pela primeira e pela segunda vez. A saída é mostrada abaixo:
---Antes--- lEstática: 8 lDinâmica: 8 ---Depois--- lEstática: 16 lDinâmica: 8
A variável lEstática é definida com a palavra Static. Isso significa que o VBA preserva na memória o valor da variável quando finda a execução da rotina.
O único problema nesse caso é que além de preservar o valor da memória ao sair da rotina, o VBA também preserva quando finda a execução de todas as rotinas. Isto é, os valores das variáveis estáticas são preservados e se você tentar executar a mesma rotina novamente, terá como resultado:
---Antes--- lEstática: 24 lDinâmica: 8 ---Depois--- lEstática: 32 lDinâmica: 8
e, se executar ainda novamente:
---Antes--- lEstática: 40 lDinâmica: 8 ---Depois--- lEstática: 48 lDinâmica: 8
...e assim por diante.
O que aconteceu é que na primeira vez que a rotina foi executada o valor da variável era igual ao seu valor na última execução da rotina. Para zerar uma variável estática no início de uma rotina, sugiro fazer algo como mostrado a seguir:
Dim blResetarEstático As Boolean Sub Principal() blResetarEstático = True Debug.Print "---Antes---" Estático Debug.Print "---Depois---" Estático End Sub Sub Estático() Dim lDinâmica As Long Static lEstática As Long If blResetarEstático = True Then lEstática = 0 blResetarEstático = False End If lDinâmica = lDinâmica + 8 lEstática = lEstática + 8 Debug.Print "lEstática: " & lEstática Debug.Print "lDinâmica: " & lDinâmica End Sub
Observe que existe uma variável no nível de Módulo chamada blResetarEstático. Ela começa como True e, quando a rotina Estático é executada pela primeira vez, zera-se o valor de lEstática e atribui-se False a blResetarEstático. Agora, lEstática será zerada novamente apenas quando a rotina Principal for executada novamente.
Fala companheiro, td bem?
ResponderExcluirBom, fiz a função que retorna uma string no
formato de um numero complexo. No entanto, em outra célula
eu coloco a formula IMABS (que calcula o módulo de um complexo)
e o excel dá um erro como se não esperasse uma string.
A questão é, como converter um tipo string no tipo complexo do excel.
string em IMABS
Public Function MANDELBROT(ByVal parte_real As Double, ByVal parte_imaginaria As Double, ByVal iteradas As Long) As String
Dim i As Long
Dim z1 As String
Dim c As String
Dim z As String
Dim p As String
c = Application.WorksheetFunction.Complex(parte_real, parte_imaginaria)
z1 = Application.WorksheetFunction.Complex(0, 0)
For i = 1 To iteradas
p = Application.WorksheetFunction.ImProduct(z1, z1)
z = Application.WorksheetFunction.ImSum(p, c)
z1 = z
Next
MANDELBROT = z
End Function
Abraços,
geniltonc@gmail.com