#CYCLE!: a cycle of cell references
#CYCLE! means that a cell of a sheet reads itself, directly or through other cells. A spreadsheet shows a circular reference warning for the same problem.
| reads | a | b | c | d | ifError |
|---|---|---|---|---|---|
| a | |||||
| b | |||||
| c | |||||
| d |
| a | 1 + b | #CYCLE! |
|---|---|---|
| b | 2 + a | #CYCLE! |
| c | 3 + ifError(a, 0) | 3 |
| d | 4 | 4 |
In the start state, the column a reads b, and b reads a. Both cells give #CYCLE!. The column c reads a, but a does not read c, so c is not on the cycle. Its ifError changes the error to 0.
| Kind | Cause |
|---|---|
cycle |
The cell is on a cycle of cell references: a column reads its own value at the same key, directly or through other cells. A cycle can go across keys, for example a column that reads itself at other. |
Why ifError does not hide it
Section titled “Why ifError does not hide it”Each cell on a cycle gives #CYCLE!, also when its formula has ifError:
const loop = root .sheet() .column("a", (r) => r.start(r.cell<number>("b")).ifError(0)._.add(1)) .column("b", (r) => r.start(r.cell<number>("a")).ifError(0)._.add(1));
loop.result("A", "a"); // => { ok: false, error: { code: "#CYCLE!", ... } }loop.result("B", "b"); // => { ok: false, error: { code: "#CYCLE!", ... } }If ifError could hide a cycle, the first cell that the sheet evaluates gets the error, and the other cell gets a value. The results then depend on the order of the evaluations. Vex finds each cycle with the algorithm of Tarjan for strongly connected components, so the result is the same in each order.
Why one expression has no cycle
Section titled “Why one expression has no cycle”A Vex expression is a tree of plain data. A let binding evaluates with the names from outside the let, so a binding cannot read its own name. Only the cell references of a sheet can make a cycle.
The fix
Section titled “The fix”- Remove one reference of the cycle. The page sheets and cycles shows each read.
- For a recurrence, read a different key: a running total reads the row above with
offset(-1), not its own row.
Refer to error values for the other codes.