]> source.dussan.org Git - poi.git/commitdiff
[github-692] D* functions are incompatible with the diamond operator. Thanks to Luk...
authorPJ Fanning <fanningpj@apache.org>
Fri, 20 Sep 2024 20:20:34 +0000 (20:20 +0000)
committerPJ Fanning <fanningpj@apache.org>
Fri, 20 Sep 2024 20:20:34 +0000 (20:20 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1920817 13f79535-47bb-0310-9956-ffa450edef68

poi/src/main/java/org/apache/poi/ss/formula/functions/DStarRunner.java
poi/src/test/java/org/apache/poi/ss/formula/functions/TestDAverage.java
poi/src/test/java/org/apache/poi/ss/formula/functions/TestDCount.java
poi/src/test/java/org/apache/poi/ss/formula/functions/TestDCountA.java
poi/src/test/java/org/apache/poi/ss/formula/functions/TestDProduct.java
poi/src/test/java/org/apache/poi/ss/formula/functions/TestDStdev.java
poi/src/test/java/org/apache/poi/ss/formula/functions/TestDVar.java
test-data/spreadsheet/DStar.xls

index 8007ad06e0541bd1ecdb9e85149e9bce452e6692..16b0b2c25985814a309e5967bf4717866b617e6b 100644 (file)
@@ -175,7 +175,8 @@ public final class DStarRunner implements Function3Arg {
         largerEqualThan,
         smallerThan,
         smallerEqualThan,
-        equal
+        equal,
+        notEqual
     }
 
     /**
@@ -295,7 +296,7 @@ public final class DStarRunner implements Function3Arg {
     }
 
     /**
-     * Test a value against a simple (< > <= >= = starts-with) condition string.
+     * Test a value against a simple (< > <= >= = <> starts-with) condition string.
      *
      * @param value The value to check.
      * @param condition The condition to check for.
@@ -307,11 +308,19 @@ public final class DStarRunner implements Function3Arg {
         if(condition instanceof StringEval) {
             String conditionString = ((StringEval)condition).getStringValue();
 
-            if(conditionString.startsWith("<")) { // It's a </<= condition.
+            if(conditionString.startsWith("<")) { // It's a </<=/<> condition.
                 String number = conditionString.substring(1);
                 if(number.startsWith("=")) {
                     number = number.substring(1);
                     return testNumericCondition(value, operator.smallerEqualThan, number);
+                } else if (number.startsWith(">")) {
+                    number = number.substring(1);
+                    boolean itsANumber = isNumber(number);
+                    if (itsANumber) {
+                        return testNumericCondition(value, operator.notEqual, number);
+                    } else {
+                        return testStringCondition(value, operator.notEqual, number);
+                    }
                 } else {
                     return testNumericCondition(value, operator.smallerThan, number);
                 }
@@ -330,23 +339,11 @@ public final class DStarRunner implements Function3Arg {
                     return value instanceof BlankEval;
                 }
                 // Distinguish between string and number.
-                boolean itsANumber;
-                try {
-                    Integer.parseInt(stringOrNumber);
-                    itsANumber = true;
-                } catch (NumberFormatException e) { // It's not an int.
-                    try {
-                        Double.parseDouble(stringOrNumber);
-                        itsANumber = true;
-                    } catch (NumberFormatException e2) { // It's a string.
-                        itsANumber = false;
-                    }
-                }
+                boolean itsANumber = isNumber(stringOrNumber);
                 if(itsANumber) {
                     return testNumericCondition(value, operator.equal, stringOrNumber);
                 } else { // It's a string.
-                    String valueString = value instanceof BlankEval ? "" : OperandResolver.coerceValueToString(value);
-                    return stringOrNumber.equalsIgnoreCase(valueString);
+                    return testStringCondition(value, operator.equal, stringOrNumber);
                 }
             } else { // It's a text starts-with condition.
                 if(conditionString.isEmpty()) {
@@ -418,6 +415,28 @@ public final class DStarRunner implements Function3Arg {
             return result <= 0;
         case equal:
             return result == 0;
+        case notEqual:
+            return result != 0;
+        }
+        return false; // Can not be reached.
+    }
+
+    /**
+     * Test whether a value matches a text condition.
+     * @param valueEval Value to check.
+     * @param op Comparator to use.
+     * @param condition Value to check against.
+     * @return whether the condition holds.
+     */
+    private static boolean testStringCondition(
+        ValueEval valueEval, operator op, String condition) {
+
+        String valueString = valueEval instanceof BlankEval ? "" : OperandResolver.coerceValueToString(valueEval);
+        switch(op) {
+        case equal:
+            return valueString.equalsIgnoreCase(condition);
+        case notEqual:
+            return !valueString.equalsIgnoreCase(condition);
         }
         return false; // Can not be reached.
     }
@@ -454,4 +473,27 @@ public final class DStarRunner implements Function3Arg {
             return e.getErrorEval();
         }
     }
+
+    /**
+     * Determines whether a given string represents a valid number.
+     *
+     * @param value The string to be checked if it represents a number.
+     * @return {@code true} if the string can be parsed as either an integer or
+     *         a double; {@code false} otherwise.
+     */
+    private static boolean isNumber(String value) {
+        boolean itsANumber;
+        try {
+            Integer.parseInt(value);
+            itsANumber = true;
+        } catch (NumberFormatException e) { // It's not an int.
+            try {
+                Double.parseDouble(value);
+                itsANumber = true;
+            } catch (NumberFormatException e2) { // It's a string.
+                itsANumber = false;
+            }
+        }
+        return itsANumber;
+    }
 }
index 6e3028492db8e972d4cd188d5477c083ff0f0bd5..a41630c4d445be54332caaa99680bf6c048d8ebd 100644 (file)
@@ -41,6 +41,8 @@ public class TestDAverage {
             HSSFCell cell = wb.getSheetAt(0).getRow(0).createCell(12);
             assertDouble(fe, cell, "DAVERAGE(A4:E10, \"Yield\", A1:B2)", 12);
             assertDouble(fe, cell, "DAVERAGE(A4:E10, 3, A4:E10)", 13);
+            assertDouble(fe, cell, "DAVERAGE(A4:E10, \"Profit\", A12:A13)", 92.6);
+            assertDouble(fe, cell, "DAVERAGE(A4:E10, \"Profit\", B12:C13)", 82.5);
         }
     }
 
@@ -57,6 +59,9 @@ public class TestDAverage {
         addRow(sheet, 7, "Apple", 14, 15, 10, 75);
         addRow(sheet, 8, "Pear", 9, 8, 8, 76.8);
         addRow(sheet, 9, "Apple", 8, 9, 6, 45);
+        addRow(sheet, 10);
+        addRow(sheet, 11, "Tree", "Height", "Height");
+        addRow(sheet, 12, "<>Apple", "<>12", "<>9");
         return wb;
     }
 }
index a75d1ca22c7c6de1e3aec6a3bc01036932087080..ea4d79e5fe74a5cd3a01fa71eec49329c7e4c8db 100644 (file)
@@ -46,6 +46,8 @@ public class TestDCount {
             assertDouble(fe, cell, "DCOUNT(A5:E11, 2, A1:F3)", 4);
             assertDouble(fe, cell, "DCOUNT(A5:E11, 3, A1:F3)", 3);
             assertDouble(fe, cell, "DCOUNT(A5:E11, 5, A1:F3)", 3);
+            assertDouble(fe, cell, "DCOUNT(A5:E11, 5, A13:A14)", 2);
+            assertDouble(fe, cell, "DCOUNT(A5:E11, 5, B13:B14)", 3);
         }
     }
 
@@ -63,6 +65,9 @@ public class TestDCount {
         addRow(sheet, 8, "Apple", 14, null, 10, 75);
         addRow(sheet, 9, "Pear", 9, 8, 8, "$77");
         addRow(sheet, 10, "Apple", 12, 11, 6, 45);
+        addRow(sheet, 11);
+        addRow(sheet, 12, "Tree", "Height");
+        addRow(sheet, 13, "<>Apple", "<>12");
         return wb;
     }
 }
index 85ee0ff5102a8b4fc7cd4bf7cf79d36728d9d276..8c531b733b470fd65f14ae3a01055a9790542943 100644 (file)
@@ -45,6 +45,8 @@ public class TestDCountA {
             assertDouble(fe, cell, "DCOUNTA(A4:E10, \"Profit\", A1:F2)", 1);
             assertDouble(fe, cell, "DCOUNTA(A4:E10, \"Profit\", A1:F3)", 3);
             assertDouble(fe, cell, "DCOUNTA(A4:E10, \"Age\", A1:F3)", 2);
+            assertDouble(fe, cell, "DCOUNTA(A4:E10, \"Profit\", A12:A13)", 3);
+            assertDouble(fe, cell, "DCOUNTA(A4:E10, \"Age\", B12:B13)", 4);
         }
     }
 
@@ -61,6 +63,9 @@ public class TestDCountA {
         addRow(sheet, 7, "Apple", 14, null, 10, 75);
         addRow(sheet, 8, "Pear", 9, 8, 8, "$77");
         addRow(sheet, 9, "Apple", 8, 9, 6, 45);
+        addRow(sheet, 10);
+        addRow(sheet, 11, "Tree", "Height");
+        addRow(sheet, 12, "<>Apple", "<>12");
         return wb;
     }
 }
index 80cef52f85c563e0669e0f8d12fa3ba4531c1b42..a654d84d65520caca9dfd4ac5c6cb81ac3fbb0ac 100644 (file)
@@ -40,6 +40,8 @@ public class TestDProduct {
             HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
             HSSFCell cell = wb.getSheetAt(0).getRow(0).createCell(12);
             assertDouble(fe, cell, "DPRODUCT(A5:E11, \"Yield\", A1:F3)", 800, 0.0000000001);
+            assertDouble(fe, cell, "DPRODUCT(A5:E11, \"Yield\", A13:A14)", 720, 0.0000000001);
+            assertDouble(fe, cell, "DPRODUCT(A5:E11, \"Yield\", B13:C14)", 7560, 0.0000000001);
         }
     }
 
@@ -72,6 +74,9 @@ public class TestDProduct {
         addRow(sheet, 8, "Apple", 14, 15, 10, 75);
         addRow(sheet, 9, "Pear", 9, 8, 8, 77);
         addRow(sheet, 10, "Apple", 8, 9, 6, 45);
+        addRow(sheet, 11);
+        addRow(sheet, 12, "Tree", "Height", "Height");
+        addRow(sheet, 13, "<>Apple", "<>12", "<>9");
         return wb;
     }
 }
index df4eb99d5cfc13c457ffa6204091fa55672dde36..b19d06bb38794291acc8de9db7aee0c0222aeb9c 100644 (file)
@@ -40,6 +40,7 @@ public class TestDStdev {
             HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
             HSSFCell cell = wb.getSheetAt(0).getRow(0).createCell(12);
             assertDouble(fe, cell, "DSTDEV(A5:E11, \"Yield\", A1:A3)", 2.96647939483827, 0.0000000001);
+            assertDouble(fe, cell, "DSTDEV(A5:E11, \"Yield\", B12:C14)", 2.66458251889485, 0.0000000001);
         }
     }
 
@@ -50,6 +51,8 @@ public class TestDStdev {
             HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
             HSSFCell cell = wb.getSheetAt(0).getRow(0).createCell(12);
             assertDouble(fe, cell, "DSTDEVP(A5:E11, \"Yield\", A1:A3)", 2.65329983228432, 0.0000000001);
+            assertDouble(fe, cell, "DSTDEVP(A5:E11, \"Yield\", A12:A13)", 0.816496580927726, 0.0000000001);
+            assertDouble(fe, cell, "DSTDEVP(A5:E11, \"Yield\", B12:C14)", 2.43241991988774, 0.0000000001);
         }
     }
 
@@ -67,6 +70,9 @@ public class TestDStdev {
         addRow(sheet, 8, "Apple", 14, 15, 10, 75);
         addRow(sheet, 9, "Pear", 9, 8, 8, 77);
         addRow(sheet, 10, "Apple", 8, 9, 6, 45);
+        addRow(sheet, 11);
+        addRow(sheet, 11, "Tree", "Height", "Height");
+        addRow(sheet, 12, "<>Apple", "<>12", "<>9");
         return wb;
     }
 }
index 6c8a86bf285496ba6e3407dd40c60de31bde2f14..46262eca04b5b2b661abd664e51f8a2efb1d7947 100644 (file)
@@ -40,6 +40,8 @@ public class TestDVar {
             HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
             HSSFCell cell = wb.getSheetAt(0).getRow(0).createCell(12);
             assertDouble(fe, cell, "DVAR(A4:E10, \"Yield\", A1:A3)", 8.8, 0.0000000001);
+            assertDouble(fe, cell, "DVAR(A4:E10, \"Yield\", A12:A13)", 1.0, 0.0000000001);
+            assertDouble(fe, cell, "DVAR(A4:E10, \"Yield\", B12:C13)", 10.9166666667, 0.0000000001);
         }
     }
 
@@ -50,6 +52,8 @@ public class TestDVar {
             HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
             HSSFCell cell = wb.getSheetAt(0).getRow(0).createCell(12);
             assertDouble(fe, cell, "DVARP(A4:E10, \"Yield\", A1:A3)", 7.04, 0.0000000001);
+            assertDouble(fe, cell, "DVARP(A4:E10, \"Yield\", A12:A13)", 0.666666666666667, 0.0000000001);
+            assertDouble(fe, cell, "DVARP(A4:E10, \"Yield\", B12:C13)", 8.1875, 0.0000000001);
         }
     }
 
@@ -66,6 +70,9 @@ public class TestDVar {
         addRow(sheet, 7, "Apple", 14, 15, 10, 75);
         addRow(sheet, 8, "Pear", 9, 8, 8, 77);
         addRow(sheet, 9, "Apple", 8, 9, 6, 45);
+        addRow(sheet, 10);
+        addRow(sheet, 11, "Tree", "Height", "Height");
+        addRow(sheet, 12, "<>Apple", "<>12", "<>9");
         return wb;
     }
 }
index 8a5a45d7ef399cd619b71220dfd5ac90f1e44f8b..e7c29bd63c5ba9010da487b31cfe6dfd2a302459 100644 (file)
Binary files a/test-data/spreadsheet/DStar.xls and b/test-data/spreadsheet/DStar.xls differ