Excel VBA Обработка ошибок не выполняет свою работу - PullRequest
2 голосов
/ 24 января 2012

Итак, я предскажу, что я все еще новичок в 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

Ответы [ 2 ]

4 голосов
/ 25 января 2012

Я подтверждаю, что вы включили обработку ошибок, и я не критикую ответ 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. Просмотрите последний месяц или два вопроса и ответов. Многие (возможно, большинство) не будут содержать ничего интересного, но многие вопросы задаются новичками, и некоторые ответы включают отличный код для обработки нескольких рабочих листов и рабочих книг и копирования данных из одной в другую. Я считаю, что изучение этих ответов быстро окупит ваше учебное время.

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

4 голосов
/ 25 января 2012

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

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

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