Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprende Automatización de gráficos | Automatización de Tablas e Informes
Excel VBA para Automatización Empresarial

Automatización de gráficos

Desliza para mostrar el menú

Los gráficos son formas que se sitúan sobre una hoja de cálculo y, como todo lo demás en este capítulo, cada propiedad que se puede configurar manualmente en el panel de formato tiene un equivalente en VBA.

Figura 4.4

Creación de un 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álisis línea por línea
expand arrow
  • AddChart2 crea la forma del gráfico en sí — Style:=201 selecciona un estilo visual incorporado, XlChartType:=xlColumnClustered elige un gráfico de columnas estándar, y Left/Top/Width/Height lo posicionan y dimensionan en la hoja en puntos, la misma unidad que Excel utiliza internamente para la colocación de formas;
  • AddChart2 en realidad devuelve un objeto Chart, no el contenedor ChartObject que lo rodea — el .Chart.Parent al final de esa línea es lo que vuelve al contenedor, que es el tipo con el que se declara chartObj; este detalle es fácil de olvidar y vale la pena copiarlo exactamente;
  • SetSourceData es lo que indica a la forma de gráfico, que de otro modo estaría vacía, qué datos graficar — apuntar a tbl.ListColumns("Profit").Range significa que grafica la columna Profit en todas las filas visibles de la tabla;
  • HasTitle = True debe establecerse antes de asignar ChartTitle.Text — intentar establecer el texto del título en un gráfico que aún no tiene título activado fallará.

Actualización de los datos del gráfico

Cuando la tabla subyacente crece, apunta el gráfico al nuevo rango con SetSourceData en lugar de eliminarlo y reconstruirlo; esto preserva cualquier formato manual ya aplicado:

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

ChartObjects(1) se refiere a la primera forma de gráfico en la hoja por posición — es adecuado cuando solo hay un gráfico, pero es frágil en cuanto se agrega un segundo gráfico, ya que "primero" puede significar algo diferente después de eso. Referenciar un gráfico por un nombre que se establece explícitamente (chartObj.Name = "ProfitChart", luego ChartObjects("ProfitChart")) es más resistente una vez que una hoja tiene más de un gráfico.

Formateo de 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) es la primera (y aquí, única) serie de datos que se grafica — su Format.Fill.ForeColor.RGB es lo que colorea las barras reales, usando la misma función RGB(...) de los ejemplos de formato del Capítulo 1. Axes(xlValue) se refiere específicamente al eje numérico (a diferencia de xlCategory, el eje que enumera los nombres de las regiones); aplicar NumberFormat allí controla cómo se muestran los números a lo largo de ese eje, exactamente igual que NumberFormat en una celda de hoja de cálculo. HasLegend = False elimina la leyenda por completo, lo cual es recomendable siempre que un gráfico solo tenga una serie, ya que una leyenda que explica un solo color añade desorden sin aportar información.

Tarea

  1. Ejecutar BuildProfitChart y confirmar que aparece un gráfico de columnas mostrando Profit para las quince filas (los tres meses, sin filtrar).
  2. Agregar tres líneas para colorear las barras del gráfico de verde oscuro (RGB(24,106,60)) y eliminar la leyenda, como se muestra arriba.
  3. Filtrar tblReports solo a enero y volver a ejecutar SetSourceData sobre tbl.ListColumns("Profit").Range — observar si el gráfico respeta el filtro.
Sugerencia
expand arrow

1. Ejecutar BuildProfitChart

  • Copiar el Sub exactamente como se muestra en el capítulo y ejecutarlo — no se necesitan cambios para esta parte.
  • Debería aparecer un gráfico en la hoja Reports que muestra la utilidad para cada fila actualmente visible en la tabla.

2. Colorear las barras y quitar la leyenda

  • Ambas propiedades pertenecen al objeto gráfico, no a la hoja de cálculo — chartObj.Chart es el punto de entrada, igual que en el ejemplo de formato del capítulo.
  • El color de las barras se encuentra en SeriesCollection(1), ya que solo se está graficando una serie de datos (Profit) — .Format.Fill.ForeColor.RGB es la propiedad específica a establecer.
  • Quitar la leyenda es una sola propiedad booleana (HasLegend), separada de la línea de color de relleno.

3. Filtrar y volver a ejecutar SetSourceData

  • Aplicar un AutoFilter en Month (Field:=1) restringido a "January" — la misma técnica de la sección 4.2.
  • Luego llamar a SetSourceData nuevamente con la misma expresión tbl.ListColumns("Profit").Range de BuildProfitChart — no es necesario cambiar nada de esa línea.
  • Observar cuidadosamente lo que sucede con el gráfico después: ¿se reduce solo a las cinco regiones de January, o sigue mostrando las quince filas incluyendo las que AutoFilter acaba de ocultar? Esa observación es el verdadero objetivo de esta tarea, no solo ejecutar el código.
Solución
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

Ejecutar estos en orden: BuildProfitChart, luego FormatProfitChart, luego FilterJanuaryAndRefreshChart. Para el punto 3 en particular — prestar atención a lo que realmente sucede. Los gráficos de Excel generalmente respetan un AutoFilter activo, ocultando automáticamente las barras de las filas filtradas, incluso sin volver a ejecutar SetSourceData. Volver a ejecutarlo aquí simplemente confirma que el gráfico sigue apuntando correctamente a toda la columna — el filtro es lo que realiza el ocultamiento visual, no la llamada a SetSourceData. Vale la pena probar con el filtro activado y desactivado para ver la diferencia.

Note
Nota

Ejecutar BuildProfitChart más de una vez crea un nuevo gráfico cada vez sin eliminar el anterior — por lo que varios gráficos terminan apilados uno sobre otro. ChartObjects(1) siempre se refiere al primero que se creó, que puede estar ahora oculto debajo de una copia más reciente. Por eso los cambios de formato pueden ejecutarse correctamente pero parecer que no tienen ningún efecto visible.

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 4. Capítulo 4

Pregunte a AI

expand

Pregunte a AI

ChatGPT

Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla

Sección 4. Capítulo 4
some-alt