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

时间:2014-03-25 00:23:38

标签: excel excel-vba user-defined-functions vba

我是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

3 个答案:

答案 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也会查看隐藏的行。

我建议采用两种替代方法:

  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.
    
  2. 请注意,这不能在UDF中完成,您必须在Sub中执行此操作。

    1. 将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列中提取所需内容。

以较快的速度取决于你的范围大小。