Work with Extended Attributes of a Project

Microsoft Project has an extensive XML data interchange schema that makes exchanging information between applications and programming with project files easier. The schema allows you to add extended attributes to tasks, resources and assignments. This article demonstrates how to work with Extended Attributes using Aspose.Tasks.

Working with Custom Fields using Microsoft Project

In this example, we will demonstrate how to work with Text1 extended attribute of a project for associating the information with a Task.

  1. In MSP, go to Project->Custom Fields.
  2. From here, select Task.
  3. Select Text as Custom Field Type from the Type combo box.
  4. Select Text1 as a custom field that you want to work with
  5. Use the “Rename” button to rename the alias of the field if it is desired and press OK button
  6. Add a new task and insert a new column to the task row with the custom field that you used in the above step

open extended attributes in Microsoft Project

Working with Custom Fields/Extended Attributes using Aspose.Tasks for C++ API

Aspose.Tasks for C++ API provides the capability of creating new extended attributes as well as working with Extended attributes already present in a document. Custom fields or Extended Attributes are represented by ExtendedAttributes collection of a project in Aspose.Tasks. It contains all the extended attributes definition of a project document. Some of the mappings of MSP Custom Field definition are as shown in the image below.

edit extended attributes in Microsoft Project

Creating a New Extended Attribute and Adding it to Task

To add a new extended attribute for task or resource, we first need to define and add the extended attribute definition to the ExtendedAttributes collection. ExtendedAttributeDefinition class is used to define a new ExtendedAttribute in a project. The FieldId must be set for proper defining an Extended attribute which is linked to ExtendedAttributeTask (in case of Task) or ExtendedAttributeResource (in case of Resource). The following sample code shows how to define a new Extended Attribute for Text1 field of project. Once the Extended Attribute definition is complete, you can now create a new Extended Attribute from it and assign it to a task.

 1System::SharedPtr<Project> project1 = System::MakeObject<Project>(dataDir + u"Blank2010.mpp");
 2        
 3System::SharedPtr<ExtendedAttributeDefinition> myTextAttributeDefinition = project1->get_ExtendedAttributes()->GetById((int32_t)Aspose::Tasks::ExtendedAttributeTask::Text1);
 4        
 5// If the Custom field doesn't exist in Project, create it
 6if (myTextAttributeDefinition == nullptr)
 7{
 8    myTextAttributeDefinition = ExtendedAttributeDefinition::CreateTaskDefinition(Aspose::Tasks::ExtendedAttributeTask::Text1, u"My text field");
 9    project1->get_ExtendedAttributes()->Add(myTextAttributeDefinition);
10}
11        
12// Generate Extended Attribute from definition
13System::SharedPtr<ExtendedAttribute> text1TaskAttribute = myTextAttributeDefinition->CreateExtendedAttribute();
14        
15text1TaskAttribute->set_TextValue(u"Text attribute value");
16        
17// Add extended attribute to task
18System::SharedPtr<Task> tsk = project1->get_RootTask()->get_Children()->Add(u"Task 1");
19tsk->get_ExtendedAttributes()->Add(text1TaskAttribute);
20        
21project1->Save(dataDir + u"CreateExtendedAttributes_out.mpp", Aspose::Tasks::Saving::SaveFileFormat::MPP);

Writing Updated Extended Attribute Definitions and Values to MPP

Aspose.Tasks for C++ API supports updating extended attribute data in a Microsoft Project MPP file and save it back.

The code example given below demonstrates how to add new extended attributes of the Resource and Task types to the source MPP file. The steps involved in this activity are:

  1. Create an instance of Project Reader.
  2. Read the source MPP file.
  3. Define a new extended attribute and update its values.
  4. Save the project using the Project Writer.

The following example shows setting the extended attributes of a resource.

  1System::SharedPtr<Project> project = System::MakeObject<Project>(dataDir + u"WriteUpdatedExtendedAttributeDefinitions.mpp");
  2        
  3        
  4// C# preprocessor directive: #region task attributes
  5        
  6        
  7// Add new text3 extended attribute with lookup and one lookup value
  8System::SharedPtr<ExtendedAttributeDefinition> taskTextAttributeDefinition = ExtendedAttributeDefinition::CreateLookupTaskDefinition(Aspose::Tasks::ExtendedAttributeTask::Text3, u"New text3 attribute");
  9taskTextAttributeDefinition->set_ElementType(Aspose::Tasks::ElementType::Task);
 10project->get_ExtendedAttributes()->Add(taskTextAttributeDefinition);
 11        
 12System::SharedPtr<Value> textVal = System::MakeObject<Value>();
 13textVal->set_Id(1);
 14textVal->set_Description(u"Text value descr");
 15textVal->set_Val(u"Text value1");
 16        
 17taskTextAttributeDefinition->AddLookupValue(textVal);
 18        
 19// Add new cost1 extended attribute with lookup and two cost values
 20System::SharedPtr<ExtendedAttributeDefinition> taskCostAttributeDefinition = ExtendedAttributeDefinition::CreateLookupTaskDefinition(Aspose::Tasks::ExtendedAttributeTask::Cost1, u"New cost1 attribute");
 21project->get_ExtendedAttributes()->Add(taskCostAttributeDefinition);
 22        
 23System::SharedPtr<Value> costVal1 = System::MakeObject<Value>();
 24costVal1->set_Id(2);
 25costVal1->set_Description(u"Cost value 1 descr");
 26costVal1->set_Val(u"99900");
 27        
 28System::SharedPtr<Value> costVal2 = System::MakeObject<Value>();
 29costVal2->set_Id(3);
 30costVal2->set_Description(u"Cost value 2 descr");
 31costVal2->set_Val(u"11100");
 32        
 33taskCostAttributeDefinition->AddLookupValue(costVal1);
 34taskCostAttributeDefinition->AddLookupValue(costVal2);
 35        
 36// Add new task and assign attribute lookup value.
 37System::SharedPtr<Task> task = project->get_RootTask()->get_Children()->Add(u"New task");
 38        
 39System::SharedPtr<ExtendedAttribute> taskAttr = taskCostAttributeDefinition->CreateExtendedAttribute(costVal1);
 40task->get_ExtendedAttributes()->Add(taskAttr);
 41        
 42System::SharedPtr<ExtendedAttributeDefinition> taskStartAttributeDefinition = ExtendedAttributeDefinition::CreateLookupTaskDefinition(Aspose::Tasks::ExtendedAttributeTask::Start7, u"New start 7 attribute");
 43        
 44System::SharedPtr<Value> startVal = System::MakeObject<Value>();
 45startVal->set_Id(4);
 46startVal->set_DateTimeValue(System::DateTime::get_Now());
 47startVal->set_Description(u"Start 7 value description");
 48        
 49taskStartAttributeDefinition->AddLookupValue(startVal);
 50        
 51project->get_ExtendedAttributes()->Add(taskStartAttributeDefinition);
 52        
 53System::SharedPtr<ExtendedAttributeDefinition> taskFinishAttributeDefinition = ExtendedAttributeDefinition::CreateLookupTaskDefinition(Aspose::Tasks::ExtendedAttributeTask::Finish4, u"New finish 4 attribute");
 54        
 55System::SharedPtr<Value> finishVal = System::MakeObject<Value>();
 56finishVal->set_Id(5);
 57finishVal->set_DateTimeValue(System::DateTime::get_Now());
 58finishVal->set_Description(u"Finish 4 value description");
 59        
 60taskFinishAttributeDefinition->get_ValueList()->Add(finishVal);
 61        
 62project->get_ExtendedAttributes()->Add(taskFinishAttributeDefinition);
 63        
 64System::SharedPtr<ExtendedAttributeDefinition> numberAttributeDefinition = ExtendedAttributeDefinition::CreateLookupTaskDefinition(Aspose::Tasks::ExtendedAttributeTask::Number20, u"New number attribute");
 65        
 66System::SharedPtr<Value> val1 = System::MakeObject<Value>();
 67val1->set_Id(6);
 68val1->set_Val(u"1");
 69val1->set_Description(u"Number 1 value");
 70System::SharedPtr<Value> val2 = System::MakeObject<Value>();
 71val2->set_Id(7);
 72val2->set_Val(u"2");
 73val2->set_Description(u"Number 2 value");
 74System::SharedPtr<Value> val3 = System::MakeObject<Value>();
 75val2->set_Id(8);
 76val3->set_Val(u"3");
 77val3->set_Description(u"Number 3 value");
 78        
 79numberAttributeDefinition->AddLookupValue(val1);
 80numberAttributeDefinition->AddLookupValue(val2);
 81numberAttributeDefinition->AddLookupValue(val3);
 82        
 83project->get_ExtendedAttributes()->Add(numberAttributeDefinition);
 84        
 85        
 86// C# preprocessor directive: #endregion
 87        
 88        
 89System::SharedPtr<ExtendedAttributeDefinition> rscStartAttributeDefinition = ExtendedAttributeDefinition::CreateLookupResourceDefinition(Aspose::Tasks::ExtendedAttributeResource::Start5, u"New start5 attribute");
 90        
 91System::SharedPtr<Value> startVal2 = System::MakeObject<Value>();
 92startVal2->set_Id(9);
 93startVal2->set_DateTimeValue(System::DateTime::get_Now());
 94startVal2->set_Description(u"this is start5 value descr");
 95        
 96rscStartAttributeDefinition->AddLookupValue(startVal2);
 97        
 98project->get_ExtendedAttributes()->Add(rscStartAttributeDefinition);
 99        
100// Define a duration attribute without lookup.
101System::SharedPtr<ExtendedAttributeDefinition> taskDurationAttributeDefinition = ExtendedAttributeDefinition::CreateTaskDefinition(Aspose::Tasks::ExtendedAttributeTask::Duration1, u"New Duration");
102project->get_ExtendedAttributes()->Add(taskDurationAttributeDefinition);
103        
104// Add new task and assign duration value to the previously defined duration attribute.
105System::SharedPtr<Task> timeTask = project->get_RootTask()->get_Children()->Add(u"New task");
106        
107System::SharedPtr<ExtendedAttribute> durationExtendedAttribute = taskDurationAttributeDefinition->CreateExtendedAttribute();
108        
109durationExtendedAttribute->set_DurationValue(project->GetDuration(3.0, Aspose::Tasks::TimeUnitType::Hour));
110timeTask->get_ExtendedAttributes()->Add(durationExtendedAttribute);
111        
112System::SharedPtr<MPPSaveOptions> mppSaveOptions = System::MakeObject<MPPSaveOptions>();
113mppSaveOptions->set_WriteViewData(true);
114        
115// Save the project as MPP project file
116project->Save(dataDir + u"WriteUpdatedExtendedAttributeDefinitions_out.mpp", mppSaveOptions);
Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.