在Excel中操作范围 – 返回值(错误2029)

我是一个相当新的Excel VBA,我来自一个更传统的编程背景(Java,C)。 我在传递一个Range对象作为我的用户自定义函数中的参数时遇到了问题(见下文)。 我的function的想法是采取几个参数来完成过滤范围的VLOOKUP。

我可能有几个语法问题(我不确定我的返回types和我的使用VLOOKUP),我将不胜感激这方面的一些指导。 查看结果,更多信息在我的代码中:

Public Function GETVALUE(screen As String, strEvent As String, dataRange As Range, strDate As String) As String 'ASSUMPTION: dataRange has three columns; first column contains lookup values; Second ' column contains dates for filtering; Third column contains return values Dim result As String 'remove irrelevant dates in dataRange; apply filter 'ASSUMPTION: This process should return a Range that is removes all Rows that does 'not have strDate in the second column Dim newRange As Range 'RESULT: Returns #VALUE!. I know this is not the typical := syntax I see in many 'examples but this one apparently compiles, so I use it. I comment this line out 'and try to make the other lines below work with dummy parameters or fixed ranges newRange = dataRange.AutoFilter(2, strDate) 'Now I try to use the newly filtered, "newRange" and use that in my VLOOKUP 'and return it. result = [VLOOKUP("*" & screen & "/" & strEvent & "*", newRange, 3, False)] 'I can see an Error 2029 here on Result GETVALUE = result 'RESULT: Returns #VALUE! End Function 

VLOOKUP忽略对数据的任何过滤。 换句话说,VLOOKUP也会在隐藏的行中查看。

我会build议两种替代方法:

  1. 将已过滤范围的可见单元格复制到新工作表中并在其中执行查找:

     Set newRange = dataRange.AutoFilter(2, strDate).SpecialCells(xlCellTypeVisible) set ws = worksheets.Add ws.Range("A1").Resize(newRange.Rows.Count,newRange.Columns.Count).Value = newRange.Value etc. 

请注意,这不能在一个UDF中完成,你将不得不在一个Sub。

  1. 将dataRange中的值存储在variables数组中,并循环search所需的值:

     Dim arr() as Variant arr = dataRange.Value For i = LBound(arr,1) to UBound(arr,1) If (arr(i,2) = strDate) And (arr(i,1) LIKE "*" & screen & "/" & strEvent & "*"( Then GETVALUE = arr(i,3) Exit Function End If Next 

这我觉得导致你的问题:

 result = [VLOOKUP("*" & screen & "/" & strEvent & "*", newRange, 3, False)] 

取而代之的是:

 result = Evaluate("VLOOKUP(*" & screen & "/" & strEvent _ & "*, " & newRange.Address & ", 3, False)") 

用于Evaluate快捷键[]不适用于variables。
如果是像下面这样的直接VLOOKUP

 result = [VLOOKUP(D1,Sheet1!$A:$C,3,FALSE)] 

它会工作。 但是,如果你正在用你的例子中的variables,你必须明确说明它。
请注意, Evaluate接受以stringforms的Name参数。
所以你只需要连接你所有的string,然后明确地使用Evaluate

编辑1:其他input

这不会工作: newRange = dataRange.AutoFilter(2, strDate)
要将Objects传递给Variable您需要像这样使用Set

 Set newrange = dataRange.AutoFilter(2, strDate) 

另一方面, AutoFilter方法虽然返回一个Range Object失败。
我不完全确定这是不是真的能做到。
向前迈进,为了使你的代码有效,我想你必须这样写:

编辑2:函数过程只返回值,不执行方法

 Public Function GETVALUE(screen As String, strEvent As String, rng As Range) GETVALUE = Evaluate("VLOOKUP(*" & screen & "/" & strEvent & "*, " _ & rng.Address & ", 3, False)") End Function 

为了得到你想要的,在一个Sub Procedure使用上面的函数。

 Sub Test() Dim dataRange As Range, strDate As String, myresult As String Set dataRange = Sheet2.Range("A2:E65") 'Assuming Sheet2 as property name. strDate = "WhateverDateString" dataRange.AutoFilter 2, strDate myresult = GETVALUE("String1", "String2", dataRange) End Sub 

顺便说一句,这样做的更快,更简单的方法,试试波特兰张贴。

基本上你必须写:

 Getvalue = Application.VLookup( StringVar, RangeVar, ColumnNumberVar) 

Vlookup需要您的数据先前按字母顺序排列,否则不起作用。

Excel开发人员的方法也很好,使用VBA数组。 我也可以指出VBA函数FIND和MATCH,它们会得到你search到的数据行,然后你可以从那行的第三列中得到你所需要的。

取决于你的范围的大小取决于更快。