EXTRAER INFORMACIÓN ESPECÍFICA DE UNA CADENA ALFANUMÉRICA UTILIZANDO TEXTO EN COLUMNAS

Hace unos días os dejé un post de cómo se podía extraer información de una cadena de texto alfanumérica, utilizando varias funciones conseguíamos el dato que necesitábamos: EXTRAER INFORMACIÓN ESPECÍFICA DE UNA CADENA DE DATOS

Pues bien, me han vuelto a solicitar otra macro que sea capaz de extraer determinada información, el enunciado de la consulta es el siguiente:

Buenas! quisiera saber si se puede modificar el código de tal manera que permita extraer dos números diferentes que corresponden a diferentes cosas de una misma cadena de texto, y almacenarlas en dos celdas diferentes, por ejemplo: “las condiciones ambientales del experimento fueron 24,5 grados y 1,5 atmósferas ” poder extraer ambos datos y almacenarlos en celdas contiguas.

Bien, al igual que el post original, podríamos solucionar este problema de forma sencilla utilizando la siguiente macro, de hecho esta fue la macro que hice en ese momento:

Sub Extrae_numeros()
Dim i As Integer, j As Integer, Micelda As String, nCifra As Double
With Sheets("Hoja1")
fin = Application.CountA(.Range("A:A"))
For j = 2 To fin
Micelda = .Cells(j, 1)
For i = Len(Micelda) To 1 Step -1
If Not IsNumeric(Mid(Micelda, i, 1)) And Mid(Micelda, i, 1) <>"," Then Mid(Micelda, i, 1) = " "
Next
Micelda = Trim(Micelda)
nCifra = Application.WorksheetFunction.Search(" ", Micelda)
.Cells(j, 2) = Trim(Mid(Micelda, 1, nCifra)) * 1
.Cells(j, 3) = Trim(Mid(Micelda, nCifra, 10000)) * 1
Next
End With
End Sub

Como podéis ver la macro nos permite extraer las dos cifras y colocarlas en celdas contiguas. Es decir, que en principio realiza todo lo que necesitamos.

Pero después de analizarlo detenidamente, concluyo que este código tiene limitaciones importantes, es decir: no contempla los números negativos, los puntos, que sean más de dos cifras las que debemos extraer, etc.

En efecto, si el lector necesitase extraer 3 cifras tendría un problema, de hecho tendría que definir un nuevo punto (nCifra) desde el cual extraer la cuarta cantidad. Esto se puede hacer, pero tenemos otras formas más eficientes para obtener la información.

Os voy a presentar una macro que he programado para extraer cualquier cantidad que se encuentre en una cadena de texto y que permite colocar esos datos en celdas contiguas. Pero primero vamos a ver los datos que queremos extraer:

EXTRAER INFORMACIÓN DE UNA CADENA DE TEXTO UTILIZANDO TEXTO EN COLUMNAS

Y ahora la vamos a ver la macro:

Sub Extrae_numeros()
'Definimos variables
Dim i As Integer, j As Integer, n As Integer, fin As Integer
Dim nCampos As Integer, n_Colum As Integer
Dim miCelda As String
Dim miArray As Variant, iArray As Variant
'Iniciamos la macro
With Sheets("DATOS")
Application.ScreenUpdating = False
fin = Application.CountA(.Range("A:A"))
'Borramos información a partir de la columna "B"
.Range(.Cells(2, 2), ActiveCell.SpecialCells(xlLastCell)).Select
Selection.ClearContents
'Iniciamos bucle para recorrar todas las filas
For j = 2 To fin
'Seleccionamos la fila
miCelda = .Cells(j, 1)
'Extraemos solo los números, los puntos, las comas y el signo - (si existen)
For i = Len(miCelda) To 1 Step -1
If Not IsNumeric(Mid(miCelda, i, 1)) And Mid(miCelda, i, 1) <> "," _
And Mid(miCelda, i, 1) <> "-" And Mid(miCelda, i, 1) <> "." Then Mid(miCelda, i, 1) = " "
Next
'Eliminamos espacios
miCelda = Trim(miCelda)
'Realizamos un segundo bucle y eliminamos todos los puntos, comas o signos - que aparezan antes de un
'carácter numérico
For n = Len(miCelda) To 1 Step -1
If Mid(miCelda, n, 1) = "," And Not IsNumeric(Mid(miCelda, n + 1, 1)) Then Mid(miCelda, n, 1) = " "
If Mid(miCelda, n, 1) = "." And Not IsNumeric(Mid(miCelda, n + 1, 1)) Then Mid(miCelda, n, 1) = " "
If Mid(miCelda, n, 1) = "-" And Not IsNumeric(Mid(miCelda, n + 1, 1)) Then Mid(miCelda, n, 1) = " "
Next
'Volvemos a eliminar espacios y ya tenemos la cadena de texto depurada.
.Cells(j, 2) = Trim(miCelda)
'Dimensionamos matrices con los datos que tenemos en miCelda
'para determinar las columnas de la función textToColumns
nCampos = Len(.Cells(j, 2))
nCampos = nCampos - 1
ReDim miArray(0 To nCampos)
For n_Colum = 0 To nCampos
ReDim iArray(0 To 1)
iArray(0) = n_Colum + 1
iArray(1) = 1
miArray(n_Colum) = iArray
Next n_Colum
'Aplicamos la función texto en columnas a partir de la segunda columna
'delimitamos el texto en caracteres (en este ejemplo utilizamos los espacios).
Cells(j, 2).TextToColumns Destination:=Range("B" & j), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=True, Space:=True, FieldInfo:=miArray
'Indicamos que todas las matrices tengan formato general, pero podríamos indicar que sea número, etc
Next
.Cells(j, 1).Select
End With
End Sub

Con esta macro, iniciamos varios procesos que debemos comentar (aunque ya lo indico en el código). En primer lugar necesitamos realizar dos bucles, en el primero eliminamos los caracteres no numéricos excepto los puntos, las comas y el signo -.

Por ejemplo, para la primera frase, después de aplicar el primer bucle, nos quedamos con estos datos en la variable “miCelda”:  24,5          1,5
Efectivamente, hemos eliminado los caracteres no numéricos y hemos dejado las comas y los números:

For i = Len(miCelda) To 1 Step -1
If Not IsNumeric(Mid(miCelda, i, 1)) And Mid(miCelda, i, 1) <> "," _
And Mid(miCelda, i, 1) <> "-" And Mid(miCelda, i, 1) <> "." Then Mid(miCelda, i, 1) = " "
Next

Pero en el segundo bucle, si tuviésemos por ejemplo, puntos o comas o guiones que no tienen que ver con números, por ejemplo un punto y seguido o una coma, los eliminaríamos, dejando solo dichos caracteres cuando están incluidos en números:

For n = Len(miCelda) To 1 Step -1
If Mid(miCelda, n, 1) = "," And Not IsNumeric(Mid(miCelda, n + 1, 1)) Then Mid(miCelda, n, 1) = " "
If Mid(miCelda, n, 1) = "." And Not IsNumeric(Mid(miCelda, n + 1, 1)) Then Mid(miCelda, n, 1) = " "
If Mid(miCelda, n, 1) = "-" And Not IsNumeric(Mid(miCelda, n + 1, 1)) Then Mid(miCelda, n, 1) = " "
Next

Una vez que tenemos los datos totalmente depurados, solo queda utilizar el texto en columnas para, precisamente, colocar cada número en la columna contigua.

Cells(j, 2).TextToColumns Destination:=Range("B" & j), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=True, Space:=True

Y de esta forma ya tendríamos la macro totalmente finalizada, ya podríamos extraer las cifras en cada cadena de texto y colocarlas en las columnas que automáticamente generará la función texto en columnas y aplicando formato “general”.

Pero imaginad que queréis aplicar formato texto o formato de fecha a los datos que vayáis a extraer. Para poder hacer eso, debemos trabajar con matrices, dimensionando los campos a que vamos a pasar a cada columna y aprovechando para indicar el formato que queremos utilizar en cada uno de ellos:

nCampos = Len(.Cells(j, 2))
nCampos = nCampos - 1
ReDim miArray(0 To nCampos)
For n_Colum = 0 To nCampos
ReDim iArray(0 To 1)
iArray(0) = n_Colum + 1
iArray(1) = 1
miArray(n_Colum) = iArray
Next n_Colum

En este caso, el formato es general: iArray(1) = 1, si fuese texto, sería 2.

Por eso, ahora podemos especificar en el código “de texto en columnas” la información de los campos, es decir, podemos añadir que FielInfo sea igual a la matriz que hemos definido y dimensionado.

Cells(j, 2).TextToColumns Destination:=Range("B" & j), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=True, Space:=True, FieldInfo:=miArray

Para finalizar, este sería el resultado de aplicar la macro:

EXTRAER INFORMACIÓN DE UNA CADENA DE TEXTO UTILIZANDO TEXTO EN COLUMNAS1.jpg

Hemos extraído todas las cifras, conservando puntos, comas y signos negativos. El resto de información de la cadena de texto, simplemente la hemos omitido.

Si no necesitáis darle un formato específico a texto en columnas, podéis eliminar la parte de la macro que hace referencia a las matrices y el FielInfo de la función, aunque yo lo conservaría.

Y aunque seguro que llegarán otras consultas con nuevos planteamientos, creo que esta macro es válida para un amplio abanico de situaciones y necesidades.

Descarga el archivo de ejemplo pulsando en: EXTRAER INFORMACIÓN ESPECÍFICA DE UNA CADENA ALFANUMÉRICA UTILIZANDO TEXTO EN COLUMNAS

 

Anuncios

6 pensamientos en “EXTRAER INFORMACIÓN ESPECÍFICA DE UNA CADENA ALFANUMÉRICA UTILIZANDO TEXTO EN COLUMNAS

  1. Pingback: EXTRAER DATOS DE UNA CADENA DE TEXTO DE DOS EN DOS O MÁS CARACTERES | EXCEL SIGNUM

  2. Pingback: EXTRAER INFORMACIÓN DE UNA CADENA ALFANUMÉRICA EN FUNCIÓN DE VARIOS CRITERIOS | EXCEL SIGNUM

  3. excelente manera de abarcar la solución, muy didáctico.
    agradeceré tu ayuda si te el tiempo te lo permite, una modificación a lo ya explicado,
    resulta que tengo la estructura de una hoja fuente.(codigo, identificador y comentario)

    Codigo Identificador comentario
    AF0002545 ID47492ID47493ID47494 nuevo
    AF0002926 ID69990 ID69991 ID69992 Antiguo
    AF0003927 ID 15524, ID 20178 pendiente
    AF0003928 OSCAR2 ID 77421 ID 77411 ID 77417 ID 77418 ID 77346 extra
    AF0004529 ID: 75958 – 75959 – 75960 – 75961 nuevo
    AF0004620 ID: 36256 pendiente
    AF0005031 ID: 77426 LIMA ICA ID 77424 LIMA CHINCHA Antiguo
    AF0004620 FR: 36256 Nuevo

    se requiere colocar en otra hoja e identificar cada paquete de números (almacenándolos en un arreglo) – para luego presentarlos de forma vertical – cada grupo con su código y comentario respectivo. permitiendo obtener el siguiente resultado:

    Codigo Identificador Comentario
    AF0002545 ID 47492 nuevo
    AF0002545 ID 47493 nuevo
    AF0002545 ID 47494 nuevo
    AF0002926 ID 69990 Antiguo
    AF0002926 ID 69991 Antiguo
    AF0002926 ID 69992 Antiguo
    AF0003927 ID 15524 pendiente
    AF0003927 ID 20178 pendiente
    AF0003928 ID 77421 extra
    AF0003928 ID 77411 extra
    AF0003928 ID 77417 extra
    AF0003928 ID 77418 extra
    AF0004529 ID 75958 nuevo
    AF0004529 ID 75960 nuevo
    AF0004529 ID 75960 nuevo
    AF0004620 ID 36256 pendiente
    AF0005031 ID 77426 Antiguo
    AF0005031 ID 77424 Antiguo
    AF0004620 FR 36256 Nuevo

    gracias desde ya por tu apoyo.
    Oscar V

    Me gusta

    • Hola Oscar:

      Realizar el proceso que indicas en VBA es complejo debido a la calidad de los datos que me muestras. El problema está en la estructura de información de los ID, es decir en cada caso es distinto. Precisamente eso impide automatizar la tarea que requieres. Deberías previamente conseguir datos uniformes, de otra forma no es posible realizar una rutina.

      Saludos.

      Me gusta

      • gracias Segu por tu presta atención, habrá posibilidad de contactar por correo?
        estuve pensando que una caracteristica comun es que todos los valores numéricos siempre tendrán 5 dígitos, En verdad estoy necesitado en encontrarle solucion a este proceso.

        saludos

        Me gusta

¿Te ha gustado?, Realiza un comentario.

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s