martes, 30 de noviembre de 2021

Recuperar número entre textos

Hace tiempo publiqué un artículo donde explicaba una forma de extraer valores numéricos 'mezclados' con texto en una celda.
Muy frecuentemente nos encontramos determinar si un caracter es o no numérico, lo que hacemos empleando la función ESNUMERO combinada con VALOR (o el doble --)... sin duda efectivo ;-)

Hoy propongo emplear la función CODIGO o UNICODE para detectar sobre qué caracter ANSI (o unicode) estamos trabajando...

Replicaremos el caso propuesto para el artículo anterior comentado:
Recuperar número entre textos

Donde la función construida es:
=LET(cadena;B2; numeros;LET(tratado1;LET(kn;SECUENCIA(LARGO(cadena)); an;EXTRAE(cadena;kn;1); SI(CODIGO(an)>59;"";SI(CODIGO(an)=32;"";an)) ); UNIRCADENAS("";VERDADERO;tratado1)); Separadores;LET(tratado2;LET(ks;SECUENCIA(LARGO(cadena)); as;EXTRAE(cadena;ks;1); SI(CODIGO(as)={44\46};as;"" ) ); UNIRCADENAS("";VERDADERO;UNICOS(tratado2))); separador1;EXTRAE(Separadores;2;1); separador2;EXTRAE(Separadores;1;1); SI.CONJUNTO(LARGO(Separadores)=0;VALOR(numeros); LARGO(Separadores)=1;VALOR.NUMERO(numeros;separador2); LARGO(Separadores)=2;VALOR.NUMERO(numeros;separador1;separador2) ) )
Observemos que el resultado es correcto en los casos expuestos...

La diferencia con el ejercicio anterior se basa en el uso de CODIGO para diferenciar cuáles son los caracteres numéricos... sabiendo que en el código ANSI los diez dígitos responden a los caracteres:
0 - ANSI 48
1 - ANSI 49
2 - ANSI 50
...
9 - ANSI 57
y que además, otros caracteres relevantes son:
32 - ANSI ' ' (espacio en blanco!)
44 - ANSI ,
45 - ANSI -
46 - ANSI .
59 - ANSI ;

Así pues al evaluar caracter a caracter y verificando que sea >59, y con el condicional SI sustituyéndolo por 'nada', al igual que para el caracter 32 (espacio en blanco), estamos limpiando la cadena de texto de cualquier caracter 'no numérico' (como queríamos:
numeros;LET(tratado1;LET(kn;SECUENCIA(LARGO(cadena)); an;EXTRAE(cadena;kn;1); SI(CODIGO(an)>59;"";SI(CODIGO(an)=32;"";an)) ); UNIRCADENAS("";VERDADERO;tratado1))

De forma similar, y con la misma finalidad del artículo comentado, extraemos de manera única los caracteres empleados como separadores decimales o de grupo (miles, millones, etc..):
Separadores;LET(tratado2;LET(ks;SECUENCIA(LARGO(cadena)); as;EXTRAE(cadena;ks;1); SI(CODIGO(as)={44\46};as;"" ) ); UNIRCADENAS("";VERDADERO;UNICOS(tratado2)))
En este caso, los códigos ANSI buscados son o el 44 o el 46, esto es, la coma o el punto.

El resto de la función es idéntica a la anterior, donde identificamos cúal es el separador de grupo ('separador1')y el separador decimal ('separador2'), para finalmente, emplear una función VALOR o VALOR.NUMERO, que convierta el texto 'numérico' obtenido en un número cierto.
Sin duda otra forma de trabajar, alternativamente a ESNUMERO... y quizá algo más corta.

No hay comentarios:

Publicar un comentario

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