XCubes

Populating cubes — Links & integrations

You can type values straight into a cube, but most real models are fed from somewhere else. A Link is a saved definition that populates a cube from a source: it remembers how the source's data maps onto the cube's coordinates, and you can re-run it whenever the source changes.

Source types

A Link draws from one of four kinds of source:

How the mapping works

When you create a Link (the Link editor walks you through it), you tell XCubes:

A Link can also carry several value columns at once: a multi-value link binds each chosen column to an item of one dimension — a Debit and a Credit column landing on the matching items of a Measure dimension, say — and every source row then writes one cell per bound column. Value columns are matched by column name, so reordering or inserting source columns does not disturb a saved Link.

Cube-to-cube links map dimension to dimension instead of column to dimension, and can pin unmapped dimensions to a fixed item.

Transform columns. Links that read a URL, a stored file, an integration or a Data Table can add computed columns written as formulas over the source columns — such as [Debit] - [Credit] or UPPER([Account]) — before the data is mapped. Every source runs them the same way, and the Transform step's preview shows exactly what the run will use. The functions are listed in the link transform function reference.

Row filter. The Transform step also says which rows the link reads. Each clause names a column (a computed one too) and a condition — equals, is one of, starts with one of, does not start with, contains, is between, is empty — and every clause must hold. A P&L fed from a French FEC keeps only the income-statement accounts with CompteNum starts with one of 6, 7; the preview, the Mapping step's values and coverage, the run and drill-down then all see only those rows, so balance-sheet accounts never show up as unmapped. Prefixes ignore case and surrounding spaces, and a blank cell starts with nothing. The filter belongs to the link: a Data Table still shows every row.

Date columns. To land a date column on a Time dimension you do not need a formula: map it as Date → period on the Mapping step and each row is bucketed onto the period its date falls in. Reach for a transform column when the period must exist as a column — PERIOD([Date], "yyyy-mm") writes the same code a Time dimension uses — or when a model keeps Year and Month as separate dimensions: Split date adds YEAR([Date]), MONTH([Date]), QUARTER([Date]) and WEEK([Date]) columns. Both are one click away on the ▾ of a column in the Transform step's data preview, whatever the source.

The Link mapping editor: source columns matched to cube dimensions, with unmapped dimensions pinned to fixed items.

Mapping an Excel source onto a cube: each source column is matched to a cube dimension (or skipped), the remaining (unmapped) dimensions are pinned to a fixed item (Version → Actual, YTD → Current…), and the transfer mode sets how values are written. Auto-map and AI Suggest can propose the mapping for you.

Running, refreshing, reverting

A cube's Data menu listing its incoming links — a spreadsheet, a data table and another cube — each with actions to preview, run, edit or inspect its history, and one flagged stale because its source moved on.

Locks and protections

A Link run is an automated writer, and two things keep it off a cell. A lock (a cell lock or a workflow lock) blocks everyone: people, the Excel add-in, API writes and Links. A protection blocks Links only. It is a named selection of the cube — per dimension a list of items, or a range of periods such as the closed months; a dimension left out means all its items, including ones added later — that Link runs and reverts neither write nor clear, while people can still edit it. Protect the slices that must stay hand-entered (a budget version, top-side adjustments, closed periods) and let the Link refresh the rest. Several protections may overlap.

A plain protection guards the cells a Link would write; it does not freeze formula results. A protected FY2025 depreciation still moves if an asset's cost is corrected in another cube. For a closed period, tick Freeze (closed period) in Protect Cells (or pass frozen: true to protect_cells). A frozen protection holds the computed values it has when you freeze it: formulas inside stop recalculating, everything that reads them (time functions, totals, other cubes) sees the frozen numbers, nobody can write its cells, and the cells carry a snowflake. When a driver elsewhere would restate the period, the cube's Checks (and the MCP tools get_cube_diagnostics and check_assertions) report Frozen period differs from live — how many cells, frozen value against live value. To restate the period on purpose, Re-baseline on that card (or accept_protected_values). Only a project owner or admin can remove a frozen protection. A correction booked after the close lands in open periods only if the model's formulas read the frozen history — depreciation computed from the remaining net book value catches up; a straight-line cost ÷ life does not.

A run or a preview reports the cells it kept under each rule (locked kept, protected kept — a cell can be both, and the total counts it once) and, for a replace Link, the cells it emptied. Removing a protection or a lock changes no data; it only lets the next writer in. Both live in the cube's Commands menu (Lock / Unlock, Protect / Unprotect), and in the MCP tools lock_cells, unlock_cells, list_locks, protect_cells, unprotect_cells and list_protections.

Budget beside linked data. A cube that holds linked actuals and a hand-entered budget in one Version dimension: Protect the BUD slice so no Link run ever writes or clears it, and Lock it as well once the budget is signed off, so people, imports and allocations cannot change it either. The actuals refresh around it.

Large sources stream in, so an integration can load far more rows than would fit in memory at once.

Re-running is safe with replace: a replace-mode Link remembers the cells it wrote last time, so a second run overwrites them rather than adding to them, and cells whose source rows have since been deleted — or whose account a mapping table now sends to another line — are cleared. It never clears a cell it did not write itself: a budget column typed in beside the linked actuals survives every rerun. (An integration Link overwrites the cells it writes but does not yet clear the ones its query stops returning; revert it before a rerun that drops rows.) Add and subtract accumulate — running one twice counts the data twice, so revert first if you need to re-run one of those.

Within a single run the mode is not what combines rows: several source rows landing on the same cell always sum first, and the mode then decides how that total meets the value already in the cell. This is what makes a journal work — twenty entries hitting the same account and period become one figure.

Both move numbers between cubes, so it is worth being deliberate. The difference is push versus pull:

Link Reference() / path lookup
Direction Pushes values into the destination Pulls a value into a formula
When it happens On a run you control Live, on every recompute
What lands in the cell Real stored data, editable afterwards A computed result
Undo Revert puts back what the run changed Nothing to undo — change the formula
Source can be a Data Table Yes No — formulas read cubes only
Can do arithmetic No: copy, add, or subtract only Yes — any formula

Reach for a Link when:

Reach for Reference() (or the inline "Cube"!"ITEM" path lookup) when:

Many correct models use both, split along that line — a formula for the hop that computes, a Link for the hop that stores:

P&L — UK (GBP)   --[ formula: local × FX rate ]-->   P&L — UK (USD)
                                                            |
Elimination journal (Data Table)  --[ Link ]-->      Consolidation (USD)
                                  --[ Link, Entity pinned to UK ]-->

See Cube references and Reference transfer options for the pull side.

Integrations

XCubes ships connectors for these external systems:

Category Integrations
SQL databases PostgreSQL, MySQL, SQL Server, Redshift
Accounting Pennylane, Xero
Banking Plaid
CRM Salesforce, HubSpot (guide)
ERP Dynamics 365 Business Central (guide)
Market data Currencies, Stock prices

You configure a connection once (credentials are stored encrypted), then point Links at it — choosing a table or writing your own query — to feed cubes from live data.

For bringing in cross-tab spreadsheets (a grid of dates × accounts), the grid/matrix importer maps the sheet's rows, columns, and value area onto a cube in one pass, and remembers the layout for next time.

See Cubes & coordinates for where the data lands, and Collaboration for controlling who may change it.