Uso de la función Index and Match en Excel VBA VLookup
Frecuentes
Visto 61,456 veces
1
Tengo una fórmula de Excel que uso a menudo que hace un VLookup
. Tiene un incrustado Index/Match
que da el último valor numérico en la columna "M".
La fórmula de la hoja de trabajo es esta:
=VLOOKUP(INDEX($M$10:$M75,MATCH(9.99999999999999E+307,$M$10:$M75)),Data,4)
Celular $M75
siendo la celda de la fila en la que se encuentra esta fórmula. Hay celdas numéricas, no numéricas y en blanco en la Columna M, pero las ID que quiero son siempre numéricas.
Así que estoy tratando de escribir una función personalizada que me permita simplemente escribir =current()
Esto es lo que tengo:
Function Current()
Dim LookupRange As Variant
Dim indexVar As Variant
LookupRange = Range("$M$1:M" & ActiveCell.Row)
indexVar = Application.Index(Range(LookupRange), Application.Match(9.99999999999999E+307, Range(LookupRange)))
Current = Application.WorksheetFunction.VLookup(indexVar, Worksheets("Info").Range("Data"), 4)
End Function
He intentado usar diferentes tipos de variables (String, Long, Variant) pero parece que no puedo hacer que la función funcione.
No sé si esto es suficiente información, pero ¿alguien puede ver si me estoy perdiendo algo?
Solo consigo #VALUE!
Usando Excel 2013 en Windows 7
1 Respuestas
3
Hay algunos problemas con este código que no concuerdan con su descripción.
LookupRange
es una matriz variante. Cuando pruebo esto, plantea un1004 Method 'Range' of object '_Global' failed
error en la asignación aindexVar
.- Si yo
Dim LookupRange As String
según sus comentarios, también recibo unType Mismatch
error.
Como LookupRange
debe ser un rango, lo declaro como un rango, y uso el Set
palabra clave en la instrucción de asignación.
Set lookupRange = Range("$M$10:$M" & ActiveCell.Row)
- Posible error tipográfico en su asignación a
lookupRange
. En su fórmula, originalmente usa$M$1
, pero en la función que usas$M$10
.
Si comienza este rango en $M$10
e intente evaluar la fórmula en cualquier celda entre las filas 1-9, obtendrá un error.
En una nota relacionada, si no hay valores numéricos en el capítulo respecto a la lookupRange
, esto devolverá un error, por ejemplo, poniendo Current()
en la celda M2
hace un rango de búsqueda de M1:M2
, donde no tengo datos numéricos.
No estoy seguro de cómo quiere manejar esto, pero mi respuesta incluye una forma de evitar ese error. Puede modificar según sea necesario. Finalmente:
- Confiando en
ActiveCell.Row
parece una mala idea, ya que esta fórmula puede volver a calcular con resultados no deseados.
En su lugar, haga de este un argumento requerido para la fórmula, que luego puede llamar desde la hoja de trabajo como: =Current(Row())
.
Poniéndolo todo junto, creo que esto debería funcionar, y proporciono un ejemplo/escape para el error de coincidencia no encontrada. :
Public Function Current(r As Long)
Const bigNumber As Double = 9.99999999999999E+307
Dim wsInfo As Worksheet: Set wsInfo = Worksheets("Info")
Dim lookupRange As Range
Dim indexVar As Long
Dim myVal As Variant
Set lookupRange = Range("$M$1:$M" & r)
If Not Application.WorksheetFunction.Sum(lookupRange) = 0 Then
indexVar = Application.Index(lookupRange, Application.Match(bigNumber, lookupRange))
myVal = Application.WorksheetFunction.VLookup(indexVar, wsInfo.Range("Data"), 4)
Else:
myVal = "No numbers found in: " & lookupRange.Address
End If
Current = myVal
End Function
ACTUALIZAR DESDE COMENTARIOS
Puede añadir Application.Volatile
aquí antes de las declaraciones de variables. Esto debería obligar a volver a calcular:
siempre que se produzca un cálculo en cualquier celda de la hoja de cálculo.
Sin embargo, esto no forzará el cálculo cuando los valores en otras hojas de trabajo (por ejemplo, su Worksheets("Info")
es otra hoja de trabajo) cambio.
Para forzar el recálculo cada vez que activa la hoja que contiene el =Current(Row())
función, podría poner esto en el módulo de código de la hoja de trabajo:
Private Sub Worksheet_Activate()
Me.Calculate
End Sub
Esto es probablemente lo más cerca que puede estar: de replicar el nativo VLOOKUP
funcionalidad sin utilizar realmente un VLOOKUP
fórmula.
Notas adicionales:
Favoreciendo las variables correctamente/fuertemente tipadas, declaro indexVar as Long
y crea una variable de doble precisión para 9.99999999999999E+307
(es más fácil trabajar de esta manera). También creo una variable de objeto de hoja de trabajo, nuevamente, me resulta más fácil trabajar con ellos.
Respondido 14 Jul 15, 19:07
Eso funciona y me da la información correcta. Lo interesante es que no vuelve a calcular si el número que habría encontrado cambia. ¿Es esto debido al índice/coincidencia? - Brad
Se actualizará si entro en la celda, pero no por sí mismo como lo hacen otras funciones de Vlookup. ¿Esto se debe a que el índice/coincidencia solo se ejecuta una vez cuando se ingresa la función? - Brad
Esto no es un Vlookup
función :) es simplemente usar el Vlookup
para buscar un valor de desplazamiento coincidente. Agregaré algunos comentarios adicionales a mi respuesta para aclarar/sugerir lo que podría hacer. - david zemens
Si esto resuelve su problema, @Brad, marque la respuesta como "Aceptada". ¡Salud! - david zemens
Gracias por toda tu ayuda. Es extraño porque tengo una función que usa el mismo método vlookup, excepto que en lugar de calcular 'indexVar' con índice/coincidencia, le doy una celda que contiene una fórmula de índice/coincidencia. Y eso vuelve a calcular cada vez que hay un cambio. - Brad
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas excel vba excel-formula vlookup excel-2013 or haz tu propia pregunta.
Antes de ir a VBA, ¿su función de Excel devuelve resultados correctos? - sam092
Revise su código y determine 1) es el valor asignado a
LookupRange
de acuerdo? 2) es el valor asignado aindexVar
¿correcto? - David Zemens@ sam092 - Mi fórmula original funciona correctamente. - Brad
@DavidZemens: My LookupRange muestra el rango correcto si lo convierto en una cadena. Y si convierto indexVar en una cadena y uso una macro para insertar una fórmula vLookup en una celda de mi hoja, me da el número de ID correcto. Pero las cadenas no funcionan cuando intento hacer Vlookup en VBA. - Brad
Está bien, déjame probar algunas cosas... - David Zemens