Retrieving the Time scaled data from MS Project (mpp)

The TimeScaleValue method is very sensitive to multiple access without garbage clean up. 

Note: The key to avoiding the COM exceptions is to clean up after yourself explicitly through calls to Marshal.FinalReleaseComObject.  If you comment out the release made inside the loop, it will throw an exception every time.

Here's a code snippet that shows the correct way to manipulate time scaled data.

    1:  Application winProj = new Application();
    2:   
    3:  winProj.FileNew(Type.Missing, Type.Missing, Type.Missing, Type.Missing);
    4:  winProj.Visible = true;
    5:   
    6:  Project project = winProj.ActiveProject;            
    7:  Resource resource = project.Resources.Add("Res1", Type.Missing);
    8:   
    9:  Task task = project.Tasks.Add("Task1", Type.Missing);
   10:  task.Duration = "1000d";
   11:   
   12:  winProj.ViewApply("Task Usage", Type.Missing, Type.Missing);
   13:              
   14:  Assignment assignment = task.Assignments.Add(task.ID, resource.ID, 1);
   15:   
   16:  DateTime start = DateTime.Now;
   17:   
   18:  TimeScaleValues timeScaleValues = null;
   19:   
   20:  try
   21:  {
   22:                  winProj.ScreenUpdating = false;
   23:                  winProj.Calculation = PjCalculation.pjManual;
   24:   
   25:                  timeScaleValues = task.Assignments[1].TimeScaleData(task.Start,
   26:                                                                      task.Finish,
   27:                                                                      PjAssignmentTimescaledData.pjAssignmentTimescaledWork,
   28:                                                                      PjTimescaleUnit.pjTimescaleDays,
   29:                                                                      1);
   30:                  Debug.WriteLine(timeScaleValues.Count);
   31:   
   32:                  for (int i = 1; i < timeScaleValues.Count; i++)
   33:                  {
   34:                      TimeScaleValue timeScaleValue = timeScaleValues[i];
   35:   
   36:                      Debug.WriteLine(timeScaleValue.StartDate);
   37:                      Debug.WriteLine(timeScaleValue.EndDate);
   38:                      Debug.WriteLine(timeScaleValue.Value);
   39:   
   40:                      if (!string.IsNullOrEmpty(timeScaleValue.Value.ToString()))
   41:                      {
   42:                          timeScaleValue.Value = 360;
   43:                      }
   44:                      Marshal.FinalReleaseComObject(timeScaleValue);
   45:                  }
   46:                  
   47:              }
   48:              catch
   49:              {
   50:                  Debugger.Break();
   51:              }
   52:              finally
   53:              {
   54:                  winProj.ScreenUpdating = true;
   55:   
   56:                  winProj.Calculation = PjCalculation.pjAutomatic;
   57:                  winProj.CalculateAll();
   58:   
   59:                  if (timeScaleValues != null)
   60:                  {
   61:                      Marshal.FinalReleaseComObject(timeScaleValues);
   62:                  }                    
   63:              }
   64:   
   65:             Marshal.FinalReleaseComObject(project);
   66:             Marshal.FinalReleaseComObject(resource);
   67:             Marshal.FinalReleaseComObject(task);      
   68:             Marshal.FinalReleaseComObject(assignment);                        
   69:             Debug.WriteLine((DateTime.Now - start).Seconds);
   70:  }

Windows Live Tags: Time,Project,TimeScaleValue,FinalReleaseComObject,TimeScaleValues,TimeScaleData

Blogger Labels:

Time,Project,TimeScaleValue,FinalReleaseComObject,TimeScaleValues,TimeScaleData