VBA - Artigo 001 - Escopo de Variável: O que é e como usar


Escopo de variável: o que é e como usar

O escopo de uma variável determina sua disponibilidade, ou seja, onde ela pode ser utilizada. É essencial conhecer este conceito para entender melhor o funcionamento dos procedimentos (sub-rotinas e funções). 

Existem três níveis de escopo:
- Nível de procedimento;
- Nível de módulo;
- Nível de projeto ou público.

Para compreender melhor o funcionamento do escopo, vamos exercitar no editor de macros. Use o seguinte código:

Sub DentroDoEscopo()

    Dim VariavelLocal As String
    VariavelLocal = "Esta variável só é visível na sub-rotina DentroDoEscopo"
    Msgbox VariavelLocal

End Sub

Sub ForaDoEscopo()

    Msgbox VariavelLocal

End Sub

Use F8 em cada uma das sub-rotinas para executar passo a passo e veja o conteúdo apresentado. A primeira sub-rotina coloca um valor na variável e exibe a mensagem, a segunda exibe uma caixa de mensagem vazia. Isto significa que somente o procedimento que declarou a variável poderá a utilizar. Para todas as outras é como se não existisse.
Agora experimente este código em um módulo:

Dim VariavelModulo As String

Sub Sub-rotina1()

    VariavelModulo = "Esta variável é visível em qualquer sub-rotina deste módulo"
    MsgBox VariavelModulo

End Sub

Sub Sub-rotina2()

    MsgBox VariavelModulo

End Sub

E acrescente um novo módulo, com este código:

Sub Sub-rotina3()

    MsgBox VariavelModulo

End Sub

Pois bem, desta vez a variável foi declarada no início do módulo, fora de qualquer procedimento. Executando a Sub-rotina1, a variável é preenchida e a mensagem de texto é exibida. Executando em seguida a Sub-rotina2, vemos que agora ela não só está acessível como ainda manteve o mesmo conteúdo. Agora experimente executar a Sub-rotina3, que está isolada em outro módulo. O resultado é uma mensagem vazia. Voltando ao primeiro módulo e executando a Sub-rotina2 vemos que a mensagem é preenchida. Ou seja, o valor que foi preenchido na Sub-rotina1 permanece visível para qualquer procedimento dentro daquele mesmo módulo, mas não é visível em outros módulos. Isto é muito útil quando se tem vários procedimentos em um mesmo módulo e é necessário preencher variáveis em um procedimento e acessar em outro. Podemos atribuir um valor à variável em uma sub-rotina de inicialização e acessar ou mesmo modificar o valor em outras sub-rotinas do mesmo módulo.

Neste exemplo declaramos a variável fora dos procedimentos com Dim. Troque o Dim por Private no código anterior e veja que o funcionamento é o mesmo. Assim sendo, prefira sempre declarar variáveis fora de procedimentos com Private ao invés de Dim, deixando mais explícita a intenção da variável mais visível para futuras manutenções no código. Dentro dos procedimentos, porém, o Dim é a única opção, não é possível declarar de outra forma.

O terceiro nível de escopo é público e provavelmente você deve ter entendido a utilidade. Vejamos o código a seguir:

Public VariavelPublica As String

Sub Sub-rotina1()

    VariavelPublica = "Esta variável é visível em qualquer sub-rotina"
    MsgBox VariavelPublica

End Sub

Sub Sub-rotina2()

    MsgBox VariavelPublica

End Sub

Em outro módulo, coloque o seguinte código:

Sub Sub-rotina3()

    MsgBox VariavelPublica

End Sub

Se executar a Sub-rotina2 ou a Sub-rotina3 antes da Sub-rotina1, veremos uma caixa de mensagens vazia, pois nenhum conteúdo foi colocado em VariavelPublica. Ao executar a Sub-rotina1, colocamos conteúdo na variável e esse conteúdo é visível em qualquer outra sub-rotina que for executada depois. Podemos alterar ou apagar o conteúdo dessa variável em qualquer sub-rotina, não só do módulo, como de todo o projeto que estiver usando, inclusive pelos eventos de planilhas e formulários.

Agora que você conhece o funcionamento de escopo de variável, deve estar com algumas ideias de como utilizar. Fica mais prático para dividir o projeto em várias sub-rotinas e assim poder reutilizar código, evitando ter de reescrever em alguns pontos. Vejamos um exemplo:

Private strCPF  As String
Private dblCPF  As Double

Sub ValorCPFQualquer()

    strCPF = "123.456.789-01"
    ConverterCPFParaNumero
    MsgBox dblCPF

End Sub

Sub ConverterCPFParaNumero()

    dblCPF = CDbl(Replace(Replace(strCPF, ".", ""), "-", ""))
                       
End Sub

Neste exemplo simples colocamos um CPF na variável strCPF do tipo string, com pontos e traço. A sub-rotina ConverterCPFParaNumero gera o conteúdo da variável dblCPF  a partir do que estiver na variável strCPF . Se houver outros pontos do código em que seja preciso efetuar essa conversão, basta processar essa sub-rotina ConverterCPFParaNumero, ao invés de colocar o código da conversão em cada ponto que for preciso. Se for preciso alterar alguma coisa no processo, basta alterar em uma única sub-rotina e não mais em vários pontos dispersos do código. Essa é a maior vantagem de usar várias sub-rotinas separadas para efetuar partes específicas de código: evita-se replicar código já escrito e facilita muito futuras manutenções.

Uma observação importante sobre escopo é sobre o conteúdo da variável. Se for declarada em nível de módulo, ela expira tão logo o módulo acabe e seu valor se perde. Já em nível de módulo ou público, o valor permanece até ser alterado por alguma sub-rotina. Dependendo da quantidade de variáveis declaradas desta forma e do computador utilizado, pode-se comprometer o desempenho da planilha. As variáveis do tipo objeto podem ser esvaziadas quando não forem mais necessárias a fim de poupar memória do computador, desta forma:

Set varObjeto = Nothing

Por fim, a dica mais importante: deixe as variáveis com um nome que deixe bem claro o propósito dela. Evite declarar variáveis com nomes curtos ou mesmo de um caractere. Assim também fica mais fácil lembrar para que serve quando for rever o código no futuro. Veja o código abaixo:

Sub TabelaDeCores()

    Dim intHorizontal   As Integer
    Dim intVertical     As Integer

    Range("A1").Select

    For intHorizontal = 1 To 4
        For intVertical = 1 To 14
            ActiveCell.Value = intVertical + (14 * (intHorizontal - 1))
            ActiveCell.Offset(0, 1).Interior.ColorIndex = intVertical + _
(14 * (intHorizontal - 1))
            ActiveCell.Offset(1, 0).Select
        Next
        Cells(1, 2 * (intHorizontal + 1) - 1).Select
    Next

End Sub


Essa rotina tem apenas duas variáveis e alimentam duas estruturas de repetição. Pelo nome dá para perceber facilmente que uma trata de movimentação na horizontal e outra na vertical. Se as variáveis fossem nomeadas simplesmente i e j, como muitos costumam fazer, não teríamos a menor noção do que elas fazem sem executar o código. Ao executá-lo, vê-se que essa sub-rotina coloca o número e a cor do respectivo colorindex, divididos em quatro colunas. Com nomes explícitos fica mais fácil entender a lógica usada. Se quiser mexer no código, pelo nome das variáveis dá para perceber qual estrutura de repetição cada uma delas trata.


Pedro Martins

Formado em Tecnologia em Eletrônica Digital, já trabalhou como artefinalista, eletrotécnico, programador de CLP (para máquinas industriais) e analista de sistemas em sistema bancário, programando em COBOL.
Mexe com computadores e programação desde a segunda metade dos anos 1980, quando teve um MSX e aprendeu a programar em BASIC. É a favor da disseminação do conhecimento.






Catálogo de aulas (NOVIDADE)

Criei um catálogo de aulas para ajudar você em seus estudos. Acesse clicando na imagem abaixo ou clique aqui.


Postagem Anterior Próxima Postagem