检测循环引用

介绍

工作簿可能存在循环引用,有时需要检测是否存在循环引用。

检测循环引用的概念

只有在计算公式时才能检测循环引用,因为一个公式的引用通常依赖于其他部分或其他公式的计算结果。因此,为满足此需求(收集具有循环引用的单元格),在公式计算过程中我们提供了新的API:

CalculationCell:表示正在计算的一个单元格的相关数据

AbstractCalculationMonitor.OnCircular(IEnumerator circularCellsData): 在遇到循环引用时,将由公式计算引擎调用此方法,枚举器中的元素是一个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;
}
}