« A different pair of eyes | Main | Free PMBOK Download - This nonsense thing »

Working With Microsoft Project Events - On Open

Working With Events

Often one wants Project to do something when something changes in the project file. An example of this is having some sort of macro run when the project is opened or when it is saved. Project offers a number of Project events which allow this. They include:

  • Project_Open (which acts like the On_Open event you may be familiar with),
  • Activate,
  • BeforeClose,
  • BeforeSave,
  • Calculate,
  • Change,
  • Deactivate

These events apply to the project and are fairly simple to implement. There are also a number of application level events which allow you to specify actions based on changes in individual fields. They are somewhat more difficult to implement, but if you can follow the example below you will have no problems.

The list of application events includes:
  • ProjectAfterSave, ProjectAssignmentNew,
  • ProjectBeforeAssignmentChange, ProjectBeforeAssignmentChange2,
  • ProjectBeforeAssignmentDelete, ProjectBeforeAssignmentDelete2,
  • ProjectBeforeAssignmentNew, ProjectBeforeAssignmentNew2,
  • ProjectBeforeClearBaseline,
  • ProjectBeforeClose, ProjectBeforeClose2,
  • ProjectBeforePrint, ProjectBeforePrint2,
  • ProjectBeforeResourceChange, ProjectBeforeResourceChange2,
  • ProjectBeforeResourceDelete, ProjectBeforeResourceDelete2,
  • ProjectBeforeResourceNew, ProjectBeforeResourceNew2,
  • ProjectBeforeSave, ProjectBeforeSave2,
  • ProjectBeforeSaveBaseline,
  • ProjectBeforeTaskChange, ProjectBeforeTaskChange2,
  • ProjectBeforeTaskDelete, ProjectBeforeTaskDelete2,
  • ProjectBeforeTaskNew, ProjectBeforeTaskNew2,
  • ProjectCalculate,
  • ProjectResourceNew,
  • ProjectTaskNew,
  • NewProject,
  • LoadWebPage,
  • ApplicationBeforeClose.

Using a Project Event

This is the simplest form of event.

Open your project file. Hit the ALT+F11 keys to open the visual basic editor. In the upper left you will see a window with a typical windows tree view. Click on the + signs until the project it expanded and you see the "ThisProject" object. It should look like the diagram on the right, although with a different project name.
Double-clicking on that item will bring up a code window. In that window you can paste the following:

Private Sub Project_Open(ByVal pj As Project)
MsgBox "Project Just Opened"
End Sub

You can replace the MsgBox code with whatever you want to happen when you open the project. For example it could call a macro which you have already written.  Similar macros can be written to take action before printing or saving. For example you may want to copy certain data into a custom field before saving the file so that you can restore it later if necessary.

Application Events:

The example above only requires pasting some code in a single place. However using application events requires a few more steps. The first step is to create a new class module and declare an object of type Application with events.
Creating the class module is done by going to the insert menu and selecting "ClassModule" as shown here:

When you have done this, double click on the class module and declare the object by using the following code:

Public WithEvents App As Application

After the new object has been declared with events, it appears in the Object drop-down list box in the class module, and you can write event procedures for the new object. (When you select the new object in the Object box, the valid events for that object are listed in the Procedure drop-down list box.)

Writing the procedure is similar to writing any macro. The image below shows a simple example using the ProjectBeforeTaskChange event.

Note that NewVal holds the value that the user has input. The original value can still be referenced in the standard way (t.Name). The code to cut and paste is shown next.

Public WithEvents App As Application

Private Sub App_ProjectBeforeTaskChange(ByVal t As Task, _
ByVal Field As PjField, _
ByVal NewVal As Variant, _
Cancel As Boolean)

If Field = pjTaskName And NewVal = "foo" Then
MsgBox ("you can not change the name to foo")
MsgBox ("The old name was " & t.Name)
Cancel = True
End If

Note that a space followed with an underscore is used to break a single line of code. This is called a line continuation and I use it to keep code readable when there is a long line. Now that you have written the code, there is one final step to undertake before using it. Before the procedures will run you must connect the declared object (in this case the one we called "App") in the class module with the Application object.
It sounds complicated, but it is really rather simple. First we declare a new object based on the class module. In this case our class module is named TEvent.
Code to do this would be something like:

Dim X As New TEvent

Now that we have this object we need to initialize it. Basically we need to tell it what the "App" is.

We do this with the following code:
Set X.App = Application

After you run the InitializeApp procedure, the App object in the class module points to the Microsoft Project Application object, and the event procedures in the class module will run when the events occur.
Most of the time you will want to do the initalization when your project opens so the events will work from the start, but you can put this information in any typical module which holds some of your macros.
The screenshot below shows what it would look like if we want it to initialize when the project file opens.

This example shows how events can be in a specific project file. You can also have this code in the global.mpt file so that things occur whenever you open Project as an application. The Project_Open event is also useful to distribute macros or other standard formatting. For example, you could have a Project_Open macro which sets up an environment for you (copying views tables etc.) using the organizer. When a user opens the file, those items could be copied into their global.mpt file. (Note: You might notice this is familiar. That is because I'm porting the material from my old Microsoft Project Macros website to this one bit by bit so that everything can be found in one place)

Comments (3)


The ProjectBeforeTaskChange is useful if you want to do validation on the newly entered data. A real lack is a ProjectAfterTaskChange event, if you want to perform an action as a result of the data that is entered. In the add-in I was working on, it was opening a form for additional data entry if a certain option was selected from a drop down.

Hopefully a forthcoming version of MSP will support a richer event model.

Chris Most:

Whenever "NA" appears in the Date1 or Date2 columns I need the NA to display in the color red. How do I do that?
Easiest way to do this is to record a macro of coloring the field, then edit it to iterate through all tasks and check the value of those fields and if that is the case then apply the formatting to that task. -Jack


This post has been very useful for me, thanks.
Can I have multiple event handler? I.e. two Project_Open subs?
I want to distribute my macros to others and they might already have a Project_Open event handler.

I do not think that would work out. The only way to be sure is to test it out. -JD

Post a comment

(Comments are moderated to fight SPAM and will be published after I have a chance to approve them. Thanks for waiting.)


The previous article is A different pair of eyes.

The next article is Free PMBOK Download - This nonsense thing.

Current articles are in the main index page and you can find a complete list of articles in the archives.

Creative Commons License
This weblog is licensed under a Creative Commons License.
Powered by
Movable Type 3.34