Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprenda Trabalhando com Tabelas do Excel | Automatizando Tabelas e Relatórios
VBA do Excel para Automação Empresarial

Trabalhando com Tabelas do Excel

Deslize para mostrar o menu

Uma Tabela do Excel — chamada de ListObject no VBA — é um intervalo nomeado e autoexpansível com setas de filtro integradas, linhas em faixas e referências estruturadas de colunas. Se seus dados ainda não forem uma Tabela, selecione qualquer célula dentro deles e pressione Ctrl+T, ou deixe o VBA criar uma usando ListObjects.Add.

Referenciando um ListObject

Dim ws As Worksheet
Dim tbl As ListObject
 
Set ws = ThisWorkbook.Worksheets("Reports")
Set tbl = ws.ListObjects("tblReports")
 
Debug.Print tbl.Range.Address        ' full table including header
Debug.Print tbl.DataBodyRange.Rows.Count   ' data rows only, no header

Declarar tbl As ListObject (em vez de apenas As Range) é o que libera todos os recursos específicos de Tabela usados no restante desta seção — ListRows, ListColumns e a Total Row vêm do objeto estar tipado corretamente. Observe a distinção entre as duas linhas de Debug.Print: tbl.Range cobre toda a Tabela, incluindo a linha de cabeçalho, enquanto tbl.DataBodyRange cobre apenas os dados abaixo dela.

Quase tudo o que você faz — adicionar uma linha, somar uma coluna, percorrer registros — deve usar DataBodyRange, justamente porque você não quer que o texto do cabeçalho seja tratado acidentalmente como uma linha de dados.

Adicionando Linhas

ListRows.Add adiciona uma nova linha diretamente abaixo da tabela — e, de forma crucial, quaisquer fórmulas de referência estruturada em outras colunas se estendem automaticamente para ela, o que é uma das maiores vantagens práticas de uma Tabela em relação a um intervalo comum.

Dim newRow As ListRow
Set newRow = tbl.ListRows.Add
 
newRow.Range(1, 1).Value = "April"
newRow.Range(1, 2).Value = "North"
newRow.Range(1, 3).Value = 45200
newRow.Range(1, 4).Value = 30750
newRow.Range(1, 5).Value = 14450
newRow.Range(1, 6).Value = 41000

tbl.ListRows.Add cria a linha em branco e a retorna como um objeto ListRow, por isso as próximas seis linhas escrevem em newRow em vez de tbl. newRow.Range(1, 1) significa "linha 1 desta nova linha específica, coluna 1" — a indexação reinicia em 1 para a nova linha, não conta a partir do topo da tabela inteira. Esse é um hábito significativamente melhor do que encontrar a última linha da planilha com End(xlUp) e escrever manualmente uma coluna além dela: ListRows.Add sempre insere corretamente dentro do limite da Tabela, então qualquer Linha de Total, fórmula de referência estruturada ou regra de formatação condicional aplicada à Tabela se estende automaticamente para incluí-la.

Atualizando Registros

Para atualizar uma linha existente, percorra o DataBodyRange e faça a correspondência em uma coluna-chave — aqui, atualizando a meta da região Central de fevereiro após uma revisão orçamentária:

Dim r As Long
For r = 1 To tbl.DataBodyRange.Rows.Count
    If tbl.DataBodyRange.Cells(r, 1).Value = "February" And _
       tbl.DataBodyRange.Cells(r, 2).Value = "Central" Then
        tbl.DataBodyRange.Cells(r, 6).Value = 52000   ' revised Target
        Exit For
    End If
Next r

Esse é o mesmo padrão de cima para baixo, parando na primeira correspondência, da lógica condicional, aplicado a linhas reais em vez de valores fixos: o loop verifica Mês e Região juntos com And, e no momento em que ambos correspondem, ele atualiza a coluna Target e chama Exit For para não continuar verificando as linhas restantes desnecessariamente. Usar tbl.DataBodyRange.Cells(r, 1) em vez de uma referência Cells no nível da planilha mantém a numeração das linhas restrita aos dados da Tabela — linha 1 aqui significa a primeira linha de dados, independentemente de em qual linha física da planilha a Tabela começa.

Referenciando Colunas da Tabela

Referências estruturadas — ListColumns("Name") — são mais legíveis e mais resilientes do que contar colunas por número, especialmente quando uma tabela é editada e as colunas mudam de posição:

Dim profitCol As Range
Set profitCol = tbl.ListColumns("Profit").DataBodyRange
 
Debug.Print Application.WorksheetFunction.Sum(profitCol)
Debug.Print Application.WorksheetFunction.Average(profitCol)

ListColumns("Profit") encontra a coluna pelo texto do cabeçalho em vez de pela posição, então o código continua funcionando mesmo que Profit depois mude da coluna E para a coluna F — contar Cells(r, 5) manualmente quebraria silenciosamente nesse cenário. Application.WorksheetFunction é a ponte que permite ao VBA chamar funções comuns do Excel como SOMA e MÉDIA diretamente em um objeto Range, em vez de você escrever um loop manual com um total acumulado, o que resulta em menos código e menos chance de erro de contagem.

Tarefa

  1. Abra o arquivo Section_4_Reports.xlsx, salve-o como Section_4_Reports.xlsm e confirme que os dados da planilha Reports estão em uma Tabela chamada tblReports (clique em qualquer célula dentro dela — a guia Design da Tabela deve aparecer).
  2. Escreva uma macro que adicione uma linha de abril para cada uma das cinco regiões usando ListRows.Add (cinco novas linhas no total, valores fictícios podem ser usados).
  3. Escreva uma segunda macro utilizando ListColumns("Sales").DataBodyRange e WorksheetFunction.Sum para imprimir o total de Sales de todas as linhas na Janela Imediata.
Dica
expand arrow

1. Abrindo e confirmando a Tabela

  • Basta salvar novamente com Arquivo → Salvar Como, escolhendo "Pasta de Trabalho Habilitada para Macro do Excel (*.xlsm)" no menu de formatos — não é necessário código para esta parte.
  • Clique em qualquer célula dentro dos dados de Reports e verifique se a faixa de opções exibe a guia Design da Tabela — isso confirma que é uma Tabela do Excel de verdade, não apenas um intervalo comum com aparência semelhante.

2. Adicionando cinco linhas de abril com ListRows.Add

  • É necessário uma variável ListObject apontando para tblReports, depois chamar .ListRows.Add uma vez para cada região — cinco chamadas separadas ou um loop que execute cinco vezes.
  • Cada nova linha precisa de seis valores preenchidos: Month, Region, Sales, Expenses, Profit, Target — referencie-os pela posição (newRow.Range(1, 1), (1, 2), etc.), da mesma forma que o exemplo prático do Capítulo 4.
  • Um array com os nomes das cinco regiões torna o loop mais limpo do que escrever cinco blocos quase idênticos manualmente.

3. Somando Sales com WorksheetFunction

  • ListColumns("Sales") localiza a coluna pelo texto do cabeçalho — .DataBodyRange restringe apenas às células de dados, sem incluir o cabeçalho.
  • Application.WorksheetFunction.Sum(...) aceita esse intervalo diretamente — não é necessário loop.
  • Debug.Print envia o resultado para a Janela Imediata (Ctrl+G) em vez de exibir um pop-up.
Solução
expand arrow
Option Explicit

Sub AddAprilRows()
    Dim tbl As ListObject
    Dim newRow As ListRow
    Dim regions As Variant
    Dim i As Long

    Set tbl = ThisWorkbook.Worksheets("Reports").ListObjects("tblReports")
    regions = Array("North", "South", "East", "West", "Central")

    For i = 0 To 4
        Set newRow = tbl.ListRows.Add
        newRow.Range(1, 1).Value = "April"
        newRow.Range(1, 2).Value = regions(i)
        newRow.Range(1, 3).Value = 46000 + i * 500   ' Sales — invented
        newRow.Range(1, 4).Value = 31000 + i * 300   ' Expenses — invented
        newRow.Range(1, 5).Value = 15000 + i * 200   ' Profit — invented
        newRow.Range(1, 6).Value = 41000              ' Target — invented
    Next i
End Sub

Sub PrintTotalSales()
    Dim tbl As ListObject
    Dim salesCol As Range

    Set tbl = ThisWorkbook.Worksheets("Reports").ListObjects("tblReports")
    Set salesCol = tbl.ListColumns("Sales").DataBodyRange

    Debug.Print "Total Sales: " & Application.WorksheetFunction.Sum(salesCol)
End Sub

Execute primeiro AddAprilRows e depois PrintTotalSales — o total já incluirá automaticamente as cinco novas linhas de abril, pois DataBodyRange sempre reflete o tamanho atual da Tabela.

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

Seção 4. Capítulo 1

Pergunte à IA

expand

Pergunte à IA

ChatGPT

Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo

Seção 4. Capítulo 1
some-alt