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.
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
- AddChart2 crea la forma del gráfico en sí —
Style:=201selecciona un estilo visual incorporado,XlChartType:=xlColumnClusteredelige 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.Parental 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; SetSourceDataes lo que indica a la forma de gráfico, que de otro modo estaría vacía, qué datos graficar — apuntar atbl.ListColumns("Profit").Rangesignifica que grafica la columna Profit en todas las filas visibles de la tabla;HasTitle = Truedebe establecerse antes de asignarChartTitle.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
- Ejecutar
BuildProfitCharty confirmar que aparece un gráfico de columnas mostrando Profit para las quince filas (los tres meses, sin filtrar). - 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.
- Filtrar tblReports solo a enero y volver a ejecutar
SetSourceDatasobretbl.ListColumns("Profit").Range— observar si el gráfico respeta el filtro.
1. Ejecutar BuildProfitChart
- Copiar el
Subexactamente 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.Chartes 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.RGBes 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
AutoFilteren Month (Field:=1) restringido a "January" — la misma técnica de la sección 4.2. - Luego llamar a
SetSourceDatanuevamente con la misma expresióntbl.ListColumns("Profit").RangedeBuildProfitChart— 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.
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 sí 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.
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.
¡Gracias por tus comentarios!
Pregunte a AI
Pregunte a AI
Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla