Hace algún tiempo vimos un ejemplo sobre como cruzar bases de datos en excel con vba, ahora veremos algo muy similar pero con un enfoque diferente, se trata de una macro para depurar bases de datos, en plantillas contables suele ser común la depuración.
En realidad la depuración de una base de datos es sencilla desde un punto de vista básico, pueden existir casos mas complicados, sobre todo cuando esta depuración se debe hacer con criterios complejos.
Básicamente lo que se tiene que hacer es recorrer las dos o mas bases de datos mediante algún ciclo, aquí lo importante es que deberá anidarse otro ciclo que contiene la base de datos a depurar, el primer ciclo debe corresponder a la base de datos que se usara como guía para la depuración.
Depurar una tabla de contactos
En este ejemplo la idea es eliminar algunos contactos de una tabla determinada.
Codigo VBA que recorre y depura las base de datos
Sub DeouraBD()
Dim r1, r2 As Range
Dim uFila1, uFila2
uFila1 = Hoja1.Cells(Rows.Count, 1).End(xlUp).Row
uFila2 = Hoja2.Cells(Rows.Count, 1).End(xlUp).Row
If Hoja2.Range("A2") <> "" Then
For Each r2 In Hoja2.Range("B2:B" & uFila2)
If Hoja1.Range("A2") <> "" Then
For Each r1 In Hoja1.Range("B2:B" & uFila1)
If r1.Value = r2.Value Then
Hoja1.Range("A" & r1.Row).EntireRow.Delete
Exit For
End If
Next r1
End If
Next r2
End If
End Sub
Explicando el codigo
Como dije anteriormente, son ciclos los que se usan para el recorrido de los datos, se inicia con un ciclo que recorrerá la tabla ( Hoja2 ) que contiene los datos que deseamos eliminar de la base de datos principal ( Hoja1 ), luego vemos un ciclo anidado que recorre precisamente los datos de la hoja1, esto para comparar con el dato activo en el ciclo para la hoja2, si el dato coincide, eso significa que deberá eliminarse de la Hoja1.
Antes de llegar a esto es necesario definir algunas variables y obtener la ultima fila con datos de cada hoja.
Las variables
Dim r1, r2 As Range
Dim uFila1, uFila2
r1 y r2 se refieren al rango que estará activo en cada iteracion de los ciclos.
uFila1 y uFila2 se refiere a la ultima fila vacia de cada hoja.
Obtener la ultima fila vacia de cada hoja.
uFila1 = Hoja1.Cells(Rows.Count, 1).End(xlUp).Row
uFila2 = Hoja2.Cells(Rows.Count, 1).End(xlUp).Row
Con esas dos lineas metemos el numero de la ultima fila de cada hoja en su variable correspondiente, esto nos servirá para obtener el rango que deberá recorrer cada ciclo, eso evita que se hagan iteraciones innecesarias.
Comprobar si hay algún dato que se desea eliminar.
If Hoja2.Range("A2") <> "" Then
Con esa linea comprobamos si en la hoja2 hay datos, esto a partir de la fila 2, si no hay nada en A2, significa que nada se eliminara, así que no se ejecuta lo que hay abajo en esa linea.
Se inicia el ciclo que itera sobre las filas de la hoja2
For Each r2 In Hoja2.Range("B2:B" & uFila2)
Con esa linea se inicia el ciclo que recorre la Hoja2, en este caso es la columna que contiene los correos, esa es la que se usara como criterio para la depuración, r2 nos dirá el dato que en ese momento este activo en la iteracion.
Comprobar si en la Hoja1 hay datos.
If Hoja1.Range("A2") <> "" Then
Con esa linea comprobamos si en la BD principal hay datos.
Recorrer la BD principal.
For Each r1 In Hoja1.Range("B2:B" & uFila1)
Con ese código se iterara sobre la tabla que contiene los datos donde la búsqueda y eliminación sera realizada, este ciclo es el que esta anidado en el anterior.
Determinar si los datos activos en cada ciclo son iguales.
If r1.Value = r2.Value Then
r1 representa el dato que en ese momento esta activo en el ciclo que recorre la BD principal, r2 representa el dato que esta activo en el ciclo que recorre la BD que contiene los datos que deseamos eliminar, el dato que devuelven en este caso r2 y r1 son los correos en ambas hojas, esto porque el rango que estamos recorriendo es en la columna B de ambas hojas.
Elimar registro si la condición se cumple.
Hoja1.Range("A" & r1.Row).EntireRow.Delete
Exit For
Con la primera linea se elimina la fila completa en la Hoja1 que en ese momento esta activa durante el ciclo, esto si la condición anterior se cumple, es decir, r1 y r2 devuelven el mismo correo.
la segunda linea hace que se salga del ciclo activo, esto para no seguir iterando puesto que el dato ya fue encontrado y eliminado, si hay registros duplicados, antes de ejecutar la macro de este ejemplo, puedes ejecutar otra que publique antes para eliminar registros duplicados.
Las lineas siguientes en el código son para cerrar los ciclos y los IF.
Elimar filas que coinciden con un dato especificado
Cabe mencionar que para este caso igual se puede usar la opción “Eliminar Duplicados” del menú datos, pero esta opción que propongo puede ser mas versátil, por ejemplo: se puede eliminar el primer ciclo for en la macro para hacer el recorrido solo en una hoja ( Hoja 1 ) y eliminar la fila cuando encuentre un nombre especifico “Logan”, quedaría de la siguiente manera esa parte.
Sub DeouraBD()
Dim r1 As Range
Dim uFila1
uFila1 = Hoja1.Cells(Rows.Count, 1).End(xlUp).Row
If Hoja1.Range("A2") <> "" Then
For Each r1 In Hoja1.Range("A2:A" & uFila1)
If r1.Value = "Logan"
Hoja1.Range("A" & r1.Row).EntireRow.Delete
Exit For
End If
Next r1
End If
End Sub
Claro que este ejemplo es considerando que es una tabla donde posiblemente se repita un dato que queremos eliminar por completo.
Adicionalmente, se pueden agregar mas condiciones, por lo que es posible hacer la depuración tomando en cuanta mas de una columna.
La siguiente condición comprueba nombre y ciudad de la persona, si ambas condiciones se cumplen se eliminara el registro.
If r1.Value = "Logan" and r1.offset(0,2)="Guadalajara"
esegovia dice
Tema muy útil, ya que nos ahorra mucho trabajo. Gracias
Antonio dice
Si quisiera no eliminar los datos sino moverlos a otra hoja (Hoja3, por ejemplo), ¿cómo sería el código?
jose camacho dice
muy buena macro……