#vba
Вопрос:
У меня есть этот код:
Dim wsFunc As WorksheetFunction: Set wsFunc = Application.WorksheetFunction Dim ws As Worksheet: Set ws = Sheets("2012") Dim rngLook As Range: Set rngLook = ws.Range("A:M") 'within a loop currName = "Example" cellNum = wsFunc.VLookup(currName, rngLook, 13, False)
Ожидается, что VLookup не всегда найдет результат; но когда он не находит результата, строка выдает ошибку еще до того, как я смогу проверить ее на следующей строке.
Ошибка:
Ошибка во время выполнения «1004»: Не удалось получить свойство VLookup класса WorksheetFunction
Это прекрасно работает, когда результат найден. Каков здесь хороший способ обработки ошибок?
Ответ №1:
Вместо WorksheetFunction.Vlookup
этого вы можете использовать Application.Vlookup
. Если вы установите Variant
значение, равное этому, оно вернет ошибку 2042, если совпадение не найдено. Затем вы можете протестировать вариант — cellNum
в данном случае — с помощью IsError
:
Sub test() Dim ws As Worksheet: Set ws = Sheets("2012") Dim rngLook As Range: Set rngLook = ws.Range("A:M") Dim currName As String Dim cellNum As Variant 'within a loop currName = "Example" cellNum = Application.VLookup(currName, rngLook, 13, False) If IsError(cellNum) Then MsgBox "no match" Else MsgBox cellNum End If End Sub
Application
Версии функций VLOOKUP
и MATCH
позволяют проверять наличие ошибок без возникновения ошибки. Если вы используете WorksheetFunction
версию, вам нужна сложная обработка ошибок, которая перенаправляет ваш код в обработчик ошибок, возвращает следующий оператор для оценки и т. Д. С Application
помощью функций вы можете избежать этого беспорядка.
Вышесказанное можно было бы еще больше упростить с помощью этой IIF
функции. Этот метод не всегда подходит (например, если вам нужно выполнить больше/другую процедуру в зависимости от If/Then
), но в случае, когда вы просто пытаетесь определить, какое приглашение отображать в поле MSG, оно должно работать:
cellNum = Application.VLookup(currName, rngLook, 13, False) MsgBox IIF(IsError(cellNum),"no match", cellNum)
Рассмотрите эти методы вместо On Error ...
утверждений. Их обоих легче читать и поддерживать-мало что сбивает с толку больше, чем попытка следовать нескольким утверждениям GoTo
и. Resume
Комментарии:
1. 1 Намного лучше, чем принятый, (который, кстати, нуждается
Err.Clear
в «когдаErr.Number lt;gt; 0
«).2. Когда я печатаю
Application.
, Vlookup не отображается. Какая-нибудь помощь?3. @krobel, попробуйте использовать его, даже если он не заполняется автоматически. Я не могу вспомнить, сработает ли это, но попробовать стоит.
4. @Douglancy пытался, но это не работает. Не будет компилироваться.
5. @Douglancy он действительно существует. Не знаю, почему это тоже не работает… в любом случае, я использовал этот
On Error Resume Next
подход. Спасибо за внимание, тхо.
Ответ №2:
Есть способ пропустить ошибки внутри кода и продолжить цикл в любом случае, надеюсь, это поможет:
Sub new1() Dim wsFunc As WorksheetFunction: Set wsFunc = Application.WorksheetFunction Dim ws As Worksheet: Set ws = Sheets(1) Dim rngLook As Range: Set rngLook = ws.Range("A:M") currName = "Example" On Error Resume Next ''if error, the code will go on anyway cellNum = wsFunc.VLookup(currName, rngLook, 13, 0) If Err.Number lt;gt; 0 Then ''error appeared MsgBox "currName not found" ''optional, no need to do anything End If On Error GoTo 0 ''no error, coming back to default conditions End Sub
Комментарии:
1. Если функция VLookup находится в цикле for, вы можете устранить ошибку в каждом цикле, выполнив:
err.Clear
Ответ №3:
Исходя из моего ограниченного опыта, это происходит по двум основным причинам:
- Значение lookup_value (arg1) отсутствует в таблице _array (arg2)
Простым решением здесь является использование обработчика ошибок, заканчивающегося на Resume Next
- Форматы arg1 и arg2 интерпретируются неправильно
Если ваша lookup_value
переменная, вы можете заключить ее в TRIM()
cellNum = wsFunc.VLookup(ОБРЕЗКА(currName), rngLook, 13, Ложь)