I am trying to add JSON data into an MPP file using the Aspose API. My data contains start date, end date, and a given duration value. However, when I insert it into the MPP file, the API automatically recalculates the duration based on the start and end dates.
I want the given duration from my JSON to remain unchanged. How can I stop the auto-calculation and keep my provided duration value?
To prevent the Aspose API from automatically recalculating the duration when you insert your JSON data into an MPP file, you can set the calculation mode of the project to manual. This ensures that the API respects the duration value you provide in your JSON data.
Cause: By default, the Aspose API recalculates task durations based on the start and end dates, which can lead to unintended changes in your specified duration.
Solution: To maintain your specified duration, you need to set the calculation mode to manual before inserting your data.
Next Steps: Follow these steps to implement the solution:
- Load your MPP file: Start by loading your existing MPP file into a
Project
object. - Set Calculation Mode: Change the calculation mode of the project to manual using the
CalculationMode
property. - Insert your data: Add your tasks with the specified start date, end date, and duration.
- Save the project: Finally, save the project back to the MPP format.
Here’s a code snippet to illustrate this:
using Aspose.Tasks;
public void AddTaskWithFixedDuration(string mppFilePath, string taskName, DateTime startDate, DateTime endDate, TimeSpan duration)
{
// Load the project
Project project = new Project(mppFilePath);
// Set calculation mode to manual
project.CalculationMode = CalculationMode.Manual;
// Create a new task
Task task = project.RootTask.Children.Add(taskName);
task.Set(Tsk.Start, startDate);
task.Set(Tsk.Finish, endDate);
task.Set(Tsk.Duration, duration);
// Save the project
project.Save(mppFilePath, SaveFileFormat.MPP);
}
By setting the calculation mode to manual, the API will not recalculate the duration based on the start and end dates, allowing you to maintain the duration you specified in your JSON data.
If you have any further questions or need additional assistance, feel free to ask!
What version of aspose.tasks should be use?
See the orignal mpp ages >>
[image]
Generated mpp >>
[image]
This is the code below we used>
Input json data is like this >>>
{
“task_id”: “1.4”,
“progress”: “”,
“description”: “Workstream Details - Dispatch”,
“duration”: “63.0d”,
“start_date”: “03/17/2025”,
“end_date”: “06/13/2025”,
“dependencies”: “4SS”,
“successors”: “”,
“stakeholder_id”: “”,
“outline_number”: “1.4”,
“numeric_id”: “60”
},
//Creating the mpp from json code below (Python)
def create_corrected_mpp_from_json(json_data, output_path):
“”“Create MPP file using correct Aspose.Tasks API methods”“”
try:
# Create new project
project = at.Project()
project.name = “Customer Transition Plan”
print(f" Created project: {project.name}")
# Track tasks by outline number for hierarchy and dependency linking
tasks_by_outline = {}
tasks_by_numeric_id = {}
tasks_by_task_id = {} # Add mapping by task_id
# First pass: create all tasks
for i, task_data in enumerate(json_data):
try:
# Get task details
description = task_data.get(‘description’, ‘’)
outline_number = task_data.get(‘outline_number’, ‘’)
task_id = task_data.get(‘task_id’, ‘’)
numeric_id = task_data.get(‘numeric_id’, i)
if not description or not outline_number:
print(f" Skipping task with missing description or outline: {task_id}")
continue
# Create task
if outline_number == ‘0’ or outline_number == ‘1’:
# Top-level task
task = project.root_task.children.add(description)
else:
# Find parent task
parent_outline = ‘.’.join(outline_number.split(‘.’)[:-1])
if parent_outline in tasks_by_outline:
parent_task = tasks_by_outline[parent_outline]
task = parent_task.children.add(description)
else:
# Fallback to root level
task = project.root_task.children.add(description)
# Set basic task properties using ONLY methods that exist
# Start date
if task_data.get(‘start_date’):
start_date = parse_date(task_data.get(‘start_date’))
if start_date:
try:
task.start = start_date
except Exception as e:
print(f" Could not set start date for task ‘{description}’: {e}")
# End date
if task_data.get(‘end_date’):
end_date = parse_date(task_data.get(‘end_date’))
if end_date:
try:
task.finish = end_date
except Exception as e:
print(f" Could not set finish date for task ‘{description}’: {e}")
# Duration (only for non-summary tasks)
duration = task_data.get(‘duration’)
if duration and duration != ‘0d’ and duration != 0:
duration_days = parse_duration(duration)
if duration_days > 0:
try:
# Use duration_text which should exist
task.duration_text = f"{duration_days}d"
except Exception as e:
print(f" Could not set duration for task ‘{description}’: {e}")
# Progress
progress = task_data.get(‘progress’)
if progress and progress != ‘’:
try:
task.percent_complete = parse_float(progress)
except Exception as e:
print(f" Could not set progress for task ‘{description}’: {e}")
# Store task for hierarchy and dependency linking
tasks_by_outline[outline_number] = task
if numeric_id is not None:
tasks_by_numeric_id[str(numeric_id)] = task # Convert to string for consistent lookup
if task_id: # Store by task_id for dependency linking
tasks_by_task_id[task_id] = task
if i % 20 == 0:
print(f" Created task {i+1}/{len(json_data)}: {description[:50]}…")
except Exception as e:
print(f" Error creating task {task_data.get(‘task_id’, ‘unknown’)}: {e}")
continue
print(f" Project created with {len(tasks_by_outline)} tasks")
# Second pass: set dependencies (using correct API)
print(f" Setting dependencies…")
for i, task_data in enumerate(json_data):
try:
outline_number = task_data.get(‘outline_number’, ‘’)
if outline_number not in tasks_by_outline:
continue
task = tasks_by_outline[outline_number]
description = task_data.get(‘description’, ‘’)
# Set dependencies (predecessors) - using correct API
dependencies = task_data.get(‘dependencies’, ‘’)
if dependencies:
try:
# Parse dependency string (e.g., “2FS”, “3FS”, “23SS”, “3FS,24FS”)
dep_parts = dependencies.split(‘,’)
for dep_part in dep_parts:
dep_part = dep_part.strip()
if dep_part:
# Extract task ID and relationship type from dependency
# Format: “2FS” = Task ID 2, Finish-to-Start
# Format: “23SS” = Task ID 23, Start-to-Start
dep_match = re.match(r’(\d+)([A-Z]+)', dep_part)
if dep_match:
dep_row_number = int(dep_match.group(1)) # Row number from MPP (1, 2, 3…)
dep_type = dep_match.group(2) # Relationship type (e.g., “FS”, “SS”)
# Convert row number to numeric_id by subtracting 1
# Original MPP: Row 1, 2, 3, 4… maps to numeric_id: 0, 1, 2, 3…
dep_numeric_id = str(dep_row_number - 1)
# Find the predecessor task by numeric_id (which is what dependencies reference)
if dep_numeric_id in tasks_by_numeric_id:
predecessor = tasks_by_numeric_id[dep_numeric_id]
# Determine link type based on dependency type
link_type = at.TaskLinkType.FINISH_TO_START # Default
if dep_type == “SS”:
link_type = at.TaskLinkType.START_TO_START
elif dep_type == “FF”:
link_type = at.TaskLinkType.FINISH_TO_FINISH
elif dep_type == “SF”:
link_type = at.TaskLinkType.START_TO_FINISH
# Create task link using correct API
try:
link = project.task_links.add(predecessor, task)
link.link_type = link_type
print(f" Added dependency: Row {dep_row_number} ({dep_numeric_id}){dep_type} → {description[:30]}…")
except Exception as e:
print(f" Could not create dependency link: {e}")
else:
print(f" Predecessor task Row {dep_row_number} (numeric_id {dep_numeric_id}) not found for task ‘{description[:30]}…’")
else:
print(f" Could not parse dependency format: ‘{dep_part}’ for task ‘{description[:30]}…’")
except Exception as e:
print(f" Could not process dependencies for task ‘{description}’: {e}")
except Exception as e:
print(f" Error setting dependencies for task {task_data.get(‘task_id’, ‘unknown’)}: {e}")
continue
# Third pass: try to set resources using correct API
print(f" Setting resources…")
for i, task_data in enumerate(json_data):
try:
outline_number = task_data.get(‘outline_number’, ‘’)
if outline_number not in tasks_by_outline:
continue
task = tasks_by_outline[outline_number]
description = task_data.get(‘description’, ‘’)
stakeholder_id = task_data.get(‘stakeholder_id’, ‘’)
if stakeholder_id:
try:
# Create resource if it doesn’t exist
resource_name = str(stakeholder_id).strip()
if resource_name:
# Try to find existing resource or create new one
resource = None
for existing_resource in project.resources:
if existing_resource.name == resource_name:
resource = existing_resource
break
if not resource:
resource = project.resources.add(resource_name)
# Try different methods to assign resource to task
try:
# Method 1: Try direct assignment
task.resources.add(resource)
print(f" Assigned resource ‘{resource_name}’ to task ‘{description[:30]}…’")
except AttributeError:
try:
# Method 2: Try using resource assignment collection
assignment = project.resource_assignments.add(task, resource)
print(f" Assigned resource ‘{resource_name}’ to task ‘{description[:30]}…’ (via assignment)")
except Exception as e2:
print(f" Could not assign resource using any method: {e2}")
except Exception as e:
print(f" Could not process resource for task ‘{description}’: {e}")
except Exception as e:
print(f" Error setting resources for task {task_data.get(‘task_id’, ‘unknown’)}: {e}")
continue
# Save the project
print(f" Saving project to: {output_path}")
try:
# Try to save as MPP first
project.save(output_path, at.saving.SaveFileFormat.MPP)
print(f" MPP file saved successfully!")
return True
except Exception as e:
print(f" Could not save as MPP: {e}")
# Fallback: try to save as XML
xml_path = output_path.replace(‘.mpp’, ‘.xml’)
try:
project.save(xml_path, at.saving.SaveFileFormat.XML)
print(f" XML file saved successfully: {xml_path}")
print(f" You can open this XML file in Microsoft Project")
return True
except Exception as e2:
print(f" Could not save as XML either: {e2}")
return False
except Exception as e:
print(f" Error creating project: {e}")
import traceback
traceback.print_exc()
return False
From: Naveen Venkatesh Naveen@coworked.ai
Sent: Wednesday, August 13, 2025 2:49 PM
To: Ravi Linganuri ravi@coworked.ai; Selva Senthamaraikannan Selva@coworked.ai
Subject: Fw: [Free Support Forum - aspose.com] [Aspose.Note Product Family] Duration Auto calculating issue
From: Admin Containerize via Free Support Forum - aspose.com forum@aspose.com
Sent: 13 August 2025 14:47
To: Naveen Venkatesh naveen@coworked.ai
Subject: [Free Support Forum - aspose.com] [Aspose.Note Product Family] Duration Auto calculating issue
You don’t often get email from forum@aspose.com. Learn why this is important
Professionalize.Discourse
August 13
To prevent the Aspose API from automatically recalculating the duration when you insert your JSON data into an MPP file, you can set the calculation mode of the project to manual. This ensures that the API respects the duration value you provide in your JSON data.
Cause: By default, the Aspose API recalculates task durations based on the start and end dates, which can lead to unintended changes in your specified duration.
Solution: To maintain your specified duration, you need to set the calculation mode to manual before inserting your data.
Next Steps: Follow these steps to implement the solution:
- Load your MPP file: Start by loading your existing MPP file into a
Project
object. - Set Calculation Mode: Change the calculation mode of the project to manual using the
CalculationMode
property. - Insert your data: Add your tasks with the specified start date, end date, and duration.
- Save the project: Finally, save the project back to the MPP format.
Here’s a code snippet to illustrate this:
using Aspose.Tasks;
public void AddTaskWithFixedDuration(string mppFilePath, string taskName, DateTime startDate, DateTime endDate, TimeSpan duration)
{
// Load the project
Project project = new Project(mppFilePath);
// Set calculation mode to manual
project.CalculationMode = CalculationMode.Manual;
// Create a new task
Task task = project.RootTask.Children.Add(taskName);
task.Set(Tsk.Start, startDate);
task.Set(Tsk.Finish, endDate);
task.Set(Tsk.Duration, duration);
// Save the project
project.Save(mppFilePath, SaveFileFormat.MPP);
}
By setting the calculation mode to manual, the API will not recalculate the duration based on the start and end dates, allowing you to maintain the duration you specified in your JSON data.
If you have any further questions or need additional assistance, feel free to ask!
but still that calculation happens need this working with python and not C+.
def create_corrected_mpp_from_json(json_data, output_path):
“”“Create MPP file using correct Aspose.Tasks API methods”“”
try:
# Create new project
project = at.Project()
project.name = “Customer Transition Plan”
# CRITICAL: Set calculation mode to Manual as recommended by Aspose team
try:
project.calculation_mode = at.CalculationMode.MANUAL
print(“ Set calculation mode to MANUAL - Aspose will respect our values”)
except Exception as e:
print(f" Could not set calculation mode to MANUAL: {e}")
print(" Duration values may be recalculated automatically")
print(f" Created project: {project.name}")
# Track tasks by outline number for hierarchy and dependency linking
tasks_by_outline = {}
tasks_by_numeric_id = {}
tasks_by_task_id = {} # Add mapping by task_id
# First pass: create all tasks
for i, task_data in enumerate(json_data):
try:
# Get task details
description = task_data.get(‘description’, ‘’)
outline_number = task_data.get(‘outline_number’, ‘’)
task_id = task_data.get(‘task_id’, ‘’)
numeric_id = task_data.get(‘numeric_id’, i)
if not description or not outline_number:
print(f" Skipping task with missing description or outline: {task_id}")
continue
# Create task
if outline_number == ‘0’ or outline_number == ‘1’:
# Top-level task
task = project.root_task.children.add(description)
else:
# Find parent task
parent_outline = ‘.’.join(outline_number.split(‘.’)[:-1])
if parent_outline in tasks_by_outline:
parent_task = tasks_by_outline[parent_outline]
task = parent_task.children.add(description)
else:
# Fallback to root level
task = project.root_task.children.add(description)
# Set basic task properties using correct Python API syntax
# Direct property assignment, not .set() method
# Start date - set directly on task property
if task_data.get(‘start_date’):
start_date = parse_date(task_data.get(‘start_date’))
if start_date:
try:
task.start = start_date
except Exception as e:
print(f" Could not set start date for task ‘{description}’: {e}")
# End date - set directly on task property
if task_data.get(‘end_date’):
end_date = parse_date(task_data.get(‘end_date’))
if end_date:
try:
task.finish = end_date
except Exception as e:
print(f" Could not set finish date for task ‘{description}’: {e}")
# Duration - try different approaches since Duration.from_days() doesn’t exist
duration = task_data.get(‘duration’)
if duration and duration != ‘0d’ and duration != 0:
duration_days = parse_duration(duration)
if duration_days > 0:
try:
# Try using duration_text property first
task.duration_text = f"{duration_days}d"
print(f" Set duration_text: {duration_days}d for task ‘{description[:30]}…’")
except Exception as e:
print(f" duration_text failed: {e}")
try:
# Try creating Duration object with different approaches
from datetime import timedelta
duration_timedelta = timedelta(days=duration_days)
# Try different Duration creation methods
try:
# Method 1: Try Duration constructor with timedelta
duration_obj = at.Duration(duration_timedelta)
task.duration = duration_obj
print(f" Set duration using Duration(timedelta) for task ‘{description[:30]}…’")
except:
try:
# Method 2: Try Duration constructor with string
duration_obj = at.Duration(f"{duration_days}d")
task.duration = duration_obj
print(f" Set duration using Duration(‘{duration_days}d’) for task ‘{description[:30]}…’")
except:
# Method 3: Try Duration constructor with integer days
duration_obj = at.Duration(duration_days)
task.duration = duration_obj
print(f" Set duration using Duration({duration_days}) for task ‘{description[:30]}…’")
except Exception as e2:
print(f" All duration methods failed for task ‘{description}’: {e2}")
print(f" Duration value: {duration_days}d")
# Progress
progress = task_data.get(‘progress’)
if progress and progress != ‘’:
try:
task.percent_complete = parse_float(progress)
except Exception as e:
print(f" Could not set progress for task ‘{description}’: {e}")
# Store task for hierarchy and dependency linking
tasks_by_outline[outline_number] = task
if numeric_id is not None:
tasks_by_numeric_id[str(numeric_id)] = task # Convert to string for consistent lookup
if task_id: # Store by task_id for dependency linking
tasks_by_task_id[task_id] = task
if i % 20 == 0:
print(f" Created task {i+1}/{len(json_data)}: {description[:50]}…")
except Exception as e:
print(f" Error creating task {task_data.get(‘task_id’, ‘unknown’)}: {e}")
continue
print(f" Project created with {len(tasks_by_outline)} tasks")
print(“ All durations, start dates, and end dates set using correct Python API syntax”)
# Second pass: set dependencies (using correct API)
print(f" Setting dependencies…")
for i, task_data in enumerate(json_data):
try:
outline_number = task_data.get(‘outline_number’, ‘’)
if outline_number not in tasks_by_outline:
continue
task = tasks_by_outline[outline_number]
description = task_data.get(‘description’, ‘’)
# Set dependencies (predecessors) - using correct API
dependencies = task_data.get(‘dependencies’, ‘’)
if dependencies:
try:
# Parse dependency string (e.g., “2FS”, “3FS”, “23SS”, “3FS,24FS”)
dep_parts = dependencies.split(‘,’)
for dep_part in dep_parts:
dep_part = dep_part.strip()
if dep_part:
# Extract task ID and relationship type from dependency
# Format: “2FS” = Task ID 2, Finish-to-Start
# Format: “23SS” = Task ID 23, Start-to-Start
dep_match = re.match(r’(\d+)([A-Z]+)', dep_part)
if dep_match:
dep_row_number = int(dep_match.group(1)) # Row number from MPP (1, 2, 3…)
dep_type = dep_match.group(2) # Relationship type (e.g., “FS”, “SS”)
# Convert row number to numeric_id by subtracting 1
# Original MPP: Row 1, 2, 3, 4… maps to numeric_id: 0, 1, 2, 3…
dep_numeric_id = str(dep_row_number - 1)
# Find the predecessor task by numeric_id (which is what dependencies reference)
if dep_numeric_id in tasks_by_numeric_id:
predecessor = tasks_by_numeric_id[dep_numeric_id]
# Determine link type based on dependency type
link_type = at.TaskLinkType.FINISH_TO_START # Default
if dep_type == “SS”:
link_type = at.TaskLinkType.START_TO_START
elif dep_type == “FF”:
link_type = at.TaskLinkType.FINISH_TO_FINISH
elif dep_type == “SF”:
link_type = at.TaskLinkType.START_TO_FINISH
# Create task link using correct API
try:
link = project.task_links.add(predecessor, task)
link.link_type = link_type
print(f" Added dependency: Row {dep_row_number} ({dep_numeric_id}){dep_type} → {description[:30]}…")
except Exception as e:
print(f" Could not create dependency link: {e}")
else:
print(f" Predecessor task Row {dep_row_number} (numeric_id {dep_numeric_id}) not found for task ‘{description[:30]}…’")
else:
print(f" Could not parse dependency format: ‘{dep_part}’ for task ‘{description[:30]}…’")
except Exception as e:
print(f" Could not process dependencies for task ‘{description}’: {e}")
except Exception as e:
print(f" Error setting dependencies for task {task_data.get(‘task_id’, ‘unknown’)}: {e}")
continue
# Third pass: try to set resources using correct API
print(f" Setting resources…")
for i, task_data in enumerate(json_data):
try:
outline_number = task_data.get(‘outline_number’, ‘’)
if outline_number not in tasks_by_outline:
continue
task = tasks_by_outline[outline_number]
description = task_data.get(‘description’, ‘’)
stakeholder_id = task_data.get(‘stakeholder_id’, ‘’)
if stakeholder_id:
try:
# Create resource if it doesn’t exist
resource_name = str(stakeholder_id).strip()
if resource_name:
# Try to find existing resource or create new one
resource = None
for existing_resource in project.resources:
if existing_resource.name == resource_name:
resource = existing_resource
break
if not resource:
resource = project.resources.add(resource_name)
# Try different methods to assign resource to task
try:
# Method 1: Try direct assignment
task.resources.add(resource)
print(f" Assigned resource ‘{resource_name}’ to task ‘{description[:30]}…’")
except AttributeError:
try:
# Method 2: Try using resource assignment collection
assignment = project.resource_assignments.add(task, resource)
print(f" Assigned resource ‘{resource_name}’ to task ‘{description[:30]}…’ (via assignment)")
except Exception as e2:
print(f" Could not assign resource using any method: {e2}")
except Exception as e:
print(f" Could not process resource for task ‘{description}’: {e}")
except Exception as e:
print(f" Error setting resources for task {task_data.get(‘task_id’, ‘unknown’)}: {e}")
continue
# Save the project
print(f" Saving project to: {output_path}")
print(“ Using correct Python API: MANUAL mode + direct properties + Duration with timedelta”)
try:
# Try to save as MPP first
project.save(output_path, at.saving.SaveFileFormat.MPP)
print(f" MPP file saved successfully!")
print(“ All durations, dependencies, and dates preserved using correct Python API”)
return True
except Exception as e:
print(f" Could not save as MPP: {e}")
# Fallback: try to save as XML
xml_path = output_path.replace(‘.mpp’, ‘.xml’)
try:
project.save(xml_path, at.saving.SaveFileFormat.XML)
print(f" XML file saved successfully: {xml_path}")
print(f" You can open this XML file in Microsoft Project")
return True
except Exception as e2:
print(f" Could not save as XML either: {e2}")
return False
except Exception as e:
print(f" Error creating project: {e}")
import traceback
traceback.print_exc()
return False
see this code which version will work for stop auto calculating
Apologies for any inconvenience caused. I am transferring your thread to the appropriate category, where a member of the Aspose.Tasks team will review your issue and provide assistance soon.
@NaveenVenkatesh ,
when CalculationMode.MANUAL is used, only important calculations are performed.
To turn off all calculations, CalculationMode.NONE should be used:
project.calculation_mode = at.CalculationMode.NONE