Windows 8 Machine (works):
Microsoft Office Professional Plus 2013
Windows 10 Machine (doesn't work):
Microsoft Office 365
Template (.dotm file) gets placed in Startup folder for Word.
When I start Word I am presented with a blank screen. Clicking on "File" causes Word to exit immediately with no error message.
The add-in has a module called MainModule and a class called WordApp. AutoExec fires up a loop which calls a dummy function.
MainModule:
'event processor class instance
Dim myWordApp As WordApp
Sub Register_Event_Handler()
Set myWordApp.appWord = Word.Application
End Sub
'gets executed automatically
Sub AutoExec()
Set myWordApp = New WordApp
Call MainProgram
End Sub
Sub MainProgram()
Register_Event_Handler
Do While True
testFunction
DoEvents
Loop
End Sub
'dummy function gets called in loop
Private Sub testFunction()
Dim i As Integer
i = 0
i = i + 1
End Sub
WordApp class:
Public WithEvents appWord As Word.Application
'fires upon closing word
Private Sub appWord_DocumentBeforeClose(ByVal Doc As Document, Cancel As
Boolean)
MsgBox "Closing"
End Sub
Related
I open Word application in VB.Net by below code:
Dim appWord As New Microsoft.Office.Interop.Word.Application
appWord.Documents.Open("path")
appWord.Visible = True
I wanna subscribe the closing event of msword and run something before closing. I read this question and this article but I really don't know how to use in VB.Net
Add a reference (Project--References...) to Microsoft Word XX.0 Object Library.
XX depends on your version of MS Office i.e. 16.0 if your MS Office is 2016.
Add a command button named Command1 to form.
Add this code to form:
Option Explicit
Public WithEvents moWord As Word.Application
Private Sub Command1_Click()
' open test document
With moWord
.Documents.Open "J:\Test.docx" ' change document path according to actual file
'.WindowState = wdWindowStateNormal
.Visible = True
End With
End Sub
Private Sub Form_Load()
Set moWord = New Word.Application
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
If Not (moWord Is Nothing) Then Set moWord = Nothing
End Sub
Private Sub moWord_DocumentBeforeClose(ByVal Doc As Word.Document, Cancel As Boolean) Handles moWord.DocumentBeforeClose
If MsgBox("Do you really want to close the document?", vbQuestion + vbYesNo + vbDefaultButton2) = vbNo Then Cancel = True
End Sub
I'm trying to use Normal.dotm as a macro storage object analogous to the Personal.xlsb object within Excel.
The built-in Document_Close() event seems like it cannot be triggered unless it's included within a specific document's ThisDocument object.
I've also tried to use this Application_Quit() event like so but to no avail:
Private Sub Application_Quit()
Msgbox "closing word"
End Sub
Is it possible to listen for closing of the word application like it is in excel with Auto_Close(), etc?
Attempt for #BigBen based on this documentation
Class Module "Event Class Module"
Public WithEvents App As Word.Application
Normal Module "Module 1"
Dim X As New Class1
Sub Register_Event_Handler()
Set X.App = Word.Application
End Sub
Private Sub App_Quit()
MsgBox "closing word"
End Sub
There are two basic ways to capture when any Word document closes:
Use a macro named AutoClose in any module of Normal.dotm (or any template loaded as an add-in). This is the "old-fashioned" way that comes from the WordBasic (Word 2.0 and 6.0) days.
Note that if any other document (or template) has AutoClose that this will over-ride the macro running a "more general" level. In other words, the document- (or template-) specific code takes priority.
Sub AutoClose()
MsgBox "The document " & ActiveDocument.FullName & " is closing."
End Sub
Work with an application-level event. This requires both a class module and a "plain" module. The event code is in the class module; the code to initialize the class must be in a "plain" module.
This event's name is DocumentBeforeClose and can be cancelled, both by the user and by code (see the Cancel parameter in the event signature).
In contrast to AutoClose, if more than one document or template has the event running all will fire - there is no priority or "override".
Class module named clsEvents
Public WithEvents app As Word.Application
Private Sub app_DocumentBeforeClose(ByVal Doc As Document, Cancel As Boolean)
MsgBox "The document " & Doc.FullName & " is being closed."
End Sub
Module
Public myEvents As New clsEvents
Public Sub StartEvents()
Set myEvents.app = Word.Application
End Sub
Public Sub EndEvents()
Set myEvents.app = Nothing
End Sub
Note that if both types of event are present the AutoClose fires after DocumentBeforeClose.
Note also that there is a document-specific event that will fire only for that document: Document_Close. This event must be in the ThisDocument class module of that document.
Private Sub Document_Close()
End Sub
Here are some codes I used to raise an event when the protected Word document is being closed. The purpose is to send a message box BEFORE the preview document is CLOSED. User is able to abort the closing event, modify the document and close the document again. The simpler Word document Document_Close() event handler does not support CANCEL = TRUE.
Step 1. Add following code into a CLASS (codes must be in class module). I named the class as 'EventClassModule', I made a public declaration 'App', these names are referenced in the module.
Public WithEvents App As Word.Application
Private Sub App_DocumentBeforeClose(ByVal Doc As Document, Cancel As Boolean)
If vbYes = MsgBox("Do you need to modify the certificate?", vbYesNo) Then
If ActiveDocument.ProtectionType <> wdNoProtection Then
ActiveDocument.Unprotect
End If
Cancel = True
End If
End Sub
Step 2: Add following code into a module. The class name 'EventClassModule' and the public declaration 'App' are referenced here. The code 'Set X.App = Word.Application' will point to the Word application object, and the event procedures in the class module will run when the events occur.
Dim X As New EventClassModule
Sub abc()
Set X.App = Word.Application
Dim Doc As Word.Document
Set Doc = ActiveDocument
If Doc.ProtectionType <> wdNoProtection Then
Doc.Unprotect
End If
ActiveDocument.Range.Text = Time
Doc.Protect wdAllowOnlyReading
End Sub
Is this a Word 2003 VBA bug? DocumentBeforePrint executes multiple times?
I reference
http://msdn.microsoft.com/en-us/library/office/aa211873(v=office.11).aspx
http://msdn.microsoft.com/en-us/library/office/aa211915(v=office.11).aspx
DocumentBeforeClose syntax
I make a test.dot with macro DocumentBeforePrint.
'ref http://msdn.microsoft.com/en-us/library/office/aa211915(v=office.11).aspx
Dim X As New EventClassModule
Sub Register_Event_Handler()
Set X.appWord = Word.Application
End Sub
Private Sub Document_New()
Call Register_Event_Handler
End Sub
Private Sub Document_Open()
Call Register_Event_Handler
End Sub
'ref http://msdn.microsoft.com/en-us/library/office/aa211873(v=office.11).aspx
Public WithEvents appWord As Word.Application
Private Sub appWord_DocumentBeforePrint _
(ByVal Doc As Document, _
Cancel As Boolean)
MsgBox "WORKING!"
End Sub
When I press Ctrl+P, the macro executes.
There is a bug. When I double click test.dot to generate two word files (a.doc/b.doc).
Press Ctrl+P,the DocumentBeforePrint will execute twice.
If I generate 3 word files, Press Ctrl+P, the Macro will execute three times.
What's wrong? I just want to execude once.
It appears you have put all the code except the printing code in the ThisDocument code module. This is incorrect. Because you put ^Dim X as NewEventClassModuleinThisDocument`, which is, itself, a class module representing each document, multiple instances were being created. Declaring it in a "plain module" doesn't cause this problem.
You need three modules:
"Plain" module:
Dim X As New EventClassModule
Sub Register_Event_Handler()
Set X.appWord = Word.Application
End Sub
"ThisDocument" module:
Private Sub Document_New()
Register_Event_Handler
End Sub
Private Sub Document_Open()
Register_Event_Handler
End Sub
"EventClassModule"
Public WithEvents appWord As Word.Application
Private Sub appWord_DocumentBeforePrint _
(ByVal Doc As Document, _
Cancel As Boolean)
MsgBox "WORKING!"
End Sub
I'm facing an annoying issue where I simply want to schedule an asynchronous macro from another instance of Word, which happens to be the same .doc file.
Meaning, in the ThisDocument namespace I have the following code snippet:
Public Sub Document_Open()
Set Obj = New Word.Application
Obj.OnTime Now + TimeValue("00:00:01"), "Module1.Test"
End Sub
I've declared a new object of Word due to the following reasons:
My macro may block user's I\O
The user may close the document before the macro finishes its task
And declared a module named Module1 with a simple MsgBox
Public Sub Test()
MsgBox "hhh"
End Sub
Needless to say, nothing happened, and I'm unable to check what OnTime function returns.
I've also tried the following combinations:
"!Module1.Test"
"c:\\....\\file.doc!Module1.Test"
What am I missing here?
Your newly created Word application, represented by a Word.Application object, doesn't have the document open. Thus there's no "Module1" as far as he's aware. The fact that you want to run code from the same document is immaterial. It's a different instance of Word.
Something like this works:
'''''''' ThisDocument
Option Explicit
Private Sub Document_Open()
Dim res As VbMsgBoxResult
Dim Obj As Word.Application
If Application.Visible Then
res = MsgBox("Hello", vbOKCancel, "Hi!")
Else
Exit Sub
End If
If res = vbOK Then
Set Obj = New Word.Application
Obj.Documents.Open "C:\Users\conio\Desktop\Hello.docm", , True
Obj.OnTime Now + TimeValue("00:00:01"), "Module1.Foo"
End If
End Sub
'''''''' Module1
Public Sub Foo()
If Not Application.Visible Then
MsgBox "Foo"
Application.Quit
End If
End Sub
Maybe you'd want to use a different check to differentiate between the interactive run and the unattended run.
Ms Word does not want to load my add-in. I want to call a userform on print event. Here is my code:
in module 1
Option Explicit
Private Sub App_DocumentBeforePrint(ByVal Doc As Document, Cancel As Boolean)
'Debug.Print Now & " " & "App_DocumentBeforePrint: " & Wb.FullName
Userform1.Show
End Sub
Sub InitializeApp()
Dim X As New EventClassModule
Set X.App = Word.Application
End Sub
in Document module
Private Sub Document_Open()
Call InitializeApp
End Sub
in EventClassModule
Public WithEvents App As Word.Application
in Userform1 Mode
Option Explicit
Private Sub UserForm1_Initialize()
End Sub
I used this 2 links to help me write this code
1) https://msdn.microsoft.com/en-us/library/bb221264%28v=office.12%29.aspx
2) https://msdn.microsoft.com/en-us/library/gg597509%28v=office.14%29.aspx
Can anyone tell why my code does not work?
As explained in the first link you show, the procedure App_DocumentBeforePrint needs to be in the CLASS module (EventClassModule, in your explanation), not in Module 1.
Other than that, it's not clear what you mean by "my add-in". Usually, I'd think of a template (or COM add-in) when this term is used that's being loaded as an add-in. I'm concerned whether Document_Open is actually being triggered to initialize your events. This event, in the ThisDocument module (in reality, it's a class) will only fire when the document containing this code is opened...
For anybody else who comes across this thread like I did, this is what worked for me:
in module 1
(your module shouldn't contain the event-based sub; also, X needs to be declared as a global variable rather than within the 'InitializeApp' sub)
Option Explicit
Dim X As New EventClassModule
Sub InitializeApp()
Set X.App = Word.Application
End Sub
in Document module
Private Sub Document_Open()
Call InitializeApp
End Sub
in EventClassModule
(your Class Module should contain the event-based sub)
Public WithEvents App As Word.Application
Private Sub App_DocumentBeforePrint(ByVal Doc As Document, Cancel As Boolean)
'''Your procedure here
End Sub