[gnumeric] Funcs: add IFS.



commit 27b79acdbc4c69a4813a20def381a73f7daad950
Author: Morten Welinder <terra gnome org>
Date:   Fri Aug 5 11:02:53 2016 -0400

    Funcs: add IFS.
    
    There are open questions about semantic details, but this handles the
    basic.  The last will have to wait until testing opportunities arise.

 NEWS                                  |    1 +
 doc/C/func.defs                       |   11 +++++++
 doc/C/functions.xml                   |   34 +++++++++++++++++++++++
 plugins/fn-logical/functions.c        |   48 +++++++++++++++++++++++++++++++++
 plugins/fn-logical/plugin.xml.in      |    1 +
 plugins/openoffice/openoffice-read.c  |    1 +
 plugins/openoffice/openoffice-write.c |    1 +
 7 files changed, 97 insertions(+), 0 deletions(-)
---
diff --git a/NEWS b/NEWS
index ef6d038..cd6fd52 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ Morten:
        * Avoid gnome-common dependency.
        * New function CONCAT.
        * New function TEXTJOIN.
+       * New function IFS.
 
 --------------------------------------------------------------------------
 Gnumeric 1.12.31
diff --git a/doc/C/func.defs b/doc/C/func.defs
index 75914c0..3aaff6c 100644
--- a/doc/C/func.defs
+++ b/doc/C/func.defs
@@ -2921,6 +2921,17 @@ The depreciation coefficient used is:
 @SEEALSO=IF,ISERROR
 
 @CATEGORY=Logic
+@FUNCTION=IFS
+@SHORTDESC=multi-branch conditional
+@SYNTAX=IFS(cond1,value1,cond2,value2,…)
+@ARGUMENTDESCRIPTION=@{cond1}: condition
+@{value1}: value if @{condition1} is true
+@{cond2}: condition
+@{value2}: value if @{condition2} is true
+@DESCRIPTION=This function returns the after the first true contional.  If no conditional is true, #VALUE! 
is returned.
+@SEEALSO=IF
+
+@CATEGORY=Logic
 @FUNCTION=NOT
 @SHORTDESC=logical negation
 @SYNTAX=NOT(b)
diff --git a/doc/C/functions.xml b/doc/C/functions.xml
index a659648..dbfc7e5 100644
--- a/doc/C/functions.xml
+++ b/doc/C/functions.xml
@@ -9298,6 +9298,40 @@
       </para>
       </refsect1>
     </refentry>
+    <refentry id="gnumeric-function-IFS">
+      <refmeta>
+        <refentrytitle>
+          <function>IFS</function>
+        </refentrytitle>
+      </refmeta>
+      <refnamediv>
+        <refname>
+          <function>IFS</function>
+        </refname>
+        <refpurpose>
+        multi-branch conditional
+      </refpurpose>
+      </refnamediv>
+      <refsynopsisdiv>
+        
<synopsis><function>IFS</function>(<parameter>cond1</parameter>,<parameter>value1</parameter>,<parameter>cond2</parameter>,<parameter>value2</parameter>,<parameter/>…)</synopsis>
+      </refsynopsisdiv>
+      <refsect1>
+        <title>Arguments</title>
+        <para><parameter>cond1</parameter>: condition</para>
+        <para><parameter>value1</parameter>: value if <parameter>condition1</parameter> is true</para>
+        <para><parameter>cond2</parameter>: condition</para>
+        <para><parameter>value2</parameter>: value if <parameter>condition2</parameter> is true</para>
+      </refsect1>
+      <refsect1>
+        <title>Description</title>
+        <para>This function returns the after the first true contional.  If no conditional is true, #VALUE! 
is returned.</para>
+      </refsect1>
+      <refsect1>
+        <title>See also</title>
+        <para><link linkend="gnumeric-function-IF"><function>IF</function></link>.
+      </para>
+      </refsect1>
+    </refentry>
     <refentry id="gnumeric-function-NOT">
       <refmeta>
         <refentrytitle>
diff --git a/plugins/fn-logical/functions.c b/plugins/fn-logical/functions.c
index 0d56b6e..1f2abe8 100644
--- a/plugins/fn-logical/functions.c
+++ b/plugins/fn-logical/functions.c
@@ -263,6 +263,51 @@ gnumeric_ifna (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 }
 
 /***************************************************************************/
+
+static GnmFuncHelp const help_ifs[] = {
+       { GNM_FUNC_HELP_NAME, F_("IFS:multi-branch conditional") },
+       { GNM_FUNC_HELP_ARG, F_("cond1:condition") },
+       { GNM_FUNC_HELP_ARG, F_("value1:value if @{condition1} is true") },
+       { GNM_FUNC_HELP_ARG, F_("cond2:condition") },
+       { GNM_FUNC_HELP_ARG, F_("value2:value if @{condition2} is true") },
+       { GNM_FUNC_HELP_DESCRIPTION, F_("This function returns the after the first true contional.  If no 
conditional is true, #VALUE! is returned.") },
+        { GNM_FUNC_HELP_EXAMPLES, "=IFS(false,1/0,true,42)" },
+       { GNM_FUNC_HELP_SEEALSO, "IF" },
+       { GNM_FUNC_HELP_END }
+};
+
+static GnmValue *
+gnumeric_ifs (GnmFuncEvalInfo *ei, int argc, GnmExprConstPtr const *argv)
+{
+       int a = 0;
+
+       for (a = 0; a + 1 <= argc; a += 2) {
+               GnmValue *v;
+               gboolean err, c;
+
+               v = gnm_expr_eval (argv[a], ei->pos, GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
+               // Strict in conditional arguments
+               if (VALUE_IS_ERROR (v))
+                       return v;
+
+               // Docs says to err on any non-boolean, but until tests
+               // verify that, we use regular boolean interpretation
+               c = value_get_as_bool (v, &err);
+               value_release (v);
+               if (err)
+                       break;
+
+               if (c)
+                       // Flags?
+                       return gnm_expr_eval (argv[a + 1], ei->pos, GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
+       }
+
+       // No match
+       return value_new_error_VALUE (ei->pos);
+}
+
+/***************************************************************************/
+
 static GnmFuncHelp const help_true[] = {
        { GNM_FUNC_HELP_NAME, F_("TRUE:the value TRUE") },
        { GNM_FUNC_HELP_DESCRIPTION, F_("TRUE returns the value TRUE.") },
@@ -319,6 +364,9 @@ GnmFuncDescriptor const logical_functions[] = {
          gnumeric_ifna, NULL, NULL, NULL,
          GNM_FUNC_SIMPLE,  GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC,
          GNM_FUNC_TEST_STATUS_NO_TESTSUITE},
+       { "ifs", NULL,  help_ifs,
+         NULL, gnumeric_ifs, NULL, NULL,
+         GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_NO_TESTSUITE },
        { "true", "", help_true, gnumeric_true,
          NULL, NULL, NULL,
          GNM_FUNC_SIMPLE + GNM_FUNC_AUTO_UNITLESS,
diff --git a/plugins/fn-logical/plugin.xml.in b/plugins/fn-logical/plugin.xml.in
index 66bd65f..623afcb 100644
--- a/plugins/fn-logical/plugin.xml.in
+++ b/plugins/fn-logical/plugin.xml.in
@@ -17,6 +17,7 @@
                                <function name="not"/>
                                <function name="iferror"/>
                                <function name="ifna"/>
+                               <function name="ifs"/>
                                <function name="true"/>
                                <function name="false"/>
                        </functions>
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index 1a9096f..050ed34 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -12931,6 +12931,7 @@ oo_func_map_in (GnmConventions const *convs, Workbook *scope,
                { "GAMMA.INV","GAMMAINV" },
                { "GAMMALN.PRECISE","GAMMALN" },
                { "HYPGEOM.DIST","HYPGEOMDIST" },
+               { "IFS","IFS" },
                { "LOGNORM.INV","LOGINV" },
                { "MODE.SNGL","MODE" },
                { "MODE.MULT","MODE.MULT" },
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index 8d94978..c8e51e2 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -2405,6 +2405,7 @@ odf_expr_func_handler (GnmConventionsOut *out, GnmExprFunction const *func)
                { "IF","IF" },
                { "IFERROR","IFERROR" },
                { "IFNA","IFNA" },
+               { "IFS","IFS" },
                { "IMABS","IMABS" },
                { "IMAGINARY","IMAGINARY" },
                { "IMARGUMENT","IMARGUMENT" },


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]