🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

GROUPBY y PIVOTBY avanzado — Porcentaje del total, varias métricas y agregaciones personalizadas

|

GROUPBY y PIVOTBY avanzado — Porcentaje del total, varias métricas y agregaciones personalizadas

ResumenGROUPBY y PIVOTBY comparten un conjunto de argumentos opcionales que hacen cosas que una tabla dinámica no puede hacer de un solo movimiento: PERCENTOF da el porcentaje del total en la ranura función (=GROUPBY(C2:C1000; D2:D1000; PERCENTOF)), un HSTACK de funciones devuelve varias métricas a la vez, un LAMBDA en esa misma ranura construye una media ponderada, y filter_array agrega solo las filas que eliges — todo en vivo. Domina la gramática de función y dejarás de recurrir a columnas auxiliares.

=GROUPBY(C2:C1000; D2:D1000; PERCENTOF)                      ' el % de cada región sobre el total general
=GROUPBY(C2:C1000; D2:D1000; HSTACK(SUM; AVERAGE; COUNT))    ' tres métricas, una al lado de otra
=GROUPBY(C2:C1000; D2:D1000; LAMBDA(v; SUM(v)/COUNT(v)))     ' una agregación personalizada
=GROUPBY(C2:C1000; D2:D1000; SUM; ; ; ; (E2:E1000="West"))   ' solo las filas donde región = West

La llamada básica a GROUPBY/PIVOTBY — agrupar, agregar, derramar — ya reemplaza a la tabla dinámica de cada día. Los argumentos opcionales son donde se ponen por delante de ella. Porcentaje del total, varias agregaciones en una cuadrícula, una media ponderada, un prefiltro sobre las filas: cada uno es un argumento de serie aquí y una tarea de clic derecho y configurar (o una imposibilidad) en una tabla dinámica. La clave que lo desbloquea todo es entender qué acepta de verdad el argumento función.

Lo que aprenderás

  • El porcentaje del total en una sola palabra con PERCENTOF — y su trampa nº1
  • Varias métricas a la vez apilando funciones
  • Una agregación personalizada dejando un LAMBDA en la ranura de la función
  • Filtrar filas antes de agregar con filter_array
  • Leer los errores: #CALC!, #FIELD!, #SPILL! apuntan cada uno a un argumento

La ranura de la función acepta más que SUM

La única idea detrás de cada truco de este artículo: el argumento función no se limita a los nombres integrados. Acepta cualquier función eta-reducida — un nombre a secas como SUM, una pila de nombres, un ayudante hecho a medida como PERCENTOF, o un LAMBDA completo que escribas. Una vez que ves esa ranura como «cualquier función que convierte una columna en un resumen», las funciones avanzadas dejan de ser funciones separadas y se convierten en un solo argumento flexible.

=GROUPBY(filas; valores; SUM)                       ' un nombre integrado
=GROUPBY(filas; valores; PERCENTOF)                 ' un ayudante hecho a medida
=GROUPBY(filas; valores; HSTACK(SUM; AVERAGE))      ' varios nombres a la vez
=GROUPBY(filas; valores; LAMBDA(v; MAX(v)-MIN(v)))  ' tu propia función

Porcentaje del total con PERCENTOF

El informe más solicitado — «¿qué porción del total representa cada grupo?» — es una sola palabra. PERCENTOF suma cada grupo y lo divide entre la suma de todo:

=GROUPBY(C2:C1000; D2:D1000; PERCENTOF)   ' Región | % del total general (cada fila, p. ej. 0,32)

La trampa: el resultado es una fracción, no un porcentaje con formato. 0,32 es treinta y dos por ciento, pero la celda muestra 0,32 hasta que aplicas el formato de número Porcentaje (Ctrl+Mayús+%) al derrame. Esto pilla a todos una vez — el número es correcto, la presentación no, y la gente supone que la fórmula está rota. Da formato de Porcentaje al rango de derrame y se lee 32%. ¿Quieres la porción y el total juntos? Apílalos: HSTACK(SUM; PERCENTOF) da el importe y su porcentaje en columnas contiguas.

Varias métricas a la vez apilando funciones

No ejecutas GROUPBY tres veces para suma, media y recuento — apilas las funciones con HSTACK y obtienes tres columnas de resultado de una sola fórmula:

=GROUPBY(C2:C1000; D2:D1000; HSTACK(SUM; AVERAGE; COUNT))
'  Región | ventas totales | venta media | número de pedidos

Cada función de la pila se convierte en una columna, en orden. Este es el informe que una tabla dinámica te obliga a construir arrastrando el mismo campo a Valores tres veces y cambiando el «Resumir por» de cada uno; aquí es una sola expresión, y se lee como la fila de encabezado que quieres: SUM; AVERAGE; COUNT. Fíjate en la diferencia con ensanchar valores: más columnas de valores agregan datos distintos de la misma forma; más funciones agregan los mismos datos de formas distintas. Combina ambas para una cuadrícula de métricas completa.

Una agregación personalizada: LAMBDA en la ranura de la función

Cuando ningún integrado encaja — una media ponderada, un rango, una cifra recortada — escribe un LAMBDA. Recibe los valores de cada grupo como una matriz v, y lo que devuelva se convierte en el agregado:

=GROUPBY(C2:C1000; D2:D1000; LAMBDA(v; MAX(v) - MIN(v)))          ' la amplitud dentro de cada grupo
=GROUPBY(C2:C1000; D2:D1000; LAMBDA(v; TEXTJOIN(", "; 1; v)))     ' lista los miembros, no los totalices
=GROUPBY(C2:C1000; D2:D1000; LAMBDA(v; SUMPRODUCT(v; w)/SUM(w)))  ' una media ponderada (w = pesos)

Este es el techo que una tabla dinámica sencillamente no puede alcanzar: su menú «Resumir valores por» es una lista fija, mientras que la ranura LAMBDA ejecuta cualquier lógica que puedas expresar. La regla que recordar — tu LAMBDA recibe los valores del grupo como un solo argumento y debe devolver un único valor por grupo; devuelve una matriz y obtendrás #CALC!. Medias ponderadas, medianas de un subconjunto filtrado, «el valor más alto como texto» — todo vive en esta ranura.

Filtra las filas antes de agregar

filter_array (el séptimo argumento de GROUPBY) toma una matriz booleana de la misma altura que tus datos y agrega solo las filas que dan VERDADERO — sin columna auxiliar, sin paso de prefiltrado:

=GROUPBY(C2:C1000; D2:D1000; SUM; ; ; ; (E2:E1000 = "West"))         ' solo las filas de la región West
=GROUPBY(C2:C1000; D2:D1000; SUM; ; ; ; (YEAR(A2:A1000) = 2026))     ' solo las filas de 2026
=GROUPBY(C2:C1000; D2:D1000; SUM; ; ; ; (D2:D1000 >= 1000))          ' solo pedidos >= 1000

La condición se escribe como una prueba de FILTER — una comparación que produce VERDADERO/FALSO por toda la columna. La única regla que evita el error: la filter_array debe tener exactamente la misma altura que campos_fila y valores. Apúntala a E2:E1000 cuando tus datos son E2:E999 y obtienes #VALUE!; mantén todos los rangos con la misma altura y funciona sin más. Así construyes resúmenes de «solo este año», «excluyendo reembolsos» o «solo Oeste y Este» sin tocar los datos de origen.

Leer los errores

Los tres errores que lanzan estas funciones apuntan cada uno a un error específico — aprende el mapa y depurar es instantáneo:

#CALC!    ' la ranura de la función está mal: SUM() en lugar de SUM, o un LAMBDA que devuelve una matriz
#FIELD!   ' una referencia de campo/columna está mal — a menudo field_headers mal puesto, y los encabezados se cuelan
#SPILL!   ' el resultado está bloqueado — despeja las celdas de abajo y de la derecha de la fórmula
#VALUE!   ' normalmente filter_array tiene una altura distinta a la de los datos

#CALC! casi siempre es el argumento función — un SUM() llamado, o un LAMBDA que devuelve más de un valor por grupo. #FIELD! apunta a la forma de los datos, con frecuencia al argumento field_headers: si tus rangos incluyen las celdas de encabezado, pon field_headers en 1 para que las etiquetas no se agrupen como datos. #SPILL! es espacial, nunca lógico — la fórmula está bien, la zona de aterrizaje no. Y #VALUE! en una agregación filtrada es el desajuste de altura de arriba. Cada error es una señal que apunta a un argumento, no un misterio.

El criterio

En cuanto un resumen necesita porcentaje del total, más de una métrica, un cálculo personalizado o un subconjunto de filas, estos argumentos opcionales superan a una tabla dinámica sin discusión — cada uno es un argumento aquí y una excursión por menús o un callejón sin salida allá. Ten a mano tres reglas: la ranura función acepta un nombre a secas, un conjunto apilado de nombres o un LAMBDA que devuelve un valor por grupo; PERCENTOF devuelve una fracción que debes formatear como porcentaje; y filter_array debe tener la misma altura que los datos. Lee los errores como un mapa — #CALC! significa la función, #FIELD! significa los encabezados, #SPILL! significa el espacio, #VALUE! significa la altura del filtro — y la última excusa para conservar una tabla dinámica (que hace lo sofisticado) se cae casi del todo.

Cómo ayuda ExcelMaster

Los argumentos avanzados son potentes e implacables — un solo LAMBDA que devuelve una matriz y todo es #CALC!. Dile a ExcelMaster «las ventas de cada región, su porción del total y el recuento de pedidos» y escribe =GROUPBY(C2:C1000; D2:D1000; HSTACK(SUM; PERCENTOF; COUNT)) y te formatea la columna de porcentaje. Pídele «un precio medio ponderado por categoría, ponderando por cantidad» y construye el LAMBDA. Y cuando una fórmula devuelve #CALC! o #VALUE!, lee el error como lo hace esta guía — apuntando al argumento exacto que está mal en lugar de dejarte contando puntos y coma.

Preguntas frecuentes

¿Cómo muestro el porcentaje del total en GROUPBY o PIVOTBY?

Usa PERCENTOF en la ranura función: =GROUPBY(C2:C1000; D2:D1000; PERCENTOF). Divide la suma de cada grupo entre el total general. El resultado es una fracción como 0,32, así que aplica el formato Porcentaje (Ctrl+Mayús+%) al derrame para ver 32%. Para mostrar el importe y su porción una al lado de otra, usa HSTACK(SUM; PERCENTOF).

¿Puede GROUPBY devolver más de una agregación a la vez?

Sí — apila las funciones: =GROUPBY(C2:C1000; D2:D1000; HSTACK(SUM; AVERAGE; COUNT)) devuelve tres columnas. Cada función se convierte en una columna de resultado, en orden. Eso es distinto de ensanchar el rango valores, que agrega columnas distintas de la misma forma; apilar funciones agrega la misma columna de varias formas.

¿Cómo uso una fórmula personalizada como agregación?

Pon un LAMBDA en la ranura función. Recibe los valores de cada grupo como una matriz y debe devolver un único valor: =GROUPBY(C2:C1000; D2:D1000; LAMBDA(v; MAX(v)-MIN(v))). Esto cubre medias ponderadas, rangos y todo lo que la lista integrada «Resumir por» no puede. Si el LAMBDA devuelve una matriz en lugar de un valor, obtendrás #CALC!.

¿Cómo filtro qué filas agrega GROUPBY?

Usa el argumento filter_array (el séptimo): =GROUPBY(C2:C1000; D2:D1000; SUM; ; ; ; (A2:A1000="West")) agrega solo las filas coincidentes. La condición se escribe como una prueba de FILTER, y la matriz booleana debe tener la misma altura que tus datos — un desajuste devuelve #VALUE!.

¿Por qué mi GROUPBY devuelve #CALC! o #FIELD!?

#CALC! casi siempre significa que el argumento función está mal: SUM() en lugar de SUM, o un LAMBDA que devuelve una matriz en vez de un valor por grupo. #FIELD! normalmente significa que el argumento field_headers está mal — ponlo en 1 cuando tus rangos incluyan celdas de encabezado para que las etiquetas no se traten como datos. #SPILL! no tiene que ver con la lógica; significa que hay celdas debajo o a la derecha bloqueando el resultado.

Probado en

Probado en: Excel 365 (Windows 11) — última verificación 18-07-2026.

Guías relacionadas: Excel GROUPBY · Excel PIVOTBY · Excel LAMBDA · Ayudantes de LAMBDA · Excel FILTER