2013-09-29 118 views
1

我有一个excel公式,我经常用它来做VLookup。它有一个嵌入式Index/Match,它给出“M”列中的最后一个数值。
工作表式是这样的:在Excel中使用索引和匹配VBA VLookup函数

=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 

我一直在使用不同的变量类型(字符串,长,变尝试)但我似乎无法获得该功能的工作。
我不知道这是否足够的信息,但任何人都可以看到我是否失去了一些东西?
我只得到#VALUE!
使用Excel 2013在Windows 7

+0

在进入VBA之前,你的excel函数返回正确的结果吗? – sam092

+0

单步执行代码并确定** 1)**是分配给“LookupRange”的值是否正确? ** 2)**是否正确指定给'indexVar'的值? –

+0

@ sam092 - 我的原始公式正确运行。 – Brad

回答

2

但是也有一些在你的描述赔率一些问题与此代码。

  • LookupRange是一个变体数组。当我测试这个时,它会在indexVar的分配中产生一个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没有数值,这将返回一个错误,例如,把在Current()细胞M2使得的M1:M2查找范围,其中我没有数字数据。

enter image description here

我不知道你想怎么处理这一点,但我的答案包括以避免错误的方法之一。您可以根据需要进行修改。最后:

  • 依赖于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 

UPDATE自评

您可以在变量声明前添加Application.Volatilelink。这应该强制重新计算:

无论何时在工作表上的任何单元格中进行计算。

但是,当其他工作表上的值(例如,Worksheets("Info")是另一个工作表)更改时,这不会强制计算。

要强制重新计算每次含有活性的=Current(Row())功能的表,你可以把这个工作表的代码模块中:

Private Sub Worksheet_Activate() 
    Me.Calculate 
End Sub 

这可能是接近你可以得到 - 要复制的原生VLOOKUP功能,而不实际使用VLOOKUP公式。

其他注意事项:

正确偏袒/强类型的变量,我宣布indexVar as Long,创造9.99999999999999E+307一个双精度变量(它只是更容易这种方式进行工作)。我也创建了一个工作表对象变量,我发现它们更容易处理。

+0

这工作并给了我正确的信息。有趣的是,它不会重新计算它是否会发现变化的数字。这是因为索引/匹配吗? – Brad

+0

它会更新,如果我进入单元格,但不是其他Vlookup函数本身。这是因为索引/匹配只在函数进入时才执行一次? – Brad

+0

这不是'Vlookup'函数:)它只是使用'Vlookup'方法来搜索匹配的偏移值。我会在我的回答中添加一些额外的评论,以澄清/建议你可能做什么。 –