【问题标题】:Skip over function error and continue with next check (VLOOKUP)跳过函数错误并继续下一次检查 (VLOOKUP)
【发布时间】:2019-05-31 05:35:57
【问题描述】:

我正在运行一个基本的 VLOOKUP 来获取员工的电子邮件地址。

但是,当查找值输入数组中不存在的员工姓名时,会引发错误。

我添加了“On Error Resume Next”,但这只是导致其余电子邮件地址成为最后遇到的电子邮件地址,而不是继续搜索并将当前员工用作搜索变量。

我想要的是当数组中不存在搜索变量ProjectManName 时,跳过该行,然后照常继续搜索。然后我会去手动填写空的电子邮件地址。

Dim myLookupValue As Range
Dim strResult As String
Dim lngLastRow As Long
Dim lngLoop As Long
Dim ProjectManName As String

Set myLookupValue = Worksheets("Employees").Range("A1", Worksheets("Employees").Range("B1").End(xlDown))

With Worksheets("Project Summary")

    lngLastRow = .Cells(.Rows.Count, 1).End(xlUp).Row

    For lngLoop = 2 To lngLastRow
        On Error Resume Next
       ProjectManName = .Cells(lngLoop, 1).Value
       strResult = Application.WorksheetFunction.VLookup(ProjectManName, myLookupValue, 2, False)
       Range("K" & lngLoop).Value = strResult
       ActiveCell.Offset(1, 0).Select
    Next

End With

另外,对于 myLookupValue,我是否需要 Worksheets("Employees") 的第二个实例?当我不这样做时,它也会出现错误,因为范围中的第二个单元格查看的是当前工作表而不是员工工作表。

最后,如何将Range("K" & lngLoop).Value 中的“K”替换为第一个空列?

【问题讨论】:

  • 删除.WorksheetFunction部分,它将允许通过。
  • 您需要找到最后一列,以便可以替换您范围内的“K”。我建议使用Cells() 而不是Range(),因为您可以使用lc = sheets("project summary").cells(1, sheets("project summary").columns.count).end(xltoleft).column 中的数字,其中单元格中的1 是第一行(通常是标题),“lc”代表最后一列。单元格引用将是 Cells(ingLoop, lc)
  • @ScottCraner 我按照你说的做了,但仍然得到 运行时错误 '13': Type mismatch
  • 见下面 Mathieu 的回答,他告诉你为什么以及如何解决

标签: excel vba


【解决方案1】:

当查找值输入数组中不存在的员工姓名时,会引发错误。

这完全是设计使然。 Application.WorksheetFunction 函数是早期绑定的,raise 错误而不是返回它们,这完全是惯用的 VB 行为。

看起来您想要“Excel 工作表”行为,其中出错的工作表函数将返回单元格显示为 #N/AVariant/Error 值:Variant/Error 值使IsError 返回True,并且只能合法地与其他错误值进行比较,例如CVErr(xlErrNa).

像许多 COM 类型一样,Excel.Application 接口是可扩展的,这意味着可以在运行时向其中添加成员。事实证明,它通过WorksheetFunction 接口的成员进行了有效扩展,因此Application.VLookup 不仅编译得非常好(Application.AnythingWhatsoever 也是如此),它是一个后期绑定的实现,其行为与工作表函数在被工作表单元格:它返回一个Variant/Error值而不是引发一个标准的、惯用的运行时错误......假设你得到所有的参数正确(后期绑定调用不要获得 IntelliSense/autocomplete),因为如果您打错字(Option Explicit 无法拯救您)或参数错误,预计会引发错误 438 或 1004。

但是您无法捕获 String 中的返回值 - 当查找产生 Error 值时,这将是一个 类型不匹配 错误(您不能强制该类型除了Variant 之外的任何东西)。

Dim lookupResult As Variant
lookupResult = Application.VLookup(ProjectManName, myLookupValue, 2, False)
If Not IsError(lookupResult) Then
    strResult = CStr(lookupResult)
    '...
''Else
''    'lookup failed
End If

也就是说,通常应该首选早期绑定版本,仅适用于 IntelliSenseOn Error Resume Next 正确使用在这里可能会有所帮助 - 只需将查找拉入它自己的范围:

For lngLoop = 2 To lngLastRow
    ProjectManName = .Cells(lngLoop, 1).Value
    [ActiveSheet.]Range("K" & lngLoop).Value = GetProjectManager(ProjectManName)
    'ActiveCell.Offset(1, 0).Select '<~ why?
Next
Private Function GetProjectManager(ByVal name As String) As String
     Dim source As Range
     With Worksheets("Employees")
         On Error Resume Next
         GetProjectManager = Application.WorksheetFunction.VLookup(name, .Range("A1", .Range("B1").End(xlDown)), 2, False)
         On Error GoTo 0
     End With
End Function

至于 myLookupValue(坏名:应该是 myLookupRangelookupSourcelookupTable - “查找值”通常被理解/读取为您正在寻找的值) - 你 绝对确实需要对Employees 工作表的引用(不合格的Range 调用是错误1004 的一个非常好的方法) - 这并不意味着您需要取消引用该对象Worksheets 集合两次 - 如上所示...请注意,通过将查找移动到它自己的范围内,我们还消除了调用者甚至需要关心查找源表的需要。

【讨论】:

  • 我从未见过在音乐之外使用过惯用语这个词(例如,巴赫的音乐通常是巴洛克时期的惯用语),所以必须在上下文中查找...今天学到了一些新东西!
  • 感谢@MathieuGuindon 我尝试了两种方法,但都无法正常工作。但是,我在运行它时意识到我错误地定义了关于缺少 ProjectManName 的问题。我想通了另一种方式。但我很高兴你向我展示了一种我将来可以使用的不同方法。并且对错误也有很好的解释。感谢您提供有关命名约定的提示。
【解决方案2】:

将评论作为答案发布,以便于阅读。只回答多问题帖子中的最后一个问题。


您需要找到最后一列,以便可以替换您范围中的“K”。我建议使用 Cells() 而不是 Range(),因为您可以使用以下数字:

dim lc as long
lc = sheets("project summary").cells(1, sheets("project summary").columns.count).end(xltoleft).column

单元格中的“1”是第一行(通常是标题),“lc”代表最后一列。以您的示例为例,单元格引用将是 Cells(ingLoop, lc)

【讨论】:

  • 谢谢,西里尔。那工作得很好。就一个问题。当我使用右侧的最后一列时,我们为什么使用 .End(xlToLeft) 而不是 xlToRight?我看不到它是如何使用 xlToLeft 拾取右侧最后一列的。
  • @eyeScream .columns.count 将定位在最大列(约为 16,000),然后从那里将自身定位到左侧,相当于发送 ctrl + 向左键。这将指示给定行的最后一列数据(在本例中为 1)。
  • 哦,是的,这是有道理的。谢谢。
猜你喜欢
  • 2014-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-18
相关资源
最近更新 更多