【问题标题】:VBA Word/Outlook - Customer User Form Cancels Event HandlerVBA Word/Outlook - 客户用户表单取消事件处理程序
【发布时间】:2022-10-06 13:19:19
【问题描述】:

我在关闭 word 文档的事件处理函数中有一些奇怪的行为。我在 Outlook 模块中使用 Word 的 DocumentBeforeClose 事件处理程序。在处理程序中,我用一条消息提示用户,询问他们是要完成文档、丢弃文档还是继续编辑。

如果我将 MsgBox 函数与 vbYesNoCancel 按钮一起使用,那么每次关闭 Word 文档时都会触发事件处理程序。这按预期工作。

如果我使用带有三个按钮(\"Finalise\"、\"Discard\"、\"Continue Editing\")的自定义用户表单,则事件处理程序仅在 Word 文档第一次关闭时触发。如果用户单击继续编辑,那么下次他们关闭文档时,不会触发事件处理程序。

我不明白为什么这两种情况会导致不同的行为?如果我使用自定义用户表单,为什么会取消事件处理程序?

事件处理程序类(非工作版本)

Option Explicit

Private WithEvents mWordApp As word.Application

Private Sub mWordApp_DocumentBeforeClose(ByVal Doc As document, Cancel As Boolean)
    Dim msgBoxResponse As String
    
    \'This code brings Outlook back to the active window so the user can response to the form
    AppActivate Application.ActiveExplorer.Caption
    SendKeys \"%\"
    
    Set finaliseUserForm = New UserFormFinaliseRFI
    finaliseUserForm.show
    msgBoxResponse = finaliseUserForm.response
    Unload finaliseUserForm
    Set finaliseUserForm = Nothing
    
    \'msgBoxResponse = MsgBox(\"Do you want to finalise the document?\", vbYesNoCancel)
    
    If msgBoxResponse = \"Finalise\" Then
    \'If msgBoxResponse = vbYes Then
        Set mWordApp = Nothing
    Else
        Cancel = True
        AppActivate \"test.docx\"
    End If
End Sub

Public Sub StartEvents()
    Set mWordApp = CreateObject(\"Word.Application\")
End Sub

Public Sub OpenWordDocument(filePath As String)
    mWordApp.Documents.Open filePath
    mWordApp.Visible = True
End Sub

事件处理程序类(工作版)

Option Explicit

Private WithEvents mWordApp As word.Application

Private Sub mWordApp_DocumentBeforeClose(ByVal Doc As document, Cancel As Boolean)
    Dim msgBoxResponse As String
    
    \'This code brings Outlook back to the active window so the user can response to the form
    AppActivate Application.ActiveExplorer.Caption
    SendKeys \"%\"
    
    \'Set finaliseUserForm = New UserFormFinaliseRFI
    \'finaliseUserForm.show
    \'msgBoxResponse = finaliseUserForm.response
    \'Unload finaliseUserForm
    \'Set finaliseUserForm = Nothing
    
    msgBoxResponse = MsgBox(\"Do you want to finalise the document?\", vbYesNoCancel)
    
    \'If msgBoxResponse = \"Finalise\" Then
    If msgBoxResponse = vbYes Then
        Set mWordApp = Nothing
    Else
        Cancel = True
        AppActivate \"test.docx\"
    End If
End Sub

Public Sub StartEvents()
    Set mWordApp = CreateObject(\"Word.Application\")
End Sub

Public Sub OpenWordDocument(filePath As String)
    mWordApp.Documents.Open filePath
    mWordApp.Visible = True
End Sub

测试模块子

Option Explicit

Private mEvents As WordEventsHelper

Public Sub testEvents()
    Set mEvents = New WordEventsHelper
    mEvents.StartEvents
    mEvents.OpenWordDocument \"\\(mypath)\\test.docx\"
    AppActivate \"test.docx\"
End Sub

用户表单代码

Private mResponse As String

Public Property Get response() As String
    response = mResponse
End Property

Private Sub CommandButtonFinalise_Click()
    mResponse = \"Finalise\"
    Me.Hide
End Sub

Private Sub CommandButtonDiscard_Click()
    mResponse = \"Discard\"
    Me.Hide
End Sub

Private Sub CommandButtonContinueEditing_Click()
    mResponse = \"Continue Editing\"
    Me.Hide
End Sub
  • 您是否尝试调试代码?您是否使用用户表单获得正确的结果?
  • 是的,一切似乎都正常工作 - 包括用户表单。除了事件处理程序仅在使用自定义用户表单时第一次触发的事实。
  • 确保将 Cancel 参数设置为 true 以再次触发事件。
  • 我在事件处理函数的 \'else\' 部分将 Cancel 设置为 true。无论是我的客户用户表单还是 msgbox,它都能正确执行。只是当我使用用户表单时,处理程序再也不会触发。
  • 尝试使用Unload 方法而不是Hide

标签: vba outlook ms-word office-automation


【解决方案1】:

使用用户表单而不是消息框时有几个方面。首先,用户窗体不知道父窗口句柄。其次,用户表单不是模态的。第三,使用Unload 而不是Hide。请参阅Changing the parent workbook window of an add-in's userform 了解更多信息。

【讨论】:

  • 我不认为我的用户表单使用(或需要使用)父窗口句柄。我的用户表单代码中没有句柄。更改活动窗口并取消关闭事件的代码位于事件处理程序中。我不确定卸载和隐藏的相关性是什么?我在我的用户表单中使用“隐藏”,以便在我能够获得 mResponse 的值之前它不会消失。即使我在将 finaliseUserForm 设置为 Nothing 之前添加了 Unload finaliseUserForm 行,错误仍然存​​在
  • 即使我在用户表单按钮单击代码中使用“卸载我”行 - 不良行为仍然存在。
  • 您的用户表单是模态的吗?它如何阻止事件处理程序在表单关闭之前停止?
  • 用户表单在打开时暂停事件处理程序的执行。当我单击一个按钮并且它被隐藏和/或卸载时,执行将继续。
  • 与消息框一起正常工作的代码看起来如何?
猜你喜欢
  • 2023-03-10
  • 2017-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-16
相关资源
最近更新 更多