先例和从属
介绍
- 前代单元格 是由另一个单元格的公式引用的单元格。例如,如果单元格D10包含公式=B5,则单元格B5是单元格D10的前代。
- 依赖单元格包含引用其他单元格的公式。例如,如果单元格 D10 包含公式 =B5,则单元格 D10 依赖于单元格 B5。
为了使电子表格易于阅读,您可能希望清楚地显示电子表格中用于公式的单元格。同样,您可能需要提取其他单元格的依赖单元格。
Aspose.Cells 允许您跟踪单元格并找出哪些是相互关联的。
跟踪先例和依赖单元格:Microsoft Excel
公式可能会根据客户做出的修改而改变。例如,如果单元格 C1 依赖于包含公式的 C3 和 C4,并且更改了 C1(使公式被覆盖),则根据业务规则需要更改 C3 和 C4,或其他单元格,以使电子表格保持平衡。
类似地,假设 C1 包含公式"=(B122)/(M2N32)"。我想找到 C1 依赖的单元格,即先例单元格 B1、M2 和 N32。
您可能需要跟踪特定单元格到其他单元格的依赖关系。如果业务规则嵌入在公式中,我们希望找出依赖关系,并根据此执行一些规则。同样,如果特定单元格的值被修改,那么工作表中哪些单元格受到此变化的影响?
Microsoft Excel 允许用户跟踪先例和依赖。
- 在查看工具栏上选择公式审计。将显示公式审计对话框。
- 跟踪先例:
- 选择包含您想要查找先例单元格的公式的单元格。
- 要向每个直接提供数据给活动单元格的单元格显示跟踪箭头,请单击公式审计工具栏上的跟踪先例。
- 跟踪引用特定单元格的公式(依赖项)
- 选择要识别其依赖单元格的单元格。
- 要向每个依赖于活动单元格的单元格显示跟踪箭头,请单击公式审计工具栏上的跟踪依赖。
跟踪先例和依赖单元格:Aspose.Cells
跟踪先例
Aspose.Cells 使得获取先例单元格变得容易。它不仅可以检索为简单公式先例提供数据的单元格,还可以找到为具有命名范围的复杂公式先例提供数据的单元格。
在下面的示例中,使用了模板Excel文件《Book1.xls》。电子表格在第一个工作表上包含数据和公式。
Aspose.Cells提供Cell类的GetPrecedents方法,用于跟踪单元格的先例。它返回一个ReferredAreaCollection。如上所示,在Book1.xls中,单元格B7包含一个公式"=SUM(A1:A3)"。因此,单元格A1:A3是单元格B7的先例单元格。以下示例演示了使用模板文件Book1.xls跟踪先例的功能。
Workbook workbook = new Workbook(dataDir + "Book1.xlsx"); | |
Cells cells = workbook.getWorksheets().get(0).getCells(); | |
Cell cell = cells.get("B2"); | |
//Tracing precedents of the cell A12. | |
//The return array contains ranges and cells. | |
ReferredAreaCollection ret = cell.getPrecedents(); | |
//Printing all the precedent cells' name. | |
if(ret != null) | |
{ | |
for(int m = 0 ; m < ret.getCount(); m++) | |
{ | |
ReferredArea area = ret.get(m); | |
StringBuilder stringBuilder = new StringBuilder(); | |
if (area.isExternalLink()) | |
{ | |
stringBuilder.append("["); | |
stringBuilder.append(area.getExternalFileName()); | |
stringBuilder.append("]"); | |
} | |
stringBuilder.append(area.getSheetName()); | |
stringBuilder.append("!"); | |
stringBuilder.append(CellsHelper.cellIndexToName(area.getStartRow(), area.getStartColumn())); | |
if (area.isArea()) | |
{ | |
stringBuilder.append(":"); | |
stringBuilder.append(CellsHelper.cellIndexToName(area.getEndRow(), area.getEndColumn())); | |
} | |
System.out.println("Tracing Precedents: " + stringBuilder.toString()); | |
} | |
} |
跟踪依赖项
Aspose.Cells允许您在电子表格中获取依赖单元格。Aspose.Cells不仅可以检索关于简单公式的提供数据的单元格,还可以针对具有命名范围的复杂公式查找提供数据的单元格。
Aspose.Cells 提供了 Cell 类的 GetDependents 方法,用于跟踪单元格的依赖单元格。例如,在 Book1.xlsx 中有公式:“=A1+20” 和 “=A1+30” 分别位于 B2 和 C2 单元格。以下示例演示了如何使用模板文件 Book1.xlsx 追踪 A1 单元格的依赖项。
Workbook workbook = new Workbook(dataDir + "Book1.xlsx"); | |
Cells cells = workbook.getWorksheets().get(0).getCells(); | |
Cell c = cells.get("A1"); | |
//Get the all the dependents of A1 cell | |
Cell[] dependents = c.getDependents(true); | |
for (int i = 0; i< dependents.length; i++) | |
{ | |
Cell d = dependents[i]; | |
System.out.println("Tracing Dependents: " + d.getWorksheet().getName() + d.getName() + ":" + d.getFormula()); | |
} |
根据计算链跟踪先行单元格和依赖单元格
上述追踪先决条件和依赖项的API是根据公式表达式本身而定的。它们为用户提供了方便的方法来跟踪一些公式之间的相互依赖关系。如果工作簿中有大量的公式,并且用户需要为每个单元格跟踪先决条件和依赖项,它们将性能不佳。在这种情况下,用户应该考虑使用GetPrecedentsInCalculation和GetDependentsInCalculation方法。这两种方法根据计算链路来跟踪依赖关系。因此,要使用它们,首先需要通过Workbook.Settings.FormulaSettings.EnableCalculationChain启用计算链路。然后应通过Workbook.CalculateFormula()为工作簿执行完整计算。然后,您可以跟踪需要的所有那些单元格的先决条件或依赖项。
对于一些公式,GetPrecedents和GetPrecedentsInCalculation得到的结果可能不同,GetDependents和GetDependentsInCalculation得到的结果也可能不同。例如,如果单元格A1的公式是"=IF(TRUE,B2,C3)",GetPrecedents将提供B2和C3作为A1的先行单元格。据此,当通过GetDependents检查时,B2和C3都有依赖项A1。然而,对于这个公式的计算,很明显只有B2可以影响计算结果。因此,GetPrecedentsInCalculation将不为A1提供C3,GetDependentsInCalculation也不会为C3提供A1。有时,用户可能只需要跟踪那些实际上根据工作簿当前数据影响公式计算结果的相互依存关系,那么他们也需要使用GetDependentsInCalculation/GetPrecedentsInCalculation而不是GetDependents/GetPrecedents。
以下示例演示了如何根据计算链追踪单元格的先行和依赖项:
Workbook workbook = new Workbook(); | |
Cells cells = workbook.getWorksheets().get(0).getCells(); | |
cells.get("A1").setFormula("=B1+SUM(B1:B10)+[Book1.xls]Sheet1!B2"); | |
cells.get("A2").setFormula("=IF(TRUE,B2,B1)"); | |
workbook.getSettings().getFormulaSettings().setEnableCalculationChain(true); | |
workbook.calculateFormula(); | |
Iterator en = cells.get("B1").getDependentsInCalculation(false); | |
System.out.println("B1's calculation dependents:"); | |
while(en.hasNext()) | |
{ | |
Cell c = (Cell)en.next(); | |
System.out.println(c.getName()); | |
} | |
en = cells.get("B2").getDependentsInCalculation(false); | |
System.out.println("B2's calculation dependents:"); | |
while(en.hasNext()) | |
{ | |
Cell c = (Cell)en.next(); | |
System.out.println(c.getName()); | |
} | |
en = cells.get("A1").getPrecedentsInCalculation(); | |
System.out.println("A1's calculation precedents:"); | |
while(en.hasNext()) | |
{ | |
ReferredArea r = (ReferredArea)en.next(); | |
System.out.println(r); | |
} | |
en = cells.get("A2").getPrecedentsInCalculation(); | |
System.out.println("A2's calculation precedents:"); | |
while(en.hasNext()) | |
{ | |
ReferredArea r = (ReferredArea)en.next(); | |
System.out.println(r); | |
} |