domingo, 21 de noviembre de 2010

VBA: FOR EACH ... NEXT

Explicaré hoy, en relación de la cuestión planteada por un usuario, el uso de la instrucción FOR EACH ... NEXT:

...tengo una columna con dos tipos de datos, por asi decirlo son estos
45126-9
452
12457-0
14562
1214
15487
154-6
Los con guión y sin guión... es una larga columna y hasta el momento lo estaba haciendo manual (copy - paste), necesito que los numeros con guion se queden ahi,. pero los sin guión los debo trasladar a otra columna....


Ya que a priori no tenemos definido nuestro rango de datos en ningún lugar concreto, es cuando esta instrucción FOR EACH...NEXT cobra todo su sentido; puesto que ésta se utiliza para recorrer, en iteración, los elementos de la colección indicada (en nuestro caso será 'Selection').
La labor a realizar será entonces que nuestra macro repase todas las celdas del rango seleccionado, esté donde esté, evaluando si el valor de cada celda contiene el texto indicado por el lector. Comprobación que realizaremos mediante la función de VBA InStr:
InStr([start, ]string1, string2[, compare])
siendo:
  • start: valor que establece la posición inicial de la búsqueda. Si se omite, la búsqueda comienza en la posición 1. El argumento inicio se requiere si se especifica compare.

  • string1: Obligatorio. Cadena en la que se busca.

  • string2: Obligatorio. Expresión de cadena buscada.

  • compare: Especifica el tipo de comparación de cadena.

Aprovechando que el valor devuelto por la función InStr es cero si no encuentra la expresión buscada, definiremos con una instrucción IF ... THEN ... ELSE (ver)


El código siguiente se incluirá dentro del editor de VBA (Alt+F11) en un módulo, como cualquier otra macro que deseemos ejecutar, lo que nos permitirá ejecutarla en cualquier hoja activa de nuestro libro de Excel:

'macro para separar elementos de un rango en dos columnas.
Sub Reempl()
Dim celdaactual As Object
Dim posicion As Integer

For Each celdaactual In Selection
posicion = InStr(celdaactual, "-")
'si el valor de posicion es mayor a cero significará que
'la celda estudiada tiene un guión como parte de sus caracteres.

If posicion > 0 Then
Cells(celdaactual.Row, celdaactual.Column + 1).Value_
= Cells(celdaactual.Row, celdaactual.Column).Value
Cells(celdaactual.Row, celdaactual.Column).Value = ""
Else
Cells(celdaactual.Row, celdaactual.Column + 1).Value = ""
Cells(celdaactual.Row, celdaactual.Column).Value_
= Cells(celdaactual.Row, celdaactual.Column).Value
End If
Next
End Sub


Con este código conseguimos que al ejecutar la macro 'Reemp' cualquiera que sea el rango seleccionado, dejará en la columna inicial de datos con todos los registros que no tengan un guión, mientras que los valores con guión se colocarán en la columna siguiente.

4 comentarios:

  1. Alguna forma que con los comandos (sin macros) se puedan eliminar los datos de una columna? Gracias!

    ResponderEliminar
  2. Hola,
    se podría aplicar un Filtro sobre la columna, para mediante el criterio adecuado seleccionar y borrar los datos...
    Slds

    ResponderEliminar
  3. hola, en mi departamento quieren crear una macro para que en una tabla tipo lista con 13000 datos mas o menos concatene varias columnas con el objetivo de crear 3 nuevas columnas de esos datos concatenados, y otra macro que nos haga la funcion buscarv el dato de la primera columna que es el numero de expediente y nos arroje 3 buscarv sobre 3 columnas diferentes, como fecha de solicitud, importe y fecha de envio por ejemplo, donde podria buscar algo que me apoyara de alguna manera?

    ResponderEliminar
  4. Hola,
    lo más sencillo para la macro que quieres hacer es que desde la Ficha de programador grabes una macro con las acciones que quieres hacer (concatenar y ejecutar uns BUSCARV), para luego ver el código VBA generado y poder retocarlo...
    echa un vistazo a:
    http://excelforo.blogspot.com/2009/11/funcion-definida-por-el-usuario-doble.html
    y si no lo ves claro, envíame un fichero con un ejemplo a
    excelforo@gmail.com
    Slds

    ResponderEliminar