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 rango r
  • 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 LAMBDA devuelve un solo valor por elemento, usa MAP, BYROW o BYCOL. Son más legibles y más rápidas.
  • Si devuelve varias filas o columnas, o un número variable de ellas, necesitas REDUCE con APILARV o APILARH.

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 una LAMBDA a cada elemento; exige un valor escalar por iteración
  • REDUCE — recorre una lista arrastrando un acumulador; admite resultados de cualquier tamaño
  • APILARV — apila matrices una debajo de otra, aunque tengan distinto número de filas
  • EXCLUIR — quita las primeras filas o columnas, perfecto para limpiar el valor inicial del acumulador
  • AGRUPARPOR — 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