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

Automatizando Gráficos

Deslize para mostrar o menu

Gráficos são formas posicionadas sobre uma planilha e, assim como tudo neste capítulo, toda propriedade que você definir manualmente no painel de Formatação possui um equivalente em VBA.

Figura 4.4

Criando um gráfico

Sub BuildProfitChart()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim chartObj As ChartObject
 
    Set ws = ThisWorkbook.Worksheets("Reports")
    Set tbl = ws.ListObjects("tblReports")
 
    Set chartObj = ws.Shapes.AddChart2(Style:=201, _
        XlChartType:=xlColumnClustered, _
        Left:=400, Top:=20, Width:=400, Height:=250).Chart.Parent
 
    With chartObj.Chart
        .SetSourceData Source:=tbl.ListColumns("Profit").Range
        .HasTitle = True
        .ChartTitle.Text = "Profit by Region"
    End With
End Sub
Análise linha por linha
expand arrow
  • AddChart2 cria a própria forma do gráfico — Style:=201 seleciona um estilo visual interno, XlChartType:=xlColumnClustered escolhe um gráfico de colunas padrão, e Left/Top/Width/Height posicionam e dimensionam o gráfico na planilha em pontos, a mesma unidade que o Excel usa internamente para posicionamento de formas;
  • AddChart2 na verdade retorna um objeto Chart, não o contêiner ChartObject ao redor dele — o .Chart.Parent no final dessa linha é o que retorna ao contêiner, que é o tipo que chartObj foi declarado; esse detalhe é fácil de esquecer e vale a pena copiar exatamente;
  • SetSourceData é o que informa à forma do gráfico, que de outra forma estaria vazia, quais dados devem ser plotados — apontar para tbl.ListColumns("Profit").Range faz com que ele plote a coluna Profit em todas as linhas visíveis da tabela;
  • HasTitle = True precisa ser definido antes de atribuir ChartTitle.Text — tentar definir o texto do título em um gráfico que ainda não tem título ativado irá falhar.

Atualizando os Dados do Gráfico

Quando a tabela base cresce, aponte o gráfico para o novo intervalo com SetSourceData em vez de excluir e reconstruir — isso preserva qualquer formatação manual já aplicada:

Dim cht As Chart
Set cht = ThisWorkbook.Worksheets("Reports").ChartObjects(1).Chart
cht.SetSourceData Source:=tbl.ListColumns("Profit").Range

ChartObjects(1) refere-se à primeira forma de gráfico na planilha por posição — adequado quando há apenas um gráfico, mas frágil no momento em que um segundo gráfico é adicionado, já que "primeiro" pode significar algo diferente depois disso. Referenciar um gráfico por um nome definido explicitamente (chartObj.Name = "ProfitChart", depois ChartObjects("ProfitChart")) é mais resiliente quando uma planilha tem mais de um gráfico.

Formatando Gráficos

With chartObj.Chart
    .ChartTitle.Font.Size = 14
    .ChartTitle.Font.Bold = True
    .SeriesCollection(1).Format.Fill.ForeColor.RGB = RGB(24, 106, 60)
    .Axes(xlValue).TickLabels.NumberFormat = "#,##0"
    .HasLegend = False
End With

SeriesCollection(1) é a primeira (e aqui, única) série de dados sendo plotada — seu Format.Fill.ForeColor.RGB é o que colore as barras, usando a mesma função RGB(...) dos exemplos de formatação do Capítulo 1. Axes(xlValue) refere-se especificamente ao eixo numérico (em oposição ao xlCategory, o eixo que lista os nomes das regiões) — aplicar NumberFormat ali controla como os números ao longo desse eixo são exibidos, exatamente como NumberFormat em uma célula da planilha. HasLegend = False remove a legenda completamente, o que é recomendável sempre que um gráfico tem apenas uma série, já que uma legenda explicando uma única cor só adiciona poluição visual sem acrescentar informação.

Tarefa

  1. Execute BuildProfitChart e confirme que um gráfico de colunas aparece mostrando o Profit para todas as quinze linhas (todos os três meses, sem filtro).
  2. Adicione três linhas para colorir as barras do gráfico de verde escuro (RGB(24,106,60)) e remover a legenda, conforme mostrado acima.
  3. Filtre tblReports apenas para janeiro e execute novamente SetSourceData em tbl.ListColumns("Profit").Range — observe se o gráfico respeita o filtro.
Dica
expand arrow

1. Executando BuildProfitChart

  • Copie o Sub exatamente como mostrado no capítulo e execute — nenhuma alteração é necessária nesta parte.
  • Você deverá ver um gráfico aparecer na planilha Reports, exibindo o Lucro para cada linha atualmente visível na tabela.

2. Colorindo as barras e removendo a legenda

  • Ambas as propriedades pertencem ao objeto do gráfico, não à planilha — chartObj.Chart é o ponto de entrada, assim como no exemplo de formatação do capítulo.
  • A cor da barra está em SeriesCollection(1), já que há apenas uma série de dados sendo exibida (Profit) — .Format.Fill.ForeColor.RGB é a propriedade específica a ser definida.
  • Remover a legenda é uma propriedade booleana única (HasLegend), separada da linha de cor de preenchimento.

3. Filtrando e executando novamente SetSourceData

  • Aplique um AutoFilter em Month (Field:=1) restrito a "January" — a mesma técnica da seção 4.2.
  • Em seguida, chame SetSourceData novamente com a mesma expressão tbl.ListColumns("Profit").Range do BuildProfitChart — nada nessa linha precisa ser alterado.
  • Observe atentamente o que acontece com o gráfico depois: ele reduz para mostrar apenas as cinco regiões de January ou ainda exibe todas as quinze linhas, incluindo as que o AutoFilter acabou de ocultar? Essa observação é o verdadeiro objetivo desta tarefa, não apenas executar o código.
Solução
expand arrow
Option Explicit

' Point 1 — run this exactly as shown in the chapter
Sub BuildProfitChart()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim chartObj As ChartObject

    Set ws = ThisWorkbook.Worksheets("Reports")
    Set tbl = ws.ListObjects("tblReports")

    Set chartObj = ws.Shapes.AddChart2(Style:=201, _
        XlChartType:=xlColumnClustered, _
        Left:=400, Top:=20, Width:=400, Height:=250).Chart.Parent

    With chartObj.Chart
        .SetSourceData Source:=tbl.ListColumns("Profit").Range
        .HasTitle = True
        .ChartTitle.Text = "Profit by Region"
    End With
End Sub

' Point 2 — color the bars and remove the legend
Sub FormatProfitChart()
    Dim ws As Worksheet
    Dim chartObj As ChartObject

    Set ws = ThisWorkbook.Worksheets("Reports")
    Set chartObj = ws.ChartObjects(1)

    With chartObj.Chart
        .SeriesCollection(1).Format.Fill.ForeColor.RGB = RGB(24, 106, 60)
        .HasLegend = False
    End With
End Sub

' Point 3 — filter to January, then re-point the chart at the same range
Sub FilterJanuaryAndRefreshChart()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim chartObj As ChartObject

    Set ws = ThisWorkbook.Worksheets("Reports")
    Set tbl = ws.ListObjects("tblReports")
    Set chartObj = ws.ChartObjects(1)

    tbl.Range.AutoFilter Field:=1, Criteria1:="January"

    chartObj.Chart.SetSourceData Source:=tbl.ListColumns("Profit").Range
End Sub

Execute nesta ordem: BuildProfitChart, depois FormatProfitChart, depois FilterJanuaryAndRefreshChart. Para o ponto 3 especificamente — preste atenção ao que realmente acontece. Os gráficos do Excel geralmente respeitam um AutoFilter ativo, ocultando automaticamente as barras das linhas filtradas, mesmo sem executar novamente o SetSourceData. Executá-lo novamente aqui serve principalmente para confirmar que o gráfico ainda está apontando corretamente para a coluna completa — é o próprio filtro que faz a ocultação visual, não a chamada do SetSourceData. Vale a pena testar com o filtro ativado e desativado para ver a diferença.

Note
Nota

Executar BuildProfitChart mais de uma vez cria um novo gráfico a cada vez sem excluir o anterior — assim, vários gráficos acabam empilhados uns sobre os outros. ChartObjects(1) sempre se refere ao primeiro criado, que pode agora estar escondido sob uma cópia mais recente. Por isso, alterações de formatação podem ser executadas com sucesso, mas parecer não ter efeito visível.

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

Seção 4. Capítulo 4

Pergunte à IA

expand

Pergunte à IA

ChatGPT

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

Automatizando Gráficos

Gráficos são formas posicionadas sobre uma planilha e, assim como tudo neste capítulo, toda propriedade que você definir manualmente no painel de Formatação possui um equivalente em VBA.

Figura 4.4

Criando um gráfico

Sub BuildProfitChart()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim chartObj As ChartObject
 
    Set ws = ThisWorkbook.Worksheets("Reports")
    Set tbl = ws.ListObjects("tblReports")
 
    Set chartObj = ws.Shapes.AddChart2(Style:=201, _
        XlChartType:=xlColumnClustered, _
        Left:=400, Top:=20, Width:=400, Height:=250).Chart.Parent
 
    With chartObj.Chart
        .SetSourceData Source:=tbl.ListColumns("Profit").Range
        .HasTitle = True
        .ChartTitle.Text = "Profit by Region"
    End With
End Sub
Análise linha por linha
expand arrow
  • AddChart2 cria a própria forma do gráfico — Style:=201 seleciona um estilo visual interno, XlChartType:=xlColumnClustered escolhe um gráfico de colunas padrão, e Left/Top/Width/Height posicionam e dimensionam o gráfico na planilha em pontos, a mesma unidade que o Excel usa internamente para posicionamento de formas;
  • AddChart2 na verdade retorna um objeto Chart, não o contêiner ChartObject ao redor dele — o .Chart.Parent no final dessa linha é o que retorna ao contêiner, que é o tipo que chartObj foi declarado; esse detalhe é fácil de esquecer e vale a pena copiar exatamente;
  • SetSourceData é o que informa à forma do gráfico, que de outra forma estaria vazia, quais dados devem ser plotados — apontar para tbl.ListColumns("Profit").Range faz com que ele plote a coluna Profit em todas as linhas visíveis da tabela;
  • HasTitle = True precisa ser definido antes de atribuir ChartTitle.Text — tentar definir o texto do título em um gráfico que ainda não tem título ativado irá falhar.

Atualizando os Dados do Gráfico

Quando a tabela base cresce, aponte o gráfico para o novo intervalo com SetSourceData em vez de excluir e reconstruir — isso preserva qualquer formatação manual já aplicada:

Dim cht As Chart
Set cht = ThisWorkbook.Worksheets("Reports").ChartObjects(1).Chart
cht.SetSourceData Source:=tbl.ListColumns("Profit").Range

ChartObjects(1) refere-se à primeira forma de gráfico na planilha por posição — adequado quando há apenas um gráfico, mas frágil no momento em que um segundo gráfico é adicionado, já que "primeiro" pode significar algo diferente depois disso. Referenciar um gráfico por um nome definido explicitamente (chartObj.Name = "ProfitChart", depois ChartObjects("ProfitChart")) é mais resiliente quando uma planilha tem mais de um gráfico.

Formatando Gráficos

With chartObj.Chart
    .ChartTitle.Font.Size = 14
    .ChartTitle.Font.Bold = True
    .SeriesCollection(1).Format.Fill.ForeColor.RGB = RGB(24, 106, 60)
    .Axes(xlValue).TickLabels.NumberFormat = "#,##0"
    .HasLegend = False
End With

SeriesCollection(1) é a primeira (e aqui, única) série de dados sendo plotada — seu Format.Fill.ForeColor.RGB é o que colore as barras, usando a mesma função RGB(...) dos exemplos de formatação do Capítulo 1. Axes(xlValue) refere-se especificamente ao eixo numérico (em oposição ao xlCategory, o eixo que lista os nomes das regiões) — aplicar NumberFormat ali controla como os números ao longo desse eixo são exibidos, exatamente como NumberFormat em uma célula da planilha. HasLegend = False remove a legenda completamente, o que é recomendável sempre que um gráfico tem apenas uma série, já que uma legenda explicando uma única cor só adiciona poluição visual sem acrescentar informação.

Tarefa

  1. Execute BuildProfitChart e confirme que um gráfico de colunas aparece mostrando o Profit para todas as quinze linhas (todos os três meses, sem filtro).
  2. Adicione três linhas para colorir as barras do gráfico de verde escuro (RGB(24,106,60)) e remover a legenda, conforme mostrado acima.
  3. Filtre tblReports apenas para janeiro e execute novamente SetSourceData em tbl.ListColumns("Profit").Range — observe se o gráfico respeita o filtro.
Dica
expand arrow

1. Executando BuildProfitChart

  • Copie o Sub exatamente como mostrado no capítulo e execute — nenhuma alteração é necessária nesta parte.
  • Você deverá ver um gráfico aparecer na planilha Reports, exibindo o Lucro para cada linha atualmente visível na tabela.

2. Colorindo as barras e removendo a legenda

  • Ambas as propriedades pertencem ao objeto do gráfico, não à planilha — chartObj.Chart é o ponto de entrada, assim como no exemplo de formatação do capítulo.
  • A cor da barra está em SeriesCollection(1), já que há apenas uma série de dados sendo exibida (Profit) — .Format.Fill.ForeColor.RGB é a propriedade específica a ser definida.
  • Remover a legenda é uma propriedade booleana única (HasLegend), separada da linha de cor de preenchimento.

3. Filtrando e executando novamente SetSourceData

  • Aplique um AutoFilter em Month (Field:=1) restrito a "January" — a mesma técnica da seção 4.2.
  • Em seguida, chame SetSourceData novamente com a mesma expressão tbl.ListColumns("Profit").Range do BuildProfitChart — nada nessa linha precisa ser alterado.
  • Observe atentamente o que acontece com o gráfico depois: ele reduz para mostrar apenas as cinco regiões de January ou ainda exibe todas as quinze linhas, incluindo as que o AutoFilter acabou de ocultar? Essa observação é o verdadeiro objetivo desta tarefa, não apenas executar o código.
Solução
expand arrow
Option Explicit

' Point 1 — run this exactly as shown in the chapter
Sub BuildProfitChart()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim chartObj As ChartObject

    Set ws = ThisWorkbook.Worksheets("Reports")
    Set tbl = ws.ListObjects("tblReports")

    Set chartObj = ws.Shapes.AddChart2(Style:=201, _
        XlChartType:=xlColumnClustered, _
        Left:=400, Top:=20, Width:=400, Height:=250).Chart.Parent

    With chartObj.Chart
        .SetSourceData Source:=tbl.ListColumns("Profit").Range
        .HasTitle = True
        .ChartTitle.Text = "Profit by Region"
    End With
End Sub

' Point 2 — color the bars and remove the legend
Sub FormatProfitChart()
    Dim ws As Worksheet
    Dim chartObj As ChartObject

    Set ws = ThisWorkbook.Worksheets("Reports")
    Set chartObj = ws.ChartObjects(1)

    With chartObj.Chart
        .SeriesCollection(1).Format.Fill.ForeColor.RGB = RGB(24, 106, 60)
        .HasLegend = False
    End With
End Sub

' Point 3 — filter to January, then re-point the chart at the same range
Sub FilterJanuaryAndRefreshChart()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim chartObj As ChartObject

    Set ws = ThisWorkbook.Worksheets("Reports")
    Set tbl = ws.ListObjects("tblReports")
    Set chartObj = ws.ChartObjects(1)

    tbl.Range.AutoFilter Field:=1, Criteria1:="January"

    chartObj.Chart.SetSourceData Source:=tbl.ListColumns("Profit").Range
End Sub

Execute nesta ordem: BuildProfitChart, depois FormatProfitChart, depois FilterJanuaryAndRefreshChart. Para o ponto 3 especificamente — preste atenção ao que realmente acontece. Os gráficos do Excel geralmente respeitam um AutoFilter ativo, ocultando automaticamente as barras das linhas filtradas, mesmo sem executar novamente o SetSourceData. Executá-lo novamente aqui serve principalmente para confirmar que o gráfico ainda está apontando corretamente para a coluna completa — é o próprio filtro que faz a ocultação visual, não a chamada do SetSourceData. Vale a pena testar com o filtro ativado e desativado para ver a diferença.

Note
Nota

Executar BuildProfitChart mais de uma vez cria um novo gráfico a cada vez sem excluir o anterior — assim, vários gráficos acabam empilhados uns sobre os outros. ChartObjects(1) sempre se refere ao primeiro criado, que pode agora estar escondido sob uma cópia mais recente. Por isso, alterações de formatação podem ser executadas com sucesso, mas parecer não ter efeito visível.

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

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