Writing Calculations
Finance Business Rules store calculated results into the cube. This guide covers the two primary calculation techniques, the difference between Calculate and CustomCalculate, and when to choose Business Rules over Member Formulas.
Stored Calculation Techniques
The api.Data.Calculate Approach
The simplest way to write a stored calculation is the
Calculate method. It accepts a formula-style string that reads like an equation:This approach is concise and easy to read. Use it when your calculation can be expressed as a straightforward formula.
The Get/Set Data Buffer Approach
For more complex scenarios — conditional logic, intermediate calculations, or working with data cell-by-cell — use the Data Buffer pattern:
You can also inspect and manipulate individual cells in a buffer before writing them back:
When to Use Each
api.Data.Calculate | Get/Set Data Buffer | |
|---|---|---|
| Best for | Simple formulas and direct expressions | Complex logic, conditional adjustments, loops |
| Readability | Very readable, formula-like syntax | More verbose but more flexible |
| Performance | Optimized internally by the engine | Slightly more overhead due to buffer operations |
| Use when | The calculation is a straight formula | You need to inspect or transform data before storing |
Calculate vs. CustomCalculate
Both
Calculate and CustomCalculate are used for stored calculations, but they fire at different points and serve different purposes.Calculate runs inside the Data Unit Calculation Sequence (DUCS). Every time an entity is calculated or consolidated, your Calculate logic fires. This is the standard approach for most calculations.
CustomCalculate runs outside the DUCS on a separate pass. It was designed for Planning projects with large volumes of calculations where you need more control over when and how calculations execute. CustomCalculate can be triggered from:
- A Data Management Custom Calculate step — the most common approach for running calculations on demand
- A Dashboard Parameter Component server task action
- A Forms Event Handler (e.g., when a user clicks Save on a Form in Workflow)
Running CustomCalculate from Data Management
The Custom Calculate Data Management step lets you run a Finance Business Rule's
CustomCalculate function on a specific slice of data without triggering a full Calculate or Consolidation. This is particularly useful for What-if analysis — a user can make changes in a Form, run the Custom Calculate step, and immediately see the results.The step has two key properties:
- Business Rule / Function Name — the Finance Business Rule and the function name to execute. Your rule matches on
args.CustomCalculateArgs.FunctionNameto run the correct logic. - POV Settings — non-Data Unit dimensions (View, Account, Flow, Origin, IC, UD1–UD8) that can be referenced in your rule via
api.Pov. This makes your rule reusable across multiple steps with different POV configurations.
Because CustomCalculate runs outside the normal sequence, you must manually clear previously calculated data at the top of your rule to avoid stale results:
Business Rules vs. Member Formulas
OneStream offers two approaches to writing calculations — Business Rules and Member Formulas. Understanding when to use each is important:
| Business Rules | Member Formulas | |
|---|---|---|
| Location | Centralized in the Business Rule library | Written directly on individual members |
| Best for | Cross-dimensional dependencies, complex sequential logic, custom translation/consolidation | Standard calculations tied to specific members |
| Maintenance | All logic in one place, easier to review holistically | Distributed across members, closer to the data they affect |
| Performance | Runs for each Data Unit (entity) in the workflow profile's scope | Scoped to the member automatically |
| Drill-down | Requires separate CalcDrillDownMemberFormula logic | Drill-down built in |
The Member Formula Skeleton
Member formulas are VB.NET only — you write them in the UI formula editor on a dimension member. OneStream wraps your code in auto-generated boilerplate; you only edit what goes inside the
Try block. The boilerplate differs depending on whether the formula is a stored calculation or a dynamic calculation.For comparison, the Finance Business Rule skeleton is covered in Getting Started with Finance Rules.
Stored Calculation Member Formula
A stored calculation member formula writes data into the cube during calculation. The entry point is a
Sub (void) — it does not return a value.Key points:
Public Sub Main— void, no return value. Writes data viaapi.Data.Calculateorapi.Data.SetDataCell.- No
DivideByZeroExceptioncatch — you handle divide-by-zero yourself if needed. - Same
FinanceRulesApiandFinanceRulesArgsparameters as Finance Business Rules.
Dynamic Calculation Member Formula
A dynamic calculation member formula computes a value on the fly every time a cell is viewed. The entry point is a
Function that must return the displayed value.Key points:
Public Function Main(...) As Object— must return a value (the displayed cell value).Catch dbzEx As DivideByZeroException— auto-catches divide-by-zero and returns0.0.Return 0.0afterEnd Try— fallthrough if your code doesn't explicitlyReturn.
Helper Functions in Member Formulas
Both formula types support helper functions via the
##XFHelperFunctions## separator. Code above the marker goes inside Main; code below becomes class-level methods on MainClass.Summary: Business Rules vs. Member Formulas
| Business Rule | Stored Calc Formula | Dynamic Calc Formula | |
|---|---|---|---|
| Language | VB.NET or C# | VB.NET only | VB.NET only |
| Entry point | Function Main(...) As Object | Sub Main(...) | Function Main(...) As Object |
| Returns | Object (typically Nothing) | Nothing (void) | Object (displayed value) |
| Divide-by-zero | You handle it | You handle it | Auto-catch, returns 0.0 |
| Fallthrough | Returns your value | N/A | Returns 0.0 |
| Helpers | Class methods | ##XFHelperFunctions## | ##XFHelperFunctions## |
Related Content
- The Finance Rules API — Explore the full API object, BRApi, and code sharing patterns
- Debugging Business Rules — The StringBuilder debug logging pattern and understanding rule error handling