aboutsummaryrefslogtreecommitdiffstats
path: root/src/java
diff options
context:
space:
mode:
authorNick Burch <nick@apache.org>2021-03-14 22:53:27 +0000
committerNick Burch <nick@apache.org>2021-03-14 22:53:27 +0000
commit82b5113ba97b0c590bdd8696e5c1251e158b143a (patch)
tree0fd3c448225521492dde64ddb117b3c3d1aa5d33 /src/java
parent120566991b1dbd19726473cbd68516eb818eb753 (diff)
downloadpoi-82b5113ba97b0c590bdd8696e5c1251e158b143a.tar.gz
poi-82b5113ba97b0c590bdd8696e5c1251e158b143a.zip
Implement CONCAT function #65185
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1887656 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java')
-rw-r--r--src/java/org/apache/poi/ss/formula/atp/AnalysisToolPak.java4
-rw-r--r--src/java/org/apache/poi/ss/formula/functions/Single.java67
-rw-r--r--src/java/org/apache/poi/ss/formula/functions/TextFunction.java48
3 files changed, 107 insertions, 12 deletions
diff --git a/src/java/org/apache/poi/ss/formula/atp/AnalysisToolPak.java b/src/java/org/apache/poi/ss/formula/atp/AnalysisToolPak.java
index 076eafd03c..096f6b2ed2 100644
--- a/src/java/org/apache/poi/ss/formula/atp/AnalysisToolPak.java
+++ b/src/java/org/apache/poi/ss/formula/atp/AnalysisToolPak.java
@@ -37,7 +37,9 @@ import org.apache.poi.ss.formula.functions.ImReal;
import org.apache.poi.ss.formula.functions.Imaginary;
import org.apache.poi.ss.formula.functions.Oct2Dec;
import org.apache.poi.ss.formula.functions.Quotient;
+import org.apache.poi.ss.formula.functions.Single;
import org.apache.poi.ss.formula.functions.Sumifs;
+import org.apache.poi.ss.formula.functions.TextFunction;
import org.apache.poi.ss.formula.functions.WeekNum;
import org.apache.poi.ss.formula.udf.UDFFinder;
@@ -95,6 +97,7 @@ public final class AnalysisToolPak implements UDFFinder {
r(m, "BIN2HEX", null);
r(m, "BIN2OCT", null);
r(m, "COMPLEX", Complex.instance);
+ r(m, "CONCAT", TextFunction.CONCAT);
r(m, "CONVERT", null);
r(m, "COUNTIFS", Countifs.instance);
r(m, "COUPDAYBS", null);
@@ -175,6 +178,7 @@ public final class AnalysisToolPak implements UDFFinder {
r(m, "RECEIVED", null);
r(m, "RTD", null);
r(m, "SERIESSUM", null);
+ r(m, "SINGLE", Single.instance);
r(m, "SQRTPI", null);
r(m, "SUMIFS", Sumifs.instance);
r(m, "TBILLEQ", null);
diff --git a/src/java/org/apache/poi/ss/formula/functions/Single.java b/src/java/org/apache/poi/ss/formula/functions/Single.java
new file mode 100644
index 0000000000..38e8a20fdc
--- /dev/null
+++ b/src/java/org/apache/poi/ss/formula/functions/Single.java
@@ -0,0 +1,67 @@
+/* ====================================================================
+ 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.ss.formula.functions;
+
+import org.apache.poi.ss.formula.OperationEvaluationContext;
+import org.apache.poi.ss.formula.eval.AreaEvalBase;
+import org.apache.poi.ss.formula.eval.ErrorEval;
+import org.apache.poi.ss.formula.eval.ValueEval;
+
+/**
+ * Implementation of the SINGLE function, used by Dynamic Arrays, which is
+ * now largely replaced by the &#064; character.
+ */
+public final class Single implements FreeRefFunction {
+ public static final FreeRefFunction instance = new Single();
+ private Single() {
+ // Enforce singleton
+ }
+
+ public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
+ // Look for a single Eval which matches either our Row or
+ // our Column
+ ValueEval intersect = null;
+ int col = ec.getColumnIndex();
+ int row = ec.getRowIndex();
+
+ for (ValueEval val : args) {
+ if (val instanceof AreaEvalBase) {
+ AreaEvalBase area = (AreaEvalBase)val;
+
+ if (area.contains(row, col)) {
+ if (intersect != null) return ErrorEval.VALUE_INVALID;
+ intersect = area.getAbsoluteValue(row, col);
+ } else if (area.containsRow(row)) {
+ if (intersect != null) return ErrorEval.VALUE_INVALID;
+ intersect = area.getAbsoluteValue(row, area.getFirstColumn());
+ } else if (area.containsColumn(col)) {
+ if (intersect != null) return ErrorEval.VALUE_INVALID;
+ intersect = area.getAbsoluteValue(area.getFirstRow(), col);
+ }
+ }
+ }
+
+ // If we found only one, it's that
+ if (intersect != null) {
+ return intersect;
+ }
+
+ // If in doubt, it's probably invalid
+ return ErrorEval.VALUE_INVALID;
+ }
+}
diff --git a/src/java/org/apache/poi/ss/formula/functions/TextFunction.java b/src/java/org/apache/poi/ss/formula/functions/TextFunction.java
index 74573f7dd0..f344d57ca5 100644
--- a/src/java/org/apache/poi/ss/formula/functions/TextFunction.java
+++ b/src/java/org/apache/poi/ss/formula/functions/TextFunction.java
@@ -19,6 +19,8 @@ package org.apache.poi.ss.formula.functions;
import java.util.Locale;
+import org.apache.poi.ss.formula.OperationEvaluationContext;
+import org.apache.poi.ss.formula.eval.AreaEval;
import org.apache.poi.ss.formula.eval.BoolEval;
import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.EvaluationException;
@@ -268,19 +270,41 @@ public abstract class TextFunction implements Function {
public static final Function LEFT = new LeftRight(true);
public static final Function RIGHT = new LeftRight(false);
+ public static final FreeRefFunction CONCAT = new FreeRefFunction() {
+ public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
+ StringBuilder sb = new StringBuilder();
+ for (ValueEval arg : args) {
+ try {
+ if (arg instanceof AreaEval) {
+ AreaEval area = (AreaEval)arg;
+ for (int rn=0; rn<area.getHeight(); rn++) {
+ for (int cn=0; cn<area.getWidth(); cn++) {
+ ValueEval ve = area.getRelativeValue(rn, cn);
+ sb.append(evaluateStringArg(ve, ec.getRowIndex(), ec.getColumnIndex()));
+ }
+ }
+ } else {
+ sb.append(evaluateStringArg(arg, ec.getRowIndex(), ec.getColumnIndex()));
+ }
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ }
+ return new StringEval(sb.toString());
+ }
+ };
public static final Function CONCATENATE = new Function() {
-
- public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
- StringBuilder sb = new StringBuilder();
- for (ValueEval arg : args) {
- try {
- sb.append(evaluateStringArg(arg, srcRowIndex, srcColumnIndex));
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- }
- return new StringEval(sb.toString());
- }
+ public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
+ StringBuilder sb = new StringBuilder();
+ for (ValueEval arg : args) {
+ try {
+ sb.append(evaluateStringArg(arg, srcRowIndex, srcColumnIndex));
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ }
+ return new StringEval(sb.toString());
+ }
};
public static final Function EXACT = new Fixed2ArgFunction() {