我是Excel VBA的新手,我来自更传统的编程背景(Java,C)。我在将用户定义函数中的Range对象作为参数传递时遇到问题(见下文)。我的功能的想法是采取几个参数来完成过滤范围的VLOOKUP。
我可能有几个语法问题(我不确定我的返回类型和我对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
答案 0 :(得分:1)
我想这会引起你的问题:
result = [VLOOKUP("*" & screen & "/" & strEvent & "*", newRange, 3, False)]
替换为:
result = Evaluate("VLOOKUP(*" & screen & "/" & strEvent _
& "*, " & newRange.Address & ", 3, False)")
[]
这是Evaluate
的快捷方式,它不会处理变量
如果它是直接VLOOKUP
,如下所示:
result = [VLOOKUP(D1,Sheet1!$A:$C,3,FALSE)]
它会起作用。但是,如果您正在使用示例中的变量,则必须明确说明它
请注意Evaluate
以字符串形式接受Name
参数
因此,您只需连接所有字符串,然后明确使用Evaluate
。
编辑1:其他输入
这也行不通:newRange = dataRange.AutoFilter(2, strDate)
。
要将Objects
传递给Variable
,您需要像这样使用Set
。
Set newrange = dataRange.AutoFilter(2, strDate)
另一方面,虽然返回 AutoFilter
,Range Object
方法失败。
我不能完全确定这是否真的可以完成。
继续前进,为了使你的代码有效,我猜你必须这样写:
Edit2:函数过程只返回值,而不是执行方法
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
顺便说一句,为了更快,更简单的方式,尝试波特兰发布的内容。
答案 1 :(得分:1)
VLOOKUP会忽略对数据的任何过滤。换句话说,VLOOKUP也会查看隐藏的行。
我建议采用两种替代方法:
将过滤范围的可见单元格复制到新工作表并在那里执行查找:
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中的值存储在变量数组中并循环搜索所需的值:
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
答案 2 :(得分:0)
基本上你必须写:
Getvalue = Application.VLookup( StringVar, RangeVar, ColumnNumberVar)
Vlookup需要您的数据先前按字母顺序排序,否则无效。
使用VBA阵列,Excel开发人员的方法也很好。 我还可以指出VBA函数FIND和MATCH,它将为您提供搜索数据行,然后您可以从该行的第3列中提取所需内容。
以较快的速度取决于你的范围大小。