尝试评估包含另一个计算单元格公式的单元格时出错

时间:2017-09-11 17:42:44

标签: java excel apache-poi

我有一个包含很多公式的电子表格和几个标签。其中一个选项卡用于将数字输入到10个字段中。另一个选项卡用于查看计算公式的输出。

使用Apache POI,我打开了电子表格并输入了我的号码。当我尝试评估电子表格时出现问题。 我试过了

FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
helper.createFormulaEvaluator();
evaluator.evaluateAll();

我得到一个错误(似乎没有人有答案):Unexpected arg eval type (org.apache.poi.ss.formula.eval.MissingArgEval)] with root cause

所以我改为单独评估单元格,以便找到哪个单元格有错误,所以我的代码如下所示:

FormulaEvaluator evaluator = this.workbook.getCreationHelper().createFormulaEvaluator();
for (Sheet sheet : this.workbook) {
  System.out.println("Evaluating next sheet");
  System.out.println(sheet.getSheetName());
  for (Row r : sheet) {
    System.out.println("Row Number:");
    System.out.println(r.getRowNum());
    for (Cell c : r) {
      if (c.getCellType() == Cell.CELL_TYPE_FORMULA) {
          System.out.println(c.getColumnIndex());
          try {
            evaluator.evaluateFormulaCell(c);
          } catch (Exception e) {
              rowArray.add(r.getRowNum());
              cellArray.add(c.getColumnIndex());
            System.out.println("Skipping failed cell");
          }
      }
    }
  }

我得到了与运行evaluateAll时相同的错误。 通过在那里进行一点调试,我发现错误来自Cell L3,其中包含公式:=D5。由于求值程序逐行:列,它在到达5之前首先计算第3行的所有内容,因此L3引用尚未评估的字段,因此会抛出错误。

我尝试捕获错误并将行和单元格编号存储在数组中,然后在处理完工作表中的所有内容后,尝试重新处理未处理的单元格,但我仍然得到相同的结果。我有点困惑为什么重试不起作用。

重试代码:

  // try to fix any failed evaluations here
  Iterator cellItr = cellArray.iterator();
  Iterator rowItr = rowArray.iterator();

  while (cellItr.hasNext()) {
    Integer cellElement = (int) cellItr.next();
    Integer rowElement = (int) rowItr.next();

      XSSFRow row = sheet.getRow(rowElement);
      XSSFCell cell = row.getCell(cellElement);

      System.out.println("Re-evaluating: " + rowElement + " : " + cellElement);
      evaluator.evaluateFormulaCell(cell);
  }
}

重试代码给出了相同的结果。 我尝试更改原始评估程序以使用evaluateInCell将公式更改为实际数字,但这似乎没有帮助。

-----------------更新--------------------- 我刚才意识到不推荐使用evaluateFormulaCell,而是赞成evaluateFormulaCellEnum。我将所有代码放入一个函数并多次运行该函数,并意识到它一遍又一遍地评估所有单元格,所以我切换到使用evaluateInCell并发现它只评估每个单元格一次,但仍然无法获得通过提到的细胞。 这是我更新的代码,我在一个运行5次的函数中有:

for (Sheet sheet : this.workbook) {
    System.out.println("Evaluating next sheet" + sheet.getSheetName());
  for (Row r : sheet) {
    for (Cell c : r) {
      if (c.getCellType() == Cell.CELL_TYPE_FORMULA) {
          System.out.println("Cell index: " + r.getRowNum() + " - " + c.getColumnIndex());
          try {
            evaluator.evaluateInCell(c);
          } catch (Exception e) {
              try {
                evaluator.evaluateFormulaCellEnum(c);
              } catch (Exception ee) {
                System.out.println("Skipping failed cell after 2 attempts");
              }
          }
      }
    }
  }

1 个答案:

答案 0 :(得分:0)

通过我的调试,我能够看到电子表格中的哪些单元格失败,所以我从文本文档中的失败单元格中保存了公式,并将公式替换为它们的值,然后重新编译代码和实际评估了电子表格!

然后我仔细检查了所有的细胞并将它们的公式一两回来,直到它再次破裂。事实证明这是我已经知道的一个案例,但是搜索电子表格并不是件好事。

这是问题的公式:=ROUNDUP('HW page'!$H$53*'HW page'!$H$54,) 我添加了一个0作为最后一个参数,所以它看起来像这样:=ROUNDUP('HW assumptions'!$H$53*'HW assumptions'!$H$54,0),然后评估者工作。