VBA vlookup参考在不同的表中

VBA vlookup参考在不同的表中,vba,excel,Vba,Excel,在Excel2007中,我将遍历表2中第4列的值。仍然在第2页中,我想将vlookup公式的结果输出到第5列。vlookup公式需要参考表1,其中参考列为。为了做到这一点,我有以下公式 Range("E2") = Application.WorksheetFunction.VLookup(Range("D2"), _ Worksheets("Sheet1").Range("A1:C65536"), 1, False) 问题,它返回错误代码1004。我读到这是因为我需要在运行

在Excel2007中,我将遍历表2中第4列的值。仍然在第2页中,我想将vlookup公式的结果输出到第5列。vlookup公式需要参考表1,其中参考列为。为了做到这一点,我有以下公式

Range("E2") = Application.WorksheetFunction.VLookup(Range("D2"), _
          Worksheets("Sheet1").Range("A1:C65536"), 1, False)
问题,它返回错误代码1004。我读到这是因为我需要在运行公式之前选择表1,例如:

ThisWorkbook.Worksheets("Sheet1").Select
但是,搜索的值范围D2不属于表1,并且在将表1带入视图后仍然返回代码1004

在这种情况下,引用其他工作表的正确方法是什么?

尝试以下方法:

Dim ws as Worksheet

Set ws = Thisworkbook.Sheets("Sheet2")

With ws
    .Range("E2").Formula = "=VLOOKUP(D2,Sheet1!$A:$C,1,0)"
End With

End Sub
这只是你想要的东西的简化版本。 如果只输出范围2中的答案,则无需使用应用程序

如果你想坚持你的逻辑,声明变量。 例如,见下文

Sub Test()

Dim rng As Range
Dim ws1, ws2 As Worksheet
Dim MyStringVar1 As String

Set ws1 = ThisWorkbook.Sheets("Sheet1")
Set ws2 = ThisWorkbook.Sheets("Sheet2")
Set rng = ws2.Range("D2")

With ws2
    On Error Resume Next 'add this because if value is not found, vlookup fails, you get 1004
    MyStringVar1 = Application.WorksheetFunction.VLookup(rng, ws1.Range("A1:C65536").Value, 1, False)
    On Error GoTo 0
    If MyStringVar1 = "" Then MsgBox "Item not found" Else MsgBox MyStringVar1
End With

End Sub

希望这是您的开始。

您的代码运行良好,提供了Sheet2中的值!D2存在于表1中!答:答:如果没有,则引发错误1004

要处理此情况,请尝试

Sub Demo()
    Dim MyStringVar1 As Variant
    On Error Resume Next
    MyStringVar1 = Application.WorksheetFunction.VLookup(Range("D2"), _
      Worksheets("Sheet1").Range("A:C"), 1, False)
    On Error GoTo 0
    If IsEmpty(MyStringVar1) Then
        MsgBox "Value not found!"
    End If

    Range("E2") = MyStringVar1

End Sub
回答您的问题:参考不同表格的正确方法是适当地限定您使用的每个范围。 请阅读本文及其结论,我想这将提供必要的信息

您得到的错误可能是由于查找值表2导致的!在搜索范围表1中未找到D2!A1:A65536。这可能源于两种情况:

chris nielsen指出,价值实际上并不存在

您正在搜索错误的范围。如果活动工作表是Sheet1,则使用Range2而不限定它将搜索Sheet1!D2,即使搜索的值在正确的范围内,它也会抛出相同的错误。 此项目和以下项目的代码如下:

Sub srch()
    Dim ws1 As Worksheet, ws2 As Worksheet
    Dim srchres As Variant

    Set ws1 = Worksheets("Sheet1")
    Set ws2 = Worksheets("Sheet2")

    On Error Resume Next
    srchres = Application.WorksheetFunction.VLookup(ws2.Range("D2"), ws1.Range("A1:C65536"), 1, False)
    On Error GoTo 0
    If (IsEmpty(srchres)) Then
      ws2.Range("E2").Formula = CVErr(xlErrNA) ' Use whatever you want
    Else
      ws2.Range("E2").Value = srchres
    End If
End Sub
我将指出另外几个值得注意的问题:

按照chris nielsen的做法捕获错误是一种很好的做法,如果使用Application.WorksheetFunction.VLookup,可能是强制性的,尽管它不会适当地处理上述情况2

该捕捉实际上由在单元格中输入的函数VLOOKUP执行,如果未找到所寻求的值,则错误结果在结果中显示为N/a。这就是为什么L42的第一个解决方案不需要任何额外的错误处理,它由=VLOOKUP…处理

使用=VLOOKUP。。。与Application.WorksheetFunction.VLookup根本不同:第一个留下一个公式,如果引用的单元格发生变化,其结果可能会发生变化;第二个写入一个固定值

L42的两种解决方案都适当地限定了范围

您正在搜索范围的第一列,并返回同一列中的值。其他功能也可用于此,尽管您的工作正常


自从我发布这个问题以来,已经有很多函数、宏和对象了。我处理它的方法(在这里的一个答案中提到)是通过创建一个字符串函数来处理由vlookup函数生成的错误,并返回nothing或vlookup结果(如果有)

Function fsVlookup(ByVal pSearch As Range, ByVal pMatrix As Range, ByVal pMatColNum As Integer) As String
    Dim s As String
    On Error Resume Next
    s = Application.WorksheetFunction.VLookup(pSearch, pMatrix, pMatColNum, False)
    If IsError(s) Then
        fsVlookup = ""
    Else
        fsVlookup = s
    End If
End Function

有人可能会争论错误处理的位置,或者缩短代码,但它在所有情况下都适用于我,正如他们所说,如果它没有损坏,不要尝试修复它。

为什么要使用VBA返回可以直接输入到工作表Sheets2.Range2中的公式的结果?我同意Mark的逻辑,因此我发布了一个替代代码,该代码将完全相同。但是,如果您想坚持您的逻辑,那么请尝试向数组参数添加.Value。与此类似,Application.WorksheetFunction.VlookupRangeD2,worksheetsheets1.RangeA1:C65536.Value,1,False。另外,是否返回A列中的值?在Vlookup第三个参数中使用1,它是col_index_num。@标记:这段代码包含在一个循环中,对几列进行迭代,将结果输出到字符串变量中,我将在处理完每行后将其连接到最后一列。我只是简化了代码,以避免将整个宏粘贴到此处。@L42:正如我在Mark中提到的,我正在将结果输出到一个变量中;Range2实际上是MyStringVar1,因为我有几个这样的变量/公式需要设置。我尝试过使用.value,但它使循环速度大大减慢,仍然返回1004。是的,我添加了一些符合您逻辑的内容。另外,正如我对代码的评论,如果您的搜索没有找到,Vlookup将失败并返回运行时错误1004。因此,您必须使用代码中也显示的错误处理程序来处理它。是的,使用IsEmpty检查MyStringVar1不需要添加.Value.+1。我觉得这样安全多了我刚刚意识到,我在矩阵中搜索的参考值必须在第一列,至少在创建简单公式时是这样。因此,我已经连接了基于初始需求的所有需要的值,并且效果很好。
但我将测试您的测试宏,因为我感兴趣的是在后台运行此逻辑,而不是有一个单元格公式。+1用于定义rng所属的工作表。如果声明变量并正确定义它们,则不必选择工作表。如果出现错误,这将始终返回上一次成功查找的值。至少对我来说。。