VBA Word/Outlook-客户用户窗体取消事件处理程序



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

如果我将MsgBox函数与vbYesNoCancel按钮一起使用,那么每次关闭Word文档时,事件处理程序都会触发。这是意料之中的事。

如果我使用带有三个按钮("Finalise"、"Discard"one_answers"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

使用用户表单而不是消息框有几个方面。首先,用户窗体不知道父窗口句柄。其次,用户表单不是模态的。第三,使用Unload而不是Hide。有关详细信息,请参阅更改外接程序用户窗体的父工作簿窗口。

我本来会添加一个注释,但它太长了。

更换此部件:

Set finaliseUserForm = New UserFormFinaliseRFI
finaliseUserForm.show
msgBoxResponse = finaliseUserForm.response
Unload finaliseUserForm
Set finaliseUserForm = Nothing

带有:

With New UserFormFinaliseRFI
.Show vbModal
msgBoxResponse = .response
End With

不需要调用UnloadSet finaliseUserForm = Nothing,因为您创建的新表单实例会在某个时候被VB本身终止,而且Unload方法在各种Office版本中都会导致错误和崩溃,应该避免。

此外,你可能想阻止用户点击表单上的X按钮。将其添加到你的表单代码中:

'Handles click on the X (close) button
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
Cancel = True
End If
End Sub

忽略X按钮或类似的东西:

'Handles click on the X (close) button
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
Cancel = True
mResponse = "Discard"
Me.Hide
End If
End Sub

以获得特定的行为。

最新更新