2013-09-29 117 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'方法來搜索匹配的偏移值。我會在我的回答中添加一些額外的評論,以澄清/建議你可能做什麼。 –