用户定义的函数将VLookup转换为已关闭的工作簿

时间:2015-05-21 15:16:37

标签: excel vba excel-vba

我尝试在vlookup创建用户定义函数到我的计算机上的已关闭工作簿中。以下函数在VBA中测试时可以正常工作,但在尝试使用该函数时,我在Excel中遇到#VALUE错误。有什么想法吗?我相信我可以使用VBA Evaluate功能来帮助,但到目前为止还没有运气。

Function CUSIP_Deal_Map(CUSIP As String, DataField As String) As Variant

Dim colIndex As Integer ' for vlookup
Dim invalidDataField As Boolean
invalidDataField = False

' Switch statement, to transform from a "DataField" into a column number to be used in VLookUp

Select Case DataField
   Case "Deal"
      colIndex = 2
   Case "Class"
      colIndex = 5
   Case "DealNum"
      colIndex = 6
   Case "Vintage"
      colIndex = 11
   Case "Pool"
      colIndex = 12
   Case "Index"
      colIndex = 13
   Case Else
      invalidDataField = True
   End Select

'Dim wbk As Workbook
Set wbk = Workbooks.Open("C:\CUSIP_Map.xlsx") 'hard code location

Dim VLU_data As Variant
VLU_data = wbk.Application.WorksheetFunction.VLookup(CUSIP, Worksheets("CUSIP_Map").Range("A:M"), colIndex, False) 'vlookup data from "database"

Call wbk.Close(False) 'close connection

' Return data
If invalidDataField Then
    CUSIP_Deal_Map = "Invalid DataField"
Else
    CUSIP_Deal_Map = VLU_data
End If

End Function

Excel中的预期用途是使用类似=CUSIP_Deal_Map("123ABC","Deal")

的公式

我可以在VBA中使用此代码对其进行测试,该代码返回我期望的值:

Sub test()
MsgBox CUSIP_Deal_Map("123ABC", "Deal")
End Sub

尽管如此,这在Excel本身并不起作用。我在网上发现了一个"pull" UDF似乎做了类似的事情,但是为了我的目的而修改它却没有成功。

2 个答案:

答案 0 :(得分:2)

这是因为来自Sub中的 UDF()调用可以打开文件,但是从工作表单元调用的 UDF()不能。

修改#1:

  • 确保 UDF 位于标准模块中。
  • 位于模块的最顶层,包括Public wbk as Workbook
  • 在工作簿代码区域中创建工作簿打开事件宏以打开辅助工作簿并初始化wbk

答案 1 :(得分:0)

好的,由于Gary's Student已经提供了限制,您可能想要重新考虑UDF的想法。使用封闭的 CUSIP_Map 工作表的第一行中的Select Case语句中的值,这些标准工作表公式中的任何一个都可以。

=VLOOKUP(A1, 'C:\[CUSIP_Map.xlsx]CUSIP_Map'!$A:$M, MATCH("Vintage", 'C:\[CUSIP_Map.xlsx]CUSIP_Map'!$1:$1, 0), FALSE)

=VLOOKUP(A1, 'C:\[CUSIP_Map.xlsx]CUSIP_Map'!$A:$M, LOOKUP("Class", {"Class","Deal","DealNum","Index","Pool","Vintage"}, {5,2,6,13,12,11}), FALSE)

A1将是在CUSIP_Map的列A中查找的值。而不是VBA选择案例,要返回的列由第一行列标题的MATCH function或硬盘确定已编码的LOOKUP function文本和列号。请注意,LOOKUP的值按升序排列,并且它可能没有MATCH那么多的错误控制,因为它会尝试部分匹配。作为包装器的IFERROR function可以返回" Invalid DataField"关于MATCH错误。