Build a fault tree from an Excel spreadsheet
Most fault trees start life in a spreadsheet. Someone lists the failure events, someone else adds failure rates from a handbook, and a third column appears saying which subsystem each event belongs to. By the time anyone opens a drawing tool, the analysis already exists — it is just in rows rather than boxes. This guide covers the part that turns one into the other: a single column that carries the tree structure, the row schema around it, and what the importer checks before it will build anything.
Why the spreadsheet comes first
Drawing is the wrong first activity for a fault tree, and experienced analysts tend to discover this the hard way. Laying out boxes forces you to commit to a structure before you have finished arguing about it, and moving a subtree after the fact is tedious enough that people leave bad structure in place. A spreadsheet has none of that friction: reassigning an event to a different gate is one cell, three engineers can work on different columns at once, and the failure-rate data usually arrives as a spreadsheet anyway — from a reliability handbook, a supplier's FMEDA, or a maintenance database export.
What a spreadsheet cannot do is check the tree. It will happily let you point an event at a gate that does not exist, create two top events, or build a parent chain that loops back on itself. The value of importing rather than retyping is not saved keystrokes — it is that the import is the first moment anything verifies that the rows describe a well-formed tree at all.
IdeaOne column carries the structure
A fault tree is a set of events plus the answer to one question for each: what does this feed into? That is all the structure there is. So the table needs exactly two structural columns:
uid— your own identifier for the row.TE-001,G-04,BE-17, or whatever your project already uses. It has to be unique, and it is what the diagram displays as the event identifier.parent— theuidof the gate this event feeds into. Exactly one row leaves this empty: the top event.
Everything else — layout, connector routing, page breaks — is derived. Row order does not matter; the importer resolves parent references by name, not by position, so you can sort the sheet by failure rate or by subsystem without disturbing the tree. Once the tree is built it is laid out automatically, so no coordinates ever appear in the spreadsheet.
This is worth dwelling on because it is the part people expect to be harder than it is. There is no indentation convention to get right, no separate "connections" sheet, and no requirement that children appear below their parent. One column of identifiers, one column of parents.
Step 1One row per event
Each row also needs a name and a type. The type is what distinguishes a gate from a leaf:
| type | Meaning |
|---|---|
top | The top event. Exactly one per file, and the only row with an empty parent. |
gate | An intermediate event. Needs a gate column value: AND, OR, XOR, PAND, INHIBIT, NOT, NAND, NOR or VOTE. |
basic | A basic event — the leaves that carry probability data. |
undeveloped | An event not developed further, usually for lack of data or because it is out of scope. |
conditioning | A condition attached to an INHIBIT or PAND gate. |
house | A house event — on or off by assumption, used to switch configurations. |
For a VOTE gate, votingK carries the k in k-of-n; the n is however many children the gate ends up with, so you never state it twice.
Step 2The numbers, where you have them
Quantitative columns are all optional — a structure-only import is perfectly valid, and it is often the right first pass. When you do have data:
| Column | Meaning |
|---|---|
prob | Direct failure probability, 0–1. Use this when you have a demand-based probability rather than a rate. |
lambda | Failure rate λ per hour. Leave prob empty when using it. |
missionTime | Mission time T in hours. Defaults to 8760 — one year — if omitted. |
mu, tau | Repair rate and proof-test interval, per hour. Present for repairable and periodically tested components. |
sil | Integrity rating in whichever scheme the project uses: SIL1–SIL4, DAL-A–DAL-E, ASIL-A–ASIL-D or PL-a–PL-e. Matched case-insensitively, so asil-b is fine. |
failureMode, detection | Free text. These feed the FMEA view. |
severity, occurrence, detectability | FMEA scores 1–10, from which RPN is computed. |
desc | Free-text description, shown in the properties panel. |
Column order is irrelevant — the importer matches on header names — and any line beginning with # is skipped, which is how the downloadable template carries its own legend without breaking the parse.
sil column accepts all four integrity schemes, not just SIL, because a supplier's data rarely arrives in the scheme your project uses. An ASIL-rated component in a table otherwise expressed in SIL is not an error — record what the source says and let the crosswalk happen deliberately, not in a cell. If you need the mapping, the ASIL ↔ DAL ↔ SIL crosswalk lays out where the correspondence holds and where it does not.
Step 3Start from the template, not a blank sheet
File ▾ → Table (CSV) → Table Import Template downloads a CSV that already carries the full column legend as comments and a worked four-node example — a top event, an AND gate, a VOTE gate and three leaves. Open it in Excel, read the legend, delete the example rows, and type your own. Starting here removes the two most common import failures at a stroke: a misspelled header, and guessing at what a column expects.
If you would rather see the schema populated with something real, build any tree in the app — or open one of the eight industry templates — and use Export Table CSV. That writes the current tree out in exactly the format the importer reads, so it doubles as a reference and as a starting point for a variant.
Step 4Save as CSV, then import
From Excel: File → Save As, and pick CSV UTF-8 (Comma delimited). The UTF-8 variant matters if any cell contains a degree sign, a Greek letter, or a non-English name — the plain "CSV (Comma delimited)" option writes the local code page and those characters arrive corrupted.
Then File ▾ → Table (CSV) → Import Table CSV…. A preview opens listing every row with its status. Import never silently accepts a table: the Build fault tree button stays disabled while any row is in error, so a table either imports completely or not at all. Each rejected row carries the specific reason on that row, and each rule exists because the alternative is a tree that looks fine and is not:
| Rejected | Why it cannot be waved through |
|---|---|
Duplicate uid | Parent references are resolved by uid. Two rows sharing one means every child pointing at it lands on an arbitrary parent. |
Unknown parent | Almost always a typo or a row deleted after its children were written. Attaching the orphan to the top event would silently change the logic. |
| Parent chain forms a cycle | Not a tree. Usually two gates that were swapped during an edit. |
| No top row, or more than one | A fault tree has exactly one top event by definition; two means two analyses pasted into one sheet. |
| A leaf used as a parent | Only a gate or the top event can have children. |
prob outside 0–1 | Usually a percentage typed as 5 rather than 0.05, which would understate the top event by a factor of a hundred. |
| A numeric cell that is not a number | Rejected rather than dropped to empty — a rate that silently became "no data" is worse than a rate that failed to import. |
| FMEA score outside 1–10 | RPN is only interpretable on the standard scale. |
Importing replaces the current diagram, so you are asked to confirm if it already has nodes. Reference nodes are the one thing a table cannot express — recreate those in the diagram afterwards.
The round trip, and when to use it
Export and import share one row schema, so a tree exported as a table re-imports unchanged. That makes the spreadsheet useful well past the first build:
- Bulk data updates. A new revision of a failure-rate handbook lands. Export, paste the new λ column, re-import.
- Review outside the tool. A reviewer who will not install anything can still read and comment on a table.
- Variants. Export, change the redundancy in a few rows, import as a new tree, and compare top-event probabilities.
- Diffing. Two exported CSVs diff cleanly in Git or any text tool, which a diagram does not.
Values that begin with =, +, - or @ — a temperature written as -40C, say — are protected in both directions, so Excel treats them as text rather than formulas and they survive repeated round trips without accumulating quote marks.
For smaller edits, the Table view inside the app is the same schema as an editable grid, with no file involved. Use the CSV path when the data starts outside the tool or has to go back out; use the table view when you just want to edit many rows at once.
Where a spreadsheet stops being the right tool
Two honest limits. First, a table is a poor medium for discovering structure. Deciding whether a failure belongs under one gate or another is a reasoning task, and the diagram is a much better thinking surface for it than a column of identifiers — which is why the recommended path is a rough table in, then restructure on the canvas, rather than perfecting the sheet first.
Second, everything that is not the tree itself lives outside the table: common-cause failure groups, disjoint event groups, transfer gates across diagram pages, the hazard register, and event tree analyses. Those are set up in the app after import. The table is a fast way to get the skeleton and the numbers in; it is not a serialisation format for the whole analysis. For that, the JSON export is the complete record.
If you are building your first tree, the worked SPAD example walks through the structural reasoning itself — which events belong where, and why — and is worth reading before you start filling in rows.