Software

How to automatically execute a Word macro when you create, open, or close a document

By adding a macro to a template's New, Open, and Close event procedures, you can automate a number of tasks, making you more efficient and productive.

You probably know that you can reduce the amount of time you spend formatting documents by making those format changes to your template, but did you know that you can add macros to a template? You'd do so to automate a regular task in all documents based on the template. Specifically, you can add macros to a template that run when you create a new document or open and close an existing document (based on the template).

Automate a task when creating a new document To create a new document, you click New, press [Ctrl]+N, or choose New from the File menu/tab. You can get Word to execute a task when you create a new document using the Document_New event procedure, as follows:

  1. Open the template. You'll find normal.dot or normal.dotm in the Documents and Settings\Administrator/user\Application Data\Microsoft\Templates folder. You can use any template, not just normal.dot or normal.dotm.
  2. Launch the Visual Basic Editor (VBE) by pressing [Alt]+F11.
  3. In the Project Explorer, double-click ThisDocument.
  4. In the resulting module, enter the event procedure shown below.
  5. Click Save and close the VBE.

Private Sub Document_New()

  'Greet user.

  MsgBox "Greetings", vbOKOnly, "Greetings"

End Sub

When you return to Word, close the template file. Then, create a new document. Word will open a new blank document and display a simple greeting in a message box. Click OK to close the message. (The macro is simple on purpose as this technique is about the event procedure and its relationship to a template. What the macro does isn't important to the technique.) Automate a task when opening an existing document You can automate a task when opening an existing document in much the same way. The only thing that changes is the event procedure. In this case, you'd use the following Document_Open event:
Private Sub Document_Open()

  'Greet user.

  MsgBox "Greetings", vbOKOnly, "Greetings"

End Sub

You can apply this macro to a template or to an existing document. If you add this macro to the template, Word will save it with every new document you create. In other words, every document you create (based on that template) will execute this macro every time you open it.

Automate a task when closing an existing document I have one last event procedure to cover - one that automates a task when you close a document. Like the last macro, if you add the macro to a template, Word will execute the macro every time you  close any document based on the template. Use the following event procedure:
Private Sub Document_Close()

  'Greet user.

  MsgBox "Greetings", vbOKOnly, "Greetings"

End Sub

Automating a task for all documents by adding it to the template could make you more efficient!

About

Susan Sales Harkins is an IT consultant, specializing in desktop solutions. Previously, she was editor in chief for The Cobb Group, the world's largest publisher of technical journals.

15 comments
PattiCakes1229
PattiCakes1229

Why isn't this working for me?  I need to make spell check auto run on Saving file, however, when I use the Document_Close(), my codes won't work.  It will, however, work when I exit by clicking the red x (we have cautioned our employees not to exit documents thru the X and therefore, this is useless for me.  Can someone please tell me if it is even possible to add a macro on Save or Save As function?


arvindpatil
arvindpatil

i used to create a macro in word 2003 whereby could make the cursor appear at the same position where it was when that doc was closed. how do i do it (and other helpful ones) in word 2010

lspringle
lspringle

Good stuff! For doc open: Turn on the ruler. Turn on table gridlines. Turn off/on paragraph marks. Change the view to draft (or print layout). Change to the desired zoom. For new docs: Insert page numbering. For saved docs: Insert the path/filename in the footer.

Andy P Roberts
Andy P Roberts

I have lots of things in my Document Cosing and file saving macros - the one I've had the longest is something that copies the backup file to another directory with the date and time added to the file name which creates an audit trail of documents. I also have something in the EditFind macro that highlights all occurences of a search string in a similar way to Internet Explorer which is really useful but this requires the Document Close / File save macros to clear this highlighting when the document is saved. There's probably other stuff in there that I've forgotten - There is too much code to load it here.

Andy P Roberts
Andy P Roberts

Similarly this isn't the Document_Open but the AutoExec which is run when Word is started and it isn't put in the 'ThisDocument' module but in a normal macro module. Another I find very useful is to open the last document worked on (or it could be more than one doc) by opening the top entry in the recent files list. Code below. Can also hard code a file to open that you are currently working on or always open for refrence. This code needs some Public functions to be declared at the top of the module because it checks whether Word was started by clicking on a document (in which case you don't want the extra file opened). Note: This code also includes a commad to run a separate macro after 3 seconds (i.e. when the autoexec is finished) and that changes which command bars were visible. That macro is below. Public Declare Function GetCommandLine Lib "kernel32" _ Alias "GetCommandLineA" () As Long 'copy the string we have a pointer to into our new string - used to copy command line string Public Declare Function lstrcpy Lib "kernel32" _ Alias "lstrcpyA" (ByVal lpString1 As String, _ ByVal lpString2 As Long) As Long 'get the length of the string (not including the terminating null character) - used on command line string Public Declare Function lstrlen Lib "kernel32" _ Alias "lstrlenA" (ByVal lpString As Long) As Long Sub AutoExec() ' NOTE: This doesn't run if a document already opened from the internet ' For processing of recent files list Dim oRecentFile As RecentFile ' For command line processing Dim strCommandLine As String, strReturn As String, StringLength As Long ' Turn off specified command bars ' ------------------------------- ' Set command to remove PDF and other unwanted command bars at startup ' Application.OnTime When:=Now + TimeValue("00:00:03"), Name:="ZapCmdBar4AutoExec" ' Open most Recent available document ' ----------------------------------- If RecentFiles.Count >= 1 Then ' Get the commandline (because don't want to open document if word is starting from clicking on a .doc file) ' ------------------- On Error GoTo 0 strCommandLine = GetCommandLine() 'get the length of the string (not including the terminating null character) StringLength = lstrlen(strCommandLine) 'initialize our string so it has enough characters including the null character strReturn = String$(StringLength + 1, 0) 'copy the string we have a pointer to into our new string lstrcpy strReturn, strCommandLine 'now strip off the null character at the end strReturn = Left$(strReturn, StringLength) ' If Word was launched from its icon If Len(strReturn) 0 Then Application.CommandBars(i).Visible = False Count = Count + 1 If Count = 2 Then Exit For End If Next i CommandBars("Reviewing").Visible = False CommandBars("Web").Visible = False 'Debug.Print "Zap exit lngFindStart = " + CStr(lngFindStart) End Sub

Andy P Roberts
Andy P Roberts

This isn't the Document_Open but the AutoOpen which is run when documents are opened and it isn't put in the 'ThisDocument' module but in a normal macro modul - I find it very useful to put the document back to the last edit point when it is opened. This is my code - Sub AutoOpen() ' Run when a document is opened ' Set Cursor to last edit location ' -------------------------------- ' If not a protected document then put cursor back to last position in document If ActiveDocument.ProtectionType = wdNoProtection Then ' Save new document sDoc = LCase(ActiveDocument.Path + ActiveDocument.Name) ' Go to place cursor was at when the document was last saved Application.GoBack Sometimes the opened document isnt left as the active document so activate this doc - ' Loop through the docs to find the doc number because activating using the doc name ' causes an error when the doc is opened within an Internet Explorer (or other) Window. For iIdx = 1 To Documents.Count If LCase(Documents(iIdx).Path + Documents(iIdx).Name) = sDoc Then Documents(iIdx).Activate Exit For End If Next iIdx End If End Sub

jonc2011
jonc2011

When working on a Word document in track changes, by default it shows formatting changes. For me, I never need to see these so turn them off. This can also be achieved using an AutoOpen macro in Normal.dot. This is a bit different vba terminology to Susan's approach, but seems to have the same outcome. Sub AutoOpen() ' ' AutoOpen Macro ' Macro recorded 22/10/2010 by Jon ' WordBasic.ShowFormatting End Sub For this to work, track changes needs to be on when the file is saved. There are several auto execute macros AutoExec - runs when Word is started (from the start menu or desktop shortcut) or a global template is loaded. AutoNew - runs on creating a new document. AutoOpen - runs on opening an existing document. AutoClose - runs when a document is closed. AutoExit - runs on closing Word or unloading a global template.

Full Tao-er
Full Tao-er

The simple message box code Susan included in the examples belies the real power available. This tip probably isn't useful for everyone, and I wouldn't use it for most of the work I do, but I can imagine a couple of scenarios. What one has to ask themselves is, "What do I do every time I open Word?" Templates are useful for basic layout of a document. Imagine you are in marketing and regularly send out promotional letters. You will probably have a template with mail merge fields already inserted. But what if the product you are promoting changes often? You could edit the text directly. However, with some careful thought, you could craft the text with a variable field where the product name should go, then have a macro greet you and allow you to input the name of the product, which would be stored as a variable in memory. Upon merging the document, the variable field you carefully inserted in the standard text would be replaced by the product name you entered at the start. Doing that seems like more work than it is worth, unless you use that file often. Consider that this also lets you pass that mail merge task to someone with less technical aptitude, freeing your time up for other things. I would be more inclined to use the closing macro. There could be code that automatically saves a copy of the document with a date tag as part of the filename, then e-mails the document to a pre-defined contact list (distribution list in older versions of Outlook.) A yes/no message box could let you decide whether or not to run the rest of the code. Letting code handle those tasks ensures the same format is always used for the filename and no recipients would be forgotten, which is again useful when others will use the document, too. My examples are likely beyond just a macro and would require some VBA code, but at least you get the idea.

throuble
throuble

Yes, it is good to know that this option is available, but can anyone provide some practical uses for this? Personally, nothing comes to mind...

krsmav
krsmav

Interesting to know, but what are the uses for these techniques? If for example I want to create a letter adjusted to the company letterhead and formatted to company style, I'll create a new template called "CompanyLetterhead" or some such. Other than inserting a footer slug with the document number, creation date and so on, I can't think of many uses for an opening macro in normal.dotx, and if your company is big enough to need this, it's big enough to have a document management system that will do it automatically. I can't think of any use for a document closing macro,

Darryl~
Darryl~ moderator

@PattiCakes1229


Try replacing Document_Close with FileSave

I didn't try it but I think that should work.


Darryl

gmichaels
gmichaels

Good stuff here -- too bad I can't use it. I'm just a plain old Word user, write a doc, format it, save and print. I knew about macros but didn't know there were so many things you could do. I'm assuming this is with the new versions of Word, not my ancient Word 2000? Also, many anti-virus programs trap macros from running -- I'm assuming that they can be allowed to run. You must be a VB programmer?

krsmav
krsmav

Ctrl-Alt-Z jumps to the last cursor position before the prior save.

Andy P Roberts
Andy P Roberts

Macros go back for as long as I can remember Word - I'm sure that was way before Word 2000. The easiest way to get started is to use the 'Record Macro' (Probably under Tools --> Macro --> Record Macro in Word 2000) type in a few commands and then run the macro you've created (Tools --> Macro --> Macros --> Select macro --> click run) or look at the macro code that was created (Macros ... --> Edit). This is not totally 'fool proof' for 2 reasons - - 1. The recorder can't be ceratin what you intend - E.g. if you get to the top of a document by pressing the up arrow 5 times it doesn't know whether you wanted to move up 5 lines or go to the top line of the document however many lines down you are - 2. It doesn't record everything - I don't know why they didn't write it properly but some more obscure commands just don't get written to the macro (E.g If I do a Find to look for Blue text it misses out the bit about Blue and just does a find). For both of these problems you can learn what it's doing by stepping through the macro and seeing what happens on the screen. The code looks horrible to begin with if you're not used to VB/VBA but it becomes more and more useful as time goes on.

Editor's Picks