|| Home | Excel | Access | Word | Outlook | FrontPage | VBA | Downloads | Index ||
Where Does the Code Go?
You can build the calendar in Normal.dot which is Word's "Normal" template. It is loaded whenever Word opens so if placed here, you calendar will always be available to you. If you plan to distribute the calendar tool to other users it would be better to create it in a new, empty document which can be saved as a template. This template can be loaded automatically like an Add-In, so that it is available whenever Word opens, without the need to alter individual users' copies of Normal.dot.
Building the Calendar
Step 1: Open a New UserForm
Open Microsoft Word. If you are planning to create your calendar in a template you will need a new, empty document. Next, open the Visual Basic Editor by choosing Tools > Macro > Visual Basic Editor (or keys: Alt+F11).
In the Project Explorer window, normally in the upper left corner of the Visual Basic editor) locate and click on the document in which you want to build the calendar, either Normal (the Normal Template) or Project (Document1) (where "Document1" is the name of your new, empty document in Word). If the Project Explorer is not visible, open it from the View menu.
In this example I am going to create the calendar in the new document (shown here as "Document1").
The Properties Window (usually located in the lower left corner of the Visual Basic Editor) displays all the properties of the the currently selected object. If the Properties Window is not visible open it from the View menu. Click on the UserForm to select it and make the following changes in the Properties Window:
Step 2: Locate the Calendar Control Tool
You need to draw a Calendar Control (active objects on forms are called "controls") on the UserForm, but the one you need is not normally included in the Toolbox. If you haven't already installed the Calendar Control tool, go to Tools > Additional Controls. If you find that the Additional Tools option is greyed-out, it's because the Toolbox is not visible. Switch it on with View > Toolbox. In the dialog box find Calendar Control 10.0 (10.0 for Word 2002, 9.0 for Word 2000 and 8.0 for Word 97) and select it. Click the <OK> button to close the dialog. This adds a new button to the toolbox, labelled Calendar:
NOTE: The Calendar Control is an ActiveX control (actually a file called mscal.ocx) supplied with Microsoft Office. It is normally installed with a standard installation of Microsoft Office Professional or Microsoft Access, but if you can't find it on the list you will need to get hold of a copy. If you are distributing your file, or planning to use it on more than one computer, you will also need to make sure that the host computer has the mscal.ocx file installed. You will find it on the CD that your copy of Microsoft Office Professional came on, or you can download a copy from here.
Step 3: Add a Calendar Control to the UserForm
Click the Calendar tool then click on the UserForm near its upper left corner to place a calendar on the UserForm.
Make sure the calendar is selected then take a look at the choices in the properties window. Click on the Custom category (near the top of the list) and click the [...] button to open the calendar control's custom properties dialog. You can format the calendar any way you like. I made the following changes...
General - Show Month/Year
Omitting the title and making the text smaller allowed me to resize the calendar to a smaller rectangle by dragging the resize handles (white rectangles)...
Now click on the UserForm itself so that you can see its resizing handles and resize it to fit the calendar...
To get a preview of how the calendar will look click the F5 key. When you do this the UserForm will open in Word as it would in use. Click the UserForm's close button ([x]) to return to the Visual Basic Editor.
Step 4: Add a Command Button
If the user opens the calendar by mistake, they will be able to close it by clicking the [x] button without inserting a date on the document. Most users also expect a form or dialog box to close without making changes if they press the [ESCAPE] key on their keyboard. This doesn't happen by itself. You have to program the UserForm to respond to this event. To do this you will place a command button on the UserForm which closes it when clicked. By setting the button's Cancel property to True the effect of the user hitting the [ESCAPE] key will be to programmatically click the button. The user doesn't need to see the button, so you can hide it behind the calendar.
Click the Command Button tool on the toolbox then click on the calendar (just left of centre) to place a command button on the UserForm. Note that the command button places itself behind the calendar by default, although you can still see its outline when it is selected...
With the command button selected, make the
following changes in the properties window... Name: cmdClose
Step 5: Write Code for the Command Button
This step adds some code to the Click event of the command button so that when clicked (i.e. when the user hits the [ESCAPE] key) the UserForm closes without anything else happening.
Go to View > Code (Keys: F7) to open the UserForm's code window. If the command button was still selected there will already be an entry. If not, choose cmdClose from the left hand (General) drop-down list at the top of the code window. It should automatically select Click from the right-hand (Declarations) list. Place your cursor between the Sub... and End Sub lines and press the [TAB] key to indent your code. Type Unload Me. Your line of code will look like this:
Use [CTRL]+[TAB] (or go to Window > frmCalendar(UserForm)) to switch back to the UserForm window and test the code. Press [F5] to open the form in Word. Notice that the command button is invisible (it is behind the calendar). Press the [ESCAPE] key and see that the UserForm closes.
This step builds the code that will transfer the date that the user chooses to the insertion point on the Word document. If anything is selected the selection will be replaced by the date.
Return to the UserForm's code window. Open the left-hand (General) drop-down list at the top of the code window and choose Calendar1. If it is not already selected, choose Click in the right-hand list. This enters the start and end lines of the Calendar1_Click procedure.
Place the cursor between the two lines and press [TAB] to indent your code (indenting blocks of code is good practice - it makes the code easier to read) then type:
Selection.Text = Format(Calendar1.Value, "dd mmmm yyyy")
...which transfers the date selected on the calendar to the insertion point on the document.
[NOTE: You can use any date format you choose. If you are unfamiliar with date format codes, see the explanation at the end of this tutorial.]
On the next line type:
Selection.MoveRight Unit:=wdCharacter, Count:=1
...which moves the insertion point to the end of the date text, ready for the user to continue typing. On the next line type:
...which closes the form. Your code should look like this:
To make the calendar a bit more user-friendly you will now add some code that checks to see if the user's selection already contains a date. If it does, then the calendar will show the same date when it opens. If there is no text selected (or if the selected text is not a date) the calendar will show today's date. To do this we make use of the UserForm's Initialize event, which happens as the UserForm opens.
Open the left-hand drop-down list at the top of the code window and choose UserForm, then open the right-hand list and choose Initialize. (You will notice that when you chose "Initialize" the start and end lines for the UserForm_Click procedure were created. You don't need these so it is safe to delete them.)
Place your cursor between the start and end lines of the UserForm_Initialize procedure and type the following:
If IsDate(Selection.Text) Then
This IF Statement checks the current selection for a date. If it is a date then the calendar displays the same date. If not it uses the VBA Date function to display the current date. Your completed code should look like this:
Now you need to write some code to display the UserForm on demand:
Type the line Sub OpenCalendar and press enter. The Visual Basic Editor places a pair of brackets at the end of the line and adds the line End Sub, placing your cursor between them. Press [TAB] then type frmCalendar.Show. Your code should look like this:
This simple procedure will display the UserForm when run from Word.
At this point it is a good idea to save your file in case something goes wrong! In the Visual Basic Editor window select your file in the Project Explorer and choose File > Save Document1 (or whatever your file is called) and give it a suitable name. Save it as a document for now - you will convert it to a template later.
If you are working in Normal.dot select Normal in the Project Explorer and choose File > Save Normal.
Switch to Word and place the cursor where you want to insert a date. Choose Tools > Macro > Macros (Keys: Alt + F8) to open the Macro dialog. Make sure that the macro OpenCalendar is selected and click <Run>.
When the calendar opens it will display today's date. Choose a date (NOTE: always choose month and year before choosing day because clicking on a day fires the Calendar1_Click event). When you click the day the calendar closes and enters your date into the document.
Now type a date into your document, select it, and run the macro. If the program recognises that your selection is a date, the calendar will display that date when it opens. If you wish you can choose another date, or you can press the [ESCAPE] key to close the calendar without making any changes.
Step 8: Install the File
If you have been working in Normal.dot you don't need to do anything else, but remember to save the changes to the Normal Template if Word asks you when you close it down. If you intend to distribute your calendar, you will have followed my advice earlier to create it in a new document and later save it as a template. If you want to add the extra features of a keyboard shortcut and right-click menu option, continue with the tutorial. Otherwise jump to the final section "Install the Calendar" below...
Adding Extra Features
Adding a Toolbar Button or Menu Item
It is usually convenient to assign your macros to custom toolbar buttons or menu items. The method for doing this was covered in detail in my tutorial A Pop-up Calendar for Excel so I won't repeat it here. That tutorial also describes how to add a command to the context (right-click) menu and set a keyboard shortcut programmatically. The method for doing that in Word is slightly different from that in Excel so here's how to do it...
Assign a Keyboard Shortcut with Code
In the Visual Basic Editor double-click the ThisDocument entry in the Project Explorer for the document that contains your calendar. Open the left-hand (General) drop-down list at the top of the code window and choose Document and in the right-hand (Declarations) list choose Open. This creates the start and end lines for the Document_Open procedure. This is a special macro that runs automatically whenever the document is opened. Between the start and end lines type the lines:
NOTE: To make the code easy to read, some of the code lines have been broken using the VBA line-break character which is a Space followed by an Underscore ( _). This character ensures that the code is read as a single line. Without it the code would not be accepted.
These statements assign the keyboard shortcut Ctrl+Shift+C to the macro that opens the calendar UserForm. You can choose a different combination of keys if you wish. If your OpenCalendar procedure is in a different module you must enter the module name instead of "ThisDocument" or omit it (and the dot separator) altogether. Here's how the code should look:
This keyboard shortcut is assigned whenever the document is opened. It is a good idea to create a corresponding procedure to cancel the shortcut when the document closes.
In the same way as you did above, create a Document_Close procedure and enter the line:
On Error Resume Next
followed by the lines:
The first line tells Word to ignore any error that might occur in this procedure (this is safe to do here because the only possible error is that there is no such keyboard shortcut, so if the instruction to delete it fails it's OK to ignore it). Then comes the statement which cancels the keyboard shortcut assignment as the document closes. The code should look like this:
You will need to save and close the workbook and then reopen it before you can test your keyboard shortcut. If you are using Normal.dot you will need to close Word and reopen it. Save the file first!
Add an Item to the Right-Click (Context) Menu
It is also a simple matter to place a command on Word's text context menu. This will allow the user to right-click where the date is to be inserted and choose from the pop-up menu.
This is how you add an "Insert Date" entry (or whatever wording you choose) to the right-click menu. As with the procedure for assigning a keyboard shortcut, this requires two sets of code: one to create the menu item when the document opens, and another to remove it when the document closes.
First, find the Document_Open procedure in which you placed the code for creating a keyboard shortcut (or if you chose not to use a shortcut, create the procedure as described above). Insert the following line at the top of the procedure:
Dim NewControl As CommandBarControl
Move to the end of the procedure and add the line:
Set NewControl = Application.CommandBars("Text").Controls.Add
These two lines add the new control (i.e. menu item) to the menu (called in VBA a "command bar") that appears when the user right-clicks on text (i.e. on the editable part of a page). The next step is to describe the control's properties. Enter the following:
As before, if your OpenCalendar procedure is in a different module you must enter the module name instead of "ThisDocument" or omit it (and the dot separator) altogether.
The finished Document_Open procedure looks like this:
Finally, add this line to the end of the Document_Close procedure:
This line removes the entry from the right-click menu as the document closes. The finished Document_Close procedure looks like this:
Help! I've Got Too Many Menu Items...
Into the Immediate Window type the line:
then press the [Enter] key. Go back onto Word and right-click on the page. One of the "Insert Date" entries should have disappeared. Do it as many times as necessary to remove the unwanted copies. Then look through your code and try to find the error that is causing the problem.
Unless you have been working in the Normal template, your calendar will now have to be saved as a Word template (*.dot) file. So, the next step is to save your working document as a template in Word's Startup folder. The reason for storing it here is that it will open automatically (and invisibly) whenever Word is started so the pop-up calendar tool will be available to any document.
First you need to ascertain the location of the Word's Startup folder on your computer. This differs with different versions of Windows and Office, and several programs have their own Startup folders, so it is important to get the right one. In Word choose Tools > Options > File Locations and locate "Startup" in the list:
To automatically install the Popup Calendar template for the first time you must close Word and open it again. After that it will load by itself each time Word opens.
Using the Pop-up Calendar
From now on each time you start Word the Pop-up Calendar will be available by using the keyboard shortcut you assigned or from the new item on the right-click menu.
If you chose not to add these enhancements you can open the calendar by running the OpenCalendar macro as described in Step 7: Test the Code above. You can also add a custom toolbar button or menu item if you wish.
Deactivating the Pop-up Calendar Template
You can temporarily deactivate the Pop-up Calendar template from Word by choosing Tools > Templates and Add-Ins where you will see it listed in the Templates and Add-Ins dialog. Remove the tick from the checkbox next to the template's name to unload the template for the current session. If you want to prevent the template from loading at startup you should also remove the template file from the Startup folder. [Click the thumbnail below to see a full-sized image of the Templates and Add-Ins dialog.]
Modifying the Pop-up Calendar Template
The Visual Basic Editor will not allow you to view the code of a template that is loaded from the Startup folder. If you attempt to do so a message will be displayed notifying you that the "Project is unviewable". If you need to modify the code, first deactivate the template as described above, then open the file in Word using the File > Open command. You will then be able to work on the code as normal.
Different Versions of Word
The VBA code used in this tutorial is suitable for all current versions of Microsoft Word (97, 2000 and 2002). If you create the Pop-up Calendar template in one version of Word and plan to use it in another version you should not encounter any problems but it is a good idea to check first. Each version of Microsoft Office comes with its own version of the ActiveX Calendar Control (8.0 for Office 97, 9.0 for Office 2000 and 10.0 for Office 2002). The first time you activate the template in a version of Office different from the one in which you created it, the program should automatically substitute the existing Calendar Control to the one current for that version. I found that when converting back from Word 2002 to Word 2000 this resulted in a change in the font size of the calendar buttons. This was easily fixed by redrawing the calendar in the current version.
There is a standard notation for specifying date formats using a combination of codes for day, month and year (also hour, minute and second of you wish to specify time):
Using these codes, in conjunction with slashes, spaces or other punctuation characters you can construct any date format you choose, for example:
In different parts of the world there are different conventions for writing dates. In the US dates are normally written in the order Month, Day, Year but in Europe Day, Month, Year is used. If you are not sure where your users will be located you may not want to "hard code" a date format into your code as this might lead to misunderstandings. Instead you can display the date based on the computer's date settings in the Regional Settings section of the Windows Control Panel. In VBA you can still retain a degree of control by choosing one of the VBA date formats, for example:
NOTE: The user can modify these settings so they might appear different from those shown here. The ISO standard date format is yyyy-mm-dd (ISO 8601) e.g.: 2003-09-27.
You can download a fully working example of the Pop-up Calendar as a Word template (.dot) file. There is one for each version of Microsoft Word although they should convert easily between versions. If the template fails to run correctly, it will be because your system does not contain a copy of the ActiveX Calendar Control. See the note above for how to obtain a copy. To download one of the files right-click the link and choose Save Target As...
Want to Build a Better Calendar?
Do you want to build a more fully-functioned calendar and learn some more useful VBA programming techniques? The second part of this tutorial shows you how to take the Pop-up Calendar project a step further by offering a the user a choice of formats and allowing a default date format to be set. Find out more in A Pop-up Calendar for Word Part 2: Customizing the Calendar.