martes, 23 de febrero de 2021

Reemplazar TODOS los caracteres especiales en un paso

Días atrás, con un compañero de un grupo de Excel (Frèdèric LE GUEN - Excel MVP francés ), estuvimos viendo diferentes formas de forzar un reemplazamiento maivo de todos los posibles caracteres especiales que existían en los distintos idiomas... y con una única fórmula, sin programación!!.

LLegamos a soluciones algo diferentes, pero igualmente válidas... Os muestro mi solución.

Emplearemos funciones clásicas ya conocidas de todos: INDICE, BUSCARV, SI.ERROR, TRUNCAR, RESIDUO, CONTARA, COLUMNAS, EXTRAE, LARGO, CARACTER, UNICODE
y otras más novedosas como: UNIRCADENAS, SECUENCIA o LET

Por suerte se emplearán métodos ya conocidos y expuestos en este blog ;-)
Reemplazar TODOS los caracteres especiales en un paso

Y la fórmula 'fabricada' sería:
=UNIRCADENAS("";0;
LET(reference;A1;
rpl_a; {"à"\"á"\"â"\"ã"\"ä"\"å"};
rpl_e; {"é"\"è"\"ê"\"ë"};
rpl_i; {"ì"\"í"\"î"\"ï"};
rpl_o; {"ò"\"ó"\"ô"\"õ"\"ö"\"ø"};
rpl_u; {"ù"\"ú"\"û"\"ü"\"ů"};
rpl_y; {"Ý"\"Ÿ"};
rpl_c; {"ç"\"ć"};
rpl_l; {"ł"};
rpl_n; {"ñ"\"ń"};
rpl_r; {"ř"};
rpl_s; {"š"\"ś"};
rpl_z; {"ž"\"ż"\"ź"};
rpl_aa; {"À"\"Á"\"Â"\"Ã"\"Ä"\"Å"\"Ą"};
rpl_ee; {"È"\"É"\"Ê"\"Ë"\"Ę"};
rpl_ii; {"Ì"\"Í"\"Î"};
rpl_oo; {"Ò"\"Ó"\"Ô"\"Õ"\"Ö"\"Ø"};
rpl_uu; {"Ù"\"Ú"\"Û"\"Ü"\"Ů"};
rpl_yy; {"Ý"\"Ÿ"};
rpl_cc; {"Ç"\"Ć"};
rpl_ll; {"Ł"};
rpl_nn; {"Ñ"\"Ń"};
rpl_rr; {"Ř"};
rpl_ss; {"Š"\"Ś"};
rpl_zz; {"Ž"\"Ż"\"Ź"};
arrRpl;SI.ERROR(ELEGIR(SECUENCIA(24);rpl_a; rpl_e; rpl_i; rpl_o; rpl_u; rpl_y; rpl_c; rpl_l; rpl_n; rpl_r; rpl_s; rpl_z; rpl_aa; rpl_ee; rpl_ii; rpl_oo; rpl_uu; rpl_yy; rpl_cc; rpl_ll; rpl_nn; rpl_rr; rpl_ss; rpl_zz);"");

arrRpla;INDICE(arrRpl;TRUNCAR(SECUENCIA(CONTARA(arrRpl);1;0;1/COLUMNAS(arrRpl)))+1;RESIDUO(SECUENCIA(CONTARA(arrRpl);1;0;1);COLUMNAS(arrRpl))+1);
arrBy;ELEGIR(SECUENCIA(24);"a";"e";"i";"o";"u";"y";"c";"l";"n";"r";"s";"z";"A";"E";"I";"O";"U";"Y";"C";"L";"N";"R";"S";"Z");
arrPor;INDICE(arrBy;1+(MULTIPLO.SUPERIOR.MAT(SECUENCIA(CONTARA(arrRpl));COLUMNAS(arrRpl))-COLUMNAS(arrRpl))/COLUMNAS(arrRpl));
array;ELEGIR({1\2};arrRpla;arrPor);
txt;LET(
n;SECUENCIA(LARGO(reference));
chr;EXTRAE(reference;n;1);
SI.ERROR(CARACTER(BUSCARV(UNICODE(chr);UNICODE(array);2;0));chr));
txt))
Fórmula monstruosa seguramente mejorable... ¿te atrevés? ;-)

En líneas generales, antes de entrar en detalle, lo que hace la fórmula (ayudado por LET) es identificar grupos o matrices de caracteres especiales a ser reemplazados (las 24 matrices 'rpl_').
A continuación unificamos dichas 24 matrices en una sola:
arrRpl;SI.ERROR(ELEGIR(SECUENCIA(24);rpl_a; rpl_e; rpl_i; rpl_o; rpl_u; rpl_y; rpl_c; rpl_l; rpl_n; rpl_r; rpl_s; rpl_z; rpl_aa; rpl_ee; rpl_ii; rpl_oo; rpl_uu; rpl_yy; rpl_cc; rpl_ll; rpl_nn; rpl_rr; rpl_ss; rpl_zz);"");
Esto nos generaría una matriz bidimensional de 24 filas x 7 columnas (dependerá del número de matrices indicadas y del tamaño de la mayor de ellas).
Reemplazar TODOS los caracteres especiales en un paso


Igualmente generamos una matriz de 24 filas x 1 columna de manera manual... debiendo corresponder el orden con el de las matrices previas... tal y como se ve en la imagen anterior.
arrBy;ELEGIR(SECUENCIA(24);"a";"e";"i";"o";"u";"y";"c";"l";"n";"r";"s";"z";"A";"E";"I";"O";"U";"Y";"C";"L";"N";"R";"S";"Z");
En los pasos siguientes pasamos estas matrices anteriores (arrRpl y arrBy) de matrices bidimensionales a vectores de una sola columna (lee aquí el proceso)
arrRpla;INDICE(arrRpl;TRUNCAR(SECUENCIA(CONTARA(arrRpl);1;0;1/COLUMNAS(arrRpl)))+1;RESIDUO(SECUENCIA(CONTARA(arrRpl);1;0;1);COLUMNAS(arrRpl))+1);
y
arrPor;INDICE(arrBy;1+(MULTIPLO.SUPERIOR.MAT(SECUENCIA(CONTARA(arrRpl));COLUMNAS(arrRpl))-COLUMNAS(arrRpl))/COLUMNAS(arrRpl));
Consiguiendo algo como esto (dentro de la fórmula, de forma virtual!!), dos vectores de 168 filas x 1 columnas:
Reemplazar TODOS los caracteres especiales en un paso


En el siguiente paso unificamos en una sola matriz los dos vectores (arrRpla y arrPor):
array;ELEGIR({1\2};arrRpla;arrPor);

La parte final del proceso o tratamiento de esa matriz 'array' se consigue con un nuevo LET anidado, que se encarga de forzar ese reemplazamiento buscado.
txt;LET(
n;SECUENCIA(LARGO(reference));
chr;EXTRAE(reference;n;1);
SI.ERROR(CARACTER(BUSCARV(UNICODE(chr);UNICODE(array);2;0));chr));
txt)

Donde la cadena de texto de referencia se descompone caracter a caracter, realizando la búsqueda individualmente, de cada uno de ellos, convertidos previamente a codificación ANSI para ser precisos en la sustitución.
La fórmula, para aquellos casos que no encuentra coincidencia devuelve el caracter inicial...
Dicho de otro modo, solo se reemplazarán los caracteres especiales listados...

El resultado es el esperado. Cualquiera de los caracteres desplegados en la fórmula será reemplazado por su correspondiente caracter 'limpio' de signos especiales de puntuación: acentos, tildes, virgulillas, dieresis, etc.

No hay comentarios:

Publicar un comentario

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