Some problems with Tasks and ResourceAssignment

Hi there,

I have got a problem with Tasks and the ResourceAssignment

a)
First I created a task like that:

Task childTask = new Task
{
Uid = taskCounter++,
Start = ebTask.EstimatedStart,
Finish = ebTask.EstimatedEnd,
Duration = ebTask.EstimatedEnd - ebTask.EstimatedStart,
DurationFormat = TimeUnitType.MinuteEstimated,

Name = ebTask.Name,
IsMilestone = false,
Type = TaskType.FixedWork,
Notes = ebTask.Description
};

When I export it and open the file in MS Project 2003 the Task looks ok except the Start and Finish dates. What I need to do to get MS Project to display the Start and Finish date as specified at the Task object?

b) I created a resource like that:

foreach (EBStaff ebStaff in staffs)
{
Resource res = new Resource(ebStaff.Name);
res.Uid = staffCounter++;
res.Type = ResourceType.Work;

res.Start = MsProject.StartDate;
res.Finish = new DateTime(2100, 1, 1);

res.AvailableFrom = MsProject.StartDate;
res.AvailableTo = new DateTime(2100, 1, 1);

res.Calendar = Calendar.MakeStandardCalendar();

MsProject.Resources.Add(res);
}

and created the Task and ResourceAssignment like that:
foreach (EBTask ebTask in tasks)
{
Task childTask = new Task
{
Uid = taskCounter++,
Start = ebTask.EstimatedStart,
Finish = ebTask.EstimatedEnd,
Duration = ebTask.EstimatedEnd - ebTask.EstimatedStart,
DurationFormat = TimeUnitType.MinuteEstimated,

Name = ebTask.Name,
IsMilestone = false,
Type = TaskType.FixedWork,
Notes = ebTask.Description
};

rootTask.Children.Add(childTask);

if (ebTask.Staff != null)
{

ResourceAssignment assignment = new ResourceAssignment(childTask, aResource);
assignment.Uid = assignmentCounter++;
assignment.Start = childTask.Start;
assignment.Finish = childTask.Finish;
assignment.Units = 1;
assignment.TimephasedDataFromTaskDuration(assignment.Resource.Calendar);
MsProject.ResourceAssignments.Add(assignment);
}
}
}

As soon as I assign a resource to a task, the task duration is “0”. I have no idea what I need to adjust.

Right now neither the right task dates are displaye nor the resource are correctly assigned :frowning:

Can someone please help me?

Kind regards,
Sörnt

Hi,

Thank you a lot for your interesting in Aspose.Tasks and your questions. See my answers below:
a) This is because by default task’s constraint type is AsSoonAsPossible, you can change it to MustStartOn for example if you want the task be started exactly in this day. I case your task has been started at the date you can set its ActualStart date. It’ll fix the date too.

b) When the task assigned resources its durations depends on the resources work or resources time phased data, when there is not work duration is 0 too.

See some code sample below:

using System;
using System.Collections.Generic;
using System.Text;
using Aspose.Tasks;
using System.IO;

namespace TestStartDateBug
{
    class Program
    {
        static void Main(string[] args)
        {
            Project project = new Project();
            Calendar calendar = Aspose.Tasks.Calendar.MakeStandardCalendar();
            project.Calendars.Add(calendar);
            project.Calendar = calendar;
            project.IsScheduleFromStart = true;
            project.StartDate = new DateTime(2000, 11, 2);
            //You have to set this to use durations in days, weeks or months.
            project.DaysPerMonth = 20;
            project.MinutesPerWeek = 2400;

            Task root = new Task();
            project.RootTask = root;
            Task task1 = new Task();
            task1.Start = new DateTime(2000, 11, 3);
            task1.Duration = new TimeSpan(80, 0, 0);
            task1.DurationFormat = TimeUnitType.Hour;
            task1.Name = "Task1";
            task1.IgnoreResourceCalendar = true;
            task1.Type = TaskType.FixedUnits;
            //The task has to be started in this day.

            task1.ConstraintType = ConstraintType.MustStartOn;
            task1.DurationFormat = TimeUnitType.Hour;

            Task task2 = new Task();
            task2.Start = new DateTime(2000, 11, 12);
            task2.Duration = new TimeSpan(60, 0, 0);
            task2.DurationFormat = TimeUnitType.Hour;
            task2.Name = "Task2";

            task2.IgnoreResourceCalendar = true;
            task2.Type = TaskType.FixedUnits;
            task2.ConstraintType = ConstraintType.MustStartOn;
            task2.DurationFormat = TimeUnitType.Hour;
            root.Children.AddRange(new Task[] { task1, task2 });

            Resource res1 = new Resource("res1");
            res1.Type = ResourceType.Work;
            ResourceAssignment ra1 = new ResourceAssignment(task1, res1);
            ra1.Units = 0.1;

            ra1.RemainingWork = new TimeSpan((long)(ra1.Units * task1.Duration.Ticks));
            Resource res2 = new Resource("res2");
            res2.Type = ResourceType.Material;

            ResourceAssignment ra2 = new ResourceAssignment(task1, res2);
            ra2.Units = 2;
            res2.RemainingWork = new TimeSpan((long)(ra2.Units * task1.Duration.Ticks));
            Resource res3 = new Resource("res3");
            res1.Type = ResourceType.Work;

            ResourceAssignment ra3 = new ResourceAssignment(task2, res3);
            ra3.Units = 2;
            ra3.RemainingWork = new TimeSpan((long)(ra2.Units * task2.Duration.Ticks));

            project.Resources.AddRange(new Resource[] { res1, res2, res3 });
            project.ResourceAssignments.AddRange(new ResourceAssignment[] { ra1, ra2, ra3 });

            project.CalcTaskIds();
            project.CalcTaskUids();
            project.CalcCalendarUids();
            project.CalcResourceIds();
            project.CalcResourceUids();
            project.CalcResourceAssignmentIds();
            project.CalcResourceAssignmentUids();

            ProjectWriter writer = new ProjectWriter();
            using (FileStream fs = new FileStream("project.xml", FileMode.Create, FileAccess.Write))
            {
                writer.Write(project, fs, TasksDataFormat.XML);
            }
        }
    }
}

Please feel free to contact with us in case you have any further questions.

Hi,

thank you very much! Perfect :slight_smile:

Another thing: I need to specifiy that every resource is 24h*365day is assignable.
For example

I have got a task with a duration of 24h. Based on the default Calender it will take 3 working days (24/8 = 3).
What I need is that this task takes one work day (24/24=1).

In your example you created the calendar via <span style=“font-size: 10pt; font-family: “Courier New”;” lang=“EN-US”>Calendar.MakeStandardCalendar();

I created my own calendar via:


private static Calendar create24HWorkDayCalendar()
{
// Calendar calendar = Calendar.MakeStandardCalendar();
Calendar calendar = new Calendar();

calendar.Days.Clear();
calendar.Days.Add(create24HWorkDay(DayType.Monday));
calendar.Days.Add(create24HWorkDay(DayType.Tuesday));
calendar.Days.Add(create24HWorkDay(DayType.Wednesday));
calendar.Days.Add(create24HWorkDay(DayType.Thursday));
calendar.Days.Add(create24HWorkDay(DayType.Friday));
calendar.Days.Add(create24HWorkDay(DayType.Saturday));
calendar.Days.Add(create24HWorkDay(DayType.Sunday));
return calendar;
}

private static WeekDay create24HWorkDay(DayType dayType)
{
WeekDay day = new WeekDay { DayType = dayType, DayWorking = true};
WorkingTime allDay = new WorkingTime
{
FromTime = new DateTime(1, 1, 1, 0, 0, 0, 0),
ToTime = new DateTime(1, 1, 1, 23, 59, 59, 59)
};

day.WorkingTimes.Clear();
day.WorkingTimes.Add(allDay);
return day;
}

But that doesn’t work the way I wanted. The task still takes 3 working days.
Can you please give me a hint want I need to adjust?

Kind regards,
Sörnt

Hi Soernt,


MS Project converts durations using MinutesPerDay, MinutesPerWeek and DaysPerMonth parameters. I think you can set project’s MinutesPerDay to 24 * 60:

project.MinutesPerDay = 24 * 60;

Hope it helps.

Hi,

A thought ... Sergey has provided me with a set of templates for 'new' projects as I realised very early in the process that setting everything up by code was a challenge.

Now, for new projects, I just read a default plan (XML file) with all the settings and then start from there.

So, as an example, it is possible to create a project in MS Project with the calendar, initial settings, etc the way you want them to be and save this as a MS Project XML file and read this using Aspose.Tasks to create a project ... This may seem like an overkill - however, MS Project is actually pretty good at exporting projects in XML with everything needed to open the project correctly.

I've also started another 'message' about rules ... work = 0 is probably another such rule...

HTH ... Maybe Sergey can make something like this part of the product ... like a new project template????

Regards, Bruce

Hi Sergey,

I did two things to get it to work

a) apply the MinutesPerDay, MinutesPerWeek as you suggested.

b) create a Calender, clear out the WeekDays and re added them with a FromTime and ToTime like that:

FromTime = new DateTime(1, 1, 1, 0, 0, 0, 0)
and
ToTime = new DateTime(1, 1, 1, 0, 0, 0, 0)

And that times looks to be a problem for Aspose.Tasks. The FromTime and ToTimes are not saved to the XML file. I changed them to:

FromTime = new DateTime(1, 1, 2, 0, 0, 0, 0)

and

ToTime = new DateTime(1, 1, 2, 0, 0, 0, 0)

Since the interesting part is the time part.

And now the times are saved and my task is displayed as I wanted it within msProject.

Kind regards,
Sörnt







Hi Soernt,


Yes, you are right.

Aspose.Tasks interprets the 1.1.1 date which is DataTime.MinValue as a missed value when read data from MPP or XML (mainly XML) and we do not export it to XML. So it can be a problem in some cases.

Sorry for inconvenience.

Hi Bruce,


Again a good idea!

We are thinking about it. Now Aspose.Tasks allows creating tasks not connected to any project. May be we have to add some methods to create tasks from project or summary tasks to inherit default values from them like task.CreateNewChild(…).

We need some time to investigate the possible architectural solution.

Thank you again!

Hi Sergey,

... how about a .clone or .copyto as in the arraylist (which is being used in many places).

newTask = DefTask.clone()

or newTask = DefTask.clone(NewUID, Name)

Almost like the .add for MS Project :-)

Regards, Bruce

Hi Bruce,


You can use the approach now, see task’s Clone() method description here.

But in MS Project when you create a task you create it in the project and in the defined place of the project as a child of some summary task, may be project summary (root) task. For example, it’s start date is a summary task start date and so on.

Hi Sergey,

A quick question about the way you describe summary tasks. As the property IsSummaryTask appears to be readonly in the help file, is the property IsSummaryTask actually derived from the context of the task?

.IsSummaryTask = (SomeTask.children isnot nothing andalso SomeTask.children.count > 0) (approx)

These are the kind of rules that really simplify the checking / setting of properties. I also think these types of rules are also in line with the MS Project Automation functions.

Is this roughly how this is defined? Is it always returned this way? If it is, great!!

Regards, Bruce

Hi Bruce,


Yes, if task has children it is a summary task, so this is why the property is read only. So you don’t need to worry about the flag.

Hi Sergey,

I have problem with the calenders.

I created my “My 24h” calender (each day 24h working time) and assigend it to the project as in your example. The Project uses it when opening in MS Project.

But the resources didn’t pick them up by default. So did test this

a) create a resource and assign the resource calendar to projects calendar:

Resource res = new Resource(ebStaff.Name)

{

Type = ResourceType.Work,

MaxUnits = 1.0,
Calendar = MsProject.Calendar

};

b) create a new calender and assign it to the resource:

Resource res = new Resource(ebStaff.Name)
{
Type = ResourceType.Work,
MaxUnits = 1.0
};
Calendar resCalendar = create24HWorkDayCalendar(true, ebStaff.Name + " 24h");
MsProject.Calendars.Add(resCalendar);
res.Calendar = resCalendar;

At the XML I see the resource calendars definitions.

But I can’t find the association at the resource to that calendar.

When opening in MS Project, each resource uses the default calendar.
Can you please help me here again?

Kind regards,
Sörnt




Hi,


Have you recalculated the calendars UIDs? The resources are connected to calendars by calendar UID.

See the field description at the Project XML Data Interchange Schema here.

Hi Sergy,

Yes I did. At the very end of the creation process I call these Methods:

MsProject.CalcTaskIds();
MsProject.CalcTaskUids();

MsProject.CalcCalendarUids();

MsProject.CalcResourceIds();
MsProject.CalcResourceUids();

MsProject.CalcResourceAssignmentUids();
MsProject.CalcResourceAssignmentIds();


Hi,

I have put a sample below for nonstandard calendar. I have tried to define a minimum fields to set to get the result.

using System;
using System.Collections;
using Aspose.Tasks;
namespace TaskDurationCS
{
    class TaskDurationCS
    {
        static void Main(string[] args)
        {
            License license = new Aspose.Tasks.License();
            license.SetLicense("Aspose.Tasks.lic");
            Project project = new Project();
            project.StartDate = new DateTime(2010, 5, 27);
            project.FinishDate = new DateTime(2010, 6, 30);
            project.Calendar = Calendar.MakeStandardCalendar();
            project.Calendars.Add(project.Calendar);
            project.Calendar.Uid = project.NextCalendarUid;
            project.MinutesPerDay = 24 * 60;
            project.MinutesPerWeek = 7 * project.MinutesPerDay;
            project.DaysPerMonth = 30;
            WorkingTime wTime = new WorkingTime();
            wTime.FromTime = new DateTime(2000, 1, 1);
            wTime.ToTime = new DateTime(2000, 1, 1);
            Calendar my24Hrs = new Calendar("My 24 Hours");
            for (int i = 1; i <= 7; i++)
            {
                WeekDay workDay = new WeekDay((DayType)i, new ArrayList(new object[] { wTime }));
                workDay.DayWorking = true;
                my24Hrs.Days.Add(workDay);
            }
            project.Calendars.Add(my24Hrs);
            my24Hrs.Uid = project.NextCalendarUid;
            // Root task
            Task rootTask = new Task();
            project.RootTask = rootTask;
            rootTask.Uid = project.NextTaskUid;
            // Root resource
            Resource rootResource = new Resource();
            rootResource.Uid = project.NextResourceUid;
            project.Resources.Add(rootResource);
            Task taskFixedDuration = new Task("Fixed duration task");
            taskFixedDuration.Type = TaskType.FixedDuration;
            taskFixedDuration.Uid = project.NextTaskUid;
            taskFixedDuration.Start = new DateTime(2010, 5, 28);
            taskFixedDuration.Finish = new DateTime(2010, 6, 2);
            taskFixedDuration.ConstraintDate = taskFixedDuration.Start;
            taskFixedDuration.ConstraintType = ConstraintType.MustStartOn;
            taskFixedDuration.Duration = new TimeSpan(5 * 24, 0, 0);
            taskFixedDuration.DurationFormat = TimeUnitType.Day;
            taskFixedDuration.IgnoreResourceCalendar = true;
            taskFixedDuration.Calendar = my24Hrs;
            rootTask.Children.Add(taskFixedDuration);
            Resource res1 = new Resource("Resource1");
            res1.Uid = project.NextResourceUid;
            res1.Type = ResourceType.Work;
            res1.MaxUnits = 1.0;
            res1.RegularWork = new TimeSpan(5 * 24, 0, 0);
            project.Resources.Add(res1);
            ResourceAssignment asmt1 = new ResourceAssignment(taskFixedDuration, res1);
            asmt1.Units = 1.0;
            asmt1.Start = new DateTime(2010, 5, 28);
            asmt1.Work = new TimeSpan(5 * 24, 0, 0);
            asmt1.RemainingWork = new TimeSpan(5 * 24, 0, 0);
            project.ResourceAssignments.Add(asmt1);
            Calendar res1Cal = new Calendar("Resource1");
            res1Cal.BaseCalendar = my24Hrs;
            res1Cal.Uid = project.NextCalendarUid;
            project.Calendars.Add(res1Cal);
            project.CalcTaskIds();
            project.CalcResourceFields();
            project.CalcResourceAssignmentIds();
            project.CalcResourceAssignmentUids(1);
            ProjectWriter writer = new ProjectWriter();
            writer.Write(project, "project24hours.xml", TasksDataFormat.XML);
        }
    }
}

In case if all your project’s resources are using 24 Hours calendar you can set it as the project calendar instead of Standart.

Hi Soernt,


I have created a new issue ‘Incorrect ignoring new DateTime() in Calendar’s week days’ with ID = 17387 and linked it to this forum thread.

We are ignoring the empty or DateTime.MinValue dates when export project’s data to XML but as in this case we need the date’s time only (00:00:00) so we are going to update the data processing.

The issues you have found earlier (filed as 17387) have been fixed in this update.


This message was posted using Notification2Forum from Downloads module by aspose.notifier.

I’m having trouble generating tasks with assigned resources. The dates look fine to me in the generated XML, but when Project imports them, the task start dates are set to 1/1/2001. I’m using Aspose Tasks 6.2 and MS Project 2013. I found the TaskDurationCS sample that Sergey Polshkov wrote and it has the same problem.


I did make one change to the sample. When I first tried it, Project gave me an error when importing the file. The error is “An import error occurred. The element in the element with = 1 has invalid data. The calendar name does not exist. Click on a calendar in the list, and then press Enter.” I worked around this error by commenting out the following two lines:
//project.Calendar = Calendar.MakeStandardCalendar();

//project.Calendars.Add(project.Calendar);

Now when Project imports the xml file, there is warning: "The start of task 3 Fixed work task of "TaskDurationCS" is before the project starts.". In the XML the start and actual start date of task 3 is 11 Jan 2010 but Project imports the actual start and start dates of task 3 as 01 Jan 2001.

Hi Daniel,


Thanks for contacting support.

Aspose.Tasks has provided new features for adding tasks and resource assignments which initialize most of the required settings. Could you please give a try to the new features demonstrated in the following sample code and let us know your feedback?

Project project = new Project();
for (int i = 0; i < 3; i++)
{
Task task1 = project.AddTask("Task " + (i + 1)); // adds after the last project’s task
task1.Start = new DateTime(2014, 2, 25) + new TimeSpan(i, 0, 0, 0);
task1.Duration = new TimeSpan(16, 0, 0);
task1.ConstraintType = ConstraintType.StartNoEarlierThan;
task1.ConstraintDate = task1.Start;
Resource rsc = project.AddResource("Resource " + (i + 1));
ResourceAssignment assgn = new ResourceAssignment(task1, rsc);
project.AddResourceAssignment(task1, rsc);
}
project.Save(“Test.xml”, Aspose.Tasks.Saving.SaveFileFormat.XML);

If this code does not fulfill your requirements, please send us the test application which is used to produce the project file displayed in the above image. We will analyze the code and share our findings as soon as possible.