Import and export Microsoft Project files using Aspose.Tasks API

XenTek is a small software house developing primarily a product called Plan Runner – a tool to aid Project Managers. There is just one employee, Jonathan Tooth who is an accomplished software developer, analyst & consultant with over 30 years of commercial experience ranging from Z80 machine code to C#, VB.Net.

Problem

The tool Planrunner is a complex piece of software that provides a level of control and visibility of ‘running’ projects previously unreachable by Project Managers. Vital to this is being able to accept the assets the Project Manager has created. To this end, the tool provides two mechanisms to input existing project plans. A sync tool that sits inside Microsoft Project and provides the easiest method to the user and import/export tool built into the website for Project Managers who are unwilling or unable to download and install programs from the internet. It is this import/export tool that requires a mechanism to read and write Microsoft project files.

Solution

Three solutions have been trialed over the course of developing PlanRunner, the first two (Microsoft Interop and MPXJ) have been discounted for reasons discussed below. The third solution trialed is that of Aspose.Tasks for .NET. Whilst cost is an issue for a ‘Start-up’ company; having a commercially developed tool does ensure that it is kept up to date and faults are dealt with and fixed in a timely manner.

PlanRunner users do not directly experience the tool directly; they are presented with an interface as shown below:

Project file upload page

Upload

This facilitates the user to get their project plan into Plan Runner. By simply selecting their project file using the ‘Choose file’ button and clicking on the ‘Upload’ button the website uploads and reads their project file, storing selected contents inside a SQL Server database.

The user can control whether the data is merged into the website or erase and overwrite it.

Project file download page

Download

This facilitates the additional information stored by the website to be inserted into the project file the user originally uploaded. The simplest use is to click the ‘Prepare and download the file’ button which updates the originally uploaded project file and downloads it to the user.

Experience

Finding a solution

Originally the reading and writing of Microsoft project files were performed by Microsoft’s own Interop assemblies. This is fine for organizations that are hosting the website internally; however, Microsoft licensing prevents this from being used on public-facing websites.

A decision was made to use MPXJ, an open-source library that enables reading of Microsoft Project files. Unfortunately, this tool would sometimes read Microsoft Project 2013 files incorrectly; this has affected our first customer extensively and is not an acceptable solution.

Aspose.Tasks was trialed to see if it could read and write all of the project files currently available. A free trial reduced financial risk enabling a full POC to be performed. The following criteria were measured to determine the suitability of the product:

  • Ease of integration
  • Reliability of product
  • Performance of product
  • Quality of help
  • Availability of support

Implementation

Effort

Integration of Aspose.Tasks into the Plan Runner import/export mechanism took:

  • Coding and unit testing Upload mechanism – 7 hours
  • System Testing including bug fixing – 7 hours
  • Coding and unit testing Download mechanism – 5 hours
  • System Testing including bug fixing – 7 hours
  • User Acceptance Testing (of both mechanisms) – 6.5 hours

This results in a total of 32.5 hours.

A rough comparison to the integration of MPXJ is possible. It is favorable to Aspose.Tasks as MPXJ coding was quicker at ~10 hours however testing and debugging took over 40 hours.

Technical Solution

Implementation was made easier by having had two previous mechanisms. While integrating MPXJ the decision was made to isolate all project file reading and writing. A shared library that provided the business logic and connectivity to SQL Server was created along with a ‘Neutral Task’ class that hid tool specific code.

Sample implementation to read Task Name

Public ReadOnly Property Name() As String
  Get
    Select Case cGlobals.ActiveImportExportMechanism
      Case cGlobals.ImportExportMechanism.UseMPXJ
        Return _TaskMPXJ.Name
      Case cGlobals.ImportExportMechanism.UseMicrosoft_OfficeInterop
        Return _TaskMSP.Name
      Case cGlobals.ImportExportMechanism.UseAsposeTasks
        Return _TaskAspose.Name
      Case Else
        Return String.Empty
    End Select
  End Get
End Property

However some task elements did present in significantly different ways, Predecessors and Duration fields required the most work to convert them into the visual format users expect.

Setting fields is also hidden from the Plan Runner specific code, the three interface methods:

Public Function SetFieldValue(ByVal task As Aspose.Tasks.Task, ByVal eFieldName 
As AsposeFieldNames, ByVal Value As String) As Boolean

Public Function SetFieldValue(ByVal task As Aspose.Tasks.Task, ByVal eFieldName 
As AsposeFieldNames, ByVal Value As DateTime) As Boolean

Public Function SetFieldValue(ByVal task As Aspose.Tasks.Task, ByVal eFieldName 
As AsposeFieldNames, ByVal Value As Integer) As Boolean

Allow Plan Runner to set any field in a task without needing to understand how it is done.

Note that Plan Runner does not use calendars, resource scheduling or project information so these have not been used or evaluated.

Challenges

Initial provision of the import and export mechanisms was relatively straight forward; the example code supplied on the ExamplesDashboard and online help provided enough help.

A later addition to creating a new project file on download proved more problematical. The forums proved very useful here providing advice and example code the online help didn’t contain, for example using a blank project file. Many problems were experienced with Start and Finish times being set incorrectly, Appendix 1 provides some guidance on this.

Outcome

For the most part, a successful outcome was achieved. Importing and exporting to MPP files is fully operational and tested successfully with over 20 different project files from various versions of Microsoft Project. Export to CSV has been rewritten to generate directly from the PlanRunner SQL Server database as going via Microsoft Project gave no real benefit. Export to Excel proved to be problematic, the files generated could not be opened with Excel 2010. It was deemed prudent at this time to disable the facility and revisit when the impact on delaying other development is reduced.

Next Steps

At present the facility is working, over the coming weeks, it is expected to have to tweak the mechanism to allow for edge cases and bugs being found. At some point, further refactoring of the code is required including the removal of Interop code and integration of MPXJ to cater to formats not present in Aspose.Tasks.

Summary

Overall, the implementation went reasonably smoothly. The online help could be improved with examples that showed the whole process. The product appears robust, performs well and once coded was stable. It coped well with Project files from 2007 to 2013, extensive testing was performed to ensure that the task fields were being read and written correctly. Once users have put a few of their own project files through this new mechanism we expect to be able to fully sign off this part of the system.

I certainly would recommend Aspose.Tasks to anyone requiring read and write access to Microsoft Project files.

Appendix 1 – Recommendations on creating a new task

When creating a new task you may experience problems with the Start and Finish times (and to a lesser extent dates) changing or being reset. The following rules should provide some help in this endeavour.

  • Set Duration first
  • Then set Work, RemainingWork, RegularWork and Work again to the duration
  • Then set DurationFormat
  • Then set the Start, ManualStart, Finish and ManualFinish

If you assign resources to the task use

Resource = mppFile.AddResource(resourceName)

Don’t use

 Resource = New Aspose.Tasks.Resource mppFile.Resources.Add(resource)

As is discussed in one of the forum entries, Microsoft Project automatically assigns the times and dates to the resource assignment when you link them using Microsoft’s interface. When using Aspose.Tasks this needs to be done manually.

How to assign a resource

Dim ra As New ResourceAssignment(Me.neutralTask, resource)
ra.Start = Me.neutralTask.Start
ra.Finish = Me.neutralTask.Finish
ra.Task.Work = ra.Task.Duration
ra.RemainingWork = ra.Task.Work
ra.RegularWork = ra.RemainingWork
ra.Work = ra.RegularWork
ra.Finish = Me.neutralTask.Finish
mppFile.ResourceAssignments.Add(ra)

Similarly, we found that using AddTaskLink in preference to TaskLinks.Add seemed to create a more stable result.

Jonathan Tooth
Managing Director, XenTek Ltd
www.xentek.co.uk
www.planrunner.co.uk