Computed Fields
This topic introduces the concept of computed fields and gives an in-depth explanation of how you can use such fields and the functions that are available in Codebeamer.
Tracker fields can be defined as read-only computed fields, in which the content is calculated from other tracker item fields. Computed fields can be created by specifying an expression or formula in unified expression language. For more information on the language expressions, see
Syntax.
| Some built-in fields, such as summary cannot be defined as computed. Computed as is not available for these fields at editing. |
Use Cases
Use Case 1: Past Deadline Test (for Issue Resolution)
In this use case, the goal is to display whether the item has already passed the scheduled end date. Click TrackerConfigureFields and then click More Field at the bottom of the tab.
| Past end date is indicated with a red exclamation mark in the item display in Codebeamer. |
The custom field is called Past Deadline, and you must set it to the boolean type. The field returns true if the issue is very late. Under the layout and content column of the fields, for the custom field, the = field is defined as:
not(endDate >= fn:Date("today"))
Select the checkbox in the List column on the
Fields tab, to display the custom field on the item list or details page. You must set up permissions on the
Permissions tab. A computed field is always read only; write permission is only possible when the field definition is deleted, and the field becomes non- computed. For more information about functions available for the computed tracker fields, see
FunctionsUse Case 2: Weight = Priority * Severity
The goal is to combine issue priority and severity into a new Weight field with the following expression:
Weight = Priority * Severity
Priority is a single choice field with the following choice values:
Severity is a multiple-choice field with the following defined values:
| All choice fields, except Status and Priority, are lists or arrays of values. However, the GUI for static choice fields currently only allows selection of a single value. So, in order to access the first or single value of a multiple-choice field, you must use the [0] operator. For example, Severity[0]. |
The highest priority and the highest severity (Blocker) selections have the lowest ID. So, to compute a Weight proportional to the logical order of Priority and Severity, you must use operands that are inversely proportional to the choice value IDs.
Example:
integer Weight = (5 - Priority.id) * (6 - Severity[0].id)
An empty Priority or Severity yields an ID of null, and the above formula returns the highest-possible weight (= 30) for issues with empty Priority and Severity. To avoid this incorrect result, empty values must be handled appropriately.
Example:
integer Weight = (empty Priority ? 0 : 5 - Priority.id) * (empty Severity ? 0 : 6 - Severity[0].id)
Use Case 3: Compute columns in an embedded table from the values of other columns
A tracker (item) can have tables. A table consists of one or more columns, as shown below:
The first two columns, A and B, contain numeric operands and the other two columns must contain the product and sum or total of the operands per row.
When addressing a table column, for example by its attribute or property name tableColumn[0,1], the whole column is always addressed (an array or vector of column values, indexed by row).
Example for the Matrix table:
The expression A or tableColumn[0,0] yields [1, 2, 3] and B or
tableColumn[0,1] yields [5, 6, 7].
To address the whole table, use the name or attribute of the table, for example, Matrix or table[0], which yields an array of table rows, where each row is an array of table column values (in the order of the columns).
[
]
The index of the first row is 0 and the first table row can be accessed using one of the following ways:
• table[0][0]
• Matrix[0]
This yields [1, 5].
To address the value of Column A (tableColumn[0,0]) in the second row of the Matrix, write:
• table[0][1][0]
• Matrix[1][0]
• tableColumn[0,0][1]
• A[1]
So how can we define a third column, Product, whose value is the product of A
multiplied by B (for each row)?
If the Product is defined to be computed as
• tableColumn[0,0] * tableColumn[0,1]
• or simply A * B,
Then this means a multiplication of two vectors, for example, [1, 2, 3] * [5, 6, 7], an operation not supported by the expression language.
In addition, the result is a two-dimensional array, and not a one-dimensional column value vector.
The solution is to use a projection: table.{ row | expression } that iterates over each row in the table and produces an array of values, one value per row according to expression.
The projection or expression is the following:
table[0].{row | row[0] * row[1] }
It reads as follows:
• Iterate over table[0]
◦ for each row (an array of column values)
▪ evaluate the expression row[0] * row[1]
• return an array of the expression values per row
For the example table, the result is the array or vector: [5, 12, 21]
| The tableColumn[x,y] is a fixed property name text, and y is not adjusted when column position is changed. When defining formulas involving table columns, do not rely on the order of columns, but check the property names. You can do this by selecting the Show property name checkbox in the field configuration dialog box. At other places, [y] is used as an index number and not as text. For example table[x][y] refers to the y-th row in table[x]. |
Changes from Codebeamer 20.11
| The interpretation of table column indices has changed for Codebeamer 20.11 and later versions, and could break expressions written in older versions. |
Before Codebeamer 20.11, a column index was interpreted as the ordinal index of the column in the table columns list. Adding, removing, or re-ordering columns could therefore change the ordinal index of a column.
The ordinal index of Product, that was 2, is now 3, which leads to an inconsistency in table cell access using the table column index: table[0][row][3]
!= tableColumn[0,2][row]
From Codebeamer 20.11, a column index is always interpreted as the immutable and unique column ID, which is the second index in the immutable and unique column property name.
For example the column ID or index of Product (tableColumn[0,2]) is 2independent of its position. Adding, removing, or re-ordering columns does not change the column ID or index of existing columns and column access stays consistent: table[0][row][2]==tableColumn[0,2][row]