Creación de Tablas Dinámicas con VBA
Desliza para mostrar el menú
Una tabla dinámica resume una tabla arrastrando campos a Filas, Columnas y Valores; cada una de estas acciones de arrastrar y soltar tiene un equivalente directo en VBA, lo que significa que un informe de tabla dinámica completo puede reconstruirse desde cero mediante una macro cada vez que llegan nuevos datos.
Creación de una tabla dinámica
Sub BuildProfitPivot()
Dim wsData As Worksheet, wsPivot As Worksheet
Dim tbl As ListObject
Dim pc As PivotCache
Dim pt As PivotTable
Set wsData = ThisWorkbook.Worksheets("Reports")
Set tbl = wsData.ListObjects("tblReports")
' start clean: remove an existing Pivot sheet if this has run before
On Error Resume Next
Application.DisplayAlerts = False
ThisWorkbook.Worksheets("Pivot").Delete
Application.DisplayAlerts = True
On Error GoTo 0
Set wsPivot = ThisWorkbook.Worksheets.Add
wsPivot.Name = "Pivot"
Set pc = ThisWorkbook.PivotCaches.Create( _
SourceType:=xlDatabase, SourceData:=tbl.Range)
Set pt = pc.CreatePivotTable( _
TableDestination:=wsPivot.Range("A3"), _
TableName:="ptProfitByRegion")
With pt
.PivotFields("Region").Orientation = xlRowField
.PivotFields("Month").Orientation = xlColumnField
.AddDataField .PivotFields("Profit"), "Sum of Profit", xlSum
End With
End Sub
- On Error Resume Next junto con el cambio de
DisplayAlertsy.Deletees un patrón seguro de "eliminar si existe": eliminar una hoja que no existe normalmente generaría un error y detendría la macro, pero On Error Resume Next le indica a VBA que continúe silenciosamente ante ese error específico;DisplayAlerts = Falsesuprime la ventana emergente de confirmación de Excel "¿Está seguro de que desea eliminar esta hoja?"; - On
Error GoTo 0inmediatamente después restablece la notificación normal de errores — dejarOn Error Resume Nextactivo durante el resto delSubocultaría silenciosamente cualquier error posterior no relacionado, lo cual es una trampa que conviene evitar; ThisWorkbook.PivotCaches.Createtoma una instantánea de los datos de la tabla — el PivotCache, no la propia tabla dinámica — que es el objeto a partir del cual realmente se construye cada tabla dinámica en segundo plano;pc.CreatePivotTableconvierte esa instantánea en una tabla dinámica visible, ubicada a partir de la celda A3 en la nueva hoja Pivot y con el nombre ptProfitByRegion para que el código posterior (como RefreshTable) pueda encontrarla por nombre;PivotFields("Region").Orientation = xlRowFieldy la línea de Month justo debajo son el equivalente en código a arrastrar Region al cuadro de Filas y Month al cuadro de Columnas en la lista de campos;AddDataFieldes lo que llena el área de Valores — el segundo argumento ("Sum of Profit") es solo la etiqueta que Excel muestra como encabezado de columna, y xlSum le indica que sume los valores en lugar de promediarlos o contarlos.
Actualización de informes
Una vez que existe una tabla dinámica, no se reconstruye cada vez que llegan nuevos datos — se actualiza, lo cual es más rápido y conserva cualquier ajuste manual de diseño realizado por el usuario:
ThisWorkbook.Worksheets("Pivot").PivotTables("ptProfitByRegion").RefreshTable
Esta sola línea vuelve a leer el PivotCache desde el estado actual de tblReports y actualiza todos los números en la tabla dinámica para que coincidan — pero deja el diseño exactamente igual, incluyendo anchos de columna, formato de números o disposición de campos que el usuario haya ajustado manualmente después de crear la tabla dinámica. Esa es la principal ventaja frente a llamar de nuevo a BuildProfitPivot: reconstruir desde cero recrearía la hoja y eliminaría todos esos ajustes manuales.
Actualización de gráficos dinámicos
Un gráfico dinámico basado en una tabla dinámica actualiza sus datos automáticamente cada vez que se actualiza la tabla dinámica — por lo tanto, refrescar la tabla suele ser todo lo que necesita hacer una macro de informe para mantener actualizado un gráfico vinculado:
Dim pt As PivotTable
Set pt = ThisWorkbook.Worksheets("Pivot").PivotTables("ptProfitByRegion")
pt.RefreshTable
' any PivotChart based on pt updates automatically — no extra code needed
Esto contrasta con los gráficos normales que se verán en la siguiente sección: un gráfico regular necesita una llamada explícita a SetSourceData para apuntar a los nuevos datos, mientras que un gráfico dinámico está permanentemente vinculado a su tabla dinámica y simplemente se actualiza automáticamente. Si un panel necesita un gráfico que siempre refleje los últimos datos de la tabla dinámica con el menor código posible, crearlo como gráfico dinámico en lugar de gráfico independiente suele ser la mejor opción.
Tarea
- Ejecutar
BuildProfitPivotexactamente como se muestra y confirmar que aparece una nueva hoja "Pivot" con Region en las filas y Month en las columnas. - Agregar manualmente una nueva fila de March a
tblReportspara una sexta región ficticia, luego ejecutar solo la línea RefreshTable — confirmar que la tabla dinámica se actualiza sin reconstruirla desde cero. - Modificar
BuildProfitPivotpara resumir Sales en lugar de Profit, e intercambiar Region y Month para que Month esté en las filas y Region en las columnas.
Aquí tienes el código para agregar una sexta región como una nueva fila de marzo en tblReports, usando ListRows.Add en lugar de escribirla manualmente:
Sub AddSixthRegion()
Dim tbl As ListObject
Dim newRow As ListRow
Set tbl = ThisWorkbook.Worksheets("Reports").ListObjects("tblReports")
Set newRow = tbl.ListRows.Add
newRow.Range(1, 1).Value = "March" ' Month
newRow.Range(1, 2).Value = "Southwest" ' Region
newRow.Range(1, 3).Value = 41500 ' Sales
newRow.Range(1, 4).Value = 28200 ' Expenses
newRow.Range(1, 5).Value = 13300 ' Profit
newRow.Range(1, 6).Value = 39000 ' Target
End Sub
Ejecuta esto una vez y luego ejecuta la Sub RefreshProfitPivot de antes — la tabla dinámica ahora debería mostrar "Southwest" como una nueva fila junto a North, South, East, West y Central, sin que hayas modificado en absoluto la macro que construye la tabla dinámica.
1. Ejecutar BuildProfitPivot tal cual
- Copia la
Subexactamente como está escrita en el capítulo en tu módulo y ejecútala una vez. - Revisa el Explorador de Proyectos o las pestañas de tu hoja — debería aparecer una nueva hoja llamada literalmente "Pivot", con Región listada en las filas y Mes distribuido en las columnas, sumando el Beneficio.
2. Agregar una sexta región y solo actualizar
- Escribe la nueva fila directamente en la hoja de cálculo (no mediante código) — ve al final de
tblReportsy agrega una fila de marzo para una región inventada, por ejemplo "Southwest". - No vuelvas a ejecutar
BuildProfitPivot— eso eliminaría y reconstruiría toda la hoja Pivot desde cero, lo que va en contra del objetivo de este ejercicio. - En su lugar, ejecuta solo la instrucción de una línea
RefreshTabledel capítulo — necesitarás hacer referencia a la tabla dinámica existente por nombre, de la misma manera que el ejemplo de actualización del capítulo.
3. Intercambiar campos y cambiar el valor resumido
- Debes cambiar tres líneas dentro del bloque
With pt: qué campo esxlRowField, cuál esxlColumnFieldy a qué campo apuntaAddDataField. - Da a esta versión modificada un nombre de
Subdiferente y unTableNamediferente — reutilizar los mismos nombres que el original provocaría un error o sobrescribiría silenciosamente la primera tabla dinámica. - La etiqueta pasada a
AddDataField(el segundo argumento, como"Sum of Profit") es solo texto de visualización — actualízala para que coincida con lo que realmente estás resumiendo ahora.
Punto 2 — después de agregar manualmente la fila de la sexta región, ejecuta solo esto:
Sub RefreshProfitPivot()
ThisWorkbook.Worksheets("Pivot").PivotTables("ptProfitByRegion").RefreshTable
End Sub
Punto 3 — una versión modificada y separada:
Sub BuildSalesPivotByMonth()
Dim wsData As Worksheet, wsPivot As Worksheet
Dim tbl As ListObject
Dim pc As PivotCache
Dim pt As PivotTable
Set wsData = ThisWorkbook.Worksheets("Reports")
Set tbl = wsData.ListObjects("tblReports")
On Error Resume Next
Application.DisplayAlerts = False
ThisWorkbook.Worksheets("SalesPivot").Delete
Application.DisplayAlerts = True
On Error GoTo 0
Set wsPivot = ThisWorkbook.Worksheets.Add
wsPivot.Name = "SalesPivot"
Set pc = ThisWorkbook.PivotCaches.Create( _
SourceType:=xlDatabase, SourceData:=tbl.Range)
Set pt = pc.CreatePivotTable( _
TableDestination:=wsPivot.Range("A3"), _
TableName:="ptSalesByMonth")
With pt
.PivotFields("Month").Orientation = xlRowField
.PivotFields("Region").Orientation = xlColumnField
.AddDataField .PivotFields("Sales"), "Sum of Sales", xlSum
End With
End Sub
Ejecuta BuildSalesPivotByMonth y deberías obtener una nueva hoja "SalesPivot" con Mes en las filas, Región en las columnas y totales de Ventas en el cuerpo — la imagen reflejada de la disposición original.
¡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