excel - 跳过函数错误并继续下一次检查 (VLOOKUP)
问题描述
我正在运行一个基本的 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") 的第二个实例?当我没有这样做时,它也给出了一个错误,因为范围中的第二个单元格查看的是当前工作表而不是员工工作表。
最后,如何将“K”替换Range("K" & lngLoop).Value
为第一个空列?
解决方案
当查找值输入数组中不存在的员工姓名时,会引发错误。
这完全是设计使然。Application.WorksheetFunction
函数是早期绑定的并引发错误而不是返回它们,这完全是惯用的 VB 行为。
看起来您想要“Excel工作表”行为,其中出错的工作表函数将返回一个Variant/Error
单元格显示为的值#N/A
:该Variant/Error
值IsError
返回True
,并且只能合法地与其他错误值进行比较,例如CVErr(xlErrNa)
。
像许多 COM 类型一样,该Excel.Application
接口是可扩展的,这意味着可以在运行时向其添加成员。事实证明,它通过接口的成员进行了有效扩展WorksheetFunction
,因此Application.VLookup
不仅编译得非常好(就像 一样Application.AnythingWhatsoever
),它是一个后期绑定的实现,其行为与工作表单元格调用时的工作表函数完全相同:它返回一个Variant/Error
值而不是引发一个标准的、惯用的运行时错误...假设您正确设置了所有参数(后期绑定调用没有获得IntelliSense /autocomplete),因为如果您打错字(Option Explicit
无法保存您)或获取参数错误,预计会引发错误 438 或 1004。
但是您无法在 a 中捕获返回值-当查找产生一个值时String
,这将是一个类型不匹配Error
错误(您不能将该类型强制转换为 a 以外的任何内容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
也就是说,通常应该首选早期绑定版本,仅适用于IntelliSense。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
至于myLookupValue
(坏名:应该是myLookupRange
或lookupSource
或lookupTable
-“查找值”通常被理解/读取为您要查找的值)-您绝对需要对工作表的引用Employees
(不合格Range
的调用是一个很好的错误方法1004) - 这并不意味着您需要从Worksheets
集合中取消引用该对象两次 - 如上所示...请注意,通过将查找移动到其自己的范围内,我们还消除了调用者甚至需要关心的需要查找源表。
推荐阅读
- wix - Wix 补丁:启动应用程序或执行 CustomAction
- python - 如何删除数据框中的停用词(Python)
- joomla3.0 - Robots.txt 阻止除 Google 和合作伙伴之外的所有内容
- sql - BigQuery SQL:带 2 位小数的百分比
- php - 日期序列化后 Laravel 7 中的时区错误
- csv - 如何使用 Perl 将字符串拆分为不同的 csv 字段?
- karate - 发送不带文件名的多部分文件
- xml - 如果使用powershell与我的key = value匹配,我想删除/删除xml中节点中的属性
- node.js - 如何与winston做相关ID?
- qt - QML Swipeview 动态添加和删除页面