Vetores

Esta página explica como utilizar vetores (arrays) no VBA.

Introdução

Antes de prosseguir, recomenda-se ler a página Variáveis e Constantes e Sintaxe do VBA.

Vetores são variáveis ou expressões que podem armazenar mais de um valor.

Para declarar um vetor, especifique entre parênteses sua dimensão máxima:

Dim Nomes(3)

Você pode especificar o tipo de dados de um vetor, como:

Dim Nomes(3) As String

Para povoar um vetor, faça atribuição de seus elementos pelo índice do vetor através de seu índice. O número que você coloca entre parênteses representa o índice do elemento acessado:

Sub FillNomes()
  Dim Nomes(3) As String
  
  Nomes(0) = "Felipe"
  Nomes(1) = "Renata"
  Nomes(2) = "Rodrigo"
  Nomes(3) = "José"
  
  'Exibe Rodrigo:
  Debug.Print Nomes(2)
End Sub

Para limpar um vetor, utilize a instrução Erase:

Erase Nomes

Para descobrir os limites de um vetor, utilize a função LBound (limite inferior, L de Lower) e UBound (limite superior, U de Upper):

Sub ShowBounds()
  Dim Nomes(3) As String
  
  'Limite inferior. Retorna 0:
  Debug.Print LBound(Nomes)
 
  'Limite superior. Retorna 3:
  Debug.Print UBound(Nomes)
End Sub

Por padrão, o VBA atribui 0 ao limite inferior de vetores declarados dessa forma. Você pode forçar que o VBE considere que o limite inferior de todos os vetores declarados seja 1 se utilizar a instrução Option Base na seção de declaração do seu módulo:

Option Base 1
 
Sub LimitesOptionBase()
  Dim Nomes(3) As String
  
  'Limite inferior. Retorna 1:
  Debug.Print LBound(Nomes)
 
  'Limite superior. Retorna 3:
  Debug.Print UBound(Nomes)
End Sub

A declaração Option Base afeta apenas o módulo em que ela se encontra, e seus valores possíveis são apenas 0 e 1. Omitir essa declaração é equivalente a Option Base 0. Particularmente, não utilizo a instrução Option Base porque infelizmente ela não afeta alguns vetores, como os que são criados a partir da função Split, por exemplo, criando confusão. Além disso, o VBA permite que se especifiquem os limites de um vetor de uma forma bem mais concisa, independente da declaração Option Base, que é a forma que recomendo:

Sub DeclaraçãoConcisaDeVetor()
  Dim Invoices(-10 To 5) As Double
  
  'Limite inferior. Retorna -10:
  Debug.Print LBound(Invoices)
 
  'Limite superior. Retorna 5:
  Debug.Print UBound(Invoices)
End Sub

Se você tentar especificar um índice que esteja fora dos limites de um vetor, obterá um erro de Subscrito fora do intervalo na linha de leitura/atribuição do elemento do vetor:

Você pode usar um laço For...Next para ler todos os valores de um vetor:

Sub ForNext()
  Dim Nomes(3) As String
  Dim i As Long
  
  Nomes(0) = "Felipe"
  Nomes(1) = "Renata"
  Nomes(2) = "Rodrigo"
  Nomes(3) = "José"
  
  For i = LBound(Nomes) To UBound(Nomes)
    Debug.Print Nomes(i)
  Next i
End Sub

Você pode também usar um laço do tipo For...Each, mas a variável de controle deverá ser, obrigatoriamente, uma Variant. Vale ressaltar que, neste caso, o laço percorre os elementos do vetor, e não seus índices:

Sub ForEach()
  Dim Nomes(3) As String
  Dim i As Variant
  
  Nomes(0) = "Felipe"
  Nomes(1) = "Renata"
  Nomes(2) = "Rodrigo"
  Nomes(3) = "José"
  
  For Each i In Nomes
    Debug.Print i
  Next i
End Sub

Vetores são úteis para criar listas. Usando a função Array, você pode criar um vetor que recebe valores de uma lista:

Sub CriarLista()
  Dim Países As Variant
  
  Países = Array("Brasil", "Uruguai", "México", "EUA")
End Sub

Observe que nesse caso o tipo de dados deve ser Variant, e você não deve especificar as dimensões do vetor. Vale ressaltar que o tipo de dados Variant pode assumir qualquer tipo de dados, inclusive um vetor ou até mesmo um vetor cujos elementos são outros vetores.

A função Array é útil para fazer laços em listas personalizadas. O exemplo a seguir preenche a célula A1 das planilhas cujos nomes se referem aos elementos da lista:

Sub Planilhas1()
  Dim iSheet As Variant
  
  For Each iSheet In Array("Leste", "Oeste", "Norte", "Sul")
    ThisWorkbook.Worksheets(iSheet).Range("A1").Value = "Teste"
  Next iSheet
End Sub

Ou então até mesmo:

Sub Planilhas2()
  Dim iSheet As Variant
  
  For Each iSheet In ThisWorkbook.Worksheets(Array("Leste", "Oeste", "Norte", "Sul"))
    iSheet.Range("A1").Value = "Teste"
  Next iSheet
End Sub

Vetores podem ter mais de uma dimensão:

Sub ExemploMatriz()
  Dim Matriz(1 To 10, 1 To 20) As Double
 
  Matriz(1, 1) = 25
  Matriz(1, 2) = 3.85
  '...
  Matriz(1, 20) = 2
  Matriz(2, 1) = 14
  Matriz(2, 2) = -854
  '...
  Matriz(10, 20) = -55.9
End Sub

Vetores podem ter até 60 dimensões, mas é raro usarmos mais de 3. Para descobrir os limites de uma dimensão específica, utilize o segundo argumento das funções LBound e Ubound:

Sub MostrarDimensões()
  Dim Cubo(-5 To 5, 0 To 10, 20 To 100) As Double
 
  'Limites da primeira dimensão:
  Debug.Print LBound(Cubo, 1) & " e " & UBound(Cubo, 1)
  
  'Limites da segunda dimensão:
  Debug.Print LBound(Cubo, 2) & " e " & UBound(Cubo, 2)
  
  'Limites da terceira dimensão:
  Debug.Print LBound(Cubo, 3) & " e " & UBound(Cubo, 3)
End Sub

Vetores Dinâmicos

Em algumas situações, você usará um vetor, mas não saberá previamente o limite de suas dimensões. Por exemplo: suponha que você queira armazenar os arquivos de extensão TXT de um diretório num vetor, sem saber previamente quantos arquivos esse diretório tem. O exemplo a seguir armazena os nomes dos arquivos do diretório c:\temp\ num vetor, e o tamanho desse vetor é alterado em tempo de execução graças à instrução ReDim:

Sub ListarArquivos()
    Dim NewDir As String
    Dim Files() As String
    Dim FileType As String
    Dim iCount As Long
    
    'Armazenar arquivos num vetor:
    FileType = "c:\temp\*.txt"
    NewDir = Dir(FileType)
    Do Until NewDir = ""
        iCount = iCount + 1
        ReDim Preserve Files(1 To iCount)
        Files(iCount) = NewDir
        NewDir = Dir
    Loop
    
    'Listar arquivos
    If iCount = 0 Then
        MsgBox "Não foi encontrado nenhum arquivo.", vbInformation
    Else
        For iCount = 1 To UBound(Files)
            Debug.Print Files(iCount)
        Next iCount
    End If
End Sub

A cada vez que a função Dir é chamada, ela retorna o nome de um arquivo até que terminem os arquivos. Então, ela retorna uma sequência de texto vazia e essa é a condição de saída do laço.

Vale ressaltar que a palavra Preserve foi utilizada nesse exemplo na função ReDim. Se Preserve fosse omitido, os valores do vetor seriam limpados quando fossem definidos os novos limites.

Por |2018-07-18T08:27:13+00:00julho 18th, 2018|VBA|0 Comentários

Sobre o Autor:

Felipe Costa Gualberto é Microsoft Most Valuable Professional (MVP) desde 2013 e é Diretor Técnico da MLF Soluções Tecnológicas e Educação Corporativa. Áreas de interesse: Power BI, Excel, VBA, Office Addins, Sql Server, .NET

Deixe um comentário