检测一个对象是否已与它的客户端断开连接

时间:2021-01-14 02:30:48

I am having an issue with automating an Excel file. The VBA script within Excel first opens a Word application and Word document:

我有一个自动处理Excel文件的问题。Excel中的VBA脚本首先打开Word应用程序和Word文档:

    Dim wordApp As Object
    Set wordApp = CreateObject("Word.Application")

    vPath = Application.ActiveWorkbook.Path
    Set wordDoc = wordApp.Documents.Open(vPath & "\test.doc")

And then I call a subroutine within the Word document passing some data from the Excel file:

然后调用Word文档中的子例程,从Excel文件中传递一些数据:

    Call wordApp.Run("StartWithData", variable1, variable2)

If Excel detects that an error occurs in that subroutine, I close the Word document and Word application from Excel in a label I call Err1:

如果Excel检测到该子例程中出现错误,我将从Excel中关闭Word文档和Word应用程序,并将其标记为Err1:

    On Error Goto Err1
    'all the code from above
    Exit Sub

    Err1:
    wordDoc.Close wdCloseWithoutSaving
    wordApp.Quit SaveChanges:=wdDoNotSaveChanges
    Set wordDoc = Nothing
    Set wordApp = Nothing

This works perfectly fine under normal circumstances; however, if the Word document or application are closed before the Err1 label executes (such as the user manually closing the document), I get the following error:

这在正常情况下是完全正常的;但是,如果在Err1标签执行之前关闭Word文档或应用程序(例如用户手动关闭文档),则会出现以下错误:

Run-time error '-2147417848 (80010108)':
Automation error The object invoked has disconnected from its clients.

运行时错误'-2147417848(80010108)':被调用的对象已从其客户端断开连接的自动化错误。

which makes perfect sense because the wordApp and/or wordDoc variables still reference the Application and Document objects and those objects do not exist anymore (yet are also not considered to be Nothing).

这非常有意义,因为wordApp和/或wordDoc变量仍然引用应用程序和文档对象,而这些对象不再存在(但也不认为什么都不是)。

So here is my inquiry: Is there a way to check if an object has been disconnected from its client before the run-time error occurs so as to avoid having to rely on on error resume next?

我的问题是:是否有一种方法可以在运行时错误发生之前检查一个对象是否已经与它的客户端断开连接,从而避免接下来不得不依赖于错误恢复?

Such as:

    If Not isDisconnected(wordDoc) Then
    wordDoc.Close wdCloseWithoutSaving
    End If

    If Not isDisconnected(wordApp) Then
    wordApp.Quit SaveChanges:=wdDoNotSaveChanges
    End If

Update 1:

更新1:

After looking at omegastripes' answer, I realized that the error given above only occurs when the document (wordDoc) was the object that got disconnected. If the Word application (wordApp) is what got disconnected, I get the following error:

看到omegastripes的答案后,我意识到上面给出的错误只发生在文档(wordDoc)是断开连接的对象时。如果Word application (wordApp)被断开连接,我得到以下错误:

Run-time error '462':

运行时错误“462”:

The remote server machine does not exist or is unavailable

远程服务器计算机不存在或不可用

1 个解决方案

#1


3  

Consider the below example:

考虑下面的例子:

Sub Test()
    Dim wordApp As Object
    Dim wordWnd As Object
    Dim wordDoc As Object

    Set wordApp = CreateObject("Word.Application")
    Set wordWnd = wordApp.Windows ' choose any object property as indicator
    wordApp.Visible = True ' debug
    Set wordDoc = wordApp.Documents.Open(Application.ActiveWorkbook.Path & "\test.doc")
    MsgBox IsObjectDisconnected(wordWnd) ' False with opened document
    wordDoc.Close
    MsgBox IsObjectDisconnected(wordWnd) ' False with closed document
    wordApp.Quit ' disconnection
    MsgBox IsObjectDisconnected(wordWnd) ' True with quited application
End Sub

Function IsObjectDisconnected(objSample As Object) As Boolean
    On Error Resume Next
    Do
        IsObjectDisconnected = TypeName(objSample) = "Object"
        If Err = 0 Then Exit Function
        DoEvents
        Err.Clear
    Loop
End Function

Seems any type detection of the variable, which references to the intrinsic Word objects, like .Documents, .Windows, .RecentFiles, etc., made immediately after document close or application quit commands have been invoked, may throw the error 14: Out of string space, while Word application processing the command. The same detection on the Applicationobject , may also hang Excel application.

似乎任何类型的变量检测(它引用了内部的单词对象,如. documents、. windows、. recent files等),在文档关闭或应用程序退出命令被调用之后立即执行,都可能抛出错误14:在字符串空间之外,而Word应用程序处理命令。在Applicationobject上进行相同的检测,也可以挂起Excel应用程序。

In the example TypeName() call is wrapped into OERN loop, that should skip irrelevant results to get explicit disconnection feedback, relying on the type name, but not on the error number. To avoid hanging, .Windows property is being checked instead of Application.

在示例TypeName()调用被封装到OERN循环中,它应该跳过无关的结果以获得显式的断开反馈,依赖于类型名,而不是在错误号上。为了避免挂起,正在检查. windows属性而不是应用程序。

#1


3  

Consider the below example:

考虑下面的例子:

Sub Test()
    Dim wordApp As Object
    Dim wordWnd As Object
    Dim wordDoc As Object

    Set wordApp = CreateObject("Word.Application")
    Set wordWnd = wordApp.Windows ' choose any object property as indicator
    wordApp.Visible = True ' debug
    Set wordDoc = wordApp.Documents.Open(Application.ActiveWorkbook.Path & "\test.doc")
    MsgBox IsObjectDisconnected(wordWnd) ' False with opened document
    wordDoc.Close
    MsgBox IsObjectDisconnected(wordWnd) ' False with closed document
    wordApp.Quit ' disconnection
    MsgBox IsObjectDisconnected(wordWnd) ' True with quited application
End Sub

Function IsObjectDisconnected(objSample As Object) As Boolean
    On Error Resume Next
    Do
        IsObjectDisconnected = TypeName(objSample) = "Object"
        If Err = 0 Then Exit Function
        DoEvents
        Err.Clear
    Loop
End Function

Seems any type detection of the variable, which references to the intrinsic Word objects, like .Documents, .Windows, .RecentFiles, etc., made immediately after document close or application quit commands have been invoked, may throw the error 14: Out of string space, while Word application processing the command. The same detection on the Applicationobject , may also hang Excel application.

似乎任何类型的变量检测(它引用了内部的单词对象,如. documents、. windows、. recent files等),在文档关闭或应用程序退出命令被调用之后立即执行,都可能抛出错误14:在字符串空间之外,而Word应用程序处理命令。在Applicationobject上进行相同的检测,也可以挂起Excel应用程序。

In the example TypeName() call is wrapped into OERN loop, that should skip irrelevant results to get explicit disconnection feedback, relying on the type name, but not on the error number. To avoid hanging, .Windows property is being checked instead of Application.

在示例TypeName()调用被封装到OERN循环中,它应该跳过无关的结果以获得显式的断开反馈,依赖于类型名,而不是在错误号上。为了避免挂起,正在检查. windows属性而不是应用程序。