Esta es una variante de la función Buscar o Vlookup de Excel que me he implementado para poder darle mayor flexibilidad a mis hojas excel. Se llama VLOOKUP Modificado y con la que se pueden realizar búsquedas condicionales.
Como no soy experto en VBA, la función puede tardar mucho en ejecutarse si se utiliza sobre mucha cantidad de filas. Aunque está diseñada para que realice las menos iteraciones posibles en el bucle. No se ha implementado con ningún algoritmo de búsqueda avanzado.
La función sería:
'VLOOKUP que busca la celda proporcionada en otra columna (col_n) que no sea la 1a, y devuelve el resultado de la columna (col_result) 'col_resultado = numero de la columna resultado a devolver 'col_n = numero de la columna sobre la que hacemos la buqueda Function VLOOKUP_ncol(valor_buscar As Variant, rango As Range, col_n As Integer, col_result As Integer) Dim CurCell As Variant For Each f In rango.Rows If (f.Cells(1, col_n) = valor_buscar) Then CurCell = f.Cells(1, col_result) Exit For End If Next f VLOOKUP_ncol = CurCell End Function
Usando el algoritmo de búsqueda rápida sería lo siguiente, pero sólo sería aplicable si la columna sobre la que buscamos está ordenada ascendentemente:
(De momento sólo la he probado con una columna de búsqueda de tipo Number)
Function VLOOKUP_ncol(valor_buscar As Variant, rango As Range, col_busq As Integer, col_result As Integer) ' Usa algoritmo de búsqueda rápida ' Descripción de los parámetros: ' - valor_buscar: Valor a buscar en la columna "col_busq" ' - rango: rango sobre el que buscar. Debe ser un rango finito: 'Sheet1'!H$2:P$253 ' - col_busq: Columna sobre la que se hace la búsqueda de "valor_buscar" ' - col_result: Columna resultado que se quiere obtener ' Los valores de col_busq y col_result van de 1..N ' Ejemplo: ' =VLOOKUP_bin(P33;'Sheet1'!H$2:P$253;9;1) Dim result, izq, der, cen As Integer izq = 0 der = rango.Rows.Count - 1 result = "" Do While (izq <= der) cen = (izq + der) / 2 If (rango.Columns(col_busq).Cells(cen, 1) = valor_buscar) Then result = rango.Columns(col_result).Cells(cen, 1) Exit Do End If If (valor_buscar > rango.Columns(col_busq).Cells(cen, 1)) Then izq = cen + 1 Else der = cen - 1 End If Loop VLOOKUP_ncol = result End Function
El VLOOKUP original de Excel te obliga a buscar sobre la primera columna del rango de búsqueda. Con esta función podemos buscar sobre cualquier columna del rango y devolver la columna que queramos.
Herramienta ExcelFIX
Repara tus archivos Excel en menos de 15 minutos y recupera tu información fácilmente. Pruébalo GRATIS.
- Garantía de devolución completa si no consigues reparar tu archivo
- Repara en menos 15 de minutos
- Soporte técnico gratuito
- Herramienta recomendada por Microsoft
- Disponible versión de prueba
Si te ha parecido interesante, pincha en la imagen para acceder a la versión de muestra que podrás descargar gratuitamente. Si decides comprarlo, me estarás ayudando a mantener el blog para poder seguir escribiendo artículos como este. Muchas gracias.
Buenas tardes
tengo un formulario VBA el cual cuando le doy buscar un valor lo busca pero si quiero buscar otro con el mismo valor no lo hace solo registra el primer dato que encuentra. trabaja como buscarV. pero me gustaria que hiciera varias busquedas en una columna con varios nombre iguales.
Ejemplo si quiero buscar carlos en una culumna y hay varios carlos no se traslada a la siguiente celda sino que busca el primer dato encontrado me gustaria que funcionara como el buscado de excel. que se traslada a la siguiente celda si hay otro valor igual.
tengo este codigo. espero que me puedan ayudar.
Private Sub BUSCAR3_CON_Click()
Dim ID_nombre, IDBUSCAR As String
Dim fila As Integer
fila = 5
ID_nombre = CAJA_30
Do While IDBUSCAR ID_nombre
fila = fila + 1
Sheets("registro").Select
IDBUSCAR = Range("E" & fila).Value
If IDBUSCAR = Empty Then
MsgBox "no se encontro el dato"
Exit Do
End If
Loop
Dim servicio, id As String
servicio = Range("a" & fila).Value
CBO_SERVICIO_2 = servicio
CAJA_13.SetFocus
Dim i As Integer
If CAJA_30.Text = "" Then
MsgBox "FIND CARGA BLANCO", vbInformation + vbOKOnly
CAJA_30.SetFocus
Exit Sub
End If
End Sub
Hola Gonzalo. Estoy un poco liado y ahora no tengo tiempo para hacerte un ejemplo, pero la idea es sencilla. Bajo el bucle principal que recorra toda la columna pon una variable que guarde el nº de la fila donde se encontró el valor en esa iteración, y si en la siguientes iteraciones lo vuelves a encontrar, pues machacas el valor de esa variable con el nº de la nueva fila. La condición para salir del bucle será hasta que no haya datos en la columna, que eso lo sabes con "rango.Rows.Count". Espero que esto pueda guiarte y consigas lo que necesitas. Un saludo.