2016-05-10 32 views
-1

我有一个项目,需要我在Word中打开文档并等待文档打开。用户然后需要编辑文档,打印或保存文档,然后手动关闭文档。当文档(或Word本身)关闭时,我想在Access中继续使用我的VBA脚本。MS Access VBA检查Word是否已关闭?

我有以下代码

If Len(Dir(sDocName)) > 0 Then 
    Dim wordApp As Word.Application 
    Dim wordDoc As Word.Document 

    ' Launch Word 
    Set wordApp = New Word.Application 

    ' Open the document 
    With wordApp 
     Set wordDoc = .Documents.Open(sDocName, , False) 

     ' Pass data 
     With wordDoc 
      .Variables("bmArchitectCompanyName").Value = "Hello" 
      .Variables("bmArchitectCompanyAddress").Value = "Hello" 
      .Variables("bmArchitectCompanyPostCode").Value = "Hello" 
      .Variables("bmArchitectContactFirstName").Value = "Hello" 
      .Variables("bmProjectTitle").Value = ProjectTitle 
      .Fields.Update 
     End With 
     .Visible = True 
     .Activate 

     Do Until wordApp Is Nothing 
      ' Wait for Word to be closed 
     Loop 

     ' Display a success message 
     MsgBox "Success!" 
    End With 
End If 

然而,做循环永远不会退出。

如何检查通过VBA启动的文档是否已由用户从我的VBA代码中关闭?

+0

你在哪里关闭wordApp?由于它仍在运行,循环将永远不会停止。 – INOPIAE

+0

我将在if语句(未包含在上面)后关闭wordApp对象。一旦我知道应用程序已被用户关闭,我会将对象设置为Nothing。我需要知道应用程序何时关闭。 – alcomcomputing

+0

所以等待循环必须包含一个DoEvents循环,然后检查文档是否关闭,否则coninue DoEvents循环。 –

回答

0

您必须使用DoEvents屈服于操作系统,然后检查文档是否关闭,否则coninue DoEvents循环。以下是我不幸测试不到的大纲代码。

Do 
     DoEvents 
     For i = 1 to wordApp.Documents.Count 
      If (wordApp.Documents(i).Name = sDocName) Then Exit For 
     Next i 
     If (i > wordApp.Documents.Count) Then Exit Loop 
    Loop While (True) 

注意:您可能不想关闭应用程序,因为用户可能打开了其他文档。也许你应该测试一下。

+0

我用这种方法得到的错误(以及几乎所有其他错误)是运行时错误'462':远程服务器机器不存在或不可用。调试在行停止对于i = 1到wordApp.Documents.Count。我怀疑是因为单词已关闭,对象不再有效。 Nothing对象也不是。我需要测试我认为的对象。 – alcomcomputing

0

我已经找到了解决办法...

Do While .Visible 
     ' wait until the window is no longer visible  
Loop 

不正是我一直在寻找,等待,直到字被关闭,然后用MS访问VBA脚本继续。

+0

尽管_what_可见? wordApp或wordDoc? –

+0

这个循环替换原来的文章中的直到循环。所以它是wordApp。 – alcomcomputing

+0

如果您在Access创建的Word实例中打开另一个文档,然后关闭Access打开的文档,会发生什么情况? –

0

基于Paul输入的内容,使用不同的方法来测试文档是否打开。

Sub Test() 

    Dim wordApp As Word.Application 
    Dim wordDoc As Word.Document 
    Dim sDocName As String 

    sDocName = "<Full path to document>" 

    Set wordApp = New Word.Application 

    With wordApp 
     Set wordDoc = .Documents.Open(sDocName, , False) 
     .Visible = True 
     .Activate 

     Do 
      DoEvents 
     Loop While FileIsOpen(sDocName) 

    End With 

    MsgBox "Finished" 

End Sub 

Public Function FileIsOpen(FullFilePath As String) As Boolean 

    Dim ff As Long 

    On Error Resume Next 

    ff = FreeFile() 
    Open FullFilePath For Input Lock Read As #ff 
    Close ff 
    FileIsOpen = (Err.Number <> 0) 

    On Error GoTo 0 

End Function 
0

与检查,看看是否wordApp Is Nothing是VBA不知道取消引用对象时其外部关闭了该问题。换句话说,当wordApp引用的文档关闭时,指向该对象的指针变成虚假但不是Nothing。要捕获的事件,您可以在出现错误做在环路的文档对象的无意义的通话,并退出:

On Error Resume Next 
With wordDoc 
    Do 
    DoEvents 
    'This will only occur if there is an error: 
    If .Visible<>.Visible Then Exit Do 
    Loop 
End With 
Err.Clear 
On Error Goto 0 
0

我只是没有回路或其他任何测试。 Access中的宏代码等待,直到Word应用程序的实例在完成执行之前关闭。下面是我测试过,并MSGBOX后,才退出Word执行:要确保将对象设为Nothing或 你很有可能在未来的时间遇到​​错误信息

' Open the document 
With wordApp 
    Set wordDoc = .Documents.Add 

    ' Pass data 
    With wordDoc 
     .Variables("bmArchitectCompanyName").Value = "Hello" 
     .Variables("bmArchitectCompanyAddress").Value = "Hello" 
     .Variables("bmArchitectCompanyPostCode").Value = "Hello" 
     .Variables("bmArchitectContactFirstName").Value = "Hello" 
     .Content.Text = "test" 
     '.Variables("bmProjectTitle").Value = ProjectTitle 
     '.Fields.Update 
    End With 
    .Visible = True 
    .Activate 

    ' Display a success message 
    MsgBox "Success!" 
    Set wordDoc = Nothing 
    Set wordApp = Nothing 
End With 

注你运行代码 ,因为它会让WinWord的实例在内存中打开。

+0

这对我不起作用。脚本运行,并且在单词打开时显示消息框。我需要MS Access等到Word关闭。 – alcomcomputing

0

如果您在类模块或窗体模块处理Word文档,请尝试声明一个Word.Document对象是这样的:

Dim WithEvents w As Word.Document 

,那么你可以使用Word.Document对象事件“关闭“:

Private Sub w_Close() 

    'Things you want to do when the Word.Document is closed 

    'reset object 
    set w=nothing 

End Sub 

您不能让”容器“窗体关闭或者对象终止,除非w不为空。表单或对象是安静的(或任何你想要他们做的),直到你的Word文档被关闭。

+0

谢谢,但我不需要处理关闭事件,只需检测关闭事件。 – alcomcomputing

+0

@alcomcomputing我最初想要提出这种方法,但无法让它与Access中的类一起工作,这是您的代码执行的地方。但是,如果它确实可行,那么当事件触发时,您可以调用更多代码 - IOW将随后将命令发送到Word(MsgBox)的代码。但是,您需要在声明代码的末尾释放对象。 –

+0

@alcomcomputing处理和检测关闭事件没有区别。对我而言,它们与检测Word文档的结束时相同,因此您必须首先处理关闭事件。我不知道其他方式。 –