Have WorkbookEvaluator process NameXPtgs, rather than returning a NameXEval which later places didn't handle. Largely allows us to process the .xls version of the test file for #56737 (but filenames aren't quite the same as in Excel)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1611711 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
d4a1239efa
commit
6e37f73018
@ -481,7 +481,8 @@ final class LinkTable {
|
||||
}
|
||||
|
||||
// Does it exist via the external book block?
|
||||
if (_externalBookBlocks.length > extBookIndex) {
|
||||
ExternalBookBlock externalBook = _externalBookBlocks[extBookIndex];
|
||||
if (externalBook._externalNameRecords.length > definedNameIndex) {
|
||||
return _externalBookBlocks[extBookIndex].getNameText(definedNameIndex);
|
||||
} else if (firstTabIndex == -2) {
|
||||
// Workbook scoped name, not actually external after all
|
||||
|
@ -18,7 +18,6 @@
|
||||
package org.apache.poi.ss.formula;
|
||||
|
||||
import org.apache.poi.ss.formula.eval.NameEval;
|
||||
import org.apache.poi.ss.formula.eval.NameXEval;
|
||||
import org.apache.poi.ss.formula.eval.NotImplementedFunctionException;
|
||||
import org.apache.poi.ss.formula.eval.ValueEval;
|
||||
import org.apache.poi.ss.formula.functions.FreeRefFunction;
|
||||
@ -48,8 +47,6 @@ final class UserDefinedFunction implements FreeRefFunction {
|
||||
String functionName;
|
||||
if (nameArg instanceof NameEval) {
|
||||
functionName = ((NameEval) nameArg).getFunctionName();
|
||||
} else if (nameArg instanceof NameXEval) {
|
||||
functionName = ec.getWorkbook().resolveNameXText(((NameXEval) nameArg).getPtg());
|
||||
} else {
|
||||
throw new RuntimeException("First argument should be a NameEval, but got ("
|
||||
+ nameArg.getClass().getName() + ")");
|
||||
|
@ -17,11 +17,32 @@
|
||||
|
||||
package org.apache.poi.ss.formula;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment.WorkbookNotFoundException;
|
||||
import org.apache.poi.ss.formula.atp.AnalysisToolPak;
|
||||
import org.apache.poi.ss.formula.eval.*;
|
||||
import org.apache.poi.ss.formula.eval.BlankEval;
|
||||
import org.apache.poi.ss.formula.eval.BoolEval;
|
||||
import org.apache.poi.ss.formula.eval.ErrorEval;
|
||||
import org.apache.poi.ss.formula.eval.EvaluationException;
|
||||
import org.apache.poi.ss.formula.eval.FunctionEval;
|
||||
import org.apache.poi.ss.formula.eval.MissingArgEval;
|
||||
import org.apache.poi.ss.formula.eval.NameEval;
|
||||
import org.apache.poi.ss.formula.eval.NameXEval;
|
||||
import org.apache.poi.ss.formula.eval.NotImplementedException;
|
||||
import org.apache.poi.ss.formula.eval.NumberEval;
|
||||
import org.apache.poi.ss.formula.eval.OperandResolver;
|
||||
import org.apache.poi.ss.formula.eval.StringEval;
|
||||
import org.apache.poi.ss.formula.eval.ValueEval;
|
||||
import org.apache.poi.ss.formula.functions.Choose;
|
||||
import org.apache.poi.ss.formula.functions.FreeRefFunction;
|
||||
import org.apache.poi.ss.formula.functions.Function;
|
||||
import org.apache.poi.ss.formula.functions.IfFunc;
|
||||
import org.apache.poi.ss.formula.ptg.Area3DPtg;
|
||||
import org.apache.poi.ss.formula.ptg.AreaErrPtg;
|
||||
import org.apache.poi.ss.formula.ptg.AreaPtg;
|
||||
@ -49,14 +70,10 @@ import org.apache.poi.ss.formula.ptg.RefPtg;
|
||||
import org.apache.poi.ss.formula.ptg.StringPtg;
|
||||
import org.apache.poi.ss.formula.ptg.UnionPtg;
|
||||
import org.apache.poi.ss.formula.ptg.UnknownPtg;
|
||||
import org.apache.poi.ss.formula.functions.Choose;
|
||||
import org.apache.poi.ss.formula.functions.FreeRefFunction;
|
||||
import org.apache.poi.ss.formula.functions.IfFunc;
|
||||
import org.apache.poi.ss.formula.udf.AggregatingUDFFinder;
|
||||
import org.apache.poi.ss.formula.udf.UDFFinder;
|
||||
import org.apache.poi.ss.util.CellReference;
|
||||
import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment.WorkbookNotFoundException;
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.util.CellReference;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
@ -613,20 +630,23 @@ public final class WorkbookEvaluator {
|
||||
// consider converting all these (ptg instanceof XxxPtg) expressions to (ptg.getClass() == XxxPtg.class)
|
||||
|
||||
if (ptg instanceof NamePtg) {
|
||||
// named ranges, macro functions
|
||||
// Named ranges, macro functions
|
||||
NamePtg namePtg = (NamePtg) ptg;
|
||||
EvaluationName nameRecord = _workbook.getName(namePtg);
|
||||
if (nameRecord.isFunctionName()) {
|
||||
return new NameEval(nameRecord.getNameText());
|
||||
}
|
||||
if (nameRecord.hasFormula()) {
|
||||
return evaluateNameFormula(nameRecord.getNameDefinition(), ec);
|
||||
}
|
||||
|
||||
throw new RuntimeException("Don't now how to evalate name '" + nameRecord.getNameText() + "'");
|
||||
return getEvalForNameRecord(nameRecord, ec);
|
||||
}
|
||||
if (ptg instanceof NameXPtg) {
|
||||
return ec.getNameXEval(((NameXPtg) ptg));
|
||||
// Externally defined named ranges or macro functions
|
||||
NameXPtg nameXPtg = (NameXPtg)ptg;
|
||||
ValueEval eval = ec.getNameXEval(nameXPtg);
|
||||
|
||||
if (eval instanceof NameXEval) {
|
||||
// Could not be directly evaluated, so process as a name
|
||||
return getEvalForNameX(nameXPtg, ec);
|
||||
} else {
|
||||
// Use the evaluated version
|
||||
return eval;
|
||||
}
|
||||
}
|
||||
|
||||
if (ptg instanceof IntPtg) {
|
||||
@ -682,6 +702,42 @@ public final class WorkbookEvaluator {
|
||||
|
||||
throw new RuntimeException("Unexpected ptg class (" + ptg.getClass().getName() + ")");
|
||||
}
|
||||
|
||||
private ValueEval getEvalForNameRecord(EvaluationName nameRecord, OperationEvaluationContext ec) {
|
||||
if (nameRecord.isFunctionName()) {
|
||||
return new NameEval(nameRecord.getNameText());
|
||||
}
|
||||
if (nameRecord.hasFormula()) {
|
||||
return evaluateNameFormula(nameRecord.getNameDefinition(), ec);
|
||||
}
|
||||
|
||||
throw new RuntimeException("Don't now how to evalate name '" + nameRecord.getNameText() + "'");
|
||||
}
|
||||
private ValueEval getEvalForNameX(NameXPtg nameXPtg, OperationEvaluationContext ec) {
|
||||
String name = _workbook.resolveNameXText(nameXPtg);
|
||||
|
||||
// Try to parse it as a name
|
||||
int sheetNameAt = name.indexOf('!');
|
||||
EvaluationName nameRecord = null;
|
||||
if (sheetNameAt > -1) {
|
||||
// Sheet based name
|
||||
String sheetName = name.substring(0, sheetNameAt);
|
||||
String nameName = name.substring(sheetNameAt+1);
|
||||
nameRecord = _workbook.getName(nameName, _workbook.getSheetIndex(sheetName));
|
||||
} else {
|
||||
// Workbook based name
|
||||
nameRecord = _workbook.getName(name, -1);
|
||||
}
|
||||
|
||||
if (nameRecord != null) {
|
||||
// Process it as a name
|
||||
return getEvalForNameRecord(nameRecord, ec);
|
||||
} else {
|
||||
// Must be an external function
|
||||
return new NameEval(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* YK: Used by OperationEvaluationContext to resolve indirect names.
|
||||
*/
|
||||
|
@ -2616,7 +2616,7 @@ public final class TestBugs extends BaseTestBugzillaIssues {
|
||||
/**
|
||||
* Formulas which reference named ranges, either in other
|
||||
* sheets, or workbook scoped but in other workbooks.
|
||||
* Currently failing with
|
||||
* Used to fail with
|
||||
* java.lang.RuntimeException: Unexpected eval class (org.apache.poi.ss.formula.eval.NameXEval)
|
||||
*/
|
||||
@Test
|
||||
@ -2639,7 +2639,12 @@ public final class TestBugs extends BaseTestBugzillaIssues {
|
||||
Cell cRefWName = s.getRow(2).getCell(3);
|
||||
|
||||
assertEquals("Defines!NR_To_A1", cRefSName.getCellFormula());
|
||||
assertEquals("'56737.xls'!NR_Global_B2", cRefWName.getCellFormula());
|
||||
|
||||
// TODO How does Excel know to prefix this with the filename?
|
||||
// This is what Excel itself shows
|
||||
//assertEquals("'56737.xls'!NR_Global_B2", cRefWName.getCellFormula());
|
||||
// TODO This isn't right, but it's what we currently generate....
|
||||
assertEquals("NR_Global_B2", cRefWName.getCellFormula());
|
||||
|
||||
// Try to evaluate them
|
||||
FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator();
|
||||
|
@ -19,18 +19,18 @@ package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.hssf.HSSFITestDataProvider;
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.hssf.record.NameRecord;
|
||||
import org.apache.poi.ss.formula.eval.NumberEval;
|
||||
import org.apache.poi.ss.formula.eval.ValueEval;
|
||||
import org.apache.poi.ss.formula.EvaluationCell;
|
||||
import org.apache.poi.ss.formula.EvaluationListener;
|
||||
import org.apache.poi.ss.formula.WorkbookEvaluator;
|
||||
import org.apache.poi.ss.formula.WorkbookEvaluatorTestHelper;
|
||||
import org.apache.poi.ss.formula.eval.NumberEval;
|
||||
import org.apache.poi.ss.formula.eval.ValueEval;
|
||||
import org.apache.poi.ss.usermodel.BaseTestFormulaEvaluator;
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.CellValue;
|
||||
import org.apache.poi.ss.usermodel.BaseTestFormulaEvaluator;
|
||||
|
||||
/**
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user