DStar functions need to support field params provided as numbers as well as field names

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1901250 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2022-05-25 15:54:29 +00:00
parent fdc20e96ef
commit 39dff4479d
9 changed files with 17 additions and 13 deletions

View File

@ -29,8 +29,8 @@ public final class DCount implements IDStarAlgorithm {
private int count;
@Override
public boolean processMatch(ValueEval eval, String field) {
if (field == null || eval instanceof NumericValueEval) {
public boolean processMatch(ValueEval eval, int fieldNumber) {
if (fieldNumber < 0 || eval instanceof NumericValueEval) {
count++;
}
return true;

View File

@ -31,7 +31,7 @@ public final class DGet implements IDStarAlgorithm {
private ValueEval result;
@Override
public boolean processMatch(ValueEval eval, String field) {
public boolean processMatch(ValueEval eval, int fieldNumber) {
if(result == null) // First match, just set the value.
{
result = eval;

View File

@ -33,7 +33,7 @@ public final class DMax implements IDStarAlgorithm {
private ValueEval maximumValue;
@Override
public boolean processMatch(ValueEval eval, String field) {
public boolean processMatch(ValueEval eval, int fieldNumber) {
if(eval instanceof NumericValueEval) {
if(maximumValue == null) { // First match, just set the value.
maximumValue = eval;

View File

@ -33,7 +33,7 @@ public final class DMin implements IDStarAlgorithm {
private ValueEval minimumValue;
@Override
public boolean processMatch(ValueEval eval, String field) {
public boolean processMatch(ValueEval eval, int fieldNumber) {
if(eval instanceof NumericValueEval) {
if(minimumValue == null) { // First match, just set the value.
minimumValue = eval;

View File

@ -104,12 +104,13 @@ public final class DStarRunner implements Function3Arg {
final IDStarAlgorithm algorithm = algoType.newInstance();
int fc = -1;
String field = null;
try {
filterColumn = OperandResolver.getSingleValue(filterColumn, srcRowIndex, srcColumnIndex);
fc = getColumnForName(filterColumn, db);
if (filterColumn instanceof StringEval) {
field = ((StringEval)filterColumn).getStringValue();
if (filterColumn instanceof NumericValueEval) {
//fc is zero based while Excel uses 1 based column numbering
fc = (int) Math.round(((NumericValueEval)filterColumn).getNumberValue()) - 1;
} else {
fc = getColumnForName(filterColumn, db);
}
if(fc == -1 && !algorithm.allowEmptyMatchField()) {
// column not found
@ -140,7 +141,7 @@ public final class DStarRunner implements Function3Arg {
if(matches) {
ValueEval currentValueEval = resolveReference(db, row, fc);
// Pass the match to the algorithm and conditionally abort the search.
boolean shouldContinue = algorithm.processMatch(currentValueEval, field);
boolean shouldContinue = algorithm.processMatch(currentValueEval, fc);
if(! shouldContinue) {
break;
}

View File

@ -33,7 +33,7 @@ public final class DSum implements IDStarAlgorithm {
private double totalValue = 0;
@Override
public boolean processMatch(ValueEval eval, String field) {
public boolean processMatch(ValueEval eval, int fieldNumber) {
if(eval instanceof NumericValueEval) {
double currentValue = ((NumericValueEval)eval).getNumberValue();
totalValue += currentValue;

View File

@ -27,10 +27,10 @@ public interface IDStarAlgorithm {
/**
* Process a match that is found during a run through a database.
* @param eval ValueEval of the cell in the matching row. References will already be resolved.
* @param field the field name (added in POI 5.2.3)
* @param fieldNumber the field number (added in POI 5.2.3)
* @return Whether we should continue iterating through the database.
*/
boolean processMatch(ValueEval eval, String field);
boolean processMatch(ValueEval eval, int fieldNumber);
/**
* Return a result ValueEval that will be the result of the calculation.

View File

@ -42,6 +42,7 @@ public class TestDCount {
assertDouble(fe, cell, "DCOUNT(A5:E11,,A1:A2)", 3);
assertDouble(fe, cell, "DCOUNT(A5:E11, \"Age\", A1:A2)", 2);
assertDouble(fe, cell, "DCOUNT(A5:E11, \"Age\", A1:F2)", 1);
assertDouble(fe, cell, "DCOUNT(A5:E11, 3, A1:F2)", 1);
}
}

View File

@ -43,6 +43,7 @@ public class TestDGet {
HSSFCell cell = wb.getSheetAt(0).getRow(0).createCell(100);
assertError(fe, cell, "DGET(A5:E11, \"Yield\", A1:A3)", FormulaError.NUM);
assertDouble(fe, cell, "DGET(A5:E11, \"Yield\", A1:F3)", 10);
assertDouble(fe, cell, "DGET(A5:E11, 4, A1:F3)", 10);
}
}
@ -52,6 +53,7 @@ public class TestDGet {
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
HSSFCell cell = wb.getSheetAt(0).getRow(0).createCell(100);
assertDouble(fe, cell, "DGET(A5:E11, \"Yield\", A1:F3)", 6);
assertDouble(fe, cell, "DGET(A5:E11, 4, A1:F3)", 6);
}
}