Error handling 区分使用“on error goto”出现的两个错误,并分别处理它们

Error handling 区分使用“on error goto”出现的两个错误,并分别处理它们,error-handling,ms-word,runtime-error,goto,onerror,Error Handling,Ms Word,Runtime Error,Goto,Onerror,我正在处理三个单词的文档 粗糙的 中东和拉美 迪克尔墓地 开始时,只打开粗略的文档。我需要将数据从Rough转移到CEEMEA和LATAM,并使用Ticker Graveyard匹配一些查询,因此CEEMEA和LATAM Ticker Graveyard都应该已经打开 为此,我检查其他两个文档是否已打开。如果没有,那么我需要使用Documents.open打开特定文档。为此,我正在执行以下更新的代码: 但问题是,由于两个检查点触发相同的错误号,我无法使用简单的on Error goto语句来区分

我正在处理三个单词的文档

粗糙的 中东和拉美 迪克尔墓地 开始时,只打开粗略的文档。我需要将数据从Rough转移到CEEMEA和LATAM,并使用Ticker Graveyard匹配一些查询,因此CEEMEA和LATAM Ticker Graveyard都应该已经打开

为此,我检查其他两个文档是否已打开。如果没有,那么我需要使用Documents.open打开特定文档。为此,我正在执行以下更新的代码:

但问题是,由于两个检查点触发相同的错误号,我无法使用简单的on Error goto语句来区分它们


现在我的问题是如何区分这两种错误?我如何分别处理它们?如果有其他方法处理这种情况,请分享。

对于代码需要引用可能存在或不存在的特定对象的情况,有许多处理策略。哪种方法最好,在某种程度上是一种哲学思考。基本方法是:

触发错误,然后处理它。问题中的代码就是这样设计的。当使用VBA时,它也是一种有效的方法,因为它可以相对快速。但是,对于任何.NET语言,它都会明显降低代码的速度,如果有其他可能,就不应该使用它。 迭代集合以确定相关对象是否可用。如果集合包含很多项,那么在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应用程序在文档集合中保留打开文档的运行列表。可以使用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

请同时向我们展示问题中调用sub的代码。就目前而言,断章取义,很难给出建议。不过,我要说的是,通过检查文档集合中是否存在文档,代码的结构应该有所不同。一般来说,使用Activate处理特定文档是一个坏主意-最好使用document对象。我对您的第二个建议感兴趣,因为它更有效,但我在实现它时遇到了问题。打开文档后,我需要添加其他代码,即在该特定文档中插入日期。若文档已经打开,那个么我不需要这些额外的代码。我将在最初的问题中提到这一情况。你能把这与你的第二个建议相适应吗?也可以将函数IsDocumentOpen合并到子测试中吗?
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