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.

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.