Unpivot con separación de cuentas contables concatenadas

Interesante problema planteado por Juan en el grupo: tiene una tabla de asientos contables donde las cuentas vienen concatenadas con "/" en una sola celda (por ejemplo, 621/472/410), y cada cuenta tiene su importe asociado en columnas separadas. El reto es hacer un unpivot que no solo despliegue los importes, sino que también separe las cuentas individuales y las asocie correctamente.

Los datos de partida tienen esta estructura:

| Fecha | Cuentas | Importe 1 | Importe 2 | Importe 3 | Concepto |
|-------|---------|-----------|-----------|-----------|----------|
| 2026-03-31 | 621/472/410 | 100 | 21 | -410 | Inventado |
| 2026-04-30 | 623/472/410 | 3000 | 21 | -3021 | Prueba |

Y el resultado esperado es una fila por cada cuenta individual con su importe correspondiente:

| Fecha | Cuenta | Importe | Valor | Concepto |
|-------|--------|---------|-------|----------|
| 2026-03-31 | 621 | Importe | 100 | Inventado |
| 2026-03-31 | 472 | Importe | 21 | Inventado |
| 2026-03-31 | 410 | Importe | -410 | Inventado |
| 2026-04-30 | 623 | Importe | 3000 | Prueba |
| ... | ... | ... | ... | ... |

Juan ya tenía un LAMBDA heredado de otro ejercicio que casi lo resolvía, pero la columna de cuentas se repetía en vez de dividirse. La comunidad propuso tres enfoques distintos:

Solución de Nacho usando LET con un LAMBDA auxiliar para vectorizar la operación de columnas:

``
=LET(
H; APILARH;
F; LAMBDA(x; ENCOL(SI(F5:H6 = ""; NOD(); x); 2));
APILARV(
H(
F(D5:D6);
H(
EXCLUIR(ENCOL(DIVIDIRTEXTO(CONCAT(E5:E6 & "/"); "/")); -1);
F(F4:H4);
F(F5:H6);
F(I5:I6)
)
)
)
)
`

La clave está en usar CONCAT + DIVIDIRTEXTO para unir todas las cuentas y separarlas de golpe. El SI contra F5:H6 le da a cada columna la forma de la tabla de importes (cada fecha y cada concepto, una vez por importe) y ENCOL la aplana. Su 2 le dice que tire los errores: los NOD() que marcan los importes vacíos, para que un asiento con dos cuentas no deje una fila de más.

Solución con REDUCE y EXPANDIR que usa un enfoque más funcional, construyendo el resultado fila a fila:

`
=LET(
_f; D5:D6;
_c; E5:E6;
_t; I5:I6;
_d; F5:H6;
_R; LAMBDA(x; EXCLUIR(REDUCE(0; x; LAMBDA(a; v; APILARV(a; EXPANDIR(v; 3;; v)))); 1));
APILARH(
_R(_f);
EXCLUIR(REDUCE(0; _c; LAMBDA(a; v; APILARV(a; ENCOL(--DIVIDIRTEXTO(v; "/"))))); 1);
_R(EXPANDIR(F4; FILAS(D5:D6);; F4));
EXCLUIR(REDUCE(0; _d; LAMBDA(a; v; APILARV(a; v))); 1);
_R(_t)
)
)
`

Aquí, el LAMBDA _R se encarga de repetir cada valor tantas veces como cuentas hay (3 en este caso) usando EXPANDIR, y REDUCE va apilando cada bloque verticalmente. Tal como está, vale cuando todos los asientos traen tres cuentas: ese 3 va fijo.

Solución de Gerson, la más compacta, con un truco elegante: usar CONCAT con doble separador ("/" y "|") para aplanar todo en un solo paso:

`
=LET(
a; --DIVIDIRTEXTO(CONCAT(E5:E6 & "|"); "/"; "|"; 1);
F; LAMBDA(x; ENCOL(SI(a; x); 2));
APILARH(F(D5:D6); F(a); F(F4); F(F5:H6); F(I5:I6))
)
`

El DIVIDIRTEXTO con dos delimitadores ("/" para las cuentas y "|" para separar filas) genera directamente una matriz con la forma correcta, que luego sirve como máscara booleana para ENCOL. Si un asiento trae menos cuentas que otro, DIVIDIRTEXTO rellena el hueco con #N/D, y el 2 de ENCOL los tira.

Miki también aportó su versión con una imagen que completaba el enfoque.

Las reacciones de Juan lo dicen todo: "Solución Increíble", "Perfecta", "Buenísima también".

Nota (corregido el 26/9/2026): las fórmulas de Nacho y de Gerson funcionaban con el ejemplo, en el que todos los asientos traen tres cuentas, pero con uno de dos cuentas añadían una fila de más, llena de #N/D o de vacíos. A la de Gerson le faltaba el ; 2 de ENCOL, que es el que tira esos #N/D; en la de Nacho, los huecos van ahora con NOD() en vez de "", para que ese mismo 2 los pueda tirar. La explicación decía además que el 2 de ENCOL` agrupa en bloques de 3 filas: es el argumento que ignora los errores. Comprobado en Excel.

El problema: dos transformaciones a la vez

Juan planteó en el grupo un caso que mezcla dos operaciones que normalmente se hacen por separado. Su diario contable tiene una columna donde las cuentas vienen pegadas con una barra inclinada (por ejemplo la 621, la 472 y la 410 en una sola celda) y, justo al lado, tres columnas de importes: uno por cada una de esas cuentas.

Lo que necesita es un unpivot, sí, pero uno especial: además de desplegar los importes en vertical, hay que partir la cadena de cuentas y emparejar cada cuenta con su importe correspondiente. Si haces solo el unpivot, la columna de cuentas se repite entera en las tres filas y el resultado no sirve para nada.

Partiendo de una fila con fecha, la cadena de tres cuentas, tres importes y un concepto, el resultado que busca es una fila por cuenta: la 621 con su importe, la 472 con el suyo y la 410 con el suyo, arrastrando fecha y concepto en cada una.

Juan ya tenía una LAMBDA heredada de otro ejercicio que casi lo resolvía. Casi: los importes se desplegaban bien, pero la cuenta se repetía. La comunidad respondió con tres enfoques distintos, y merece la pena verlos los tres porque cada uno ataca el problema desde un ángulo diferente.

Enfoque 1: aplanar y repartir con ENCOL

La propuesta de Nacho se apoya en un alias corto y una LAMBDA auxiliar para no repetir la misma operación cuatro veces. La estructura, en pseudocódigo, es esta:

=LET(
    H; APILARH;
    F; LAMBDA(x; ENCOL(SI(esVacio; NOD(); x); 2));
    APILARV(
        H(
            F(columnaFecha);
            H(
                EXCLUIR(ENCOL(DIVIDIRTEXTO(cuentasUnidas; barra)); ultimo);
                F(filaCabeceras);
                F(bloqueImportes);
                F(columnaConcepto)
            )
        )
    )
)

La idea clave está en el par formado por la función de unión de texto y DIVIDIRTEXTO. En vez de partir la cadena fila a fila, se une toda la columna de cuentas en una sola cadena añadiendo una barra al final de cada una, y luego se parte de golpe por esa barra. Sale un vector con todas las cuentas de todas las filas seguidas, en el orden correcto. A ese vector le sobra un elemento vacío al final, el residuo de la última barra, y ahí es donde entra EXCLUIR: en la fórmula real se le pasa un índice negativo para que quite ese elemento contando desde el final en lugar de desde el principio.

El segundo truco es el SI contra el bloque de importes: le da a cada columna (la fecha, las cabeceras, el concepto) la forma de ese bloque, con cada valor repetido una vez por importe, y ENCOL la aplana por filas, que es justo lo que hace falta para que cada bloque de tres importes quede pegado a su fecha. El 2 de ENCOL no agrupa nada: le dice que ignore los errores. Por eso los huecos van marcados con NOD(): si un asiento trae dos cuentas en vez de tres, su importe vacío desaparece al aplanar y no deja una fila de más.

Enfoque 2: construir fila a fila con REDUCE y EXPANDIR

La segunda solución cambia de mentalidad: en vez de aplanar, va acumulando bloques. La pieza central es una LAMBDA auxiliar que recibe una columna y repite cada valor tres veces usando EXPANDIR, apilando cada bloque con APILARV dentro de un REDUCE:

LAMBDA(x;
    REDUCE(
        vacio;
        x;
        LAMBDA(acumulado; valor;
            APILARV(acumulado; EXPANDIR(valor; 3;; valor))
        )
    )
)

Aplicando esa función a la fecha, al concepto y a la etiqueta de columna, los tres quedan replicados tantas veces como cuentas hay en cada fila. Los importes se apilan con un REDUCE sencillo, y las cuentas se parten con DIVIDIRTEXTO dentro del mismo patrón. Al final se pegan todas las columnas con APILARH.

Un detalle práctico: REDUCE necesita un valor inicial para el acumulador, y ese valor aparece como primera fila del resultado. Por eso la fórmula real termina con un EXCLUIR que se lo quita.

Es más largo que el anterior, pero se lee mejor: cada columna del resultado se construye por separado y luego se ensamblan. Eso sí, el 3 de EXPANDIR va fijo, así que vale cuando todos los asientos traen tres cuentas.

Enfoque 3: la versión de Gerson, dos separadores en un paso

La más compacta de las tres, y la más ingeniosa. Gerson aprovecha que DIVIDIRTEXTO acepta dos delimitadores: uno para separar columnas y otro para separar filas.

Une todas las cuentas en una sola cadena marcando el final de cada fila con un carácter poco habitual, una barra vertical que no aparece nunca en un número de cuenta, y dejando la barra inclinada como separador de cuentas. Con esos dos delimitadores, una sola llamada a DIVIDIRTEXTO devuelve ya una matriz con la forma exacta del resultado: una fila por asiento y una columna por cuenta. Una multiplicación por uno convierte el texto resultante en número.

El segundo detalle es el mejor: esa misma matriz se reutiliza como máscara. Una LAMBDA auxiliar aplica un SI sobre ella para dejar pasar solo los valores en las posiciones donde efectivamente hay cuenta, y ENCOL los apila. Si un asiento trae menos cuentas que otro, DIVIDIRTEXTO rellena el hueco con #N/D, y por eso ese ENCOL lleva un 2: tira los errores al aplanar. Una matriz que sirve a la vez de dato y de plantilla, y toda la solución cabe en cinco líneas con un APILARH final.

Funciones clave

  • Funciones de unión de texto sobre un rango — devuelven una sola cadena; es la base para aplanar antes de partir.
  • DIVIDIRTEXTO — parte texto por uno o dos delimitadores; con dos genera directamente una matriz bidimensional.
  • ENCOL — apila una matriz en una columna; su segundo argumento decide qué ignora (con un 2, los errores) y el tercero, si recorre por filas o por columnas.
  • EXPANDIR — repite o rellena un valor hasta un tamaño dado, ideal para replicar la fecha en cada cuenta.
  • REDUCE junto a APILARV — el patrón estándar para construir un resultado acumulando bloques.
  • EXCLUIR — quita filas o columnas sobrantes, tanto el valor inicial de REDUCE como el residuo del separador final.

Conclusión

Tres personas, tres caminos, el mismo resultado. La versión de Nacho es la más directa si ya dominas ENCOL; la de REDUCE es la más legible, aunque lleva fijo el número de cuentas; la de Gerson es la que menos escribe y la que más te enseña sobre lo que DIVIDIRTEXTO puede hacer con dos delimitadores.

Las reacciones de Juan en el grupo resumen bien la sesión: "Solución Increíble", "Perfecta", "Buenísima también". Este es exactamente el tipo de problema que sale a diario en la comunidad de InflueXcel: alguien trae un caso real de contabilidad y, en unas horas, hay tres formas de resolverlo sobre la mesa.

Más casos con estas funciones

Más contenido de Excel en InflueXcel