2012-01-24 4 views
2

Итак, я представлю, что я все еще очень новичок в VBA. Я набрал этот код, насколько мог, и был горд. Я решил добавить некоторые дополнительные функции. Самая последняя функция, которую я хотел, - захватить определенную информацию, когда произошла ошибка, и отобразить их в окне сообщения.Excel VBA Обработка ошибок не выполняет свою работу

Что делает код:

У меня есть две книги. Wkbook1 заполнен множеством элементов данных, а Wkbook2 является основным списком. Код выполняет поиск первой строки в wkbook1 и выполняет поиск этой фразы в Wkbook2, а затем инициализирует ее слева. Иногда повторяются элементы, и мой «DO LOOP» позаботится об этом. Моя проблема заключается в том, что не все элементы присутствуют в главном списке, и я должен знать, какие из них нет.

Я установил его так, чтобы при появлении сообщения об ошибке, поскольку он не смог найти элемент в главном списке, он перешел к моему обработчику ошибок и сохранил элит в моей переменной сообщения, которая будет использоваться позже с сообщением коробка.

Я тестировал его на других книгах с элементами данных, и если есть 0 или 1 элемент, который не найден, он работает, но если в главном списке не найдено более 1 элемента, это дает мне ошибку времени выполнения 91 на второй элемент не найден. Я уверен, что в моем коде есть много критических замечаний, поэтому, пожалуйста, успокойтесь. Это мой первый раз с использованием массивов.

Код:

Option Explicit 

Sub M2_Name_Finder() 

Dim x As String 
Dim y As Integer 
Dim z As Integer 
Dim c As Integer 
Dim m As Integer 
Dim name As String 
Dim rngCopy As Range 
Dim numRows As Long 
Dim rAddress As String 
Dim found(50) As String 
Dim previous As String 
Dim missingFields As String 
Dim message As String 

name = "JJP" 

Windows("Wbook1").Activate 
Range("D3").Select 

Set rngCopy = ActiveCell.CurrentRegion 
numRows = rngCopy.Rows.Count 

For z = 1 To numRows 

    Windows("Wkbook1").Activate 
    Range("D3").Select 
    ActiveCell.Offset(y, 0).Select 
    x = ActiveCell.Value 

    If x = vbNullString Or x = " " Then 
    GoTo Done 
    End If 

    If x = previous Then 
    GoTo Here 
    End If 

    previous = ActiveCell.Value 
    Windows("Wkbook2").Activate 
    Columns("D:D").Select 

    On Error GoTo Missing: 
    Selection.Find(what:=x, After:=ActiveCell, LookIn:=xlFormulas, LookAt _ 
    :=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase _ 
    :=False, SearchFormat:=False).Activate 

    found(c) = ActiveCell.Address 
    rAddress = ActiveCell.Address 

    If ActiveCell.Value <> Empty Or ActiveCell.Value <> 0 Then 

    Do 
     ActiveCell.Select 
     ActiveCell.Offset(0, -3).Value = name 
     c = c + 1 
     Cells.FindNext(After:=ActiveCell).Activate 
     found(c) = ActiveCell.Address 
    Loop While found(c) <> rAddress 

    End If 

    Here: 
    c = 0 
    y = y + 1 

Next z 

Missing: 
message = message & x 
m = m + 1 
GoTo Here: 

Done: MsgBox "Not found: " & message & vbLf, vbInformation 

End Sub 
+0

Это хорошая история, но в чем ваш вопрос? – JohnFx

+0

Ha. Да, должно быть, было немного более ясно, я думаю. Мой вопрос: как я могу обработать ошибку? Он не работает, если отсутствует более 1 элемента данных. Мне нужно захватить элементы данных, которые не найдены в главном списке, и хотите отобразить их в окне сообщения после завершения программы. Он делает это сейчас, если только один элемент данных не найден. Не знаю, почему я получаю сообщение об ошибке, если есть более 1 ... Помощь вообще? – Leon

+1

У Чипа Пирсона есть отличная статья об обработке ошибок в VBA по адресу http://www.cpearson.com/Excel/ErrorHandling.htm – Jesse

ответ

4

Да, есть много вещей, которые я хотел бы предложить изменения о вашей функции. Пока, хотя я просто коснусь конкретной проблемы, с которой вы сталкиваетесь. :-)

Проблема в том, что при первом входе в обработку ошибок, когда вы используете GoTo, чтобы вернуться к обычному коду, вы не оставили обработчик ошибок. Таким образом, во второй раз, когда вы получаете сообщение об ошибке, он поднимается из обработчика ошибок пользователю. Вместо этого вам нужно использовать Resume. Resume сообщает системе, что вы закончили обработку ошибки и возвращаетесь к выполнению обычного кода.

Missing: 
    message = message & x 
    m = m + 1 
    Resume Here: 
+0

Не говоря уже о том, что goto предполагает, что каждая ошибка исходила из того же места. – JohnFx

+0

Имеет смысл. Большое спасибо! – Leon

4

Я одобряю, что вы включили обработку ошибок, и у меня нет критики ответа mischab1.

Однако я не одобряю использование вами обработки ошибок, чтобы поймать ошибку, которую вы ожидаете; его там для неожиданного. Следующий код намного лучше:

Dim Rng As Range 
: 
: 
Set Rng = .... Find .... 
If Rng Is Nothing Then 
    ' The Find has failed to locate the required string 
    ' Include code for this situation 
Else 
    ' The Find has found the required string 
    ' Include code for this situation 
End If 

У вас еще есть ваши обычные ошибки неожиданностей, но с этим кодом не используются для рутинных ситуаций несостоявшейся Находки.

Вы просили нас быть нежными с вами, а mischab1 уважал ваше желание, но я собираюсь поднять один вопрос.

Если вы переключаетесь между книгами и рабочими листами и используете выбор и активацию, ваш код будет чересчур, потому что экран постоянно перекрашивается.Вы можете увеличить скорость в том числе:

Application.ScreenUpdating = False 

в начале и

Application.ScreenUpdating = True 

в конце.

При переключении книг по-прежнему будет вспышка, но большая часть активности экрана будет устранена.

Однако было бы лучше устранить Select и Activate. Просмотрите последние месяцы или два вопроса и ответы. Многие (возможно, большинство) не будут содержать ничего интересного, но многие вопросы приходят от новичков, а некоторые ответы включают отличный код для обработки нескольких рабочих листов и книг и копирования данных от одного к другому. Я считаю, что изучение этих ответов быстро погасит ваше время обучения.

Счастливое программирование!

+0

Большое спасибо за ввод. Я сам преподаю и изучаю, когда я иду. Спасибо за советы! – Leon

+3

Добро пожаловать; мы все были новичками. Я думаю, что программирование - это как вождение. В конце первого урока мы знаем, что мы НИКОГДА не сможем одновременно управлять шестерней, колесом, индикатором и тремя педалями. Но через пару месяцев мы не помним, в чем была суета. Всегда будет что-то еще, чтобы узнать о программировании, но ваша зона комфорта будет становиться все больше и больше. –

Смежные вопросы