Различают две ошибки, возникающие с `on error goto`, и обрабатывают их отдельно - PullRequest
0 голосов
/ 11 февраля 2019

Я работаю с тремя Word Documents.

  1. Rough
  2. CEEMEA & LATAM
  3. Ticker Graveyard

Только при запуске Rough Документ открыт.Мне нужно переместить данные с Rough на CEEMEA & LATAM и использовать Ticker Graveyard для соответствия некоторым запросам, поэтому оба CEEMEA & LATAM Ticker Graveyard уже должны быть открыты.

для этого я проверяю, оба других документа уже открыты или нет.если нет, то мне нужно открыть конкретный документ, используя Documents.Open.для этого я делаю следующее Обновленный код :

sub ErrHandling()

On Error GoTo PROBLEM
Windows("CEEMEA & LATAM").Activate ''''' Here checking CEEMEA & LATAM status
'''' after checking STATUS do some work on CEEMEA & LATAM '''''

Set doc = Application.Windows("Ticker Graveyard").Document ''''' Here checking Ticker Graveyard status
'''' after checking do some work on Ticker Graveyard '''''

Exit Sub
PROBLEM:
If Err.Number = 5941 Then
    Documents.Open FileName:="C:\Users\dell\Desktop\EMEA CEEMEA\CEEMEA & LATAM.docx" --- handling only CEEMEA & LATAM document

'''''' These lines handle Date in document while opening document''''
Selection.MoveDown Unit:=wdLine, Count:=2
Selection.EndKey Unit:=wdLine
Selection.MoveUp Unit:=wdParagraph, Count:=1, Extend:=wdExtend
Selection.TypeText Format(Date, "MMMM dd, yyyy")
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Else
MsgBox "UNEXPECTED ERROR = " & Err.Number
Exit Sub
End If

Resume Next
End Sub

Но проблема в том, что обе контрольные точки имеют одинаковый Error Number Я не могу различить их с помощью простого оператора on error goto.

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

1 Ответ

0 голосов
/ 12 февраля 2019

Существует множество стратегий для обработки ситуации, когда код должен ссылаться на конкретный объект, который может присутствовать или не присутствовать.Какой подход является «лучшим», отчасти философское соображение.Основные подходы:

  1. Запуск ошибки и ее обработка.Вот как разработан код в вопросе.При использовании VBA это также правильный подход, поскольку он может быть относительно быстрым.Однако для любого языка .NET он значительно замедлит код и не должен использоваться, если есть какая-либо другая возможность.
  2. Итерация коллекции для определения доступности рассматриваемого объекта.Если коллекция содержит много элементов, это может быть медленнее в VBA, чем подход к обработке ошибок.С другой стороны, это делает код более понятным (на мой взгляд).

Стратегия для обоих подходов изложена ниже, на основе кода в вопросе.

Обработка ошибок

В процедуре можно использовать более одной «метки» (цель для обработчика ошибок, к которой можно перейти), поэтому можно иметь «метку» для каждой отдельнойдокумент.Таким образом, для каждого документа доступен отдельный обработчик ошибок с собственной «веткой» кода.

On Error GoTo PROBLEM_CEEMA
Windows("CEEMEA & LATAM").Activate ''''' Here checking CEEMEA & LATAM status
On Error GoTo General
'''' after checking STATUS do some work on CEEMEA & LATAM '''''

On Error GoTo PROBLEM_TICKER
Set doc = Application.Windows("Ticker Graveyard").Document ''''' Here checking Ticker Graveyard status
On Error GoTo General
'''' after checking do some work on Ticker Graveyard '''''

Exit Sub

PROBLEM_CEEMA:
  If Err.Number = 5941 Then
    Documents.Open FileName:="C:\Users\dell\Desktop\EMEA CEEMEA\Ticker Graveyard.docx" --- handling only Ticker document    
  Else
    MsgBox "UNEXPECTED ERROR = " & Err.Number
    Exit Sub
  End If

Resume Next 

PROBLEM_TICKER:
  If Err.Number = 5941 Then
    Documents.Open FileName:="C:\Users\dell\Desktop\EMEA CEEMEA\CEEMEA & LATAM.docx" --- handling only CEEMEA & LATAM document    
  Else
    MsgBox "UNEXPECTED ERROR = " & Err.Number
    Exit Sub
  End If

Resume Next 

PROBLEM_General:
  'General, non-document-related error handling
End Sub

Итерация коллекции документов

Приложение Word сохраняеттекущий список открытых документов в коллекции Documents.Можно использовать цикл For...Each (или For) для запуска коллекции и сравнения имени документа.Это можно сделать в отдельной функции, чтобы код не нужно было повторять.

Sub Test
  Dim doc1 as Document, file1 as String
  Dim doc2 as Document, file2 as String

  file1 = "C:\Users\dell\Desktop\EMEA CEEMEA\CEEMEA & LATAM.docx"
  file2 = "C:\Users\dell\Desktop\EMEA CEEMEA\Ticker Graveyard.docx"

  If not IsDocumentOpen(file1) Then
    Set doc1 = Documents.Open(FileName:=file1)
  End If

  If not IsDocumentOpen(file2) Then
    Set doc2 = Documents.Open(FileName:=file2)
  End If
End Sub

Function IsDocumentOpen(fileName as String) as Boolean
  Dim doc as Word.Document
  Dim isOpen as Boolean

  isOpen = false
  For Each doc in Documents
     IF doc.Name = fileName Then
        isOpen = true
     End If
  Next
  IsDocumentOpen = isOpen
End Function
...