Crear una función LAMBDA reutilizable para agrupar ventas por punto de venta

Un miembro de la comunidad comparte un fichero con una función personalizada llamada xMGP_SUG registrada en el Administrador de nombres. El objetivo: a partir de una tabla de más de 500 filas con datos de ventas, obtener un resumen agrupado por Punto de Venta (PDV) mostrando la cantidad de líneas y la suma de piezas. La fórmula original usaba LAMBDA con PIVOTARPOR, pero tenía parámetros declarados que no se utilizaban y una estructura más compleja de lo necesaria.

Leo analiza la fórmula y detecta que el segundo campo no se usa en ningún escenario, y que PIVOTARPOR no aporta valor cuando lo que se necesita es una simple agrupación. Propone esta versión simplificada con AGRUPARPOR:

``
=LAMBDA(xRango;xCampo1;xValor1;
LET(
xDatos; xRango;
xCampos; ELEGIRCOLS(xDatos;xCampo1);
xValores;ELEGIRCOLS(xDatos;xValor1);
xAG; AGRUPARPOR(xCampos;xValores;APILARH(FILAS;SUMA);;;;xValores>0);
xEncabezados;{"PDV"\"CANT. LINEAS"\"CANT. PIEZAS"};
APILARV(xEncabezados;EXCLUIR(xAG;1))
)
)(B3:F523;1;3)
`

ELEGIRCOLS extrae las columnas necesarias del rango, AGRUPARPOR agrupa usando dos funciones de agregación apiladas con APILARH (FILAS para contar y SUMA para totalizar), filtrando valores mayores que 0. EXCLUIR(xAG;1) quita la fila de encabezados automáticos y APILARV añade los personalizados. Los argumentos al final son para evaluar directamente en la hoja; al registrar la LAMBDA en el Administrador de nombres se quitan.

Al revisar los datos, Leo descubre que hay campos de tienda repetidos (mismo PDV con distintos códigos de barras). En este caso sí tiene sentido una doble agrupación: primero por PDV + código de barras, y luego consolidar por PDV:

`
=LAMBDA(xRango;xCampo1;xCampo2;xValor1;
LET(
xDatos; xRango;
xCampos; ELEGIRCOLS(xDatos;xCampo1;xCampo2);
xValores;ELEGIRCOLS(xDatos;xValor1);
xAG; AGRUPARPOR(xCampos;xValores;SUMA;;0;;xValores>0);
xAGG; AGRUPARPOR(ELEGIRCOLS(xAG;1);ELEGIRCOLS(xAG;3);APILARH(FILAS;SUMA));
xEncabezados;{"PDV"\"CANT. LINEAS"\"CANT. PIEZAS"};
APILARV(xEncabezados;EXCLUIR(xAGG;1))
)
)(B3:F523;1;5;3)
`

La primera agrupación consolida por PDV + código de barras sumando piezas. La segunda toma solo la columna de PDV y vuelve a agrupar, contando líneas únicas y sumando piezas. Un buen ejemplo de cómo combinar LAMBDA con AGRUPARPOR` para crear funciones de resumen reutilizables.

El problema: una función personalizada que hacía más de lo necesario

Un miembro de la comunidad compartió un fichero con una función propia registrada en el Administrador de nombres, llamada xMGP_SUG. Su objetivo: a partir de una tabla de más de 500 filas de ventas, sacar un resumen agrupado por Punto de Venta (PDV) con dos datos por punto: cuántas líneas tiene y cuántas piezas suman.

La función funcionaba, pero arrastraba dos problemas de diseño que son muy comunes cuando una fórmula crece a base de parches:

  • Parámetros declarados que no se usan. La LAMBDA recibía argumentos que no aparecían en ningún camino de ejecución. Ruido puro: quien la use tiene que rellenarlos sin saber para qué.
  • PIVOTARPOR donde bastaba con agrupar. PIVOTARPOR está pensada para cruzar dos dimensiones, filas contra columnas. Si solo agrupas por un campo, estás pagando complejidad por una función que no aporta.

Leo cogió la fórmula y la reescribió.

La versión simplificada con AGRUPARPOR

=LAMBDA(xRango; xCampo1; xValor1;
    LET(
        xDatos;   xRango;
        xCampos;  ELEGIRCOLS(xDatos; xCampo1);
        xValores; ELEGIRCOLS(xDatos; xValor1);
        xAG;      AGRUPARPOR(xCampos; xValores; APILARH(FILAS; SUMA);;;; xValores>0);
        xEncabezados; cabecerasPersonalizadas;
        APILARV(xEncabezados; EXCLUIR(xAG; 1))
    )
)(B3:F523; 1; 3)

Donde cabecerasPersonalizadas es una constante matricial horizontal con los tres títulos que quieres ver: PDV, cantidad de líneas y cantidad de piezas. Se escribe entre llaves separando los textos con el separador de columnas de tu configuración regional.

Tres detalles que merece la pena señalar:

ELEGIRCOLS recibe el número de columna como parámetro. Esto es lo que hace la función reutilizable de verdad: no hardcodeas qué columna agrupa y cuál suma, se lo pasas al llamarla. La misma función sirve para agrupar por PDV sumando piezas o por vendedor sumando importes.

APILARH(FILAS; SUMA) es el truco central. AGRUPARPOR acepta varias funciones de agregación a la vez si se las pasas apiladas en horizontal. FILAS cuenta cuántos registros hay en cada grupo y SUMA totaliza los valores. Una sola llamada, dos columnas de resultado. Mucha gente no sabe que esto se puede hacer y acaba montando dos AGRUPARPOR separados y pegándolos.

El filtro va en el último argumento. El xValores>0 deja fuera los registros sin piezas antes de agrupar. Los puntos y comas vacíos que hay en medio son los argumentos intermedios de AGRUPARPOR (cabeceras, orden, totales) que se dejan por defecto.

Cabeceras a mano. EXCLUIR(xAG; 1) quita la fila de encabezados que genera AGRUPARPOR automáticamente y APILARV pone encima las tuyas. Así controlas los títulos exactos que quieres.

Los argumentos del final, (B3:F523; 1; 3), son para probar la función directamente en la hoja. Al registrarla en el Administrador de nombres se quitan y la llamas por su nombre.

El giro: los datos tenían PDV repetidos

Al revisar los datos, Leo encontró algo que cambiaba el planteamiento: el mismo punto de venta aparecía con distintos códigos de barras. Contar líneas directamente daba un número inflado, porque cada combinación de PDV y código contaba como registro independiente.

Aquí sí tiene sentido complicar un poco la fórmula, con una doble agrupación:

=LAMBDA(xRango; xCampo1; xCampo2; xValor1;
    LET(
        xDatos;   xRango;
        xCampos;  ELEGIRCOLS(xDatos; xCampo1; xCampo2);
        xValores; ELEGIRCOLS(xDatos; xValor1);
        xAG;   AGRUPARPOR(xCampos; xValores; SUMA;; 0;; xValores>0);
        xAGG;  AGRUPARPOR(ELEGIRCOLS(xAG; 1); ELEGIRCOLS(xAG; 3); APILARH(FILAS; SUMA));
        xEncabezados; cabecerasPersonalizadas;
        APILARV(xEncabezados; EXCLUIR(xAGG; 1))
    )
)(B3:F523; 1; 5; 3)

La lógica en dos pasos:

  1. Primera agrupación: por PDV y código de barras, sumando piezas. El resultado tiene una fila por cada combinación real.
  2. Segunda agrupación: sobre el resultado anterior, tomando solo la columna de PDV y la de piezas ya sumadas. Ahora FILAS cuenta códigos de barras distintos por punto de venta, que era el dato que de verdad se buscaba, y SUMA totaliza las piezas.

Encadenar dos AGRUPARPOR es un patrón que resuelve muchos casos donde necesitas contar elementos únicos: agrupa primero por la combinación, y vuelve a agrupar sobre ese resultado.

Funciones clave

  • LAMBDA — encapsula la lógica en una función con nombre, reutilizable desde cualquier hoja del libro.
  • LET — nombra los pasos intermedios y hace legible una fórmula que si no sería una línea ilegible.
  • ELEGIRCOLS — extrae columnas por posición; recibiendo la posición como parámetro es lo que da flexibilidad a la función.
  • AGRUPARPOR — agrupa y agrega en una fórmula derramada, con filtro incluido en el último argumento.
  • APILARH con varias funciones de agregación — permite pedir cuenta y suma en la misma llamada.
  • EXCLUIR y APILARV — quitan las cabeceras automáticas y ponen las tuyas.

Conclusión

Dos lecciones se llevan de este caso. La primera, de diseño: una función personalizada debe pedir solo lo que usa. Los parámetros muertos y las funciones sobredimensionadas hacen que nadie más que su autor se atreva a tocarla.

La segunda, de técnica: antes de escribir la fórmula, mira los datos. El planteamiento inicial era correcto para los datos que se suponía que había; en cuanto aparecieron PDV duplicados, la solución correcta pasó a ser otra. Ningún truco de fórmula arregla un supuesto equivocado sobre los datos.

Este tipo de revisión (alguien trae una fórmula que funciona y la comunidad la deja en la mitad de líneas y con el doble de sentido) es de lo más habitual en el grupo de InflueXcel.

Más casos con estas funciones

Más contenido de Excel en InflueXcel