|
La clave está en el "Para la información que aportas"
Me temo que la descripción previa al primer número no va a ser siempre de una palabra. Intuyo que habrá descripciones como "Agua destilada 3x5 (algo)" que desmontan la teoría.
Dado que llevo unos días peleando con Excel, he buscado alguna forma de hacerlo mediante funciones sin tener que recurrir a VBA (que me resultaría bastante más simple).
VAYA POR DELANTE QUE ES UN POCO LARGO Y ENREVESADO
Se trata de intentar replicar la lógica de VBA mediante funciones: - Recorrer los caracteres de la cadena de texto - Evaluar si nos encontramos ante un número o no - En caso afirmativo, tomar ese carácter como inicio de la cadena resultante. - De la cadena resultante, localizar la posición del paréntesis de cierre
Es posible que haya utilizado una forma complicada pero es la única que se me ha ocurrido. Vamos a hacerlo en varias columnas para ver como va evolucionando la función. En principio iré poniendo en negrita las funciones que aparecen nuevas en la secuencia de acciones que se realizan
Funciones necesarias: LARGO, SECUENCIA, EXTRAE, MAP, LAMBDA, SI, VALOR, ESNUMERO, FILTRAR, TOMAR, LET, IZQUIERDA y HALLAR. Las vamos viendo poco a poco
- LARGO devuelve la longitud del texto - SECUENCIA crea una secuencia numérica en base a 4 argumentos (filas, columnas, inicio y paso) - EXTRAE obtiene una parte central de una cadena de texto
Columna B. La =SECUENCIA(LARGO($A1)) nos creará una matriz con los números de posición de los caracteres.
Columna C Si nos apoyamos en esa secuencia para utilizar cada uno de los valores como valor del argumento inicio de una EXTRAE, obtenemos los caracteres de forma individual en una matriz:
=EXTRAE($A1;SECUENCIA(LARGO($A1));1)
Columna D Vamos a evaluar cada uno de los caracteres para saber si es un numérico. El binomio MAP-LAMBDA permite "mapear" n matrices para, en cada valor, realizar operaciones mediante LAMBDA. Las funciones VALOR Y ESNUMERO se utilizan para forzar un dígito a número y su posterior evaluación respectivamente. Ejemplo: =ESNUMERO("1") --> FALSO =ESNUMERO(VALOR("1")) --> VERDADERO
Utilizamos la función MAP-LAMBDA para obtener solo los valores de las posiciones numéricas. Pongo toda la función y la explico poco a poco. =MAP(EXTRAE($A1; SECUENCIA(LARGO($A1)); 1);SECUENCIA(LARGO($A1)); LAMBDA(c;p; SI(ESNUMERO(VALOR(c));p;"")))
Se incluyen 2 mapeos en los 2 primeros argumentos de la MAP: uno para cada uno de los caracteres y otro para la posición que ocupan.
La función LAMBDA que aparece en el tercer argumento contiene 3 argumentos: - nombre que recibe la variable que contiene el primero de los argumentos del MAP --> le he llamado c porque es el carácter. - nombre que recibe el segundo de los argumentos del MAP --> le he llamado p porque es la posición - el tercer argumento es la función que aplicaremos a cada una de las iteraciones por el MAP. En este caso evaluar si es numero el valor del carácter. En caso afirmativo obtenemos la posición; en caso negativo, una cadena vacía.
Columna E Aquí se trata de filtrar la cadena obtenida para quedarnos solo con los numéricos. Dado que la cadena que devuelve el resultado es muy larga y hay que escribirla 2 veces, utilizamos una función LET para poder reutilizarla dentro de la celda. Esa función tiene 3 argumentos: - nombre de variable. Le asigno el nombre de miArray. - valor que toma la variable --> le pongo todo el "churro" anterior - cálculo a realizar --> voy a filtrar el array a los no-vacios
=LET(miArray;MAP(EXTRAE($A1; SECUENCIA(LARGO($A1)); 1);SECUENCIA(LARGO($A1)); LAMBDA(c;p; SI(ESNUMERO(VALOR(c));p;"")));FILTRAR(miArray;miArray<>""))
El resultado es una matriz más pequeña con solo los numéricos del array.
Columna F Quedarnos únicamente con el primer valor de la matriz filtrada. Utilizamos la función TOMAR dónde como primer argumento ponemos el "churro de la columna anterior y, como segundo argumento, la cantidad de filas a obtener (1 en este caso)
=TOMAR(LET(miArray;MAP(EXTRAE($A1; SECUENCIA(LARGO($A1)); 1);SECUENCIA(LARGO($A1)); LAMBDA(c;p; SI(ESNUMERO(VALOR(c));p;"")));FILTRAR(miArray;miArray<>""));1)
Columna G Obtener la subcadena de texto de la celda A1 empezando en la posición obtenida del churro anterior. Utilizamos la función EXTRAE pasando un tercer argumento suficientemente alto (1000) =EXTRAE($A1;TOMAR(LET(miArray;MAP(EXTRAE($A1; SECUENCIA(LARGO($A1)); 1);SECUENCIA(LARGO($A1)); LAMBDA(c;p; SI(ESNUMERO(VALOR(c));p;"")));FILTRAR(miArray;miArray<>""));1);1000)
Columna H De la cadena obtenida solo hay que tomar los caracteres hasta la aparición de un paréntesis de cierre. O sea, una función IZQUIERDA del churro anterior hasta la posición del paréntesis obtenida con un HALLAR de la propia cadena. Dado que la cadena anterior es un churro larguísimo qua habría que poner 2 veces, volvemos a utilizar una LET. A esta variable la llamamos miCadena y la utilizamos para tomar su parte IZQUIERDA hasta la aparición del paréntesis.
Así, mi función propuesta para dar respuesta a cualquier cadena dónde se desee extraer desde el primer numérico hasta el primer paréntesis de cierre posterior a ese numérico es la siguiente:
=LET(miCadena;EXTRAE($A1;TOMAR(LET(miArray;MAP(EXTRAE($A1; SECUENCIA(LARGO($A1)); 1);SECUENCIA(LARGO($A1)); LAMBDA(c;p; SI(ESNUMERO(VALOR(c));p;"")));FILTRAR(miArray;miArray<>""));1);1000);IZQUIERDA(miCadena;HALLAR(")";miCadena)))
Nota: no serviría para "Papel DIN-A4 1x5 (20H) blanco"
Espero que sirva para el problema planteado. O por lo menos que se aprenda el funcionamiento de esas funciones (si es que se desconocía)
Insisto que es una aproximación utilizando las técnicas que conozco. Es posible que existan otras maneras más sencillas.
Un saludo
------------- Xavi, un minyó de Terrassa
http://www.llodax.com" rel="nofollow - Mi web
|