diff options
author | Nick Burch <nick@apache.org> | 2021-03-14 22:53:27 +0000 |
---|---|---|
committer | Nick Burch <nick@apache.org> | 2021-03-14 22:53:27 +0000 |
commit | 82b5113ba97b0c590bdd8696e5c1251e158b143a (patch) | |
tree | 0fd3c448225521492dde64ddb117b3c3d1aa5d33 /src/java | |
parent | 120566991b1dbd19726473cbd68516eb818eb753 (diff) | |
download | poi-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')
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 @ 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() { |