Welcome to the Axosoft Community, Sign in | Register | Help
in Search

David Higgins

General Development Blog

Design your Project in Microsoft Project, Manage it in OnTime!

As the title suggests, this article will describe how you can utilize Microsoft Project to Design your overall Project Layout and Manage it with Axosoft's OnTime 2007.  Provided with this article is complete source, written against the Office .NET Assemblies and the OnTime 2007 SDK.

As usual, let's see some eye candy first, then we'll go into details ...

 

Here's the actual startup form, the source provided allows for a
single command-line parameter to be passed, which is the path
to the MS Project (*.mpp) file to import


 

Here's a standard .NET 'OpenFileDialog', and we're selecting the example project

 

 

Here we are, selecting the OnTime 2007 Project
to import the MS Project items into 

 

 

After selecting 'Convert', you'll see MS Project launch and open the Project (*.mpp) file you selected --
and look, is that a Gantt Chart?

 

 

Here, we disable all the form controls, and show
a progress bar (this bar cycles twice, and I'll
explain why in a minute) 

 

 

Here's a nice "Complete!"
notification popup 

 

 

And here's what the tool looks like after it's complete ... 

 

 

Ok, now after seeing all that, your probably sitting there going ... "Huh?".  Trust me, I wasn't too impressed with the screenshots either, and I wrote the thing ... BUT, you want to know why this is so cool?


You do? Good ... picture this, one thing I've come across in my various positions over the years is a Project Manager using Microsoft Project to design a general time-line and work schedule, almost every one of these Project Managers turns around and spends just about as much time as they did designing the MS Project layout as they do trying to convert it into something that their employee's can work with, in this case, a Project Management Tool such as Axosoft's OnTime.  Why do Project Managers like to use Project, simple, it's got Gantt Charts and all sorts of other nifty scheduling functionalities that allows the Project Manager to design an efficient schedule.  Why do the spend so much time converting Project layouts into tools like OnTime, again, quite simple, OnTime has the tools and functionality to get things done.

 

The Technical Details

Requirements:

  • Visual Studio 2005
  • Microsoft Project 2003
  • Microsoft Office .NET Interop Assemblies
  • OnTime Client
  • OnTime SDK

Time Invested: 4 work hours (2 hours research, 2 hours code)

 

Now, onto the more technical details, and this time, I'll actually get into some source in the post, since in all honesty, this example is quite simple and contains very little source.

First, we create a new Windows Application in Visual Studio, and after the solution has been created your going to add a reference to a few things, and they are;

  • COM -> Microsoft Office 11.0 Object Library
  • COM -> Microsoft Project 11.0 Object Library
  • Web -> OnTime SDK Task Service
  • Web -> OnTime SDK Feature Service
  • Web -> OnTime SDK Project Service
  • Web -> OnTime SDK RelatedItems Server

 Once you've added all the above references, add a form Windows Form to the project (or open the default form if one exists in the project) and drop two Labels, one TextBox control and one ComboBox control, two Button controls and a progress bar.  Also, while your at it, toss an OpenFileDialog into the form as well.  We'll name the first TextBox "txtMSProject" and the ComboBox will be called mbProjects.  We'll put the first label to the left of the TextBox and put "MS Project:" as it's Text, and the second label next to the ComboBox and give it the value of "OnTime Project:".

Place the first Button to the right of the TextBox, and give it the value Text value of "..." and assign the following code to the Click event:

        private void bBrowse_Click(object sender, EventArgs e)
        {
            openFileDialog1.ShowDialog();
            txtMSProject.Text = openFileDialog1.FileName;
        }

 

Now, for the Forms Load event, we're going to grab a list of all the Projects available in OnTime and add them as objects to the ComboBox.  To do this, I created a custom 'OnTimeProject' class which contains the ProjectId and ProjectName and an override for the ToString() method so that the ComboBox displays the Project's Name rather then the Class Name.

 Here's the code for the OnTimeProject class;

    public class OnTimeProject
    {
        public string Name;
        public int ProjectId;
        public override string ToString()
        {
            return Name;
        }
    }

 
 Now, to get a list of all the projects from the OnTime SDK, we create a ProjectHandler object instance and then call the projectHandler.getAllProjects(Guid SecurityToken) method.  This will return a DataSet, containing all the information you'll need to know about your OnTime Projects, we then do a 'foreach' loop through this DataSet (more specifically, the first tables DataRow collection, 'Rows') and create a new OnTimeProject instance and assign the Name and ProjectId and add it to the ComboBox's Items, here's the code for that;

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            OnTimeProjects.ProjectHandler projectHandler =
                new OnTimeProjects.ProjectHandler();
            DataSet otProjects = projectHandler.GetAllProjects(securityToken);
            foreach (DataRow dr in otProjects.Tables[0].Rows)
            {
                OnTimeProject p = new OnTimeProject();
                p.Name = (string)dr["Name"];
                p.ProjectId = (int)dr["ProjectId"];
                cbProjects.Items.Add(p);
            }
        }

For clarification, the 'securityToken' parameter passed to GetAllProjects() is a Guid defined in the source that contains the same Guid value as the OnTime SDK's  Web.config SecurityToken value -- this is used as a security measure, to prevent unwanted users from accessing data from your OnTime SDK without authorization.

 Now, with what we have so far, you should be able to test-run your code and your ComboBox should be pre-populated with your projects from OnTime and your 'Browse' button should allow you to locate and reference a file, storing it's value in the txtMSProject TextBox.

Now for the fun part, let's do some Microsoft Project Automation!

To launch an instance of Microsoft Project, or reference the currently running instance, you need the following code;

ApplicationClass prjApp = new ApplicationClass();

This prjApp has a number of properties available, and were going to set the Visible property to true.  This is not necessary, but is helpful for debugging, by default the Application is hidden, unless it's referencing an already running instance of Microsoft Project.

To open an MS Project File (*.mpp), you use the FileOpen() method in the ApplicationClass, for this example, were not really concerned about most of the parameters passed to this method, so we pass Type.Missing rather then null.

string fName = txtMSProject.Text;
prjApp.FileOpen(fName, true, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, PjPoolOpen.pjPoolReadOnly, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing);

You'll notice the PjPoolOpen.pjPoolReadOnly value passed, this prevents our code from altering the MS Project file in any way, as the file is opened in Read-Only mode (again, not absolutely necessary, but a nice safe guard).  Once you've opened your Project file, it becomes the ActiveProject and can be referenced by the prjApp.ActiveProject, which is a Project object instance.

Now that we have a Project reference, we can begin going through all of it's tasks, which are in the Tasks collection, a property of the Project class.

foreach(Task task in project.Tasks) { }

So far, we've got the skeleton structure of our converter, now let's create some OnTime Tasks and introduce them into our OnTime database, ok?

Let's create an instance of the TaskHandler class, this will allow us to call the AddTask() method.

OnTimeTasks.TaskHandler taskHandler = new OnTimeTasks.TaskHandler();

Now, to create an OnTime Task, we have to create an OnTimeTasks.Task object, set our values, and then call the taskHandler.AddTask(Guid SecurityToken, OnTimeTasks.Task) method (FYI - OnTimeTasks is what I called my Web Reference to the OnTime Task Service), let's look at some sample code;

OnTimeTasks otTask = new OnTimeTasks.Task();
otTask.Name = task.Name; // sets the OnTime Task Name to the Project Task Name
onTask.StartDate = (DateTime)task.Start;
otTask.DueDate = (DateTime)task.Finish;
otTask.Notes = task.Notes;
// 60 minutes, 8 hours in a day
int days = (int)task.Duration / 60 / 8;
otTask.EstimatedDuration = days;
// Days (select * from OnTimeDB..TimeUnitTypes)
otTask.DurationUnitTypeId = 1;
otTask.ProjectId = (cbProjects.SelectedItem as OnTimeProject).ProjectId; 
otTask.TaskId = taskHandler.AddTask(otTask);

Ok, most of that should be fairly obvious, but the stuff toward the end might not be, the EstimationDuration and DurationUnitTypeId are probably the two most obscure properties were going to work with.  The EstimatedDuration property stores a System.Int32 which represents the number of Minutes that the task is estimated to take, however, in OnTime we want to display this as a much smaller number, since presumably we'll spend much more then a few minutes on a single task (remember, MS Project is for setting up the 'Big Picture').  The DurationUnitTypeId is another System.Int32, whose value needs to match a value from the TimeUnitTypes table in the OnTime Database.  The SQL Query needed to look at this tables data is provided in the preceeding comment.  Once you've found the value for the 'Days' type, put it in the DurationUnitTypeId.

After we set all our of Task values, and have added the Task into OnTime, we can switch over to our favorite OnTime Client (Web, Windows or VS.NET) and Refresh our view and your Task(s) should now be present.

Now, your probably thinking to yourself, "What good is this if I can't go back?".  Your right, this tool is fairly useless, as it is now, because all it does is convert an MS Project to an OnTime Project -- but, with little work, you can have a completely customized Synchronization Tool written in a matter of hours.  Why didn't I include this ability in the sample? Well, it's a tad beyond the scope of a "sample" for one, but mainly because such a tool would need to be tailored to your specific needs and usage of both applications and there is no hard-set standard for this, so I simply omitted that functionality.

 In short though, if you want to introduce tasks into Microsoft Project from OnTime, you can more or less just completely flip the logic used in this sample, and create tasks in Project from tasks in OnTime -- you can even, using Custom Fields to store meta-data (OnTime TaskId and Project TaskId) perform synchronization, so that your Project Manager can quickly say "Sychronize" from a pre-defined Macro which launches a Shell (VBA, gotta love to hate it ... I mean, hate to love it ... err ... its there, just use it ;p) that executes your custom synchronization app -- an example VBA macro would be:

 
Sub SynchronizeOnTime()
Dim i as Double
i = Shell("path\to\your\exe" & " " & ActiveProject.Path & "\" & ActiveProject.Name, vbNormalFocus)
End Sub

Which could easily launch your tool and pass the current Projects File path to it, so that a synchronization could be performed -- storing additional meta-data in your Project's Properties using Custom Fields, you can determine the OnTime project to lookup, and the Tasks to keep in sync --  

For the complete source to this example, please goto the download page.
To discuss this sample, please refer to this forum thread.
 

Published Monday, April 23, 2007 9:19 AM by David Higgins

Comments

 

DynoEnviro said:

Can you use the same project file and 'update' the OnTime project to which you originally sync'd the schedule, or will the app simply write new records to the project if you attempt this?

April 25, 2007 4:25 PM
 

David Higgins said:

Dyno -- the last 2-3 paragraphs go into a really quick summary of what your talking about -- basically, this example, as it is written ... is not capable of synchronizing project and ontime together and keeping items the same --

However, a quick run down of how to do this is mentioned in the last few paragraphs, but I'll try to go into more detail --

To synchronize the two Projects (OnTime and the MS Project) you would have to store relative information in both about each-other, the most likely thing to store is the OnTime Item ID and the Project Task.ID properties -- so when you add the MS Project Task to OnTime as an Item, simply update the MS Project Task and store the returned OnTime Item ID (TaskId, FeatureId, DefectId, IncidentId -- depending on your use).  You can then also store the MS Project Task.ID Property in a Custom Field in OnTime -- for Tasks, this is sort of simplified since there is a legacy property exposed by the SDK called "TaskNumber" which is simply a string that you can store an alphanumeric value in -- this property is not exposed through the OnTime UI however (where a Custom Field would be).

So -- in short -- create a Custom Field in MS Project (or use one of the many various fields such as Text1-20+) and a Custom Field in OnTime (code already exists in this example for writing to a 'Resources' custom field if it exists, reading from is the reverse logic).

Hope that helps answer your question --

April 25, 2007 4:32 PM
 

DynoEnviro said:

This is a great idea. I created and posted a similar application many months ago that used VBA behind MS Project, ADO and ODBC. The application worked both ways, however.

I know that the implementation is somewhat specific to individual projects manager's needs, but it wouldn't be difficult to provide your user base with one that covered the basics of two-way syncronization. Axosoft made similar assumptions in the early releases of OnTime.

Us project managers (not to mention our teams that are building OUR software) don't have a lot of time to build robust utilities...that's why we have apps like OnTime in the first place.

I don't know what the Axosoft business objectives are, but at some point it would seem pertinent to start filling in the gaps around the SDLC processes that OnTime does not cover. Maybe a Utilities division? :o)

April 25, 2007 4:33 PM
 

DynoEnviro said:

Thanks for the explanation, David. I plan to download the app and use it as a base. I'll submit anything useful that I'm able to build.

April 25, 2007 4:37 PM
 

Hamid said:

Dyno, we agree that such a tool would be useful.  We have a lot of great stuff on our plate, not sure when we'll get to a 2-way converter for MS Project though.

April 25, 2007 4:54 PM
 

free tamil polyphonic ringtones nokia said:

free tamil polyphonic ringtones nokia

October 27, 2007 2:52 AM
New Comments to this post are disabled


© 2002 - 2007, Axosoft, LLC. All Rights Reserved. | Privacy
Bug Tracking | Defect Tracking Videos | Help Desk Software