This presentation covers three main topics:
The principal objective of this session is to provide developers with practical techniques for developing applications using Microsoft Project. The main tools of the Microsoft Project developer are VBA, OLE, the Windows® API, and of course, Microsoft Project.
Another important part of the developer's toolkit is sample code. Whenever possible, I have tried to provide sample code that implements the concepts discussed during this session.
There are two categories of sample code provided with this session. The first category includes routines that accomplish useful tasks. These routines are well documented, self-contained procedures that can be used as-is. This category of procedures may be recognized by the detailed procedure headers that document arguments, return values, and special considerations for use (if any).
The second category of sample code includes routines that were specifically intended to illustrate some aspect of Microsoft Project programming. These routines are of limited usefulness, except with respect to the concepts that they illustrate.
Most of the Microsoft Project objects that an application needs to work with are part of collections. Common collections include Projects, Tasks, Resources, and Assignments.
A collection is similar to an array, in that an individual object in a collection may be accessed using an index. Microsoft Project collections have indexes that base 1 indexes, meaning that the first element of a collection has an index value of 1, the second element has index 2, and so forth. By default, arrays of standard VBA data types use 0 (base 0) as the index to the first element of the array. To make it easier to work with arrays of Microsoft Project objects, a programmer may include the Option Base 1 statement in the declarations section of code modules. This will change the default for VBA arrays to base 1.
Many Microsoft Project collections are also indexed by object name. For example, the following statements will all return the scheduled start date of the task whose name is "Task 1" and whose ID is 2:
ActiveProject.Tasks("task 1").Start ActiveProject.Tasks(2).Start
Notice that indexing by name is not case sensitive. The following collections may be indexed by object name:
Window objects are indexed by caption, rather than by name. This can lead to unexpected results. For example, suppose that an application has opened a file called "Product X Marketing Plan.MPP", and that this file has the "Read-only recommended" option turned on. In this case, the actual window caption may be "Product X Marketing Plan.MPP (Read Only)" If the application attempts to use the project name to access the project's window, a run-time error will result.
Some collections also support indexing by unique ID. The following collections may be indexed by unique ID:
The UniqueID method is used to indicate that the supplied index is a unique ID. For example, the following statements will return the name of the resource whose ID is 7, but whose unique ID is 15:
ActiveProject.Resources(7).Name ActiveProject.Resources.UniqueID(15).Name
When using the UniqueID property, keep in mind that even unique IDs may change. If a user moves a task or resource by first selecting the row, then dragging it to the new location, the unique ID will not change. However, if the user performs an Edit Cut / Edit Paste operation, then a new unique ID will be assigned to the task or resource. This means that if a user has the capability to cut and paste, then you cannot rely entirely on the UniqueID property to positively identify a task or resource object. Although Project objects have a UniqueID property, Project objects cannot be accessed using the UniqueID method.