martes, 1 de marzo de 2022

LAMBDA: Anexar rangos discontinuos

Profundizamos un poco más en el mundo LAMBDA de Excel. Hoy con un clásico: Anexar rangos discontinuos de celdas.
la idea y la línea de trabajo la tomé de un artículo que publiqué hace tiempo sobre el mismo asunto...
Se trataba de anexar distintos rangos de celdas basándose en el uso de la función INDICE que nos habilita trabajar sobre distintas áreas...

Sobre esa idea, para el ejemplo de hoy, partimos de un conjunto de cuatro rangos:
LAMBDA: Anexar rangos discontinuos

La fórmula da bastante miedo (hasta a mí, que soy el padre de la criatura jeje):
=LET(rangos;($E$2:$F$6;$B$1:$C$1;$B$3:$C$5;$B$7:$C$8);
totalfilas;REDUCE(0;SECUENCIA(AREAS(rangos));LAMBDA(ac;a;ac+CuentaFilasArray2(($E$2:$F$6;$B$1:$C$1;$B$3:$C$5;$B$7:$C$8);a)));
pos;SCAN(0;SECUENCIA(AREAS(rangos));LAMBDA(ac;a;ac+CuentaFilasArray2(($E$2:$F$6;$B$1:$C$1;$B$3:$C$5;$B$7:$C$8);a)));
filas;SCAN(0;SECUENCIA(AREAS(rangos));LAMBDA(ac;a;CuentaFilasArray2(($E$2:$F$6;$B$1:$C$1;$B$3:$C$5;$B$7:$C$8);a)));
matrizAreasPosiciones;ARCHIVOMAKEARRAY(totalfilas;2;
LAMBDA(f;c;COINCIDIRX(f;pos;1;2)&"_"&(INDICE(filas;COINCIDIRX(f;pos;1;2);0)+f-INDICE(pos;COINCIDIRX(f;pos;1;2);0))&"|"&c));
area;--IZQUIERDA(matrizAreasPosiciones);
fila;--EXTRAE(matrizAreasPosiciones;ENCONTRAR("_";matrizAreasPosiciones)+1;1);
col;--DERECHA(matrizAreasPosiciones;LARGO(matrizAreasPosiciones)-ENCONTRAR("|";matrizAreasPosiciones));
INDICE(rangos;fila;col;area))

Lo interesante de esta fórmula es que no estamos limitados a un número de rangos... podemos incorporar cuantos necesitemos!!.

Puntos a saber. El conjunto de rangos se deben incluir siempre entre paréntesis.
Se ha creado una función LAMBDA llamada 'CuentaFilasArray2' con la siguiente formulación:
=LAMBDA(rangos;pos;SUMA(BYROW(INDICE((rangos);0;0;pos);LAMBDA(arr;FILAS(arr)))))
función que realiza un conteo del número de filas de un rango dado.

Por otra parte la función LET nos permite ir gestionando mediante variables la creación de valores, vectores y matrices...
Por ejemplo, la variable:
totalfilas;REDUCE(0;SECUENCIA(AREAS(rangos));LAMBDA(ac;a;ac+CuentaFilasArray2(($E$2:$F$6;$B$1:$C$1;$B$3:$C$5;$B$7:$C$8);a)))
retorna, mediante REDUCE, la suma acumulada de todas las filas de los rangos discontinuos indicados.

Con la variable:
pos;SCAN(0;SECUENCIA(AREAS(rangos));LAMBDA(ac;a;ac+CuentaFilasArray2(($E$2:$F$6;$B$1:$C$1;$B$3:$C$5;$B$7:$C$8);a)))
obtenemos un vector con el número de filas de cada rango en modo incremental.

La variable:
filas;SCAN(0;SECUENCIA(AREAS(rangos));LAMBDA(ac;a;CuentaFilasArray2(($E$2:$F$6;$B$1:$C$1;$B$3:$C$5;$B$7:$C$8);a)))
nos devuelve el vector del número de filas de cada rango implicado.
LAMBDA: Anexar rangos discontinuos


El objetivo de estos cálculos es construir una matriz informativa que identifique todas las posiciones de filas, columnas y el rango concreto (entre los seleccionados)... lo que conseguimos en el paso siguiente:
matrizAreasPosiciones;ARCHIVOMAKEARRAY(totalfilas;2;
LAMBDA(f;c;COINCIDIRX(f;pos;1;2)&"_"&(INDICE(filas;COINCIDIRX(f;pos;1;2);0)+f-INDICE(pos;COINCIDIRX(f;pos;1;2);0))&"|"&c))
LAMBDA: Anexar rangos discontinuos

Cada elemento de esa matriz indica en primer término cuál es el número del área del rango, entre los seleccionados, seguido de la posición de fila y columna dentro de cada rango!!... Dispuestos dentro de una matriz única.

Los pasos siguientes son muy obvios... desde cada elemento de la matriz previa recuperamos:
area;--IZQUIERDA(matrizAreasPosiciones);
fila;--EXTRAE(matrizAreasPosiciones;ENCONTRAR("_";matrizAreasPosiciones)+1;1);
col;--DERECHA(matrizAreasPosiciones;LARGO(matrizAreasPosiciones)-ENCONTRAR("|";matrizAreasPosiciones));
el número del área, la fila y la columna.

Para finalizar componiendo nuestra matriz anexada resultante:
INDICE(rangos;fila;col;area)

Una gran pega con la que me he encontrado es que LAMBDA no admite el trabajo sobre conjuntos de rangos :'(
Esto impide dinamizar más la selección e incorporación de nuevos rangos de una forma sencilla...
Aún así, creo que la fórmula es bastante potente y válida.

Abierto a mejoras.

No hay comentarios:

Publicar un comentario

Nota: solo los miembros de este blog pueden publicar comentarios.