循環参照の検出

紹介

ワークブックには循環参照が存在し、時々、循環参照があるかどうかを検出する必要があります。

循環参照の検出の概念

循環参照は、式が計算される時にのみ検出されます。なぜなら、1つの式の参照は通常、他の部分や他の式の計算結果に依存するからです。そのため、この要件(循環参照を持つセルを収集するための)のために新しいAPIを提供しています。

CalculationCell: 計算されている1つのセルに関する関連データの計算を表します

AbstractCalculationMonitor.OnCircular(IEnumerator circularCellsData): は、循環参照が発生したときに式計算エンジンによって呼び出されます。列挙子内の要素は、1つのサークル内のすべてのセルを表すCalculationCellオブジェクトであり、返された値は、この呼び出し後に循環セルを計算する必要があるかどうかを示します。

ユーザーは、AbstractCalculationMonitor.OnCircular()メソッドの実装でこれらの循環参照を収集することができます。

ソースのサンプルファイルは、次のリンクからダウンロードできます:

Circular Formulas.xls

LoadOptions LoadOptions = new LoadOptions();
Workbook objWB = new Workbook(sourceDir + "Circular Formulas.xls", LoadOptions);
objWB.getSettings().getFormulaSettings().setEnableIterativeCalculation(true);
CalculationOptions copts = new CalculationOptions();
CircularMonitor cm = new CircularMonitor();
copts.setCalculationMonitor(cm);
objWB.calculateFormula(copts);
int lngCircularRef = cm.circulars.size();
System.out.println("Circular References found - " + lngCircularRef);

AbstractCalculationMonitorクラスから派生したCircularMonitorクラスの定義は次のようになります:

public class CircularMonitor extends AbstractCalculationMonitor
{
public ArrayList circulars = new ArrayList();
public ArrayList getCirculars() { return circulars; }
public /*override*/ boolean onCircular(Iterator circularCellsData)
{
CalculationCell cc = null;
ArrayList cur = new ArrayList();
while (circularCellsData.hasNext())
{
cc = (CalculationCell)circularCellsData.next();
cur.add(cc.getWorksheet().getName() + "!" + CellsHelper.cellIndexToName(cc.getCellRow(), cc.getCellColumn()));
}
circulars.add(cur);
return true;
}
}