2015-11-13 128 views
4

我在自动化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") 

然后我打电话从Excel文件通过一些数据的Word文档中的子程序:

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

如果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 

这工作完全正常ü正常情况下;但是,如果Word文档或应用程序是在Err1标签执行之前关闭(如用户手动关闭文档),我收到以下错误:

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

这是非常合情合理的,因为wordApp和/或wordDoc变量仍然引用应用程序和文档对象,并且这些对象不再存在(但也不被认为是Nothing)。

所以,这里是我的查询:有没有办法检查是否有一个对象已经从运行时错误发生之前已断开其客户端,以避免依赖于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 

更新1:

看着omegastripes' answer后,我意识到,当文档(wordDoc)是断开了对象上面仅给出的错误发生。如果Word应用程序(wordApp)是什么断开了,我得到以下错误:

Run-time error '462':

The remote server machine does not exist or is unavailable

+0

为什么你不检查错误对象? 'Err.Number'或'Err.Description' - 如果对象因为关闭而断开连接,那么没有什么可检查 - 所以你不能检查它。 –

+0

@MacroMan这是一个很好的想法;然而,所引发的错误是错误440:“自动化错误”,它将由于几种不同的原因而被抛出,包括被断开连接的对象以及远程过程调用(Word的子例程)中发生的任何错误。 – Jonathan

+0

我想你可以检查Word应用程序是否仍在运行(这很简单),但检查是否有连接断开将会非常棘手,如果可能的话,它没有连接的事实意味着它是属性和方法无法访问。只有其他的东西你可以尝试看看'wordApp'对象是否返回'Nothing' –

回答

3

考虑下面的例子:

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 

似乎任何类型的检测变量,其引用的内在Word对象,如.Documents,.Windows,.RecentFiles等等,在文档关闭或应用程序退出命令被立即调用后,可能会抛出错误14:Out of string space,而Word应用程序正在处理该命令。对Application对象进行同样的检测,也可能会挂起Excel应用程序。

在这个例子中TypeName()调用包装成OERN循环,应该跳过不相关的结果得到明确的断线反馈,依靠类型名,但不是在错误号。为避免挂起,.Windows属性被检查而不是Application

+0

这很聪明!注意文档(例如'wordDoc')通常具有“Document”类型,但在断开连接时更改为“Object”是有用的。 不幸的是,您的答案只适用于问题的一半。这是因为应用程序(例如'wordApp')在断开连接后仍然具有“应用程序”类型。所以,即使我可以检测到文档何时与您的答案断开连接,我仍然无法检测应用程序本身何时断开连接。但是,您让我意识到应用程序断开连接时会发生不同的错误(请参阅Update 1)。 – Jonathan

+0

@Jonathan - 那么为什么不把错误14陷入'IsObjectDisconnected'?我很困惑,为什么你不愿意使用错误处理程序来检测错误情况。 – Comintern

+0

@Jonathan,Document不能单独断开连接,因为它只是Word对象的一个​​属性。只有整个应用程序可能会断开连接。检查变量的类型,即涉及到其中一个属性,显示应用程序的实际状态。因此,如果对Document属性的引用类型是“Object”,那么它明确表示应用程序已断开连接。 – omegastripes

相关问题