Converted AreEval and RefEval to be lazy (part of fix for bug 45358)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@690835 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f9123d1acf
commit
43db5ea180
@ -14,30 +14,63 @@
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
==================================================================== */
|
==================================================================== */
|
||||||
|
|
||||||
package org.apache.poi.hssf.record.formula;
|
package org.apache.poi.hssf.record.formula;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common interface for AreaPtg and Area3DPtg, and their
|
* Common interface for AreaPtg and Area3DPtg, and their child classes.
|
||||||
* child classes.
|
|
||||||
*/
|
*/
|
||||||
public interface AreaI {
|
public interface AreaI {
|
||||||
/**
|
/**
|
||||||
* @return the first row in the area
|
* @return the first row in the area
|
||||||
*/
|
*/
|
||||||
public int getFirstRow();
|
public int getFirstRow();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return last row in the range (x2 in x1,y1-x2,y2)
|
* @return last row in the range (x2 in x1,y1-x2,y2)
|
||||||
*/
|
*/
|
||||||
public int getLastRow();
|
public int getLastRow();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the first column number in the area.
|
* @return the first column number in the area.
|
||||||
*/
|
*/
|
||||||
public int getFirstColumn();
|
public int getFirstColumn();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return lastcolumn in the area
|
||||||
|
*/
|
||||||
|
public int getLastColumn();
|
||||||
|
|
||||||
|
class OffsetArea implements AreaI {
|
||||||
|
|
||||||
|
private final int _firstColumn;
|
||||||
|
private final int _firstRow;
|
||||||
|
private final int _lastColumn;
|
||||||
|
private final int _lastRow;
|
||||||
|
|
||||||
|
public OffsetArea(int baseRow, int baseColumn, int relFirstRowIx, int relLastRowIx,
|
||||||
|
int relFirstColIx, int relLastColIx) {
|
||||||
|
_firstRow = baseRow + relFirstRowIx;
|
||||||
|
_lastRow = baseRow + relLastRowIx;
|
||||||
|
_firstColumn = baseColumn + relFirstColIx;
|
||||||
|
_lastColumn = baseColumn + relLastColIx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFirstColumn() {
|
||||||
|
return _firstColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFirstRow() {
|
||||||
|
return _firstRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLastColumn() {
|
||||||
|
return _lastColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLastRow() {
|
||||||
|
return _lastRow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return lastcolumn in the area
|
|
||||||
*/
|
|
||||||
public int getLastColumn();
|
|
||||||
}
|
}
|
@ -131,14 +131,6 @@ public abstract class RefPtgBase extends OperandPtg {
|
|||||||
field_2_col=colRelative.setBoolean(field_2_col,rel);
|
field_2_col=colRelative.setBoolean(field_2_col,rel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void setColumnRawX(int col) { // TODO
|
|
||||||
field_2_col = col;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getColumnRawX() { // TODO
|
|
||||||
return field_2_col;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void setColumn(int col) {
|
public final void setColumn(int col) {
|
||||||
if(col < 0 || col >= 0x100) {
|
if(col < 0 || col >= 0x100) {
|
||||||
throw new IllegalArgumentException("Specified colIx (" + col + ") is out of range");
|
throw new IllegalArgumentException("Specified colIx (" + col + ") is out of range");
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.apache.poi.hssf.record.formula.eval;
|
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.AreaPtg;
|
|
||||||
import org.apache.poi.hssf.record.formula.Ptg;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public final class Area2DEval extends AreaEvalBase {
|
|
||||||
|
|
||||||
public Area2DEval(Ptg ptg, ValueEval[] values) {
|
|
||||||
super((AreaPtg) ptg, values);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.apache.poi.hssf.record.formula.eval;
|
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
|
||||||
import org.apache.poi.hssf.record.formula.Ptg;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public final class Area3DEval extends AreaEvalBase {
|
|
||||||
|
|
||||||
private final int _externSheetIndex;
|
|
||||||
|
|
||||||
public Area3DEval(Ptg ptg, ValueEval[] values) {
|
|
||||||
super((Area3DPtg) ptg, values);
|
|
||||||
_externSheetIndex = ((Area3DPtg) ptg).getExternSheetIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getExternSheetIndex() {
|
|
||||||
return _externSheetIndex;
|
|
||||||
}
|
|
||||||
}
|
|
@ -97,4 +97,10 @@ public interface AreaEval extends ValueEval {
|
|||||||
* specified indexes should relative to the top left corner of this area.
|
* specified indexes should relative to the top left corner of this area.
|
||||||
*/
|
*/
|
||||||
ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex);
|
ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an {@link AreaEval} offset by a relative amount from from the upper left cell
|
||||||
|
* of this area
|
||||||
|
*/
|
||||||
|
AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx);
|
||||||
}
|
}
|
||||||
|
@ -22,20 +22,16 @@ import org.apache.poi.hssf.record.formula.AreaI;
|
|||||||
/**
|
/**
|
||||||
* @author Josh Micich
|
* @author Josh Micich
|
||||||
*/
|
*/
|
||||||
abstract class AreaEvalBase implements AreaEval {
|
public abstract class AreaEvalBase implements AreaEval {
|
||||||
|
|
||||||
private final int _firstColumn;
|
private final int _firstColumn;
|
||||||
private final int _firstRow;
|
private final int _firstRow;
|
||||||
private final int _lastColumn;
|
private final int _lastColumn;
|
||||||
private final int _lastRow;
|
private final int _lastRow;
|
||||||
private final ValueEval[] _values;
|
|
||||||
private final int _nColumns;
|
private final int _nColumns;
|
||||||
private final int _nRows;
|
private final int _nRows;
|
||||||
|
|
||||||
protected AreaEvalBase(AreaI ptg, ValueEval[] values) {
|
protected AreaEvalBase(AreaI ptg) {
|
||||||
if (values == null) {
|
|
||||||
throw new IllegalArgumentException("values must not be null");
|
|
||||||
}
|
|
||||||
_firstRow = ptg.getFirstRow();
|
_firstRow = ptg.getFirstRow();
|
||||||
_firstColumn = ptg.getFirstColumn();
|
_firstColumn = ptg.getFirstColumn();
|
||||||
_lastRow = ptg.getLastRow();
|
_lastRow = ptg.getLastRow();
|
||||||
@ -43,22 +39,6 @@ abstract class AreaEvalBase implements AreaEval {
|
|||||||
|
|
||||||
_nColumns = _lastColumn - _firstColumn + 1;
|
_nColumns = _lastColumn - _firstColumn + 1;
|
||||||
_nRows = _lastRow - _firstRow + 1;
|
_nRows = _lastRow - _firstRow + 1;
|
||||||
|
|
||||||
int expectedItemCount = _nRows * _nColumns;
|
|
||||||
if ((values.length != expectedItemCount)) {
|
|
||||||
// Note - this math may need alteration when POI starts to support full column or full row refs
|
|
||||||
throw new IllegalArgumentException("Array size should be (" + expectedItemCount
|
|
||||||
+ ") but was (" + values.length + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (int i = values.length - 1; i >= 0; i--) {
|
|
||||||
if (values[i] == null) {
|
|
||||||
throw new IllegalArgumentException("value array elements must not be null");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_values = values;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final int getFirstColumn() {
|
public final int getFirstColumn() {
|
||||||
@ -116,14 +96,7 @@ abstract class AreaEvalBase implements AreaEval {
|
|||||||
return _lastRow-_firstRow+1;
|
return _lastRow-_firstRow+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex) {
|
public abstract ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex);
|
||||||
int index = relativeRowIndex * _nColumns + relativeColumnIndex;
|
|
||||||
ValueEval result = _values[index];
|
|
||||||
if (result == null) {
|
|
||||||
return BlankEval.INSTANCE;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWidth() {
|
public int getWidth() {
|
||||||
return _lastColumn-_firstColumn+1;
|
return _lastColumn-_firstColumn+1;
|
||||||
|
@ -50,7 +50,6 @@ public abstract class FunctionEval implements OperationEval {
|
|||||||
|
|
||||||
static {
|
static {
|
||||||
Map m = new HashMap();
|
Map m = new HashMap();
|
||||||
addMapping(m, ID.OFFSET, new Offset());
|
|
||||||
addMapping(m, ID.INDIRECT, new Indirect());
|
addMapping(m, ID.INDIRECT, new Indirect());
|
||||||
addMapping(m, ID.EXTERNAL_FUNC, new ExternalFunction());
|
addMapping(m, ID.EXTERNAL_FUNC, new ExternalFunction());
|
||||||
freeRefFunctionsByIdMap = m;
|
freeRefFunctionsByIdMap = m;
|
||||||
@ -155,7 +154,7 @@ public abstract class FunctionEval implements OperationEval {
|
|||||||
retval[75] = new Areas(); // AREAS
|
retval[75] = new Areas(); // AREAS
|
||||||
retval[76] = new Rows(); // ROWS
|
retval[76] = new Rows(); // ROWS
|
||||||
retval[77] = new Columns(); // COLUMNS
|
retval[77] = new Columns(); // COLUMNS
|
||||||
retval[ID.OFFSET] = null; // Offset.evaluate has a different signature
|
retval[ID.OFFSET] = new Offset(); // OFFSET
|
||||||
retval[79] = new Absref(); // ABSREF
|
retval[79] = new Absref(); // ABSREF
|
||||||
retval[80] = new Relref(); // RELREF
|
retval[80] = new Relref(); // RELREF
|
||||||
retval[81] = new Argument(); // ARGUMENT
|
retval[81] = new Argument(); // ARGUMENT
|
||||||
|
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.poi.hssf.record.formula.eval;
|
||||||
|
|
||||||
|
import org.apache.poi.hssf.record.formula.AreaI;
|
||||||
|
import org.apache.poi.hssf.record.formula.AreaI.OffsetArea;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final class LazyAreaEval extends AreaEvalBase {
|
||||||
|
|
||||||
|
private final HSSFSheet _sheet;
|
||||||
|
private HSSFWorkbook _workbook;
|
||||||
|
|
||||||
|
public LazyAreaEval(AreaI ptg, HSSFSheet sheet, HSSFWorkbook workbook) {
|
||||||
|
super(ptg);
|
||||||
|
_sheet = sheet;
|
||||||
|
_workbook = workbook;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex) {
|
||||||
|
|
||||||
|
int rowIx = (relativeRowIndex + getFirstRow() ) & 0xFFFF;
|
||||||
|
int colIx = (relativeColumnIndex + getFirstColumn() ) & 0x00FF;
|
||||||
|
|
||||||
|
HSSFRow row = _sheet.getRow(rowIx);
|
||||||
|
if (row == null) {
|
||||||
|
return BlankEval.INSTANCE;
|
||||||
|
}
|
||||||
|
HSSFCell cell = row.getCell(colIx);
|
||||||
|
if (cell == null) {
|
||||||
|
return BlankEval.INSTANCE;
|
||||||
|
}
|
||||||
|
return HSSFFormulaEvaluator.getEvalForCell(cell, _sheet, _workbook);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
|
||||||
|
AreaI area = new OffsetArea(getFirstRow(), getFirstColumn(),
|
||||||
|
relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
|
||||||
|
|
||||||
|
return new LazyAreaEval(area, _sheet, _workbook);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package org.apache.poi.hssf.record.formula.eval;
|
||||||
|
|
||||||
|
import org.apache.poi.hssf.record.formula.AreaI;
|
||||||
|
import org.apache.poi.hssf.record.formula.AreaI.OffsetArea;
|
||||||
|
import org.apache.poi.hssf.record.formula.Ref3DPtg;
|
||||||
|
import org.apache.poi.hssf.record.formula.RefPtg;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
|
|
||||||
|
public final class LazyRefEval extends RefEvalBase {
|
||||||
|
|
||||||
|
private final HSSFSheet _sheet;
|
||||||
|
private final HSSFWorkbook _workbook;
|
||||||
|
|
||||||
|
|
||||||
|
public LazyRefEval(RefPtg ptg, HSSFSheet sheet, HSSFWorkbook workbook) {
|
||||||
|
super(ptg.getRow(), ptg.getColumn());
|
||||||
|
_sheet = sheet;
|
||||||
|
_workbook = workbook;
|
||||||
|
}
|
||||||
|
public LazyRefEval(Ref3DPtg ptg, HSSFSheet sheet, HSSFWorkbook workbook) {
|
||||||
|
super(ptg.getRow(), ptg.getColumn());
|
||||||
|
_sheet = sheet;
|
||||||
|
_workbook = workbook;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueEval getInnerValueEval() {
|
||||||
|
int rowIx = getRow();
|
||||||
|
int colIx = getColumn();
|
||||||
|
|
||||||
|
HSSFRow row = _sheet.getRow(rowIx);
|
||||||
|
if (row == null) {
|
||||||
|
return BlankEval.INSTANCE;
|
||||||
|
}
|
||||||
|
HSSFCell cell = row.getCell(colIx);
|
||||||
|
if (cell == null) {
|
||||||
|
return BlankEval.INSTANCE;
|
||||||
|
}
|
||||||
|
return HSSFFormulaEvaluator.getEvalForCell(cell, _sheet, _workbook);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
|
||||||
|
|
||||||
|
AreaI area = new OffsetArea(getRow(), getColumn(),
|
||||||
|
relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
|
||||||
|
|
||||||
|
return new LazyAreaEval(area, _sheet, _workbook);
|
||||||
|
}
|
||||||
|
}
|
@ -47,4 +47,7 @@ public final class Ref2DEval implements RefEval {
|
|||||||
public int getColumn() {
|
public int getColumn() {
|
||||||
return delegate.getColumn();
|
return delegate.getColumn();
|
||||||
}
|
}
|
||||||
|
public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
|
||||||
|
throw new RuntimeException("should not be called"); // TODO - delete this whole class
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.apache.poi.hssf.record.formula.eval;
|
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.Ref3DPtg;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Amol S. Deshmukh
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public final class Ref3DEval implements RefEval {
|
|
||||||
|
|
||||||
private final ValueEval value;
|
|
||||||
private final Ref3DPtg delegate;
|
|
||||||
|
|
||||||
public Ref3DEval(Ref3DPtg ptg, ValueEval ve) {
|
|
||||||
if(ve == null) {
|
|
||||||
throw new IllegalArgumentException("ve must not be null");
|
|
||||||
}
|
|
||||||
if(ptg == null) {
|
|
||||||
throw new IllegalArgumentException("ptg must not be null");
|
|
||||||
}
|
|
||||||
value = ve;
|
|
||||||
delegate = ptg;
|
|
||||||
}
|
|
||||||
public ValueEval getInnerValueEval() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
public int getRow() {
|
|
||||||
return delegate.getRow();
|
|
||||||
}
|
|
||||||
public int getColumn() {
|
|
||||||
return delegate.getColumn();
|
|
||||||
}
|
|
||||||
public int getExternSheetIndex() {
|
|
||||||
return delegate.getExternSheetIndex();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +1,19 @@
|
|||||||
/*
|
/* ====================================================================
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
* (the "License"); you may not use this file except in compliance with
|
(the "License"); you may not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
the License. You may obtain a copy of the License at
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
limitations under the License.
|
||||||
*/
|
==================================================================== */
|
||||||
|
|
||||||
package org.apache.poi.hssf.record.formula.eval;
|
package org.apache.poi.hssf.record.formula.eval;
|
||||||
|
|
||||||
@ -30,22 +30,22 @@ package org.apache.poi.hssf.record.formula.eval;
|
|||||||
public interface RefEval extends ValueEval {
|
public interface RefEval extends ValueEval {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The (possibly evaluated) ValueEval contained
|
* @return the evaluated value of the cell referred to by this RefEval.
|
||||||
* in this RefEval. eg. if cell A1 contains "test"
|
|
||||||
* then in a formula referring to cell A1
|
|
||||||
* the RefEval representing
|
|
||||||
* A1 will return as the getInnerValueEval() the
|
|
||||||
* object of concrete type StringEval
|
|
||||||
*/
|
*/
|
||||||
public ValueEval getInnerValueEval();
|
ValueEval getInnerValueEval();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the zero based column index.
|
* returns the zero based column index.
|
||||||
*/
|
*/
|
||||||
public int getColumn();
|
int getColumn();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the zero based row index.
|
* returns the zero based row index.
|
||||||
*/
|
*/
|
||||||
public int getRow();
|
int getRow();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an {@link AreaEval} offset by a relative amount from this RefEval
|
||||||
|
*/
|
||||||
|
AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
package org.apache.poi.hssf.record.formula.eval;
|
||||||
|
|
||||||
|
public abstract class RefEvalBase implements RefEval {
|
||||||
|
|
||||||
|
private final int _rowIndex;
|
||||||
|
private final int _columnIndex;
|
||||||
|
|
||||||
|
protected RefEvalBase(int rowIndex, int columnIndex) {
|
||||||
|
_rowIndex = rowIndex;
|
||||||
|
_columnIndex = columnIndex;
|
||||||
|
}
|
||||||
|
public final int getRow() {
|
||||||
|
return _rowIndex;
|
||||||
|
}
|
||||||
|
public final int getColumn() {
|
||||||
|
return _columnIndex;
|
||||||
|
}
|
||||||
|
}
|
@ -50,9 +50,9 @@ final class CountUtils {
|
|||||||
for (int rrIx=0; rrIx<height; rrIx++) {
|
for (int rrIx=0; rrIx<height; rrIx++) {
|
||||||
for (int rcIx=0; rcIx<width; rcIx++) {
|
for (int rcIx=0; rcIx<width; rcIx++) {
|
||||||
ValueEval ve = areaEval.getRelativeValue(rrIx, rcIx);
|
ValueEval ve = areaEval.getRelativeValue(rrIx, rcIx);
|
||||||
if(criteriaPredicate.matches(ve)) {
|
if(criteriaPredicate.matches(ve)) {
|
||||||
result++;
|
result++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -67,6 +67,9 @@ final class CountUtils {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
public static int countArg(Eval eval, I_MatchPredicate criteriaPredicate) {
|
public static int countArg(Eval eval, I_MatchPredicate criteriaPredicate) {
|
||||||
|
if (eval == null) {
|
||||||
|
throw new IllegalArgumentException("eval must not be null");
|
||||||
|
}
|
||||||
if (eval instanceof AreaEval) {
|
if (eval instanceof AreaEval) {
|
||||||
return CountUtils.countMatchingCellsInArea((AreaEval) eval, criteriaPredicate);
|
return CountUtils.countMatchingCellsInArea((AreaEval) eval, criteriaPredicate);
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,28 @@
|
|||||||
/*
|
/* ====================================================================
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
* (the "License"); you may not use this file except in compliance with
|
(the "License"); you may not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
the License. You may obtain a copy of the License at
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
limitations under the License.
|
||||||
*/
|
==================================================================== */
|
||||||
/*
|
|
||||||
* Created on Nov 25, 2006
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
package org.apache.poi.hssf.record.formula.functions;
|
package org.apache.poi.hssf.record.formula.functions;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.Eval;
|
import org.apache.poi.hssf.record.formula.eval.Eval;
|
||||||
|
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
|
||||||
|
import org.apache.poi.hssf.record.formula.eval.OperandResolver;
|
||||||
|
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||||
@ -34,16 +34,30 @@ public final class If implements Function {
|
|||||||
|
|
||||||
Eval evalWhenFalse = BoolEval.FALSE;
|
Eval evalWhenFalse = BoolEval.FALSE;
|
||||||
switch (args.length) {
|
switch (args.length) {
|
||||||
case 3:
|
case 3:
|
||||||
evalWhenFalse = args[2];
|
evalWhenFalse = args[2];
|
||||||
case 2:
|
case 2:
|
||||||
BoolEval beval = (BoolEval) args[0]; // TODO - class cast exception
|
boolean b;
|
||||||
if (beval.getBooleanValue()) {
|
try {
|
||||||
return args[1];
|
b = evaluateFirstArg(args[0], srcCellRow, srcCellCol);
|
||||||
}
|
} catch (EvaluationException e) {
|
||||||
return evalWhenFalse;
|
return e.getErrorEval();
|
||||||
default:
|
}
|
||||||
return ErrorEval.VALUE_INVALID;
|
if (b) {
|
||||||
|
return args[1];
|
||||||
|
}
|
||||||
|
return evalWhenFalse;
|
||||||
|
default:
|
||||||
|
return ErrorEval.VALUE_INVALID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean evaluateFirstArg(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException {
|
||||||
|
ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
|
||||||
|
Boolean b = OperandResolver.coerceValueToBoolean(ve, false);
|
||||||
|
if (b == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return b.booleanValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,6 @@
|
|||||||
|
|
||||||
package org.apache.poi.hssf.record.formula.functions;
|
package org.apache.poi.hssf.record.formula.functions;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.AreaPtg;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.Area2DEval;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.BlankEval;
|
import org.apache.poi.hssf.record.formula.eval.BlankEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||||
@ -366,13 +364,7 @@ final class LookupUtils {
|
|||||||
// Make this cell ref look like a 1x1 area ref.
|
// Make this cell ref look like a 1x1 area ref.
|
||||||
|
|
||||||
// It doesn't matter if eval is a 2D or 3D ref, because that detail is never asked of AreaEval.
|
// It doesn't matter if eval is a 2D or 3D ref, because that detail is never asked of AreaEval.
|
||||||
// This code only requires the value array item.
|
return refEval.offset(0, 0, 0, 0);
|
||||||
// anything would be ok for rowIx and colIx, but may as well get it right.
|
|
||||||
int rowIx = refEval.getRow();
|
|
||||||
int colIx = refEval.getColumn();
|
|
||||||
AreaPtg ap = new AreaPtg(rowIx, rowIx, colIx, colIx, false, false, false, false);
|
|
||||||
ValueEval value = refEval.getInnerValueEval();
|
|
||||||
return new Area2DEval(ap, new ValueEval[] { value, });
|
|
||||||
}
|
}
|
||||||
throw EvaluationException.invalidValue();
|
throw EvaluationException.invalidValue();
|
||||||
}
|
}
|
||||||
|
@ -455,85 +455,6 @@ public final class MathX {
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the sum of difference of squares of corresponding double
|
|
||||||
* value in each subarray: ie. sigma (xarr[i]^2-yarr[i]^2)
|
|
||||||
* <br/>
|
|
||||||
* It is the responsibility of the caller
|
|
||||||
* to ensure that the two subarrays are of equal length. If the
|
|
||||||
* subarrays are not of equal length, the return value can be
|
|
||||||
* unpredictable.
|
|
||||||
* @param xarr
|
|
||||||
* @param yarr
|
|
||||||
*/
|
|
||||||
public static double sumx2my2(double[] xarr, double[] yarr) {
|
|
||||||
double d = 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (int i=0, iSize=xarr.length; i<iSize; i++) {
|
|
||||||
d += (xarr[i] + yarr[i]) * (xarr[i] - yarr[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ArrayIndexOutOfBoundsException ae) {
|
|
||||||
d = Double.NaN;
|
|
||||||
}
|
|
||||||
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the sum of sum of squares of corresponding double
|
|
||||||
* value in each subarray: ie. sigma (xarr[i]^2 + yarr[i]^2)
|
|
||||||
* <br/>
|
|
||||||
* It is the responsibility of the caller
|
|
||||||
* to ensure that the two subarrays are of equal length. If the
|
|
||||||
* subarrays are not of equal length, the return value can be
|
|
||||||
* unpredictable.
|
|
||||||
* @param xarr
|
|
||||||
* @param yarr
|
|
||||||
*/
|
|
||||||
public static double sumx2py2(double[] xarr, double[] yarr) {
|
|
||||||
double d = 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (int i=0, iSize=xarr.length; i<iSize; i++) {
|
|
||||||
d += (xarr[i] * xarr[i]) + (yarr[i] * yarr[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ArrayIndexOutOfBoundsException ae) {
|
|
||||||
d = Double.NaN;
|
|
||||||
}
|
|
||||||
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the sum of squares of difference of corresponding double
|
|
||||||
* value in each subarray: ie. sigma ( (xarr[i]-yarr[i])^2 )
|
|
||||||
* <br/>
|
|
||||||
* It is the responsibility of the caller
|
|
||||||
* to ensure that the two subarrays are of equal length. If the
|
|
||||||
* subarrays are not of equal length, the return value can be
|
|
||||||
* unpredictable.
|
|
||||||
* @param xarr
|
|
||||||
* @param yarr
|
|
||||||
*/
|
|
||||||
public static double sumxmy2(double[] xarr, double[] yarr) {
|
|
||||||
double d = 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (int i=0, iSize=xarr.length; i<iSize; i++) {
|
|
||||||
double t = (xarr[i] - yarr[i]);
|
|
||||||
d += t * t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ArrayIndexOutOfBoundsException ae) {
|
|
||||||
d = Double.NaN;
|
|
||||||
}
|
|
||||||
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the total number of combinations possible when
|
* returns the total number of combinations possible when
|
||||||
|
@ -1,26 +1,22 @@
|
|||||||
/*
|
/* ====================================================================
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
* (the "License"); you may not use this file except in compliance with
|
(the "License"); you may not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
the License. You may obtain a copy of the License at
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
|
||||||
package org.apache.poi.hssf.record.formula.functions;
|
package org.apache.poi.hssf.record.formula.functions;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
|
||||||
import org.apache.poi.hssf.record.formula.AreaPtg;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.Area3DEval;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||||
@ -28,13 +24,9 @@ import org.apache.poi.hssf.record.formula.eval.Eval;
|
|||||||
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
|
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
|
||||||
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
|
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.OperandResolver;
|
import org.apache.poi.hssf.record.formula.eval.OperandResolver;
|
||||||
import org.apache.poi.hssf.record.formula.eval.Ref3DEval;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.StringEval;
|
import org.apache.poi.hssf.record.formula.eval.StringEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
|
|
||||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
|
||||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
|
||||||
/**
|
/**
|
||||||
* Implementation for Excel function OFFSET()<p/>
|
* Implementation for Excel function OFFSET()<p/>
|
||||||
*
|
*
|
||||||
@ -51,7 +43,7 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
|||||||
*
|
*
|
||||||
* @author Josh Micich
|
* @author Josh Micich
|
||||||
*/
|
*/
|
||||||
public final class Offset implements FreeRefFunction {
|
public final class Offset implements Function {
|
||||||
// These values are specific to BIFF8
|
// These values are specific to BIFF8
|
||||||
private static final int LAST_VALID_ROW_INDEX = 0xFFFF;
|
private static final int LAST_VALID_ROW_INDEX = 0xFFFF;
|
||||||
private static final int LAST_VALID_COLUMN_INDEX = 0xFF;
|
private static final int LAST_VALID_COLUMN_INDEX = 0xFF;
|
||||||
@ -125,37 +117,29 @@ public final class Offset implements FreeRefFunction {
|
|||||||
* Encapsulates either an area or cell reference which may be 2d or 3d.
|
* Encapsulates either an area or cell reference which may be 2d or 3d.
|
||||||
*/
|
*/
|
||||||
private static final class BaseRef {
|
private static final class BaseRef {
|
||||||
private static final int INVALID_SHEET_INDEX = -1;
|
|
||||||
private final int _firstRowIndex;
|
private final int _firstRowIndex;
|
||||||
private final int _firstColumnIndex;
|
private final int _firstColumnIndex;
|
||||||
private final int _width;
|
private final int _width;
|
||||||
private final int _height;
|
private final int _height;
|
||||||
private final int _externalSheetIndex;
|
private final RefEval _refEval;
|
||||||
|
private final AreaEval _areaEval;
|
||||||
|
|
||||||
public BaseRef(RefEval re) {
|
public BaseRef(RefEval re) {
|
||||||
|
_refEval = re;
|
||||||
|
_areaEval = null;
|
||||||
_firstRowIndex = re.getRow();
|
_firstRowIndex = re.getRow();
|
||||||
_firstColumnIndex = re.getColumn();
|
_firstColumnIndex = re.getColumn();
|
||||||
_height = 1;
|
_height = 1;
|
||||||
_width = 1;
|
_width = 1;
|
||||||
if (re instanceof Ref3DEval) {
|
|
||||||
Ref3DEval r3e = (Ref3DEval) re;
|
|
||||||
_externalSheetIndex = r3e.getExternSheetIndex();
|
|
||||||
} else {
|
|
||||||
_externalSheetIndex = INVALID_SHEET_INDEX;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseRef(AreaEval ae) {
|
public BaseRef(AreaEval ae) {
|
||||||
|
_refEval = null;
|
||||||
|
_areaEval = ae;
|
||||||
_firstRowIndex = ae.getFirstRow();
|
_firstRowIndex = ae.getFirstRow();
|
||||||
_firstColumnIndex = ae.getFirstColumn();
|
_firstColumnIndex = ae.getFirstColumn();
|
||||||
_height = ae.getLastRow() - ae.getFirstRow() + 1;
|
_height = ae.getLastRow() - ae.getFirstRow() + 1;
|
||||||
_width = ae.getLastColumn() - ae.getFirstColumn() + 1;
|
_width = ae.getLastColumn() - ae.getFirstColumn() + 1;
|
||||||
if (ae instanceof Area3DEval) {
|
|
||||||
Area3DEval a3e = (Area3DEval) ae;
|
|
||||||
_externalSheetIndex = a3e.getExternSheetIndex();
|
|
||||||
} else {
|
|
||||||
_externalSheetIndex = INVALID_SHEET_INDEX;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getWidth() {
|
public int getWidth() {
|
||||||
@ -170,19 +154,17 @@ public final class Offset implements FreeRefFunction {
|
|||||||
public int getFirstColumnIndex() {
|
public int getFirstColumnIndex() {
|
||||||
return _firstColumnIndex;
|
return _firstColumnIndex;
|
||||||
}
|
}
|
||||||
public boolean isIs3d() {
|
|
||||||
return _externalSheetIndex > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getExternalSheetIndex() {
|
public AreaEval offset(int relFirstRowIx, int relLastRowIx,
|
||||||
if(_externalSheetIndex < 0) {
|
int relFirstColIx, int relLastColIx) {
|
||||||
throw new IllegalStateException("external sheet index only available for 3d refs");
|
if (_refEval == null) {
|
||||||
|
return _areaEval.offset(relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
|
||||||
}
|
}
|
||||||
return (short) _externalSheetIndex;
|
return _refEval.offset(relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook, HSSFSheet sheet) {
|
public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
|
||||||
|
|
||||||
if(args.length < 3 || args.length > 5) {
|
if(args.length < 3 || args.length > 5) {
|
||||||
return ErrorEval.VALUE_INVALID;
|
return ErrorEval.VALUE_INVALID;
|
||||||
@ -206,37 +188,25 @@ public final class Offset implements FreeRefFunction {
|
|||||||
}
|
}
|
||||||
LinearOffsetRange rowOffsetRange = new LinearOffsetRange(rowOffset, height);
|
LinearOffsetRange rowOffsetRange = new LinearOffsetRange(rowOffset, height);
|
||||||
LinearOffsetRange colOffsetRange = new LinearOffsetRange(columnOffset, width);
|
LinearOffsetRange colOffsetRange = new LinearOffsetRange(columnOffset, width);
|
||||||
return createOffset(baseRef, rowOffsetRange, colOffsetRange, workbook, sheet);
|
return createOffset(baseRef, rowOffsetRange, colOffsetRange);
|
||||||
} catch (EvaluationException e) {
|
} catch (EvaluationException e) {
|
||||||
return e.getErrorEval();
|
return e.getErrorEval();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AreaEval createOffset(BaseRef baseRef,
|
private static AreaEval createOffset(BaseRef baseRef,
|
||||||
LinearOffsetRange rowOffsetRange, LinearOffsetRange colOffsetRange,
|
LinearOffsetRange orRow, LinearOffsetRange orCol) throws EvaluationException {
|
||||||
HSSFWorkbook workbook, HSSFSheet sheet) throws EvaluationException {
|
|
||||||
|
|
||||||
LinearOffsetRange rows = rowOffsetRange.normaliseAndTranslate(baseRef.getFirstRowIndex());
|
LinearOffsetRange absRows = orRow.normaliseAndTranslate(baseRef.getFirstRowIndex());
|
||||||
LinearOffsetRange cols = colOffsetRange.normaliseAndTranslate(baseRef.getFirstColumnIndex());
|
LinearOffsetRange absCols = orCol.normaliseAndTranslate(baseRef.getFirstColumnIndex());
|
||||||
|
|
||||||
if(rows.isOutOfBounds(0, LAST_VALID_ROW_INDEX)) {
|
if(absRows.isOutOfBounds(0, LAST_VALID_ROW_INDEX)) {
|
||||||
throw new EvaluationException(ErrorEval.REF_INVALID);
|
throw new EvaluationException(ErrorEval.REF_INVALID);
|
||||||
}
|
}
|
||||||
if(cols.isOutOfBounds(0, LAST_VALID_COLUMN_INDEX)) {
|
if(absCols.isOutOfBounds(0, LAST_VALID_COLUMN_INDEX)) {
|
||||||
throw new EvaluationException(ErrorEval.REF_INVALID);
|
throw new EvaluationException(ErrorEval.REF_INVALID);
|
||||||
}
|
}
|
||||||
if(baseRef.isIs3d()) {
|
return baseRef.offset(orRow.getFirstIndex(), orRow.getLastIndex(), orCol.getFirstIndex(), orCol.getLastIndex());
|
||||||
Area3DPtg a3dp = new Area3DPtg(rows.getFirstIndex(), rows.getLastIndex(),
|
|
||||||
cols.getFirstIndex(), cols.getLastIndex(),
|
|
||||||
false, false, false, false,
|
|
||||||
baseRef.getExternalSheetIndex());
|
|
||||||
return HSSFFormulaEvaluator.evaluateArea3dPtg(workbook, a3dp);
|
|
||||||
}
|
|
||||||
|
|
||||||
AreaPtg ap = new AreaPtg(rows.getFirstIndex(), rows.getLastIndex(),
|
|
||||||
cols.getFirstIndex(), cols.getLastIndex(),
|
|
||||||
false, false, false, false);
|
|
||||||
return HSSFFormulaEvaluator.evaluateAreaPtg(sheet, workbook, ap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BaseRef evaluateBaseRef(Eval eval) throws EvaluationException {
|
private static BaseRef evaluateBaseRef(Eval eval) throws EvaluationException {
|
||||||
|
@ -17,10 +17,7 @@
|
|||||||
|
|
||||||
package org.apache.poi.hssf.usermodel;
|
package org.apache.poi.hssf.usermodel;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
import org.apache.poi.hssf.model.FormulaParser;
|
import org.apache.poi.hssf.model.FormulaParser;
|
||||||
@ -29,6 +26,7 @@ import org.apache.poi.hssf.record.formula.Area3DPtg;
|
|||||||
import org.apache.poi.hssf.record.formula.AreaPtg;
|
import org.apache.poi.hssf.record.formula.AreaPtg;
|
||||||
import org.apache.poi.hssf.record.formula.BoolPtg;
|
import org.apache.poi.hssf.record.formula.BoolPtg;
|
||||||
import org.apache.poi.hssf.record.formula.ControlPtg;
|
import org.apache.poi.hssf.record.formula.ControlPtg;
|
||||||
|
import org.apache.poi.hssf.record.formula.ErrPtg;
|
||||||
import org.apache.poi.hssf.record.formula.IntPtg;
|
import org.apache.poi.hssf.record.formula.IntPtg;
|
||||||
import org.apache.poi.hssf.record.formula.MemErrPtg;
|
import org.apache.poi.hssf.record.formula.MemErrPtg;
|
||||||
import org.apache.poi.hssf.record.formula.MissingArgPtg;
|
import org.apache.poi.hssf.record.formula.MissingArgPtg;
|
||||||
@ -42,20 +40,18 @@ import org.apache.poi.hssf.record.formula.RefPtg;
|
|||||||
import org.apache.poi.hssf.record.formula.StringPtg;
|
import org.apache.poi.hssf.record.formula.StringPtg;
|
||||||
import org.apache.poi.hssf.record.formula.UnionPtg;
|
import org.apache.poi.hssf.record.formula.UnionPtg;
|
||||||
import org.apache.poi.hssf.record.formula.UnknownPtg;
|
import org.apache.poi.hssf.record.formula.UnknownPtg;
|
||||||
import org.apache.poi.hssf.record.formula.eval.Area2DEval;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.Area3DEval;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.BlankEval;
|
import org.apache.poi.hssf.record.formula.eval.BlankEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.Eval;
|
import org.apache.poi.hssf.record.formula.eval.Eval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.FunctionEval;
|
import org.apache.poi.hssf.record.formula.eval.FunctionEval;
|
||||||
|
import org.apache.poi.hssf.record.formula.eval.LazyAreaEval;
|
||||||
|
import org.apache.poi.hssf.record.formula.eval.LazyRefEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.NameEval;
|
import org.apache.poi.hssf.record.formula.eval.NameEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.NameXEval;
|
import org.apache.poi.hssf.record.formula.eval.NameXEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.OperationEval;
|
import org.apache.poi.hssf.record.formula.eval.OperationEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.Ref2DEval;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.Ref3DEval;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.StringEval;
|
import org.apache.poi.hssf.record.formula.eval.StringEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||||
@ -66,32 +62,6 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
|||||||
*/
|
*/
|
||||||
public class HSSFFormulaEvaluator {
|
public class HSSFFormulaEvaluator {
|
||||||
|
|
||||||
// params to lookup the right constructor using reflection
|
|
||||||
private static final Class[] VALUE_CONTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class };
|
|
||||||
|
|
||||||
private static final Class[] AREA3D_CONSTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class, ValueEval[].class };
|
|
||||||
|
|
||||||
private static final Class[] REFERENCE_CONSTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class, ValueEval.class };
|
|
||||||
|
|
||||||
private static final Class[] REF3D_CONSTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class, ValueEval.class };
|
|
||||||
|
|
||||||
// Maps for mapping *Eval to *Ptg
|
|
||||||
private static final Map VALUE_EVALS_MAP = new HashMap();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Following is the mapping between the Ptg tokens returned
|
|
||||||
* by the FormulaParser and the *Eval classes that are used
|
|
||||||
* by the FormulaEvaluator
|
|
||||||
*/
|
|
||||||
static {
|
|
||||||
VALUE_EVALS_MAP.put(BoolPtg.class, BoolEval.class);
|
|
||||||
VALUE_EVALS_MAP.put(IntPtg.class, NumberEval.class);
|
|
||||||
VALUE_EVALS_MAP.put(NumberPtg.class, NumberEval.class);
|
|
||||||
VALUE_EVALS_MAP.put(StringPtg.class, StringEval.class);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected HSSFSheet _sheet;
|
protected HSSFSheet _sheet;
|
||||||
protected HSSFWorkbook _workbook;
|
protected HSSFWorkbook _workbook;
|
||||||
|
|
||||||
@ -265,29 +235,29 @@ public class HSSFFormulaEvaluator {
|
|||||||
* This is a helpful wrapper around looping over all
|
* This is a helpful wrapper around looping over all
|
||||||
* cells, and calling evaluateFormulaCell on each one.
|
* cells, and calling evaluateFormulaCell on each one.
|
||||||
*/
|
*/
|
||||||
public static void evaluateAllFormulaCells(HSSFWorkbook wb) {
|
public static void evaluateAllFormulaCells(HSSFWorkbook wb) {
|
||||||
for(int i=0; i<wb.getNumberOfSheets(); i++) {
|
for(int i=0; i<wb.getNumberOfSheets(); i++) {
|
||||||
HSSFSheet sheet = wb.getSheetAt(i);
|
HSSFSheet sheet = wb.getSheetAt(i);
|
||||||
HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
|
HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
|
||||||
|
|
||||||
for (Iterator rit = sheet.rowIterator(); rit.hasNext();) {
|
for (Iterator rit = sheet.rowIterator(); rit.hasNext();) {
|
||||||
HSSFRow r = (HSSFRow)rit.next();
|
HSSFRow r = (HSSFRow)rit.next();
|
||||||
|
|
||||||
for (Iterator cit = r.cellIterator(); cit.hasNext();) {
|
for (Iterator cit = r.cellIterator(); cit.hasNext();) {
|
||||||
HSSFCell c = (HSSFCell)cit.next();
|
HSSFCell c = (HSSFCell)cit.next();
|
||||||
if (c.getCellType() == HSSFCell.CELL_TYPE_FORMULA)
|
if (c.getCellType() == HSSFCell.CELL_TYPE_FORMULA)
|
||||||
evaluator.evaluateFormulaCell(c);
|
evaluator.evaluateFormulaCell(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a CellValue wrapper around the supplied ValueEval instance.
|
* Returns a CellValue wrapper around the supplied ValueEval instance.
|
||||||
* @param eval
|
* @param eval
|
||||||
*/
|
*/
|
||||||
protected static CellValue getCellValueForEval(ValueEval eval) {
|
private static CellValue getCellValueForEval(ValueEval eval) {
|
||||||
CellValue retval = null;
|
CellValue retval = null;
|
||||||
if (eval != null) {
|
if (eval != null) {
|
||||||
if (eval instanceof NumberEval) {
|
if (eval instanceof NumberEval) {
|
||||||
@ -344,7 +314,7 @@ public class HSSFFormulaEvaluator {
|
|||||||
private static ValueEval evaluateCell(HSSFWorkbook workbook, HSSFSheet sheet,
|
private static ValueEval evaluateCell(HSSFWorkbook workbook, HSSFSheet sheet,
|
||||||
int srcRowNum, short srcColNum, String cellFormulaText) {
|
int srcRowNum, short srcColNum, String cellFormulaText) {
|
||||||
|
|
||||||
Ptg[] ptgs = FormulaParser.parse(cellFormulaText, workbook);
|
Ptg[] ptgs = FormulaParser.parse(cellFormulaText, workbook);
|
||||||
|
|
||||||
Stack stack = new Stack();
|
Stack stack = new Stack();
|
||||||
for (int i = 0, iSize = ptgs.length; i < iSize; i++) {
|
for (int i = 0, iSize = ptgs.length; i < iSize; i++) {
|
||||||
@ -369,7 +339,7 @@ public class HSSFFormulaEvaluator {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (ptg instanceof UnknownPtg) { continue; }
|
if (ptg instanceof UnknownPtg) { continue; }
|
||||||
|
Eval opResult;
|
||||||
if (ptg instanceof OperationPtg) {
|
if (ptg instanceof OperationPtg) {
|
||||||
OperationPtg optg = (OperationPtg) ptg;
|
OperationPtg optg = (OperationPtg) ptg;
|
||||||
|
|
||||||
@ -385,41 +355,11 @@ public class HSSFFormulaEvaluator {
|
|||||||
Eval p = (Eval) stack.pop();
|
Eval p = (Eval) stack.pop();
|
||||||
ops[j] = p;
|
ops[j] = p;
|
||||||
}
|
}
|
||||||
Eval opresult = invokeOperation(operation, ops, srcRowNum, srcColNum, workbook, sheet);
|
opResult = invokeOperation(operation, ops, srcRowNum, srcColNum, workbook, sheet);
|
||||||
stack.push(opresult);
|
} else {
|
||||||
}
|
opResult = getEvalForPtg(ptg, sheet, workbook);
|
||||||
else if (ptg instanceof RefPtg) {
|
|
||||||
RefPtg refPtg = (RefPtg) ptg;
|
|
||||||
int colIx = refPtg.getColumn();
|
|
||||||
int rowIx = refPtg.getRow();
|
|
||||||
HSSFRow row = sheet.getRow(rowIx);
|
|
||||||
HSSFCell cell = (row != null) ? row.getCell(colIx) : null;
|
|
||||||
stack.push(createRef2DEval(refPtg, cell, sheet, workbook));
|
|
||||||
}
|
|
||||||
else if (ptg instanceof Ref3DPtg) {
|
|
||||||
Ref3DPtg refPtg = (Ref3DPtg) ptg;
|
|
||||||
int colIx = refPtg.getColumn();
|
|
||||||
int rowIx = refPtg.getRow();
|
|
||||||
Workbook wb = workbook.getWorkbook();
|
|
||||||
HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(refPtg.getExternSheetIndex()));
|
|
||||||
HSSFRow row = xsheet.getRow(rowIx);
|
|
||||||
HSSFCell cell = (row != null) ? row.getCell(colIx) : null;
|
|
||||||
stack.push(createRef3DEval(refPtg, cell, xsheet, workbook));
|
|
||||||
}
|
|
||||||
else if (ptg instanceof AreaPtg) {
|
|
||||||
AreaPtg ap = (AreaPtg) ptg;
|
|
||||||
AreaEval ae = evaluateAreaPtg(sheet, workbook, ap);
|
|
||||||
stack.push(ae);
|
|
||||||
}
|
|
||||||
else if (ptg instanceof Area3DPtg) {
|
|
||||||
Area3DPtg a3dp = (Area3DPtg) ptg;
|
|
||||||
AreaEval ae = evaluateArea3dPtg(workbook, a3dp);
|
|
||||||
stack.push(ae);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Eval ptgEval = getEvalForPtg(ptg);
|
|
||||||
stack.push(ptgEval);
|
|
||||||
}
|
}
|
||||||
|
stack.push(opResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueEval value = ((ValueEval) stack.pop());
|
ValueEval value = ((ValueEval) stack.pop());
|
||||||
@ -428,7 +368,7 @@ public class HSSFFormulaEvaluator {
|
|||||||
}
|
}
|
||||||
value = dereferenceValue(value, srcRowNum, srcColNum);
|
value = dereferenceValue(value, srcRowNum, srcColNum);
|
||||||
if (value instanceof BlankEval) {
|
if (value instanceof BlankEval) {
|
||||||
// Note Excel behaviour here. A blank final final value is converted to zero.
|
// Note Excel behaviour here. A blank final final value is converted to zero.
|
||||||
return NumberEval.ZERO;
|
return NumberEval.ZERO;
|
||||||
// Formulas _never_ evaluate to blank. If a formula appears to have evaluated to
|
// Formulas _never_ evaluate to blank. If a formula appears to have evaluated to
|
||||||
// blank, the actual value is empty string. This can be verified with ISBLANK().
|
// blank, the actual value is empty string. This can be verified with ISBLANK().
|
||||||
@ -439,8 +379,8 @@ public class HSSFFormulaEvaluator {
|
|||||||
/**
|
/**
|
||||||
* Dereferences a single value from any AreaEval or RefEval evaluation result.
|
* Dereferences a single value from any AreaEval or RefEval evaluation result.
|
||||||
* If the supplied evaluationResult is just a plain value, it is returned as-is.
|
* If the supplied evaluationResult is just a plain value, it is returned as-is.
|
||||||
* @return a <tt>NumberEval</tt>, <tt>StringEval</tt>, <tt>BoolEval</tt>,
|
* @return a <tt>NumberEval</tt>, <tt>StringEval</tt>, <tt>BoolEval</tt>,
|
||||||
* <tt>BlankEval</tt> or <tt>ErrorEval</tt>. Never <code>null</code>.
|
* <tt>BlankEval</tt> or <tt>ErrorEval</tt>. Never <code>null</code>.
|
||||||
*/
|
*/
|
||||||
private static ValueEval dereferenceValue(ValueEval evaluationResult, int srcRowNum, short srcColNum) {
|
private static ValueEval dereferenceValue(ValueEval evaluationResult, int srcRowNum, short srcColNum) {
|
||||||
if (evaluationResult instanceof RefEval) {
|
if (evaluationResult instanceof RefEval) {
|
||||||
@ -475,105 +415,49 @@ public class HSSFFormulaEvaluator {
|
|||||||
return operation.evaluate(ops, srcRowNum, srcColNum);
|
return operation.evaluate(ops, srcRowNum, srcColNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AreaEval evaluateAreaPtg(HSSFSheet sheet, HSSFWorkbook workbook, AreaPtg ap) {
|
|
||||||
int row0 = ap.getFirstRow();
|
|
||||||
int col0 = ap.getFirstColumn();
|
|
||||||
int row1 = ap.getLastRow();
|
|
||||||
int col1 = ap.getLastColumn();
|
|
||||||
|
|
||||||
// If the last row is -1, then the
|
|
||||||
// reference is for the rest of the column
|
|
||||||
// (eg C:C)
|
|
||||||
// TODO: Handle whole column ranges properly
|
|
||||||
if(row1 == -1 && row0 >= 0) {
|
|
||||||
row1 = (short)sheet.getLastRowNum();
|
|
||||||
}
|
|
||||||
ValueEval[] values = evalArea(workbook, sheet, row0, col0, row1, col1);
|
|
||||||
return new Area2DEval(ap, values);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AreaEval evaluateArea3dPtg(HSSFWorkbook workbook, Area3DPtg a3dp) {
|
|
||||||
int row0 = a3dp.getFirstRow();
|
|
||||||
int col0 = a3dp.getFirstColumn();
|
|
||||||
int row1 = a3dp.getLastRow();
|
|
||||||
int col1 = a3dp.getLastColumn();
|
|
||||||
Workbook wb = workbook.getWorkbook();
|
|
||||||
HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(a3dp.getExternSheetIndex()));
|
|
||||||
|
|
||||||
// If the last row is -1, then the
|
|
||||||
// reference is for the rest of the column
|
|
||||||
// (eg C:C)
|
|
||||||
// TODO: Handle whole column ranges properly
|
|
||||||
if(row1 == -1 && row0 >= 0) {
|
|
||||||
row1 = (short)xsheet.getLastRowNum();
|
|
||||||
}
|
|
||||||
|
|
||||||
ValueEval[] values = evalArea(workbook, xsheet, row0, col0, row1, col1);
|
|
||||||
return new Area3DEval(a3dp, values);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ValueEval[] evalArea(HSSFWorkbook workbook, HSSFSheet sheet,
|
|
||||||
int row0, int col0, int row1, int col1) {
|
|
||||||
ValueEval[] values = new ValueEval[(row1 - row0 + 1) * (col1 - col0 + 1)];
|
|
||||||
for (int x = row0; sheet != null && x < row1 + 1; x++) {
|
|
||||||
HSSFRow row = sheet.getRow(x);
|
|
||||||
for (int y = col0; y < col1 + 1; y++) {
|
|
||||||
ValueEval cellEval;
|
|
||||||
if(row == null) {
|
|
||||||
cellEval = BlankEval.INSTANCE;
|
|
||||||
} else {
|
|
||||||
cellEval = getEvalForCell(row.getCell(y), row, sheet, workbook);
|
|
||||||
}
|
|
||||||
values[(x - row0) * (col1 - col0 + 1) + (y - col0)] = cellEval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns an appropriate Eval impl instance for the Ptg. The Ptg must be
|
* returns an appropriate Eval impl instance for the Ptg. The Ptg must be
|
||||||
* one of: Area3DPtg, AreaPtg, ReferencePtg, Ref3DPtg, IntPtg, NumberPtg,
|
* one of: Area3DPtg, AreaPtg, ReferencePtg, Ref3DPtg, IntPtg, NumberPtg,
|
||||||
* StringPtg, BoolPtg <br/>special Note: OperationPtg subtypes cannot be
|
* StringPtg, BoolPtg <br/>special Note: OperationPtg subtypes cannot be
|
||||||
* passed here!
|
* passed here!
|
||||||
*
|
|
||||||
* @param ptg
|
|
||||||
*/
|
*/
|
||||||
protected static Eval getEvalForPtg(Ptg ptg) {
|
private static Eval getEvalForPtg(Ptg ptg, HSSFSheet sheet, HSSFWorkbook workbook) {
|
||||||
Eval retval = null;
|
if (ptg instanceof RefPtg) {
|
||||||
|
return new LazyRefEval(((RefPtg) ptg), sheet, workbook);
|
||||||
Class clazz = (Class) VALUE_EVALS_MAP.get(ptg.getClass());
|
|
||||||
try {
|
|
||||||
if (ptg instanceof Area3DPtg) {
|
|
||||||
Constructor constructor = clazz.getConstructor(AREA3D_CONSTRUCTOR_CLASS_ARRAY);
|
|
||||||
retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg });
|
|
||||||
}
|
|
||||||
else if (ptg instanceof AreaPtg) {
|
|
||||||
Constructor constructor = clazz.getConstructor(AREA3D_CONSTRUCTOR_CLASS_ARRAY);
|
|
||||||
retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg });
|
|
||||||
}
|
|
||||||
else if (ptg instanceof RefPtg) {
|
|
||||||
Constructor constructor = clazz.getConstructor(REFERENCE_CONSTRUCTOR_CLASS_ARRAY);
|
|
||||||
retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg });
|
|
||||||
}
|
|
||||||
else if (ptg instanceof Ref3DPtg) {
|
|
||||||
Constructor constructor = clazz.getConstructor(REF3D_CONSTRUCTOR_CLASS_ARRAY);
|
|
||||||
retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (ptg instanceof IntPtg || ptg instanceof NumberPtg || ptg instanceof StringPtg
|
|
||||||
|| ptg instanceof BoolPtg) {
|
|
||||||
Constructor constructor = clazz.getConstructor(VALUE_CONTRUCTOR_CLASS_ARRAY);
|
|
||||||
retval = (ValueEval) constructor.newInstance(new Ptg[] { ptg });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
if (ptg instanceof Ref3DPtg) {
|
||||||
throw new RuntimeException("Fatal Error: ", e);
|
Ref3DPtg refPtg = (Ref3DPtg) ptg;
|
||||||
|
Workbook wb = workbook.getWorkbook();
|
||||||
|
HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(refPtg.getExternSheetIndex()));
|
||||||
|
return new LazyRefEval(refPtg, xsheet, workbook);
|
||||||
|
}
|
||||||
|
if (ptg instanceof AreaPtg) {
|
||||||
|
return new LazyAreaEval(((AreaPtg) ptg), sheet, workbook);
|
||||||
|
}
|
||||||
|
if (ptg instanceof Area3DPtg) {
|
||||||
|
Area3DPtg a3dp = (Area3DPtg) ptg;
|
||||||
|
Workbook wb = workbook.getWorkbook();
|
||||||
|
HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(a3dp.getExternSheetIndex()));
|
||||||
|
return new LazyAreaEval(a3dp, xsheet, workbook);
|
||||||
}
|
}
|
||||||
return retval;
|
|
||||||
|
|
||||||
|
if (ptg instanceof IntPtg) {
|
||||||
|
return new NumberEval(((IntPtg)ptg).getValue());
|
||||||
|
}
|
||||||
|
if (ptg instanceof NumberPtg) {
|
||||||
|
return new NumberEval(((NumberPtg)ptg).getValue());
|
||||||
|
}
|
||||||
|
if (ptg instanceof StringPtg) {
|
||||||
|
return new StringEval(((StringPtg) ptg).getValue());
|
||||||
|
}
|
||||||
|
if (ptg instanceof BoolPtg) {
|
||||||
|
return BoolEval.valueOf(((BoolPtg) ptg).getValue());
|
||||||
|
}
|
||||||
|
if (ptg instanceof ErrPtg) {
|
||||||
|
return ErrorEval.valueOf(((ErrPtg) ptg).getErrorCode());
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Unexpected ptg class (" + ptg.getClass().getName() + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a cell, find its type and from that create an appropriate ValueEval
|
* Given a cell, find its type and from that create an appropriate ValueEval
|
||||||
* impl instance and return that. Since the cell could be an external
|
* impl instance and return that. Since the cell could be an external
|
||||||
@ -583,7 +467,7 @@ public class HSSFFormulaEvaluator {
|
|||||||
* @param sheet
|
* @param sheet
|
||||||
* @param workbook
|
* @param workbook
|
||||||
*/
|
*/
|
||||||
protected static ValueEval getEvalForCell(HSSFCell cell, HSSFRow row, HSSFSheet sheet, HSSFWorkbook workbook) {
|
public static ValueEval getEvalForCell(HSSFCell cell, HSSFSheet sheet, HSSFWorkbook workbook) {
|
||||||
|
|
||||||
if (cell == null) {
|
if (cell == null) {
|
||||||
return BlankEval.INSTANCE;
|
return BlankEval.INSTANCE;
|
||||||
@ -605,58 +489,6 @@ public class HSSFFormulaEvaluator {
|
|||||||
throw new RuntimeException("Unexpected cell type (" + cell.getCellType() + ")");
|
throw new RuntimeException("Unexpected cell type (" + cell.getCellType() + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Ref2DEval for ReferencePtg.
|
|
||||||
* Non existent cells are treated as RefEvals containing BlankEval.
|
|
||||||
*/
|
|
||||||
private static Ref2DEval createRef2DEval(RefPtg ptg, HSSFCell cell,
|
|
||||||
HSSFSheet sheet, HSSFWorkbook workbook) {
|
|
||||||
if (cell == null) {
|
|
||||||
return new Ref2DEval(ptg, BlankEval.INSTANCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cell.getCellType()) {
|
|
||||||
case HSSFCell.CELL_TYPE_NUMERIC:
|
|
||||||
return new Ref2DEval(ptg, new NumberEval(cell.getNumericCellValue()));
|
|
||||||
case HSSFCell.CELL_TYPE_STRING:
|
|
||||||
return new Ref2DEval(ptg, new StringEval(cell.getRichStringCellValue().getString()));
|
|
||||||
case HSSFCell.CELL_TYPE_FORMULA:
|
|
||||||
return new Ref2DEval(ptg, internalEvaluate(cell, sheet, workbook));
|
|
||||||
case HSSFCell.CELL_TYPE_BOOLEAN:
|
|
||||||
return new Ref2DEval(ptg, BoolEval.valueOf(cell.getBooleanCellValue()));
|
|
||||||
case HSSFCell.CELL_TYPE_BLANK:
|
|
||||||
return new Ref2DEval(ptg, BlankEval.INSTANCE);
|
|
||||||
case HSSFCell.CELL_TYPE_ERROR:
|
|
||||||
return new Ref2DEval(ptg, ErrorEval.valueOf(cell.getErrorCellValue()));
|
|
||||||
}
|
|
||||||
throw new RuntimeException("Unexpected cell type (" + cell.getCellType() + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* create a Ref3DEval for Ref3DPtg.
|
|
||||||
*/
|
|
||||||
private static Ref3DEval createRef3DEval(Ref3DPtg ptg, HSSFCell cell,
|
|
||||||
HSSFSheet sheet, HSSFWorkbook workbook) {
|
|
||||||
if (cell == null) {
|
|
||||||
return new Ref3DEval(ptg, BlankEval.INSTANCE);
|
|
||||||
}
|
|
||||||
switch (cell.getCellType()) {
|
|
||||||
case HSSFCell.CELL_TYPE_NUMERIC:
|
|
||||||
return new Ref3DEval(ptg, new NumberEval(cell.getNumericCellValue()));
|
|
||||||
case HSSFCell.CELL_TYPE_STRING:
|
|
||||||
return new Ref3DEval(ptg, new StringEval(cell.getRichStringCellValue().getString()));
|
|
||||||
case HSSFCell.CELL_TYPE_FORMULA:
|
|
||||||
return new Ref3DEval(ptg, internalEvaluate(cell, sheet, workbook));
|
|
||||||
case HSSFCell.CELL_TYPE_BOOLEAN:
|
|
||||||
return new Ref3DEval(ptg, BoolEval.valueOf(cell.getBooleanCellValue()));
|
|
||||||
case HSSFCell.CELL_TYPE_BLANK:
|
|
||||||
return new Ref3DEval(ptg, BlankEval.INSTANCE);
|
|
||||||
case HSSFCell.CELL_TYPE_ERROR:
|
|
||||||
return new Ref3DEval(ptg, ErrorEval.valueOf(cell.getErrorCellValue()));
|
|
||||||
}
|
|
||||||
throw new RuntimeException("Unexpected cell type (" + cell.getCellType() + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mimics the 'data view' of a cell. This allows formula evaluator
|
* Mimics the 'data view' of a cell. This allows formula evaluator
|
||||||
* to return a CellValue instead of precasting the value to String
|
* to return a CellValue instead of precasting the value to String
|
||||||
@ -752,15 +584,9 @@ public class HSSFFormulaEvaluator {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* debug method
|
* debug method
|
||||||
*
|
|
||||||
* @param formula
|
|
||||||
* @param sheet
|
|
||||||
* @param workbook
|
|
||||||
*/
|
*/
|
||||||
void inspectPtgs(String formula) {
|
void inspectPtgs(String formula) {
|
||||||
FormulaParser fp = new FormulaParser(formula, _workbook);
|
Ptg[] ptgs = FormulaParser.parse(formula, _workbook);
|
||||||
fp.parse();
|
|
||||||
Ptg[] ptgs = fp.getRPNPtg();
|
|
||||||
System.out.println("<ptg-group>");
|
System.out.println("<ptg-group>");
|
||||||
for (int i = 0, iSize = ptgs.length; i < iSize; i++) {
|
for (int i = 0, iSize = ptgs.length; i < iSize; i++) {
|
||||||
System.out.println("<ptg>");
|
System.out.println("<ptg>");
|
||||||
|
@ -20,7 +20,8 @@ package org.apache.poi.hssf.record.formula.eval;
|
|||||||
import junit.framework.AssertionFailedError;
|
import junit.framework.AssertionFailedError;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
import org.apache.poi.hssf.record.formula.AreaPtg;
|
||||||
|
import org.apache.poi.hssf.record.formula.functions.EvalFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for <tt>AreaEval</tt>
|
* Tests for <tt>AreaEval</tt>
|
||||||
@ -30,8 +31,8 @@ import org.apache.poi.hssf.record.formula.Area3DPtg;
|
|||||||
public final class TestAreaEval extends TestCase {
|
public final class TestAreaEval extends TestCase {
|
||||||
|
|
||||||
public void testGetValue_bug44950() {
|
public void testGetValue_bug44950() {
|
||||||
|
// TODO - this test probably isn't testing much anymore
|
||||||
Area3DPtg ptg = new Area3DPtg("B2:D3", (short)0);
|
AreaPtg ptg = new AreaPtg("B2:D3");
|
||||||
NumberEval one = new NumberEval(1);
|
NumberEval one = new NumberEval(1);
|
||||||
ValueEval[] values = {
|
ValueEval[] values = {
|
||||||
one,
|
one,
|
||||||
@ -41,7 +42,7 @@ public final class TestAreaEval extends TestCase {
|
|||||||
new NumberEval(5),
|
new NumberEval(5),
|
||||||
new NumberEval(6),
|
new NumberEval(6),
|
||||||
};
|
};
|
||||||
AreaEval ae = new Area3DEval(ptg, values);
|
AreaEval ae = EvalFactory.createAreaEval(ptg, values);
|
||||||
if (one == ae.getValueAt(1, 2)) {
|
if (one == ae.getValueAt(1, 2)) {
|
||||||
throw new AssertionFailedError("Identified bug 44950 a");
|
throw new AssertionFailedError("Identified bug 44950 a");
|
||||||
}
|
}
|
||||||
|
@ -18,12 +18,13 @@
|
|||||||
|
|
||||||
package org.apache.poi.hssf.record.formula.eval;
|
package org.apache.poi.hssf.record.formula.eval;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.AreaPtg;
|
import org.apache.poi.hssf.record.formula.AreaPtg;
|
||||||
import org.apache.poi.hssf.record.formula.UnaryPlusPtg;
|
import org.apache.poi.hssf.record.formula.UnaryPlusPtg;
|
||||||
|
import org.apache.poi.hssf.record.formula.functions.EvalFactory;
|
||||||
import org.apache.poi.hssf.record.formula.functions.NumericFunctionInvoker;
|
import org.apache.poi.hssf.record.formula.functions.NumericFunctionInvoker;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for unary plus operator evaluator.
|
* Test for unary plus operator evaluator.
|
||||||
*
|
*
|
||||||
@ -48,9 +49,8 @@ public final class TestUnaryPlusEval extends TestCase {
|
|||||||
new NumberEval(37),
|
new NumberEval(37),
|
||||||
new NumberEval(38),
|
new NumberEval(38),
|
||||||
};
|
};
|
||||||
Eval areaEval = new Area2DEval(areaPtg, values);
|
|
||||||
Eval[] args = {
|
Eval[] args = {
|
||||||
areaEval,
|
EvalFactory.createAreaEval(areaPtg, values),
|
||||||
};
|
};
|
||||||
|
|
||||||
double result = NumericFunctionInvoker.invoke(new UnaryPlusEval(UnaryPlusPtg.instance), args, 10, (short)20);
|
double result = NumericFunctionInvoker.invoke(new UnaryPlusEval(UnaryPlusPtg.instance), args, 10, (short)20);
|
||||||
|
@ -15,16 +15,16 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
==================================================================== */
|
==================================================================== */
|
||||||
|
|
||||||
|
|
||||||
package org.apache.poi.hssf.record.formula.functions;
|
package org.apache.poi.hssf.record.formula.functions;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.AreaPtg;
|
import org.apache.poi.hssf.record.formula.AreaPtg;
|
||||||
|
import org.apache.poi.hssf.record.formula.Ref3DPtg;
|
||||||
import org.apache.poi.hssf.record.formula.RefPtg;
|
import org.apache.poi.hssf.record.formula.RefPtg;
|
||||||
import org.apache.poi.hssf.record.formula.eval.Area2DEval;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||||
|
import org.apache.poi.hssf.record.formula.eval.AreaEvalBase;
|
||||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.Ref2DEval;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||||
|
import org.apache.poi.hssf.record.formula.eval.RefEvalBase;
|
||||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -32,7 +32,7 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
|||||||
*
|
*
|
||||||
* @author Josh Micich
|
* @author Josh Micich
|
||||||
*/
|
*/
|
||||||
final class EvalFactory {
|
public final class EvalFactory {
|
||||||
|
|
||||||
private EvalFactory() {
|
private EvalFactory() {
|
||||||
// no instances of this class
|
// no instances of this class
|
||||||
@ -44,6 +44,14 @@ final class EvalFactory {
|
|||||||
*/
|
*/
|
||||||
public static AreaEval createAreaEval(String areaRefStr, ValueEval[] values) {
|
public static AreaEval createAreaEval(String areaRefStr, ValueEval[] values) {
|
||||||
AreaPtg areaPtg = new AreaPtg(areaRefStr);
|
AreaPtg areaPtg = new AreaPtg(areaRefStr);
|
||||||
|
return createAreaEval(areaPtg, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a dummy AreaEval
|
||||||
|
* @param values empty (<code>null</code>) entries in this array will be converted to NumberEval.ZERO
|
||||||
|
*/
|
||||||
|
public static AreaEval createAreaEval(AreaPtg areaPtg, ValueEval[] values) {
|
||||||
int nCols = areaPtg.getLastColumn() - areaPtg.getFirstColumn() + 1;
|
int nCols = areaPtg.getLastColumn() - areaPtg.getFirstColumn() + 1;
|
||||||
int nRows = areaPtg.getLastRow() - areaPtg.getFirstRow() + 1;
|
int nRows = areaPtg.getLastRow() - areaPtg.getFirstRow() + 1;
|
||||||
int nExpected = nRows * nCols;
|
int nExpected = nRows * nCols;
|
||||||
@ -55,13 +63,57 @@ final class EvalFactory {
|
|||||||
values[i] = NumberEval.ZERO;
|
values[i] = NumberEval.ZERO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new Area2DEval(areaPtg, values);
|
return new MockAreaEval(areaPtg, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a single RefEval (with value zero)
|
* Creates a single RefEval (with value zero)
|
||||||
*/
|
*/
|
||||||
public static RefEval createRefEval(String refStr) {
|
public static RefEval createRefEval(String refStr) {
|
||||||
return new Ref2DEval(new RefPtg(refStr), NumberEval.ZERO);
|
return createRefEval(refStr, NumberEval.ZERO);
|
||||||
}
|
}
|
||||||
|
public static RefEval createRefEval(String refStr, ValueEval value) {
|
||||||
|
return new MockRefEval(new RefPtg(refStr), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class MockAreaEval extends AreaEvalBase {
|
||||||
|
private final ValueEval[] _values;
|
||||||
|
public MockAreaEval(AreaPtg areaPtg, ValueEval[] values) {
|
||||||
|
super(areaPtg);
|
||||||
|
_values = values;
|
||||||
|
}
|
||||||
|
public ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex) {
|
||||||
|
if (relativeRowIndex < 0 || relativeRowIndex >=getHeight()) {
|
||||||
|
throw new IllegalArgumentException("row index out of range");
|
||||||
|
}
|
||||||
|
int width = getWidth();
|
||||||
|
if (relativeColumnIndex < 0 || relativeColumnIndex >=width) {
|
||||||
|
throw new IllegalArgumentException("column index out of range");
|
||||||
|
}
|
||||||
|
int oneDimensionalIndex = relativeRowIndex * width + relativeColumnIndex;
|
||||||
|
return _values[oneDimensionalIndex];
|
||||||
|
}
|
||||||
|
public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
|
||||||
|
throw new RuntimeException("Operation not implemented on this mock object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class MockRefEval extends RefEvalBase {
|
||||||
|
private final ValueEval _value;
|
||||||
|
public MockRefEval(RefPtg ptg, ValueEval value) {
|
||||||
|
super(ptg.getRow(), ptg.getColumn());
|
||||||
|
_value = value;
|
||||||
|
}
|
||||||
|
public MockRefEval(Ref3DPtg ptg, ValueEval value) {
|
||||||
|
super(ptg.getRow(), ptg.getColumn());
|
||||||
|
_value = value;
|
||||||
|
}
|
||||||
|
public ValueEval getInnerValueEval() {
|
||||||
|
return _value;
|
||||||
|
}
|
||||||
|
public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
|
||||||
|
throw new RuntimeException("Operation not implemented on this mock object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,7 @@ import junit.framework.AssertionFailedError;
|
|||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||||
import org.apache.poi.hssf.record.formula.AreaPtg;
|
|
||||||
import org.apache.poi.hssf.record.formula.RefPtg;
|
import org.apache.poi.hssf.record.formula.RefPtg;
|
||||||
import org.apache.poi.hssf.record.formula.eval.Area2DEval;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.BlankEval;
|
import org.apache.poi.hssf.record.formula.eval.BlankEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||||
@ -91,7 +89,7 @@ public final class TestCountFuncs extends TestCase {
|
|||||||
BoolEval.TRUE,
|
BoolEval.TRUE,
|
||||||
BlankEval.INSTANCE,
|
BlankEval.INSTANCE,
|
||||||
};
|
};
|
||||||
range = createAreaEval("A1:B3", values);
|
range = EvalFactory.createAreaEval("A1:B3", values);
|
||||||
confirmCountIf(2, range, BoolEval.TRUE);
|
confirmCountIf(2, range, BoolEval.TRUE);
|
||||||
|
|
||||||
// when criteria is numeric
|
// when criteria is numeric
|
||||||
@ -103,7 +101,7 @@ public final class TestCountFuncs extends TestCase {
|
|||||||
new NumberEval(2),
|
new NumberEval(2),
|
||||||
BoolEval.TRUE,
|
BoolEval.TRUE,
|
||||||
};
|
};
|
||||||
range = createAreaEval("A1:B3", values);
|
range = EvalFactory.createAreaEval("A1:B3", values);
|
||||||
confirmCountIf(3, range, new NumberEval(2));
|
confirmCountIf(3, range, new NumberEval(2));
|
||||||
// note - same results when criteria is a string that parses as the number with the same value
|
// note - same results when criteria is a string that parses as the number with the same value
|
||||||
confirmCountIf(3, range, new StringEval("2.00"));
|
confirmCountIf(3, range, new StringEval("2.00"));
|
||||||
@ -126,20 +124,15 @@ public final class TestCountFuncs extends TestCase {
|
|||||||
new NumberEval(25),
|
new NumberEval(25),
|
||||||
new NumberEval(25),
|
new NumberEval(25),
|
||||||
};
|
};
|
||||||
Area2DEval arg0 = new Area2DEval(new AreaPtg("C1:C6"), values);
|
AreaEval arg0 = EvalFactory.createAreaEval("C1:C6", values);
|
||||||
|
|
||||||
Ref2DEval criteriaArg = new Ref2DEval(new RefPtg("A1"), new NumberEval(25));
|
ValueEval criteriaArg = EvalFactory.createRefEval("A1", new NumberEval(25));
|
||||||
Eval[] args= { arg0, criteriaArg, };
|
Eval[] args= { arg0, criteriaArg, };
|
||||||
|
|
||||||
double actual = NumericFunctionInvoker.invoke(new Countif(), args);
|
double actual = NumericFunctionInvoker.invoke(new Countif(), args);
|
||||||
assertEquals(4, actual, 0D);
|
assertEquals(4, actual, 0D);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static AreaEval createAreaEval(String areaRefStr, ValueEval[] values) {
|
|
||||||
return new Area2DEval(new AreaPtg(areaRefStr), values);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void confirmCountA(int expected, Eval[] args) {
|
private static void confirmCountA(int expected, Eval[] args) {
|
||||||
double result = NumericFunctionInvoker.invoke(new Counta(), args);
|
double result = NumericFunctionInvoker.invoke(new Counta(), args);
|
||||||
assertEquals(expected, result, 0);
|
assertEquals(expected, result, 0);
|
||||||
|
@ -19,8 +19,7 @@ package org.apache.poi.hssf.record.formula.functions;
|
|||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.AreaPtg;
|
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.Area2DEval;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.Eval;
|
import org.apache.poi.hssf.record.formula.eval.Eval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||||
@ -68,7 +67,7 @@ public final class TestIndex extends TestCase {
|
|||||||
for (int i = 0; i < values.length; i++) {
|
for (int i = 0; i < values.length; i++) {
|
||||||
values[i] = new NumberEval(dValues[i]);
|
values[i] = new NumberEval(dValues[i]);
|
||||||
}
|
}
|
||||||
Area2DEval arg0 = new Area2DEval(new AreaPtg(areaRefString), values);
|
AreaEval arg0 = EvalFactory.createAreaEval(areaRefString, values);
|
||||||
|
|
||||||
Eval[] args;
|
Eval[] args;
|
||||||
if (colNum > 0) {
|
if (colNum > 0) {
|
||||||
|
@ -19,8 +19,6 @@ package org.apache.poi.hssf.record.formula.functions;
|
|||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.AreaPtg;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.Area2DEval;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||||
@ -54,13 +52,6 @@ public final class TestMatch extends TestCase {
|
|||||||
NumericValueEval nve = (NumericValueEval)actualEval;
|
NumericValueEval nve = (NumericValueEval)actualEval;
|
||||||
assertEquals(expected, nve.getNumberValue(), 0);
|
assertEquals(expected, nve.getNumberValue(), 0);
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Convenience method
|
|
||||||
* @return <code>new Area2DEval(new AreaPtg(ref), values)</code>
|
|
||||||
*/
|
|
||||||
private static AreaEval createAreaEval(String ref, ValueEval[] values) {
|
|
||||||
return new Area2DEval(new AreaPtg(ref), values);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSimpleNumber() {
|
public void testSimpleNumber() {
|
||||||
|
|
||||||
@ -72,7 +63,7 @@ public final class TestMatch extends TestCase {
|
|||||||
new NumberEval(25),
|
new NumberEval(25),
|
||||||
};
|
};
|
||||||
|
|
||||||
AreaEval ae = createAreaEval("A1:A5", values);
|
AreaEval ae = EvalFactory.createAreaEval("A1:A5", values);
|
||||||
|
|
||||||
confirmInt(2, invokeMatch(new NumberEval(5), ae, MATCH_LARGEST_LTE));
|
confirmInt(2, invokeMatch(new NumberEval(5), ae, MATCH_LARGEST_LTE));
|
||||||
confirmInt(2, invokeMatch(new NumberEval(5), ae, MATCH_EXACT));
|
confirmInt(2, invokeMatch(new NumberEval(5), ae, MATCH_EXACT));
|
||||||
@ -92,7 +83,7 @@ public final class TestMatch extends TestCase {
|
|||||||
new NumberEval(4),
|
new NumberEval(4),
|
||||||
};
|
};
|
||||||
|
|
||||||
AreaEval ae = createAreaEval("A1:A5", values);
|
AreaEval ae = EvalFactory.createAreaEval("A1:A5", values);
|
||||||
|
|
||||||
confirmInt(2, invokeMatch(new NumberEval(10), ae, MATCH_SMALLEST_GTE));
|
confirmInt(2, invokeMatch(new NumberEval(10), ae, MATCH_SMALLEST_GTE));
|
||||||
confirmInt(2, invokeMatch(new NumberEval(10), ae, MATCH_EXACT));
|
confirmInt(2, invokeMatch(new NumberEval(10), ae, MATCH_EXACT));
|
||||||
@ -112,7 +103,7 @@ public final class TestMatch extends TestCase {
|
|||||||
new StringEval("Ian"),
|
new StringEval("Ian"),
|
||||||
};
|
};
|
||||||
|
|
||||||
AreaEval ae = createAreaEval("A1:A5", values);
|
AreaEval ae = EvalFactory.createAreaEval("A1:A5", values);
|
||||||
|
|
||||||
// Note String comparisons are case insensitive
|
// Note String comparisons are case insensitive
|
||||||
confirmInt(3, invokeMatch(new StringEval("Ed"), ae, MATCH_LARGEST_LTE));
|
confirmInt(3, invokeMatch(new StringEval("Ed"), ae, MATCH_LARGEST_LTE));
|
||||||
@ -132,7 +123,7 @@ public final class TestMatch extends TestCase {
|
|||||||
BoolEval.TRUE,
|
BoolEval.TRUE,
|
||||||
};
|
};
|
||||||
|
|
||||||
AreaEval ae = createAreaEval("A1:A4", values);
|
AreaEval ae = EvalFactory.createAreaEval("A1:A4", values);
|
||||||
|
|
||||||
// Note String comparisons are case insensitive
|
// Note String comparisons are case insensitive
|
||||||
confirmInt(2, invokeMatch(BoolEval.FALSE, ae, MATCH_LARGEST_LTE));
|
confirmInt(2, invokeMatch(BoolEval.FALSE, ae, MATCH_LARGEST_LTE));
|
||||||
@ -159,7 +150,7 @@ public final class TestMatch extends TestCase {
|
|||||||
new StringEval("Ed"),
|
new StringEval("Ed"),
|
||||||
};
|
};
|
||||||
|
|
||||||
AreaEval ae = createAreaEval("A1:A13", values);
|
AreaEval ae = EvalFactory.createAreaEval("A1:A13", values);
|
||||||
|
|
||||||
assertEquals(ErrorEval.NA, invokeMatch(new StringEval("Aaron"), ae, MATCH_LARGEST_LTE));
|
assertEquals(ErrorEval.NA, invokeMatch(new StringEval("Aaron"), ae, MATCH_LARGEST_LTE));
|
||||||
|
|
||||||
@ -197,9 +188,9 @@ public final class TestMatch extends TestCase {
|
|||||||
new NumberEval(25),
|
new NumberEval(25),
|
||||||
};
|
};
|
||||||
|
|
||||||
AreaEval ae = createAreaEval("A1:A5", values);
|
AreaEval ae = EvalFactory.createAreaEval("A1:A5", values);
|
||||||
|
|
||||||
AreaEval matchAE = createAreaEval("C1:C1", new ValueEval[] { MATCH_LARGEST_LTE, });
|
AreaEval matchAE = EvalFactory.createAreaEval("C1:C1", new ValueEval[] { MATCH_LARGEST_LTE, });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
confirmInt(4, invokeMatch(new NumberEval(10), ae, matchAE));
|
confirmInt(4, invokeMatch(new NumberEval(10), ae, matchAE));
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.poi.hssf.record.formula.functions;
|
package org.apache.poi.hssf.record.formula.functions;
|
||||||
|
|
||||||
|
import org.apache.poi.hssf.record.formula.functions.XYNumericFunction.Accumulator;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||||
@ -566,97 +568,97 @@ public class TestMathX extends AbstractNumericTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testSumx2my2() {
|
public void testSumx2my2() {
|
||||||
double d = 0;
|
|
||||||
double[] xarr = null;
|
double[] xarr = null;
|
||||||
double[] yarr = null;
|
double[] yarr = null;
|
||||||
|
|
||||||
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
d = MathX.sumx2my2(xarr, yarr);
|
confirmSumx2my2(xarr, yarr, 100);
|
||||||
assertEquals("sumx2my2 ", 100, d);
|
|
||||||
|
|
||||||
xarr = new double[]{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10};
|
xarr = new double[]{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10};
|
||||||
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
d = MathX.sumx2my2(xarr, yarr);
|
confirmSumx2my2(xarr, yarr, 100);
|
||||||
assertEquals("sumx2my2 ", 100, d);
|
|
||||||
|
|
||||||
xarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
xarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
d = MathX.sumx2my2(xarr, yarr);
|
confirmSumx2my2(xarr, yarr, -100);
|
||||||
assertEquals("sumx2my2 ", -100, d);
|
|
||||||
|
|
||||||
xarr = new double[]{10};
|
xarr = new double[]{10};
|
||||||
yarr = new double[]{9};
|
yarr = new double[]{9};
|
||||||
d = MathX.sumx2my2(xarr, yarr);
|
confirmSumx2my2(xarr, yarr, 19);
|
||||||
assertEquals("sumx2my2 ", 19, d);
|
|
||||||
|
|
||||||
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
d = MathX.sumx2my2(xarr, yarr);
|
confirmSumx2my2(xarr, yarr, 0);
|
||||||
assertEquals("sumx2my2 ", 0, d);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSumx2py2() {
|
public void testSumx2py2() {
|
||||||
double d = 0;
|
|
||||||
double[] xarr = null;
|
double[] xarr = null;
|
||||||
double[] yarr = null;
|
double[] yarr = null;
|
||||||
|
|
||||||
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
d = MathX.sumx2py2(xarr, yarr);
|
confirmSumx2py2(xarr, yarr, 670);
|
||||||
assertEquals("sumx2py2 ", 670, d);
|
|
||||||
|
|
||||||
xarr = new double[]{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10};
|
xarr = new double[]{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10};
|
||||||
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
d = MathX.sumx2py2(xarr, yarr);
|
confirmSumx2py2(xarr, yarr, 670);
|
||||||
assertEquals("sumx2py2 ", 670, d);
|
|
||||||
|
|
||||||
xarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
xarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
d = MathX.sumx2py2(xarr, yarr);
|
confirmSumx2py2(xarr, yarr, 670);
|
||||||
assertEquals("sumx2py2 ", 670, d);
|
|
||||||
|
|
||||||
xarr = new double[]{10};
|
xarr = new double[]{10};
|
||||||
yarr = new double[]{9};
|
yarr = new double[]{9};
|
||||||
d = MathX.sumx2py2(xarr, yarr);
|
confirmSumx2py2(xarr, yarr, 181);
|
||||||
assertEquals("sumx2py2 ", 181, d);
|
|
||||||
|
|
||||||
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
d = MathX.sumx2py2(xarr, yarr);
|
confirmSumx2py2(xarr, yarr, 770);
|
||||||
assertEquals("sumx2py2 ", 770, d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSumxmy2() {
|
public void testSumxmy2() {
|
||||||
double d = 0;
|
|
||||||
double[] xarr = null;
|
double[] xarr = null;
|
||||||
double[] yarr = null;
|
double[] yarr = null;
|
||||||
|
|
||||||
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
d = MathX.sumxmy2(xarr, yarr);
|
confirmSumxmy2(xarr, yarr, 10);
|
||||||
assertEquals("sumxmy2 ", 10, d);
|
|
||||||
|
|
||||||
xarr = new double[]{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10};
|
xarr = new double[]{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10};
|
||||||
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
d = MathX.sumxmy2(xarr, yarr);
|
confirmSumxmy2(xarr, yarr, 1330);
|
||||||
assertEquals("sumxmy2 ", 1330, d);
|
|
||||||
|
|
||||||
xarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
xarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
d = MathX.sumxmy2(xarr, yarr);
|
confirmSumxmy2(xarr, yarr, 10);
|
||||||
assertEquals("sumxmy2 ", 10, d);
|
|
||||||
|
|
||||||
xarr = new double[]{10};
|
xarr = new double[]{10};
|
||||||
yarr = new double[]{9};
|
yarr = new double[]{9};
|
||||||
d = MathX.sumxmy2(xarr, yarr);
|
confirmSumxmy2(xarr, yarr, 1);
|
||||||
assertEquals("sumxmy2 ", 1, d);
|
|
||||||
|
|
||||||
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
d = MathX.sumxmy2(xarr, yarr);
|
confirmSumxmy2(xarr, yarr, 0);
|
||||||
assertEquals("sumxmy2 ", 0, d);
|
}
|
||||||
|
|
||||||
|
private static void confirmSumx2my2(double[] xarr, double[] yarr, double expectedResult) {
|
||||||
|
confirmXY(new Sumx2my2().createAccumulator(), xarr, yarr, expectedResult);
|
||||||
|
}
|
||||||
|
private static void confirmSumx2py2(double[] xarr, double[] yarr, double expectedResult) {
|
||||||
|
confirmXY(new Sumx2py2().createAccumulator(), xarr, yarr, expectedResult);
|
||||||
|
}
|
||||||
|
private static void confirmSumxmy2(double[] xarr, double[] yarr, double expectedResult) {
|
||||||
|
confirmXY(new Sumxmy2().createAccumulator(), xarr, yarr, expectedResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void confirmXY(Accumulator acc, double[] xarr, double[] yarr,
|
||||||
|
double expectedResult) {
|
||||||
|
double result = 0.0;
|
||||||
|
for (int i = 0; i < xarr.length; i++) {
|
||||||
|
result += acc.accumulate(xarr[i], yarr[i]);
|
||||||
|
}
|
||||||
|
assertEquals(expectedResult, result, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRound() {
|
public void testRound() {
|
||||||
|
@ -17,21 +17,17 @@
|
|||||||
|
|
||||||
package org.apache.poi.hssf.record.formula.functions;
|
package org.apache.poi.hssf.record.formula.functions;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.AreaPtg;
|
import junit.framework.TestCase;
|
||||||
import org.apache.poi.hssf.record.formula.RefPtg;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.Area2DEval;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.BlankEval;
|
import org.apache.poi.hssf.record.formula.eval.BlankEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.Eval;
|
import org.apache.poi.hssf.record.formula.eval.Eval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.Ref2DEval;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.StringEval;
|
import org.apache.poi.hssf.record.formula.eval.StringEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
/**
|
/**
|
||||||
* Tests for Excel function MID()
|
* Tests for Excel function MID()
|
||||||
*
|
*
|
||||||
@ -76,8 +72,8 @@ public final class TestMid extends TestCase {
|
|||||||
confirmMid(new NumberEval(123456), new StringEval("3.1"), new StringEval("2.9"), "34");
|
confirmMid(new NumberEval(123456), new StringEval("3.1"), new StringEval("2.9"), "34");
|
||||||
|
|
||||||
// startPos is 1x1 area ref, numChars is cell ref
|
// startPos is 1x1 area ref, numChars is cell ref
|
||||||
AreaEval aeStart = new Area2DEval(new AreaPtg("A1:A1"), new ValueEval[] { new NumberEval(2), } );
|
AreaEval aeStart = EvalFactory.createAreaEval("A1:A1", new ValueEval[] { new NumberEval(2), } );
|
||||||
RefEval reNumChars = new Ref2DEval(new RefPtg("B1"), new NumberEval(3));
|
RefEval reNumChars = EvalFactory.createRefEval("B1", new NumberEval(3));
|
||||||
confirmMid(new StringEval("galactic"), aeStart, reNumChars, "ala");
|
confirmMid(new StringEval("galactic"), aeStart, reNumChars, "ala");
|
||||||
|
|
||||||
confirmMid(new StringEval("galactic"), new NumberEval(3.1), BlankEval.INSTANCE, "");
|
confirmMid(new StringEval("galactic"), new NumberEval(3.1), BlankEval.INSTANCE, "");
|
||||||
|
@ -17,18 +17,16 @@
|
|||||||
|
|
||||||
package org.apache.poi.hssf.record.formula.functions;
|
package org.apache.poi.hssf.record.formula.functions;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.RefPtg;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.Eval;
|
import org.apache.poi.hssf.record.formula.eval.Eval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
|
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.Ref2DEval;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test cases for SUMPRODUCT()
|
* Test cases for SUMPRODUCT()
|
||||||
*
|
*
|
||||||
@ -50,7 +48,7 @@ public final class TestSumproduct extends TestCase {
|
|||||||
|
|
||||||
public void testScalarSimple() {
|
public void testScalarSimple() {
|
||||||
|
|
||||||
RefEval refEval = new Ref2DEval(new RefPtg("A1"), new NumberEval(3));
|
RefEval refEval = EvalFactory.createRefEval("A1", new NumberEval(3));
|
||||||
Eval[] args = {
|
Eval[] args = {
|
||||||
refEval,
|
refEval,
|
||||||
new NumberEval(2),
|
new NumberEval(2),
|
||||||
|
@ -17,18 +17,16 @@
|
|||||||
|
|
||||||
package org.apache.poi.hssf.record.formula.functions;
|
package org.apache.poi.hssf.record.formula.functions;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.RefPtg;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.BlankEval;
|
import org.apache.poi.hssf.record.formula.eval.BlankEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.Eval;
|
import org.apache.poi.hssf.record.formula.eval.Eval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.Ref2DEval;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.StringEval;
|
import org.apache.poi.hssf.record.formula.eval.StringEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test cases for Excel function T()
|
* Test cases for Excel function T()
|
||||||
*
|
*
|
||||||
@ -50,7 +48,7 @@ public final class TestTFunc extends TestCase {
|
|||||||
* where cell A1 has the specified innerValue
|
* where cell A1 has the specified innerValue
|
||||||
*/
|
*/
|
||||||
private Eval invokeTWithReference(ValueEval innerValue) {
|
private Eval invokeTWithReference(ValueEval innerValue) {
|
||||||
Eval arg = new Ref2DEval(new RefPtg((short)1, (short)1, false, false), innerValue);
|
Eval arg = EvalFactory.createRefEval("$B$2", innerValue);
|
||||||
return invokeT(arg);
|
return invokeT(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,8 +19,6 @@ package org.apache.poi.hssf.record.formula.functions;
|
|||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.AreaPtg;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.Area2DEval;
|
|
||||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.Eval;
|
import org.apache.poi.hssf.record.formula.eval.Eval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||||
@ -100,7 +98,7 @@ public final class TestXYNumericFunction extends TestCase {
|
|||||||
|
|
||||||
private static ValueEval createAreaEval(ValueEval[] values) {
|
private static ValueEval createAreaEval(ValueEval[] values) {
|
||||||
String refStr = "A1:A" + values.length;
|
String refStr = "A1:A" + values.length;
|
||||||
return new Area2DEval(new AreaPtg(refStr), values);
|
return EvalFactory.createAreaEval(refStr, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testErrors() {
|
public void testErrors() {
|
||||||
|
Loading…
Reference in New Issue
Block a user