Error #CALC con MAP y AGRUPARPOR: solución con REDUCE+APILARV
Nuevo reto de Excel resuelto por la comunidad: un usuario necesita aplicar AGRUPARPOR de forma iterativa sobre un rango de códigos de cuenta, pero al usar MAP obtiene el temido error #CALC. Su fórmula original:
``
=LET(
r; B9:B13;
final_r; MAP(r; LAMBDA(x;
AGRUPARPOR(
Tabla1[k_sc_codigo_cuenta];
Tabla1[n_valor_credito];
SUMA; 0; 0;;
Tabla1[k_sc_codigo_cuenta]=x
)
));
ELEGIRCOLS(final_r; 2)
)
`
Leo explica la causa: MAP, al igual que BYROW y BYCOL, no es capaz de apilar resultados que devuelvan más de un elemento. AGRUPARPOR devuelve múltiples filas, y MAP no puede manejar eso.
Gerson complementa sugiriendo MATRIZATEXTO si se necesita un solo resultado por iteración.
Leo propone la solución usando REDUCE + APILARV, que sí permite acumular resultados de tamaño variable:
`
=LET(
r; B9:B13;
final_r; EXCLUIR(
REDUCE(0; r; LAMBDA(a; x;
APILARV(a;
AGRUPARPOR(
Tabla1[k_sc_codigo_cuenta];
Tabla1[n_valor_credito];
SUMA; 0; 0;;
Tabla1[k_sc_codigo_cuenta]=x
)
)
)); 1
);
ELEGIRCOLS(final_r; 2)
)
`
El patrón REDUCE + APILARV con EXCLUIR del primer elemento (el valor inicial) es una técnica recurrente en la comunidad para superar las limitaciones de MAP/BYROW/BYCOL`.
Escribes una fórmula que parece impecable, la validas y Excel te devuelve un escueto #CALC. Sin más pistas. Le pasó a un miembro de la comunidad intentando aplicar AGRUPARPOR de forma iterativa sobre una lista de códigos de cuenta, y el diagnóstico de Leo explica una limitación que afecta a MAP, BYROW y BYCOL por igual.
El problema
La idea era recorrer un rango de códigos y, para cada uno, lanzar un AGRUPARPOR filtrado por ese código:
`` =LET( r; B9:B13; final_r; MAP(r; LAMBDA(x; AGRUPARPOR( Tabla1[k_sc_codigo_cuenta]; Tabla1[n_valor_credito]; SUMA; 0; 0;; Tabla1[k_sc_codigo_cuenta]=x ) )); ELEGIRCOLS(final_r; 2) ) ``
La lógica es correcta. El planteamiento tiene sentido. Y aun así, error.
La causa: MAP solo admite un valor por iteración
Leo da con la clave enseguida: MAP, igual que BYROW y BYCOL, no sabe apilar resultados de más de un elemento. Espera que la LAMBDA que le pasas devuelva un único valor escalar en cada vuelta.
Y AGRUPARPOR devuelve justo lo contrario: una matriz con tantas filas como grupos encuentre, y al menos dos columnas. Cuando MAP recibe eso, no tiene forma de encajarlo en la matriz de salida y responde con #CALC.
Es una limitación de diseño, no un fallo. Estas tres funciones están pensadas para transformaciones elemento a elemento, no para acumular bloques de tamaño variable.
Gerson apunta una salida rápida cuando de verdad solo hace falta un resultado por iteración: envolver la salida en MATRIZATEXTO para colapsarla en un único texto. Sirve para inspeccionar o para casos sencillos, pero no si necesitas los datos como matriz utilizable.
La solución: REDUCE con APILARV
Cuando el resultado de cada iteración tiene tamaño variable, la herramienta correcta es REDUCE. A diferencia de MAP, REDUCE va arrastrando un acumulador al que puedes apilar lo que quieras:
`` =LET( r; B9:B13; final_r; EXCLUIR( REDUCE(0; r; LAMBDA(a; x; APILARV(a; AGRUPARPOR( Tabla1[k_sc_codigo_cuenta]; Tabla1[n_valor_credito]; SUMA; 0; 0;; Tabla1[k_sc_codigo_cuenta]=x ) ) )); 1 ); ELEGIRCOLS(final_r; 2) ) ``
Vamos por partes:
REDUCE(0; r; LAMBDA(a; x; ...))arranca con un acumulador de valor 0 y recorre cada código del rangor- Dentro,
APILARV(a; AGRUPARPOR(...))pega debajo del acumulado el bloque completo que devuelve el agrupamiento - Como el acumulador arrancó con ese 0 artificial, la primera fila del resultado sobra:
EXCLUIR(...; 1)la elimina ELEGIRCOLS(final_r; 2)se queda con la columna de importes
El patrón REDUCE mas APILARV mas EXCLUIR del valor inicial es tan recurrente en la comunidad que conviene tenerlo mecanizado. Aparece cada vez que hay que acumular resultados de longitud desconocida.
Cómo elegir entre MAP y REDUCE
La regla práctica es corta:
- Si tu
LAMBDAdevuelve un solo valor por elemento, usaMAP,BYROWoBYCOL. Son más legibles y más rápidas. - Si devuelve varias filas o columnas, o un número variable de ellas, necesitas
REDUCEconAPILARVoAPILARH.
Cuando veas #CALC en una fórmula con MAP, BYROW o BYCOL, lo primero que debes preguntarte es cuántos elementos devuelve tu función interior.
Funciones clave
MAP— aplica unaLAMBDAa cada elemento; exige un valor escalar por iteraciónREDUCE— recorre una lista arrastrando un acumulador; admite resultados de cualquier tamañoAPILARV— apila matrices una debajo de otra, aunque tengan distinto número de filasEXCLUIR— quita las primeras filas o columnas, perfecto para limpiar el valor inicial del acumuladorAGRUPARPOR— agrupa y agrega, devolviendo siempre una matriz
Conclusión
Los errores #CALC casi nunca son un problema de sintaxis: son un problema de forma de los datos. Entender qué devuelve cada función y qué espera recibir la siguiente resuelve la mayoría de ellos.
Este diagnóstico salió en pocos minutos en el grupo de InflueXcel, donde a diario se cruzan problemas reales de trabajo con gente dispuesta a desmontarlos.
Más casos con estas funciones
Más contenido de Excel en InflueXcel
- Optimización de REDUCE+APILARV con LAMBDA recursiva en bisección CasoAlejandro plantea un reto de rendimiento interesante: tiene una fórmula LET enorme que calcula la permanencia de carga en puerto por matrícu
- Generar la serie de Fibonacci con REDUCE, APILARV y LAMBDA CasoInteresante ejercicio compartido en la comunidad: generar los primeros N números de la serie de Fibonacci usando exclusivamente fórmulas de
- Readmisión de pacientes en 48h: Power Query, LAMBDA/MAP y AGRUPARPOR CasoAndrés Rojas plantea un reto real de datos clínicos: a partir de una tabla con más de un millón de registros de urgencias (IdPaciente, Fecha
- Precio más reciente por artículo: REDUCE, AGRUPARPOR y números complejos CasoNuevo reto interesante planteado por Miki: dada una tabla con artículos y sus precios históricos por año (múltiples filas por artículo), obt
- Buscar prefijos de longitud variable en otra columna: BYROW, MAP, REGEX y COINCIDIRX CasoInteresante problema planteado por un miembro: tiene una columna A con ~1.200 referencias de longitud variable y una columna C con ~276 text
- Reto de agrupación y pivotado: AGRUPARPOR vs ARCHIVOMAKEARRAY vs MAP CasoLeandro trae un reto de internet al grupo: a partir de una tabla con claves repetidas y valores, generar una tabla pivotada donde cada clave
- ¿MAP o BYROW? Descubre cuándo usar cada una Tutorial¿MAP o BYROW? Descubre cuándo usar cada una y cómo estas funciones pueden transformar tu forma de trabajar en Excel. En este vídeo aprenderá
- Funciones window en Excel: el total del grupo en cada fila con LAMBDA y BYROW TutorialEn SQL se llaman funciones window: columnas que, para cada fila, traen un agregado calculado sobre un grupo mayor. El total de ese cliente a
- Resumen mensual con AGRUPARPOR en una sola fórmula y orden cronológico CasoJosé escribe desde Lima con una consulta muy práctica: tiene una tabla de movimientos financieros con fechas y valores, y quiere generar un
- Formato dinámico AGRUPARPOR PIVOTARPOR TutorialAplicar formato condicional a las matrices calculadas es fundamental para conseguir que su legibilidad sea óptima