lunes, 7 de noviembre de 2011

VBA: La funcion SPLIT en una macro de Excel.

Hoy pondré un ejemplo del uso de la función SPLIT en nuestras macros. Se trata de responder a la cuestión planteada por un lector:

...Mi problema es el siguiente en una celda me vota un dato separado por comas (2654500543210,211,213,214) lo que he realizo hasta el momento es evaluar el largo y decirme cuantos items hay, en este caso serian 4, lo que quiero hacer es que al encontrar mas de 1 item me inserte una fila por cada item nuevo con los mismos datos que hay en la misma fila y coloque un nuevo registro quedando de la siguiente forma
2654500543210 - IUYDHN
2654500543211 - IUYDHN
2654500543212 - IUYDHN
2654500543213 - IUYDHN


Lo que haremos será evaluar la celda en cuestión, de tal forma que mediante la función SPLIT, separemos los diferentes valores existentes en la celda, asignándolos posteriormente a elementos de una matriz o Array.
La última parte de la macro consistirá en añadirle el texto " - IUYDHN", y sustituir los últimos dígitos del valor principal.

Sabiendo que nuestros datos se encuentran en la 'Hoja1' y que la celda a evaluar es la A1, el código a incluir en un módulo del Editor de VBA (Alt+F11) será:

Sub separar()
Dim cadena As String, n As Long
Dim matriz() As String
Dim i As Long, izq As Long

'cadena será el contenido de la celda a evaluar
cadena = Range("A1").Value

'asignamos cada parte como un elemento de la matriz
'la función SPLIT devuelve una matriz que contiene un número especificado de subcadenas
'obtenidas o delimitadas por el operador dado
matriz = Split(Trim(cadena), ",")

'contamos el número total de elementos
n = UBound(matriz) + 1
izq = Len(matriz(0)) - 3

'obtenemos en las celdas siguientes los textos obtenidos
For i = 1 To n
If i = 1 Then
Range("A1").Offset(0, i + 1).Value = matriz(i - 1) & " - IUYDHN"
Else
Range("A1").Offset(0, i + 1).Value = Left(matriz(0), izq) & matriz(i - 1) & " - IUYDHN"
End If
Next
End Sub


El resultado será el esperado al ejecutar la macro, ya que en las columnas anexas nos dispone los valores de texto correctos:

VBA: La funcion SPLIT en una macro de Excel.
haz click en la imagen

19 comentarios:

  1. Muchas gracias, este aporte es excelente, buscaba algo asi y ya tenia rato sin dar pie.

    Saludos

    ResponderEliminar
  2. BUENAS TARDES SEÑORES DEL FORO
    la pregunta es acerca de como puedo hacer una funcio VBA que me busque una palabra de un texto que contiene una celda y la pueda ci}opiar hacia la derecha. Ejemplo: Zoe feat Enrique Bumbury quede de la siguiente manera:

    Busque la palabra feat y quede lo siguiente

    Celda A1= Zoe Celda B1= feat Enrique Bunbury.

    Y pueda buscar tambien automaticamente si la celda tiene feat, featuring, ft.

    Este es el caso que se me complica su ayuda muchas gracias

    ResponderEliminar
    Respuestas
    1. Hola Axel,
      realmente no haría falta una función VBA para esto... con funciones de hoja de cálculo estándar puedes hacerlo. Por ejemplo, en A1:
      =IZQUIERDA(A2;ENCONTRAR("feat ";A2)-1)
      en B1:
      =DERECHA(A2;LARGO(A2)-ENCONTRAR("feat ";A2)-4)

      repetir y anidar con SI.ERROR para controlar los otros dos casos para fetauring o ft.

      En todo caso, en VBA sería similar...

      Saludos

      Eliminar
  3. Hola que tal, me gustaría hacer una pregunta

    ¿Se podría partir texto según signos de puntuación?

    Mejor expongo la duda, tengo un userform con un windows media object donde puedo hacer capturas de tiempo y guardarlas en un label

    *Label1.Caption = WindowsMediaPlayer1.Controls.currentPositionString*

    bien con esto en label1, aparece el tiempo que tiene el video en ese momento en los siguientes formatos

    *mm:ss* (si el tiempo del video es menor de 1 hora)

    *hh:mm:ss* (si el tiempo del video es mayor de una hora)

    mi pregunta es, este tiempo que yo saco en una label, lo puedo partir y guardarlo en 3 variables independientes como numeros.

    Por ejemplo pongamos que tengo estas 2 horas (una en *hh:mm:ss* y otra en *mm:ss*)

    y estas variables (Horas, Minutos y Segundos)

    1:30:26 => Aquí al hacer la captura me gustaría que se partieran los numeros y fueran a la variable correspondiente

    segundos = 26
    minutos = 30
    horas = 1

    lo mismo por ejemplo con mm:ss,

    ej: 25:35

    segundos = 35
    minutos = 25
    horas = 0 (Se igualarán a 0 al principio de la función despues de declarar las variables)

    muchas gracias por tu ayuda

    ResponderEliminar
    Respuestas
    1. Hola Daniel, por que no usas las funciones Hour, Minute y Second sobre el valor de label1.caption,
      para asegurarte que detecta bien la hora completa, anídalo en TimeValue
      sec=second(timevalue(label1.caption))

      debería funcionar
      Saludos

      Eliminar
  4. Hola de nuevo, pues si, la verdad es que funciona y bastante bién ha de decir, muchas gracias.

    Sin embargo, esto me ha llevado a otro problema -.-

    Aquí te pongo el código:

    Private Sub Test_Click()

    Dim hora As Integer
    Dim minuto As Integer
    Dim segundo As Integer

    If Len(Label1.Caption) = 5 Then

    minuto = hour(TimeValue(Label1.Caption))
    segundo = Minute(TimeValue(Label1.Caption))

    MsgBox minuto & " este es el minuto "
    MsgBox segundo & " este es el segundo "

    Else

    hora = hour(TimeValue(LblTiempoV.Caption))
    minuto = Minute(TimeValue(LblTiempoV.Caption))
    segundo = Second(TimeValue(LblTiempoV.Caption))

    MsgBox hora & " esta es la hora "
    MsgBox minuto & " este es el minuto "
    MsgBox segundo & " este es el segundo "

    End If

    End Sub

    en principio cuando el video supera la hora, todo esto me lo muestra sin ningún problema (no aparecen ni cosas raras en los msgbox, ni me dan errores).

    esto me ha hecho que me hiciera 1 pregunta.

    después de mucho probar y trastear, he llegado a la conclusión de que el tiempo cuando es menor de 59 minutos 59 segundos (menos de una hora) detecta el tiempo como horas y minutos.

    En principio, con la solución que me monte arriba coje bién el tiempo pero... el día tiene 24 horas, al llegar al minuto 24 o más de la reproducción de video, un error del tipo 13. es la única conclusión que puedo llegar a entender.

    esto me ha llevado a 2 preguntas:

    La primera es... ¿Hay algún modo de indicarle al programa que ese tiempo anterior a la hora no lo detecte como minutos y segundos?

    Y la segunda, es... ¿hay algún modo de quitar el "límite 24" a lo de las horas?

    ResponderEliminar
    Respuestas
    1. perdón, que he hecho una errata en la primera pregunta. la pregunta es

      La primera es... ¿Hay algún modo de indicarle al programa que ese tiempo anterior a la hora *SI* lo detecte como minutos y segundos?

      Eliminar
    2. Hola Daniel,
      me alegro te funcionara ;-)

      Te diría que no trabajaras en formato tiempo, y que lo hicieras en formato decimal (como Clong), sabiendo que las horas en formato decimal van de 0 a 1, siendo 0 las 00:00:00 y las 24:00:00 sería el 1..
      así puedes trabajar sin restricción ni límites de 24 horas...
      por ejemplo, el valor 2,5 equivaldría a dos días y medio, esto es 60:00:00...

      Espero te oriente
      Slds

      Eliminar
  5. hola, gracias por responder, he estado experimentando un rato en lo que me has dicho, y se me ha ocurrido algo.

    ¿Es posible transformar el label.caption en segundos?

    me refiero, cojer el valor que capture (por ejemplo 5 minutos 50 segundos (05:50) y transformarlo en 350 segundos?

    gracias y perdona por ser tan pesado

    ResponderEliminar
    Respuestas
    1. Hola, puedes emplear la función CONVERTIR (creo en VBA es CONVERT) y pasar de 'day' a 'sec'.. en la hoja de cálculo sería:
      =CONVERTIR(celda;"day";"sec")
      saludos

      Eliminar
  6. Hola que tal estoy trabajando con vb y un archivo .csv tengo que cargar el contenido del archivo
    "652394532592467968,"","","2015-10-09 08:05:52 +0000","Twitter Web Client","Hay ocasiones en la que mejor prevalecer ‪#‎Sisepuede‬ y seguir adelante.","","","","" Estas es linea y puede tener N numeros de lineas. de esta linea solo quiero Hay ocasiones en la que mejor prevalecer #Sisepuede y seguir adelante El comentario estoy trabajando con Split ojala puedan ayudarme. gracias

    ResponderEliminar
    Respuestas
    1. Hola Juan,
      el trabajo es similar al que se plantea en la explicación del post, ya que debes usar Split con el separador coma (,)..
      Entenderé que la distribución de datos en cada fila es la misma.. es decir, que el texto contenido en la fila está en la posición sexta.. en ese caso, para recuperarlo emplearíamos:
      matriz=split(fila completa,",")
      msgbox matriz(5)

      matriz(5) te devolverá el dato buscado.
      Saludos

      Eliminar
    2. gracias me fue de gran ayuda

      Eliminar
  7. Buenas mi pregunta es la siguiente tengo la siguiente información 35,0;56,0;45,0;70,0 necesito sepáralo cada vez que llega al ";" ósea 35,0 en una celda 56,0 en otra y así sucesivamente lo que trató de hacer es un conteo de votos donde: 35,56,45 y 70 representan un partido y los "0" él número de votos ósea él partido 35 tiene 0 votos pero después puede pasar de 35,0 a 35,10 y sin importar él número de votos siempren se vean reflejados en la celda; muchas gracias.

    ResponderEliminar
    Respuestas
    1. Hola,
      entiendo quieres hacerlo en un contexto de programación.. si es así, emplea la función descrita en este post: Split
      celdas=split(celda con datos,";")

      Revisa el ejemplo por que sería equivalente.
      Saludos

      Eliminar
  8. hola Ismael,
    tengo un problema y no se como hacerlo, ya que recién estoy empesando a programar, mi problema es el siguiente:
    tengo varias celdas con textos separados por comas, el cual me piden que odene por filas quedando de esta forma.
    texto1 casa, habitaciones, edificio, oficinas
    texto2 licuadora, frutas, molino , grano,fiesta patrias, andera

    casa habitacion
    edificio oficinas
    licuadora frutas
    molino grano
    fiestas patrias bandera

    ResponderEliminar
    Respuestas
    1. Hola Eduardo,
      aunque no termino de ver la regla que se debería seguir (me despista el último elemento -bandera-)... parece que la idea general sería separa por pares de elementos de cada celda.

      Obviamente sería necesario aplicar una macro que realizara la acción.

      Lo tendré en cuenta para un futuro post que suba al blog.

      un saludo

      Eliminar
    2. exacto, es una separación por pares; se tendría que implementar una macro.

      gracias por tomar en cuenta, y prácticamente espero que puedas implementar una macro con esa idea; por mi parte seguiré intentando.


      Saludos

      Eliminar