在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议两种替代方法:
-
将已过滤范围的可见单元格复制到新工作表中并在其中执行查找:
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。
-
将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到的数据行,然后你可以从那行的第三列中得到你所需要的。
取决于你的范围的大小取决于更快。