Support for Evaluation of Functions in Formulas
Aspose.Tasks for .NET API supports evaluating functions defined as formulas inside Extended Attributes of a project.
This enables developers to perform calculations similar to those available in Microsoft Project, making it possible to implement dynamic fields that depend on custom logic.
The API provides evaluation support for the following categories of functions:
- Math functions
- General functions
- Text functions
- Date/Time functions
This feature is particularly useful when you need to:
- Automate project calculations,
- Implement custom business rules,
- Ensure formula compatibility between MS Project and Aspose.Tasks.
Calculation of Math Expressions
The following mathematical functions are supported:
- Abs( number )
- Atn( number )
- Cos( number )
- Exp( number )
- Fix( number )
- Int( number )
- Log( number )
- Rnd( number )
- Sgn( number )
- Sin( number )
- Sqr( number )
- Tan( number )
1static void EvaluateSine()
2{
3 Project project = CreateTestProjectWithCustomField();
4
5 // Set formula Sin(pi/2)
6 project.ExtendedAttributes[0].Formula = "Sin(3.1415926/2)";
7
8 // Print Calculated value
9 Task task = project.RootTask.Children.GetById(1);
10 Console.WriteLine("Sin(pi/2): {0}", task.ExtendedAttributes[0].NumericValue);
11}
12
13static Project CreateTestProjectWithCustomField()
14{
15 Project project = new Project();
16 ExtendedAttributeDefinition attr = ExtendedAttributeDefinition.CreateTaskDefinition(CustomFieldType.Number, ExtendedAttributeTask.Number1, "Sine");
17 project.ExtendedAttributes.Add(attr);
18
19 Task task = project.RootTask.Children.Add("Task");
20
21 ExtendedAttribute a = attr.CreateExtendedAttribute();
22 task.ExtendedAttributes.Add(a);
23 return project;
24}
Calculation of General Functions
The following functions provide logical and conditional evaluations:
Choose( index, choice-1, choice-2, ... , choice-n )
– selects a value from a list.IIf( expr, truepart, falsepart )
– returns one of two values depending on a condition.IsNumeric( expression )
– checks whether an expression is numeric.IsNull( expression )
– checks whether an expression is null.Switch( expr-1, value-1, expr-2, value-2, ... )
– evaluates expressions in order and returns the first matching value.
1static void EvaluateChoose()
2{
3 Project project = CreateTestProjectWithCustomField();
4
5 // Set Formula
6 project.ExtendedAttributes[0].Formula = "Choose(3, \"This is a\", \"right\", \"choice\")";
7
8 // Print extended attribute value
9 Task task = project.RootTask.Children.GetById(1);
10 Console.WriteLine(task.ExtendedAttributes[0].TextValue);
11}
12
13static void EvaluateIsNumeric()
14{
15 string[] numericFormulas = { "IsNumeric('AAA')", "IsNumeric(1)", "IsNumeric(1<0)", "IsNumeric(\"1.1\")", "IsNumeric(Choose((2 + Sgn(2^-3)), 123, \"one two three\"))" };
16
17 Project project = CreateTestProjectWithCustomField();
18
19 foreach (string numericFormula in numericFormulas)
20 {
21 // Set Formula
22 project.ExtendedAttributes[0].Formula = numericFormula;
23
24 // Print extended attribute value
25 Task task = project.RootTask.Children.GetById(1);
26 Console.WriteLine(task.ExtendedAttributes[0].TextValue);
27 }
28}
29
30static void EvaluateSwitch()
31{
32 Project project = CreateTestProjectWithCustomField();
33
34 // Set Formula
35 project.ExtendedAttributes[0].Formula = "Switch( 0 < 1, \"0 is lesser than 1\", 0 > 1, \"0 is greater than 1\")";
36
37 // Print extended attribute value
38 Task task = project.RootTask.Children.GetById(1);
39 Console.WriteLine(task.ExtendedAttributes[0].TextValue);
40}
Calculation of Text Functions
String manipulation functions allow formatting and comparison:
Asc( string )
– returns the ASCII code of the first character.Chr( charcode )
– returns the character for an ASCII code.Format( expression, format, firstdayofweek, firstweekofyear )
– formats numbers/dates.Instr( start, string1, string2, compare )
– finds the position of one string within another.LCase( string )
– converts to lowercase.Left( string, length )
– extracts leftmost characters.Len( string )
– returns string length.LTrim( string )
– removes leading spaces.Mid( string, start, length )
– extracts substring.Right( string, length )
– extracts rightmost characters.RTrim( string )
– removes trailing spaces.Space( number )
– returns a string with spaces.StrComp( string1, string2, compare )
– compares two strings.StrConv( string, conversion, LCID )
– converts string according to locale.String( number, character )
– returns a string repeatedn
times.Trim( string )
– removes leading and trailing spaces.UCase( string )
– converts to uppercase.
1static void EvaluateStrConv()
2{
3 Project project = CreateTestProjectWithCustomField();
4 Task task = project.RootTask.Children.GetById(1);
5
6 // Set formulas and print extended attribute value
7 project.ExtendedAttributes[0].Formula = "StrConv(\"sTring and sTRINg\",3)";
8 Console.WriteLine(task.ExtendedAttributes[0].TextValue);
9 project.ExtendedAttributes[0].Formula = "StrConv(\"sTring and sTRINg\",1)";
10 Console.WriteLine(task.ExtendedAttributes[0].TextValue);
11 project.ExtendedAttributes[0].Formula = "StrConv(\"sTring and sTRINg\",2)";
12 Console.WriteLine(task.ExtendedAttributes[0].TextValue);
13}
14
15static void EvaluateStringFunction()
16{
17 Project project = CreateTestProjectWithCustomField();
18 Task task = project.RootTask.Children.GetById(1);
19
20 // Set formulas and print extended attribute value
21 project.ExtendedAttributes[0].Formula = "String(5, 40)";
22 Console.WriteLine(task.ExtendedAttributes[0].TextValue);
23 project.ExtendedAttributes[0].Formula = "String(5, \"A\")";
24 Console.WriteLine(task.ExtendedAttributes[0].TextValue);
25 project.ExtendedAttributes[0].Formula = "String(-5, \"A\")";
26 // #Error
27 Console.WriteLine(task.ExtendedAttributes[0].TextValue);
28}
Calculation of Date/Time Functions
Aspose.Tasks supports both standard VB-style date functions and MS Project–specific scheduling functions:
CDate( expression )
– converts expression to a date.Date()
– returns the current system date.DateAdd( interval, number, date )
– adds interval to a date.DateDiff( interval, date1, date2 )
– difference between two dates.DatePart( interval, date )
– extracts part of a date (year, month, day, etc.).DateSerial( year, month, day )
– builds a date from components.DateValue( date )
– converts string to date.Day( date )
– day of the month.Hour( time )
– extracts hour.IsDate( expression )
– checks if expression is a valid date.Minute( time )
– extracts minutes.Month( date )
– extracts month.Now()
– returns current date and time.ProjDateAdd( date, duration, calendar )
– adds duration considering project calendar.ProjDateConv( expression, dateformat )
– converts date to project format.ProjDateDiff( date1, date2, calendar )
– difference considering project calendar.ProjDateSub( date, duration, calendar )
– subtracts duration.ProjDateValue( expression )
– evaluates a date expression.ProjDurConv( expression, durationunits )
– converts durations between units.ProjDurValue( duration )
– evaluates duration expression.Second( time )
– extracts seconds.Time()
– returns current system time.Timer()
– number of seconds since midnight.TimeSerial( hour, minute, second )
– builds a time value.TimeValue( time )
– converts to a time.Weekday( date, firstdayofweek )
– returns the day of week.Year( date )
– extracts year.
1Project project = CreateTestProject();
2Task task = project.RootTask.Children.GetById(1);
3
4ExtendedAttributeDefinition numberDefinition = ExtendedAttributeDefinition.CreateTaskDefinition(ExtendedAttributeTask.Number1, null);
5project.ExtendedAttributes.Add(numberDefinition);
6
7ExtendedAttribute numberAttribute = numberDefinition.CreateExtendedAttribute();
8task.ExtendedAttributes.Add(numberAttribute);
9
10// Set ProjDateDiff formula and print extended attribute value
11numberDefinition.Formula = "ProjDateDiff(\"03/23/2015\",\"03/18/2015\")";
12Console.WriteLine(numberAttribute.NumericValue);
13numberDefinition.Formula = "ProjDateDiff(\"03/23/2015\",\"03/25/2015\")";
14Console.WriteLine(numberAttribute.NumericValue);
15
16ExtendedAttributeDefinition dateDefinition = ExtendedAttributeDefinition.CreateTaskDefinition(ExtendedAttributeTask.Date1, null);
17project.ExtendedAttributes.Add(dateDefinition);
18ExtendedAttribute dateAttribute = dateDefinition.CreateExtendedAttribute();
19task.ExtendedAttributes.Add(dateAttribute);
20
21ExtendedAttributeDefinition durationDefinition = ExtendedAttributeDefinition.CreateTaskDefinition(ExtendedAttributeTask.Duration4, "Custom duration field");
22project.ExtendedAttributes.Add(durationDefinition);
23ExtendedAttribute durationAttribute = durationDefinition.CreateExtendedAttribute();
24task.ExtendedAttributes.Add(durationAttribute);
25
26ExtendedAttributeDefinition textDefinition = ExtendedAttributeDefinition.CreateTaskDefinition(ExtendedAttributeTask.Text5, "Custom text field");
27project.ExtendedAttributes.Add(textDefinition);
28ExtendedAttribute textAttribute = textDefinition.CreateExtendedAttribute();
29task.ExtendedAttributes.Add(textAttribute);
30
31// Set ProjDateSub formula and print extended attribute value
32dateDefinition.Formula = "ProjDateSub(\"3/19/2015\", \"1d\")";
33Console.WriteLine(dateAttribute.DateValue);
34
35// We can set ProjDurConv formula to duration-valued attribute as well as to text-valued attribute.
36
37// Set ProjDurConv formula to duration-valued extended attribute and print its value.
38durationDefinition.Formula = "ProjDurConv([Duration], pjHours)";
39Console.WriteLine(durationAttribute.DurationValue);
40
41// Set ProjDurConv formula to text-valued extended attribute and print its value.
42textDefinition.Formula = "ProjDurConv([Duration], pjHours)";
43Console.WriteLine(textAttribute.TextValue);
44
45textDefinition.Formula = "ProjDurConv([Duration], pjWeeks)";
46Console.WriteLine(textAttribute.TextValue);
47
48// Set Second formula and print entended attribute value
49numberDefinition.Formula = "Second(\"4/21/2015 2:53:41 AM\")";
50Console.WriteLine(numberAttribute.NumericValue);
51
52// Set Weekday formula and print entended attribute value
53numberDefinition.Formula = "Weekday(\"24/3/2015\", 1)";
54Console.WriteLine(numberAttribute.NumericValue);
55numberDefinition.Formula = "Weekday(\"24/3/2015\", 2)";
56Console.WriteLine(numberAttribute.NumericValue);
57numberDefinition.Formula = "Weekday(\"24/3/2015\", 3)";
58Console.WriteLine(numberAttribute.NumericValue);
Practical Example
Here is a real-world scenario of using formulas:
1 var project = new Project();
2 var task = project.RootTask.Children.Add("Task 1");
3
4 // Create an extended attribute with a custom formula
5 ExtendedAttributeDefinition attrDef = ExtendedAttributeDefinition.CreateTaskDefinition(
6 ExtendedAttributeTask.Text1, "Custom Formula");
7 attrDef.Formula = "IIf([Duration] > 480, \"Long Task\", \"Short Task\")";
8 project.ExtendedAttributes.Add(attrDef);
9
10 var attr = attrDef.CreateExtendedAttribute();
11 task.ExtendedAttributes.Add(attr);
12
13 // The formula is automatically evaluated by Aspose.Tasks
14 Console.WriteLine(task.Get(Tsk.Name) + " -> " + task.ExtendedAttributes[0].TextValue);
Key Benefits of Formula Support
- Full compatibility with MS Project formulas.
- Ability to automate dynamic fields and conditional logic.
- Built-in support for project calendar-aware functions (ProjDateAdd, ProjDateDiff, etc.).
- Simplifies complex calculations without writing custom C# code.