> ## Documentation Index
> Fetch the complete documentation index at: https://learn.nextedy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Formula Syntax

> Nextedy RISKSHEET formulas are JavaScript functions defined as strings in the sheet configuration.

export const LastReviewed = ({date}) => {
  if (!date) return null;
  const formatted = new Date(`${date}T00:00:00Z`).toLocaleDateString("en-US", {
    year: "numeric",
    month: "long",
    day: "numeric",
    timeZone: "UTC"
  });
  return <p className="mt-10 text-sm text-gray-400 dark:text-zinc-500 not-prose">
      Last reviewed on {formatted}
    </p>;
};

## Formula Definition

### Configuration Location

Formulas are defined in two places within sheet configuration:

| Location            | Type     | Description                                                                                           |
| ------------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `formulas`          | `object` | Top-level named formula definitions. Keys are formula names, values are JavaScript function strings.  |
| `columns[].formula` | `string` | Inline formula on a specific column. References a named formula or contains a direct function string. |

### Function Signature

Every formula function follows this pattern:

```javascript theme={null}
function(info) {
  // info.item - the current row's data object
  // info.value - the current cell value
  // info.cell  - the DOM element of the cell
  // return the computed value
}
```

| Parameter    | Type          | Description                                                                                    |
| ------------ | ------------- | ---------------------------------------------------------------------------------------------- |
| `info.item`  | `object`      | The current row's work item data. Access fields via `info.item['fieldId']`.                    |
| `info.value` | `any`         | The current stored value of the cell before formula execution.                                 |
| `info.cell`  | `HTMLElement` | The DOM element representing the cell. Used for direct DOM manipulation in advanced scenarios. |

## Accessing Item Properties

Use bracket notation to access work item field values:

```javascript theme={null}
function(info) {
  var severity = info.item['sev'];
  var occurrence = info.item['occ'];
  var detection = info.item['det'];
  return severity * occurrence * detection;
}
```

<Warning title="Enum Values Are IDs">
  When accessing enum fields, `info.item['fieldId']` returns the enum **ID** (e.g., `"yes"`), not the display name (e.g., `"Y"`). Always compare against enum IDs in formula logic.
</Warning>

### Field Access Patterns

| Pattern                         | Description                                                             |
| ------------------------------- | ----------------------------------------------------------------------- |
| `info.item['fieldId']`          | Access a direct field on the current work item                          |
| `info.item['linkedField_link']` | Access the HTML link for an item link column (using the `_link` suffix) |
| `info.item['systemItemId']`     | Access the Polarion work item ID                                        |
| `info.item['systemReadOnly']`   | Check if the item is read-only                                          |

## Return Values

| Return Type | Behavior                                 |
| ----------- | ---------------------------------------- |
| `number`    | Displayed as a numeric value in the cell |
| `string`    | Displayed as text in the cell            |
| `null`      | Cell displays as empty                   |
| `undefined` | Cell displays as empty                   |

<Tip title="Null-Safe Calculations">
  Always guard against null or undefined values. When multiplying risk parameters, return `null` for empty inputs to avoid displaying `NaN` or `0`:

  ```javascript theme={null}
  function(info) {
    var value = info.item['occ'] * info.item['det'] * info.item['sev'];
    return value ? value : null;
  }
  ```
</Tip>

## Named vs. Inline Formulas

### Named Formulas

Define reusable formulas in the top-level `formulas` object, then reference by name in column definitions:

```yaml theme={null}
formulas:
  commonRpn: function(info){ var value = info.item['occ']*info.item['det']*info.item['sev'];
    return value?value:null;}
columns:
- id: rpn
  header: RPN
  formula: commonRpn
```

### Inline Formulas

Define the formula directly on the column:

```yaml theme={null}
columns:
- id: rpn
  header: RPN
  formula: function(info){ return info.item['occ']*info.item['det']*info.item['sev'];
    }
```

## Formula Execution Behavior

<Frame>
  <img src="https://mintcdn.com/none-17b4493f/yWl5nA2D0IzEnZC1/risksheet/diagrams/reference/formulas/formula-syntax/diagram-1.svg?fit=max&auto=format&n=yWl5nA2D0IzEnZC1&q=85&s=309923b850c9046da180cad9defb956b" alt="diagram" style={{ maxWidth: "620px", width: "100%" }} width="620" height="100" data-path="risksheet/diagrams/reference/formulas/formula-syntax/diagram-1.svg" />
</Frame>

| Behavior         | Description                                                                                                                                                                         |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Execution timing | Formulas execute during cell rendering                                                                                                                                              |
| Read-only        | Columns with `formula` are automatically set to `readOnly: true`                                                                                                                    |
| Hidden columns   | Formula columns do **not** execute when hidden from the grid view. If a title column uses a formula and is hidden during item creation, the work item will have an incorrect title. |
| Change tracking  | When formula results differ from stored values, the system can mark the item as edited                                                                                              |
| Persistence      | Calculated values are persisted to Polarion fields when the item is saved                                                                                                           |

<Warning title="Hidden Formula Columns">
  Formula columns do not execute when hidden. If you use a formula for the `title` field, keep that column visible during item creation. Use [Saved Views](/risksheet/reference/saved-views) to manage column visibility for different workflows rather than hiding formula columns.
</Warning>

## Bridging Top Panel Functions

For complex calculations, define JavaScript functions in the `risksheetTopPanel.vm` file and call them from sheet configuration formulas:

```javascript theme={null}
// In risksheetTopPanel.vm <script> section:
function calculateRiskLevel(info) {
  var sev = info.item['severity'];
  var prob = info.item['probability'];
  // Complex risk matrix lookup
  if (sev >= 8 && prob >= 6) return 'Unacceptable';
  if (sev >= 5 && prob >= 4) return 'Further Investigation';
  return 'Acceptable';
}
```

```yaml theme={null}
formulas:
  riskLevel: function(info){ return calculateRiskLevel(info); }
```

<Tip title="Accessing Document Custom Fields">
  Document-level custom fields can be accessed via `$doc.getOldApi().getValue('customFieldID')` in the `risksheetTopPanel.vm` script section, then referenced from sheet configuration formulas through top panel functions.
</Tip>

## Check Stored Formulas

When formula columns have `readOnly: false`, or when items are imported without formula execution, use **Menu > Rows > Check stored formulas** (available since v24.5.1) to reconcile formula values between Polarion and Risksheet.

## Complete Example

```yaml theme={null}
formulas:
  commonRpn: function(info){ var value = info.item['occ']*info.item['det']*info.item['sev'];
    return value?value:null;}
  commonRpnNew: function(info){ var value = info.item['occNew']*info.item['detNew']*info.item['sevNew'];
    return value?value:null; }
columns:
- id: sev
  header: Severity
  type: rating:severity
- id: occ
  header: Occurrence
  type: rating:occurrence
- id: det
  header: Detection
  type: rating:detection
- id: rpn
  header: RPN
  type: int
  formula: commonRpn
- id: sevNew
  header: Severity (New)
  type: rating:severity
- id: occNew
  header: Occurrence (New)
  type: rating:occurrence
- id: detNew
  header: Detection (New)
  type: rating:detection
- id: rpnNew
  header: RPN (New)
  type: int
  formula: commonRpnNew
```

## Related Pages

* [Formula Functions](/risksheet/reference/formulas/formula-functions) -- built-in helper functions for formulas
* [Formula Examples](/risksheet/reference/formulas/formula-examples) -- ready-to-use formula patterns
* [Calculated Columns](/risksheet/reference/columns/calculated-columns) -- column configuration for calculated fields
* [Cell Decorators](/risksheet/reference/styling/cell-decorators) -- conditional styling driven by formula values
* [Top Panel Template](/risksheet/reference/templates/top-panel-template) -- defining helper functions in the top panel

<LastReviewed date="2026-06-24" />
