跳过功能错误,然后继续进行下一步检查(VLOOKUP)

时间:2019-05-30 17:44:40

标签: excel vba

我正在运行基本的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”作为第一个空列?

2 个答案:

答案 0 :(得分:3)

  

当查找值输入数组中不存在的雇员名称时,它将引发错误。

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

看起来像您想要“ Excel工作表”行为,错误的工作表函数将返回一个Variant/Error值,单元格显示为#N/A: {1}}的值使Variant/Error返回IsError,并且只能与其他错误值进行合法比较,例如True

与许多COM类型一样,CVErr(xlErrNa)接口是可扩展的,这意味着可以在运行时将成员添加到其中。事实证明,它已经有效地扩展了Excel.Application接口的成员,因此WorksheetFunction不仅编译得很好(Application.VLookup一样),而且是一个后期工作,其行为与工作表完全相同当工作表单元格调用函数时,函数会执行此操作:它会返回一个Application.AnythingWhatsoever值,而不是提高一个标准的,惯常的运行时错误……假设您已获得所有参数正确(延迟调用不会获得 IntelliSense / autocomplete),因为如果您输入错误(Variant/Error无法保存您)或参数输入错误,则可能会出错438或1004。

但是您无法捕获Option Explicit中的返回值-当查询产生String值时,这将是类型不匹配错误(您可以t强制键入除Error之外的其他任何字符)。

Variant

那是说早期绑定版本通常应该是首选,因为它仅用于 IntelliSense Dim lookupResult As Variant lookupResult = Application.VLookup(ProjectManName, myLookupValue, 2, False) If Not IsError(lookupResult) Then strResult = CStr(lookupResult) '... ''Else '' 'lookup failed End If 正确使用在这里可能会有所帮助-只需将查找放入其自己的范围即可:

On 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 (错误名称:应为myLookupValuemyLookupRangelookupSource-“查找值”通常被理解/理解为您所拥有的值寻找)-您绝对会需要对lookupTable表进行引用(不合格的Employees调用是错误1004的非常好的秘诀)-这并不意味着您需要两次从Range集合中取消引用该对象-如上所示...请注意,通过将查找移入其自己的范围,我们还消除了调用者甚至不需要关心查找源表。

答案 1 :(得分:1)

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


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

Worksheets

其中单元格中的“ 1”是第一行(通常是标题),“ lc”代表最后一列。给定示例,单元格引用将为dim lc as long lc = sheets("project summary").cells(1, sheets("project summary").columns.count).end(xltoleft).column