Una de las principales tareas que usamos diariamente en Excel es buscar datos, lo hacemos constantemente con funciones como Buscar, Buscarv, Coinicidir, etc. Pero en la mayor parte de los casos lo que buscamos es un valor concreto de una tabla, dependiendo de los criterios que consideremos oportunos.
En este sentido, la función BuscarV o BuscarH, cuando hablamos de varios criterios, solo podemos realizar la búsqueda si nos apoyamos en columnas auxiliares y concatenando datos para conseguir una clave principal (valor buscado) que debe ser exactamente igual al mismo valor en la matriz de búsqueda. Se puede combinar con otras funciones como Coincidir o Encontrar (etc) de manera que podamos incluir un segundo criterio de búsqueda o realizar combinaciones con funciones matriciales complejas.
Ante estas limitaciones, podemos recurrir a VBA para generar un código que realice búsquedas con los criterios que necesitemos y que además podamos modificar fácilmente y adaptar a nuestras bases de datos.
Para realizar el ejemplo de hoy, voy a utilizar una base de datos bastante interesante en que constan los datos de matriculación de vehículos en lo que llevamos de año. Esta información está disponible en la web de la Dirección General de Tráfico.
La información del fichero es la siguiente, Marca del vehículo, Carburante y Comunidad Autónoma de Residencia. (se puede extraer más información, pero para este ejemplo, me ha parecido la más relevante), aquí está la tabla:
Estos datos los tenemos en una hoja denominada “TABLABASE” y en otra hoja que vamos a denominar «DATOS» vamos incluir algunos vehículos (Marca, Combustible y en la Comunidad Autónoma de Madrid) de los que nos interesa buscar el número de matriculaciones:
Ahora podemos utilizar la siguiente macro para realizar la búsqueda de los valores que necesitamos:
Sub BUSCAR()
Dim i As Double
Dim j As Double
Dim Marca, Carburante, Comunidad As String
'Descativamos actualizacion de pantalla
Application.ScreenUpdating = False
'Refrescamos la columna de total por cada búsqueda que hagamos
With Worksheets("DATOS")
Total = Application.CountA(.Range("D:D"))
If Total > 1 Then .Range("D2:D" & Total).ClearContents
End With
'Definimos rango de tablabase
fin = Application.CountA(Worksheets("TABLABASE").Range("A:A"))
'Definimos rango de datos
Final = Application.CountA(Worksheets("DATOS").Range("A:A"))
With Worksheets("TABLABASE")
'Iniciamos el bucle principal en tabla Datos
For i = 2 To Final
'Definimos cada uno de los Items por los que vamos a buscar
Marca = Sheets("DATOS").Cells(i, 1)
Carburante = Sheets("DATOS").Cells(i, 2)
Comunidad = Sheets("DATOS").Cells(i, 3)
'Segundo bucle en tablabase por cada item del primer bucle
For j = 2 To fin
'Buscamos con un condicional en tablabase cada una de las variables definidas
If Marca = .Cells(j, 1) And _
Carburante = .Cells(j, 2) And _
Comunidad = .Cells(j, 3) Then
'Si encontramos coincidencia, igualamos celdas con el valor de la columna 4
Sheets("DATOS").Cells(i, 4) = .Cells(j, 4)
Exit For
End If
Next
Next
End With
Application.ScreenUpdating = True
End Sub
En resumidas cuentas, lo que hace esta macro es que por cada fila de DATOS busca coincidencias a lo largo de todas las filas de TABLABASE, y si las encuentra, incluye el valor total y sale del bucle para continuar con la siguiente fila, el resultado es exactamente el dato que buscábamos:
Normalmente las búsquedas que realizo en vba las hago con este método, puede parece complejo, pero si os detenéis un poco en el análisis del código veréis que simplemente se trata de hallar correspondencias entre combinaciones de datos.
Por cierto, muy interesante la información que se puede obtener con esta base de datos 🙂
Descarga el archivo de ejemplo pulsando en: BUSCAR CON VARIOS CRITERIOS EN VBA
AGREGAR INFORMACIÓN DEL PROCESO REALIZADO EN LA EJECUCIÓN DE UNA MACRO O UN PROGRAMA EN VBA | EXCEL SIGNUM
[…] explico con un ejemplo, voy a recurrir a un pequeño ejercicio que publiqué en su día sobre cómo buscar con varios criterios en VBA. En ese proceso utilizábamos varias instrucciones for-next y eso nos vendrá muy bien para […]
Julian Valencia
Muy buen tip, muchas gracias, esta suuper!!! donde puedo ver mas tipos tuyos como este?
coromoto
Hola buenas tardes; de antemano le doy las gracias por sus publicaciones han sido de gran ayuda; tengo una pregunta refereida al siguiente tema:
-BUSCAR CON VARIOS CRITERIOS EN VBA: Publicado el 21 abril, 2016 por Segu
me gustaria saber si uno de los criterios a buscar puede ser aproximado y no exacto.
Me explico si yo tengo los siguientes criterios: Producto, Marca, Año de Vencimiento
y me gustaria saber (el dato que se va a extraer) el Precio.
y yo coloco: Producto: Cloro, Marca: x, Año: 2020
me gustaria que la macro, sino en cuentra el año 2020 de dicho producto me colocara el monto del
Producto: Cloro, Marca x; Año 2019
gracias de antemano
Segu
Hola Coromoto:
Lee detenidamente este post:
https://excelsignum.com/2017/07/20/realizar-bucles-anidados-y-buscar-valores-aproximados/
y verifica la forma de realizar las aproximaciones en la macro, ahí tendrás la respuesta.
Saludos.
alfonso
Esta esta Genial. Mcuhas gracias por compartir tus conocimientos. Saludos
Nando Pacheco
Necesito cambiar la siguiente función a una macro de Excel.
Necesito cambiar la siguiente función a una macro de Excel, esa acción será aplicada en un formulario de VBA.
Agradezco la Ayuda!
Desarollo:
=HIPERVINCULO("#"&"DETALLES!"&DIRECCION(COINCIDIR(DETALLES!E11;Tabla2[CODIGO];0)+8;COLUMNA(Tabla2);1;1))
Segu
Hola Nando:
Puedes utilizar el grabador de macros para obtener las funciones en VBA. PEro si quieres que te lo revise con detalle, envíame un ejemplo con la fórmula en un Excel a la dirección de contacto de la web: excelsignum@yahoo.es
Marlon
Excelente Amigo, le realice algunas adaptaciones a para mi caso y funciono a la primera, Gracias.
Angela Peñaranda
Hola mira tengo este codigo que me sirve para que cuando pongo un codigo en el textbox llamado buscar me busque lo que seria la descripcion lo que sucede es que quiero que cuando yo ponga este codigo ademas de buscarme la descripcion me busque tambien la referencia, no se si me entendiste
Private Sub BUSCAR1_Click()
Dim Nombre As Variant
Dim RANGO As Range
Dim NombreBuscado As Variant
Dim REFERENCIA As Variant
On Error GoTo ManejadorErrores
Set RANGO = Sheets("DATOS2020").Range("A1").CurrentRegion
NombreBuscado = Me.PRODUCTODEVUELTO.Value
If IsNumeric(NombreBuscado) Then
NombreBuscado = VBA.CDbl(NombreBuscado)
ElseIf IsDate(NombreBuscado) Then
NombreBuscado = VBA.CLng(VBA.CDate(NombreBuscado))
End If
Nombre = Application.WorksheetFunction.VLookup(NombreBuscado, RANGO, 3, 0)
With Me
.DESCRIPCION1.Value = Nombre
.Label20.Visible = False
.PRODUCTODEVUELTO.SetFocus
End With
Exit Sub
ManejadorErrores:
If Err.Number = 424 Then
With Me
.Label20.Caption = "El valor'" & NombreBuscado & "'No fue encontrado"
.Label20.Visible = True
.DESCRIPCION1.Value = ""
.PRODUCTODEVUELTO.SetFocus
End With
Else
MsgBox "Ha ocurrido un error: " & Err.Description, vbExclamation, "DATOS2020"
End If
End Sub
Private Sub BUSCAR2_Click()
Dim Nombre As Variant
Dim RANGO As Range
Dim NombreBuscado As Variant
On Error GoTo ManejadorErrores
Set RANGO = Sheets("DATOS2020").Range("A1").CurrentRegion
NombreBuscado = Me.PRODUCTOCAMBIADO.Value
If IsNumeric(NombreBuscado) Then
NombreBuscado = VBA.CDbl(NombreBuscado)
ElseIf IsDate(NombreBuscado) Then
NombreBuscado = VBA.CLng(VBA.CDate(NombreBuscado))
End If
Nombre = Application.WorksheetFunction.VLookup(NombreBuscado, RANGO, 3, 0)
With Me
.DESCRIPCION2.Value = Nombre
.Label21.Visible = False
.PRODUCTOCAMBIADO.SetFocus
End With
Exit Sub
ManejadorErrores:
If Err.Number = 424 Then
With Me
.Label21.Caption = "El valor'" & NombreBuscado & "'No fue encontrado"
.Label21.Visible = True
.DESCRIPCION2.Value = ""
.PRODUCTOCAMBIADO.SetFocus
End With
Else
MsgBox "Ha ocurrido un error: " & Err.Description, vbExclamation, "DATOS2020"
End If
End Sub
Segu
Hola Ángela:
Con ese código no puedo ayudarte (necesito ver el ejemplo en excel) y actualmente por motivos de salud estará varios días sin poder acceder. Intenta analizar ejemplos en el blog. Saludos.
Davys
Un buen aporte con este archivo para "buscar con varios criterios en VBA", pero también me surge una duda es posible tomar una sola condición por ejemplo solo la marca del automóvil y suma acumulada de los valores que posean la misma condición y es decir solo la marca de automóvil, y luego al ingresar la marcar de automóvil en la siguiente linea repita el ciclo. Realice algunos intentos modificando el código "buscar con varios criterios en VBA" pero solo realizo en forma correcta la suma acumulada de la primera marca de automóvil que introducid, cuando introduzco la segunda marca en la fila siguiente, realiza la suma pero también suma el valor de la marca que introducid anteriormente. Les envío el código para en lo posible por favor contribuir con este archivo es de gran ayuda para crear útiles reportes en diferentes áreas
Sub BUSCAR()
Dim i As Double
Dim j As Double
Dim Marca As String
'Descativamos actualizacion de pantalla
Application.ScreenUpdating = False
'Refrescamos la columna de total por cada búsqueda que hagamos
With Worksheets("Resultados")
Total = Application.CountA(.Range("D:D"))
If Total > 1 Then .Range("D2:D" & Total).ClearContents
End With
'Definimos rango de tablabase
fin = Application.CountA(Worksheets("Datos").Range("A:A"))
'Definimos rango de datos
Final = Application.CountA(Worksheets("Resultados").Range("A:A"))
With Worksheets("Datos")
'Iniciamos el bucle principal en tabla Datos
For i = 2 To Final
'Definimos cada uno de los Items por los que vamos a buscar
Marca = Worksheets("Resultados").Cells(i, 1)
'Segundo bucle en tablabase por cada item del primer bucle
For j = 2 To fin
' Buscamos con un condicional en tablabase cada una de las variables definidas
If Worksheets("Datos").Cells(j, 1) = Worksheets("Resultados").Cells(i, 1).Value Then
Suma = Suma + Worksheets("Datos").Cells(j, 2)
End If
Next
Worksheets("Resultados").Cells(i, 4).Value = Suma
Next
End With
Application.ScreenUpdating = True
End Sub
Segu
Hola Davys:
Lo que debes hacer es enviar un archivo con los datos que tengas y cómo quieres el resultado. La macro que has enviado no se ajusta al ejemplo del post.
Debería recibir un archivo y al ejecutarlo mostrar el resultado que indicas.
Saludos