数式は依存グラフを持ち、値が変わったセルに依存する数式だけが再計算されます。 シート全体を舐め直すことはありません。
基本
using unvell.ReoGrid.Core;
ws.SetNumber(0, 0, 10);
ws.SetNumber(1, 0, 20);
ws.SetFormula(2, 0, "SUM(A1:A2)"); // 先頭の '=' は付けない
Console.WriteLine(ws.GetDisplayText(2, 0)); // 30
// A1 を変えると A3 は自動で再計算される
ws.SetNumber(0, 0, 15);
Console.WriteLine(ws.GetDisplayText(2, 0)); // 35
先頭の = は付けません。 V4 は "=SUM(A1:A2)" を値として代入していましたが、
V5 は数式専用の API を持ち、記号は API の側で表現されます。
ユーザーの入力文字列(= で始まるかどうかで数式かを判定する)を扱いたい場合は、
コントロールの SetActiveCellInput(text) を使ってください。
確認と削除
bool has = ws.HasFormula(2, 0);
string? text = ws.GetFormula(2, 0); // "SUM(A1:A2)"
ws.ClearFormula(2, 0); // 数式を消す(値は残らない)
ws.Recalculate(); // シート全体を再計算
Recalculate() が必要なのは、XLSX を読み込んだ直後などまとめて計算し直したいときだけです。
通常の編集では依存再計算が自動的に走ります。
一括投入
// 大量に書き込むときは再計算をまとめる
ws.Formulas.BeginBatch();
try
{
for (int r = 0; r < 10_000; r++)
ws.SetFormula(r, 2, $"A{r + 1}*B{r + 1}");
}
finally
{
ws.Formulas.EndBatch(); // ここで 1 回だけ再計算される
}
BeginBatch / EndBatch を使わないと、1 セット書くたびに依存する数式が再計算されます。
数千件以上を投入する場合は必ずまとめてください。
再計算のしくみ
SetFormulaが数式を解析し、参照しているセル・範囲を依存グラフへ登録する- セルの値が変わると、そのセルに依存する数式が特定される
- 依存関係の順(トポロジカル順)に評価される
この順序づけにより、A1 → B1 → C1 のように連鎖する数式でも 1 回の走査で正しい値になります。
循環参照
循環を検出すると #CIRCULAR! を返します。Excel は警告ダイアログを出しますが、
V5 は値として表面化させます。ヘッドレスで動く必要があるためです。
構造変更への追従
行や列を挿入・削除すると、数式の中の参照が自動的にシフトします。
| 操作 | 挙動 |
|---|---|
| 参照の前に行を挿入 | 参照がずれる(A5 → A7) |
| 参照している行を削除 | #REF! になる |
絶対参照 $A$1 | 同じくシフトする($ は「コピー時に動かない」の意味であり、構造変更とは別) |
| シートのリネーム | クロスシート参照が追従する |
| シートの削除 | そのシートを参照していた数式が #REF! になる |
クロスシート参照
Sheet2!A1 の形で他シートを参照できます。値が変わると、他シートの依存数式まで
連鎖して再計算されます。
詳しくは 参照の書き方 を参照してください。
数式の数を確認する
int formulaCount = ws.Formulas.Count;
bool hasOne = ws.Formulas.HasFormula(2, 0);
現在の制限
動的配列(spill)は未対応です。 FILTER / SORT / UNIQUE / SEQUENCE /
LET / LAMBDA は実装されていません。1 つの数式が複数セルへ結果をこぼす仕組み自体が
まだ無いためです。