In order to hijack the native “SaveAs” dialog in Word, you need to lever the Application-level event for DocumentBeforeSave
, and then call the FileDialog manually, in order to validate the extension.
1. Create a standard code module and name it modEventHandler
. Put the following code in it.
Option Explicit
Public TrapFlag As Boolean
Public cWordObject As New cEventClass
'You may not need these in a DOCM, but I needed to implement this in an ADD-IN
Sub TrapEvents()
If TrapFlag Then
Exit Sub
End If
Set cWordObject.DOCEvent = Application
TrapFlag = True
End Sub
Sub ReleaseTrap()
If TrapFlag Then
Set cWordObject.DOCEvent = Nothing
Set cWordObject = Nothing
TrapFlag = False
End If
End Sub
2. Create a Class Module called cEventClass
and put this code in the module:
Option Explicit
Public WithEvents DOCEvent As Application
Private Sub DOCEvent_DocumentBeforeSave(ByVal Doc As Document, SaveAsUI As Boolean, Cancel As Boolean)
' Do not prevent SAVEAS for *other* documents
If ObjPtr(Doc) <> ObjPtr(ThisDocument) Then
Exit Sub
End If
If SaveAsUI Then
' The user has invoked SAVE AS command , so we will hijack this and use our own FileDialog
Call CustomSaveAs(Doc)
' Prevent duplicate appearance of the SAVEAS FileDialog
Cancel = True
End If
End Sub
Private Sub CustomSaveAs(ByRef Doc As Document)
Dim fd As FileDialog
Dim filename$
Set fd = Application.FileDialog(msoFileDialogSaveAs)
fd.Show
If fd.SelectedItems.Count = 0 Then Exit Sub
filename = fd.SelectedItems(1)
If Not Right(filename, 4) = "docm" Then
' ### DO NOT EXECUTE this dialog unless it matches our .DOCM file extension
MsgBox "This document should only be saved as a DOCM / Macro-Enabled Document", vbCritical, "NOT SAVED!"
Else
fd.Execute
End If
End Sub
3. In ThisDocument
module, do the following code:
Private Sub Document_Close()
Call modEventHandler.ReleaseTrap
End Sub
Private Sub Document_Open()
Call modEventHandler.TrapEvents
End Sub
How Does This Work?
ThisDocument
raises the Document_Open
event which calls on the TrapEvents
procedure.
TrapEvents
procedure creates a WithEvents
instance of Word.Application
class, exposing additional events to automation. One of these is DocumentBeforeSave
.
We use the DocumentBeforeSave
event to trap the SaveAs
operation. If the User has requested a SaveAs
, then we force the dialog with logic as created in CustomSaveAs
procedure. This uses simple logic to test the file extension provided, and prevents the document from being saved if it is not a DOCM extension. If the FileDialog does receive a valid DOCM extension, then we Execute
the dialog which saves the file as the new name.
2
solved Word VBA force save as .docm