同一工作簿多工作表Vlookup取值及IF函数类型不匹配报错问题
解决VLOOKUP跨表查找的类型不匹配问题及双表 fallback 实现
首先,咱们先理清楚你遇到的核心问题:运行时错误13(类型不匹配) 大概率是因为当VLOOKUP返回错误值(比如#NA)时,你直接用IF语句去判断这个错误值,而VBA里错误值和常规数据类型不兼容,导致判断失败。接下来我给你两种靠谱的实现方式,既能解决错误问题,又能实现「E列#NA时自动查第二个工作表」的需求。
方法一:用IsError函数处理错误值,实现双表查找
这种方式是先捕获VLOOKUP的错误结果,再决定是否去第二个表查找,完全避免类型不匹配问题:
Sub DoubleVLookup() Dim wsTarget As Worksheet Dim wsSource1 As Worksheet Dim wsSource2 As Worksheet Dim lastRow As Long Dim i As Long Dim lookupValue As Variant Dim result1 As Variant Dim result2 As Variant ' 定义工作表(根据你的实际表名修改) Set wsTarget = ThisWorkbook.Worksheets("目标表") ' 要写入结果的表 Set wsSource1 = ThisWorkbook.Worksheets("第一个查找表") Set wsSource2 = ThisWorkbook.Worksheets("第二个查找表") ' 获取目标表E列最后一行 lastRow = wsTarget.Cells(wsTarget.Rows.Count, "E").End(xlUp).Row ' 遍历E列数据(假设从第2行开始,第1行是表头) For i = 2 To lastRow lookupValue = wsTarget.Cells(i, "E").Value ' 先查第一个表,用IsError捕获可能的#NA错误 result1 = Application.VLookup(lookupValue, wsSource1.Range("A:B"), 2, False) If Not IsError(result1) Then ' 第一个表找到值,写入结果列(比如写入F列,可自行修改) wsTarget.Cells(i, "F").Value = result1 Else ' 第一个表没找到,查第二个表 result2 = Application.VLookup(lookupValue, wsSource2.Range("A:B"), 2, False) ' 第二个表找到就写入,没找到可以留空或写提示 If Not IsError(result2) Then wsTarget.Cells(i, "F").Value = result2 Else wsTarget.Cells(i, "F").Value = "无匹配值" ' 可选,也可以留空 End If End If Next i End Sub
关键说明:
- 用
Application.VLookup而不是WorksheetFunction.VLookup:前者返回错误值(比如#NA)时不会直接抛出运行时错误,而是把错误值存到变量里,方便我们用IsError判断。后者如果找不到值会直接炸错,这也是你之前可能踩的坑。 - 先判断第一个表的结果是否为错误,不是就用第一个结果,否则再查第二个表,完美实现你的需求。
方法二:用IFERROR函数直接写公式(如果不想用VBA循环,更简洁)
如果你的需求可以通过直接写入公式实现,不用VBA循环,那可以直接给目标列批量写入带IFERROR的嵌套公式:
Sub WriteDoubleLookupFormula() Dim wsTarget As Worksheet Dim lastRow As Long Dim formulaStr As String Set wsTarget = ThisWorkbook.Worksheets("目标表") lastRow = wsTarget.Cells(wsTarget.Rows.Count, "E").End(xlUp).Row ' 构建嵌套IFERROR公式:先查第一个表,失败就查第二个表,再失败返回空 formulaStr = "=IFERROR(VLOOKUP(E2,'第一个查找表'!A:B,2,FALSE),IFERROR(VLOOKUP(E2,'第二个查找表'!A:B,2,FALSE),""""))" ' 给F列批量写入公式(从第2行到最后一行) wsTarget.Range("F2:F" & lastRow).Formula = formulaStr ' 可选:把公式转成值,避免后续修改源表影响结果 ' wsTarget.Range("F2:F" & lastRow).Value = wsTarget.Range("F2:F" & lastRow).Value End Sub
为什么之前的IF代码会报错?
你之前的代码应该是直接用了类似If VLookup(...) = "#N/A"或者直接拿错误值和字符串/数值比较,而VBA里错误值(比如xlErrNA)是特殊的Variant类型,不能直接和常规类型比较,必须用IsError函数来判断,这就是「类型不匹配」的根源。
额外提示
- 记得修改代码里的工作表名称、查找范围(比如
A:B)、结果列(比如F列)为你实际的内容。 - 如果查找范围很大,建议定义具体的数据源范围(比如
wsSource1.Range("A1:B1000")),比整列查找效率更高。
内容的提问来源于stack exchange,提问作者user2574
相关产品推荐
相关产品推荐

