[英]Using Index and Match in Excel VBA VLookup function
我有一个excel公式,我经常使用它做一个VLookup
。 它有一个嵌入的Index/Match
,它给出“M”列中的最后一个数值。
工作表公式是这样的:
=VLOOKUP(INDEX($M$10:$M75,MATCH(9.99999999999999E+307,$M$10:$M75)),Data,4)
单元格$M75
是此公式所在行的单元格。列M中有数字,非数字和空白单元格,但我想要的ID始终为数字。
所以我试着写一个自定义函数,让我简单地写=current()
这是我有的:
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
我尝试使用不同的变量类型(String,Long,Variant),但我似乎无法使函数工作。
我不知道这是否足够信息,但任何人都可以看到我是否遗漏了什么?
我只得到#VALUE!
在Windows 7上使用Excel 2013
此代码存在一些与您的描述不一致的问题。
LookupRange
是一个变体数组。 当我测试它时,它在indexVar
的赋值中引发了1004 Method 'Range' of object '_Global' failed
错误的1004 Method 'Range' of object '_Global' failed
。 Dim LookupRange As String
,我也会收到Type Mismatch
错误。 由于LookupRange
应该是一个范围,我将其声明为范围,并在赋值语句中使用Set
关键字。
Set lookupRange = Range("$M$10:$M" & ActiveCell.Row)
lookupRange
的分配可能存在拼写错误。 在你的公式中,最初使用$M$1
,但在函数中你使用$M$10
。 如果您以$M$10
开始此范围,并尝试在第1-9行之间的任何单元格中评估公式,则会出现错误。
在相关的说明中, 如果 lookupRange
中没有数值 ,则这将返回错误,例如,将单元格M2
Current()
置于M1:M2
的查找范围内,其中我没有数字数据。
我不确定你想怎么处理这个,但我的答案包括一种避免这种错误的方法。 您可以根据需要进行修改。 最后:
ActiveCell.Row
似乎是一个坏主意,因为这个公式可能会重新计算不良结果。 相反,将其设为公式的必需参数,然后可以从工作表调用,如: =Current(Row())
。
把它们放在一起,我认为这应该工作,我提供了一个示例/转义匹配未找到错误。 :
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
评论的更新
您可以在变量声明之前添加Application.Volatile
链接 。 这应该强制重新计算:
只要在工作表上的任何单元格中进行计算。
但是,当其他工作表上的值(例如,您的Worksheets("Info")
是另一个工作表)更改时,这不会强制计算。
要在每次激活包含=Current(Row())
函数的工作表时强制重新计算,可以将其放在工作表的代码模块中:
Private Sub Worksheet_Activate()
Me.Calculate
End Sub
这可能就像你可以得到的那样 - 复制本机VLOOKUP
功能而不实际使用VLOOKUP
公式。
补充笔记:
偏好正确/强类型变量,我将indexVar as Long
声明indexVar as Long
并为9.99999999999999E+307
创建一个双精度变量(这样更容易使用)。 我还创建了一个工作表对象变量,我再次发现它们更容易使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.