[Libreoffice-commits] core.git: formula/source include/formula sc/inc sc/qa sc/source

Winfried Donkers winfrieddonkers at libreoffice.org
Wed Apr 2 07:01:59 PDT 2014


 formula/source/core/resource/core_resource.src |   14 +
 include/formula/compiler.hrc                   |    4 
 include/formula/opcode.hxx                     |    2 
 sc/inc/helpids.h                               |    2 
 sc/qa/unit/subsequent_filters-test.cxx         |   24 ++-
 sc/qa/unit/ucalc.cxx                           |    2 
 sc/source/core/inc/interpre.hxx                |    5 
 sc/source/core/tool/interpr2.cxx               |  196 +++++++++++++++++++++++++
 sc/source/core/tool/interpr4.cxx               |    2 
 sc/source/core/tool/parclass.cxx               |    2 
 sc/source/filter/excel/xlformula.cxx           |    9 -
 sc/source/filter/oox/formulabase.cxx           |    6 
 sc/source/ui/src/scfuncs.src                   |   96 ++++++++++++
 13 files changed, 352 insertions(+), 12 deletions(-)

New commits:
commit 22dac22fe256b28b78c8e0783f2625aee0f75ace
Author: Winfried Donkers <winfrieddonkers at libreoffice.org>
Date:   Thu Mar 27 13:33:15 2014 +0100

    fdo#73147 add Excel2010 functions NETWORKDAYS.INTL and WORKDAY.INTL
    
    Change-Id: I3ab9dde5c421a3a3e6022a27be37f23547197317
    Reviewed-on: https://gerrit.libreoffice.org/8772
    Reviewed-by: Eike Rathke <erack at redhat.com>
    Tested-by: Eike Rathke <erack at redhat.com>

diff --git a/formula/source/core/resource/core_resource.src b/formula/source/core/resource/core_resource.src
index 28ecee3..e008f6c 100644
--- a/formula/source/core/resource/core_resource.src
+++ b/formula/source/core/resource/core_resource.src
@@ -385,6 +385,8 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF
     String SC_OPCODE_WEEK { Text = "ISOWEEKNUM" ; };
     String SC_OPCODE_EASTERSUNDAY { Text = "ORG.OPENOFFICE.EASTERSUNDAY" ; };
     String SC_OPCODE_GET_DAY_OF_WEEK { Text = "WEEKDAY" ; };
+    String SC_OPCODE_NETWORKDAYS_MS { Text = "COM.MICROSOFT.NETWORKDAYS.INTL" ; };
+    String SC_OPCODE_WORKDAY_MS { Text = "COM.MICROSOFT.WORKDAY.INTL" ; };
     String SC_OPCODE_NO_NAME { Text = "#NAME!" ; };
     String SC_OPCODE_STYLE { Text = "ORG.OPENOFFICE.STYLE" ; };
     String SC_OPCODE_DDE { Text = "DDE" ; };
@@ -786,6 +788,8 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_OOXML
     String SC_OPCODE_WEEK { Text = "WEEKNUM" ; };
     String SC_OPCODE_EASTERSUNDAY { Text = "EASTERSUNDAY" ; };
     String SC_OPCODE_GET_DAY_OF_WEEK { Text = "WEEKDAY" ; };
+    String SC_OPCODE_NETWORKDAYS_MS { Text = "NETWORKDAYS.INTL" ; };
+    String SC_OPCODE_WORKDAY_MS { Text = "WORKDAY.INTL" ; };
     String SC_OPCODE_NO_NAME { Text = "#NAME!" ; };
     String SC_OPCODE_STYLE { Text = "STYLE" ; };
     String SC_OPCODE_DDE { Text = "DDE" ; };
@@ -1189,6 +1193,8 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH
     String SC_OPCODE_WEEK { Text = "WEEKNUM" ; };
     String SC_OPCODE_EASTERSUNDAY { Text = "EASTERSUNDAY" ; };
     String SC_OPCODE_GET_DAY_OF_WEEK { Text = "WEEKDAY" ; };
+    String SC_OPCODE_NETWORKDAYS_MS { Text = "NETWORKDAYS.INTL" ; };
+    String SC_OPCODE_WORKDAY_MS { Text = "WORKDAY.INTL" ; };
     String SC_OPCODE_NO_NAME { Text = "#NAME!" ; };
     String SC_OPCODE_STYLE { Text = "STYLE" ; };
     String SC_OPCODE_DDE { Text = "DDE" ; };
@@ -2606,6 +2612,14 @@ Resource RID_STRLIST_FUNCTION_NAMES
     {
         Text [ en-US ] = "WEEKDAY" ;
     };
+    String SC_OPCODE_NETWORKDAYS_MS
+    {
+        Text [ en-US ] = "NETWORKDAYS.INTL" ;
+    };
+    String SC_OPCODE_WORKDAY_MS
+    {
+        Text [ en-US ] = "WORKDAY.INTL" ;
+    };
     String SC_OPCODE_NO_NAME
     {
         Text [ en-US ] = "#NAME!" ;
diff --git a/include/formula/compiler.hrc b/include/formula/compiler.hrc
index 23eedf3..47d22aa 100644
--- a/include/formula/compiler.hrc
+++ b/include/formula/compiler.hrc
@@ -463,8 +463,10 @@
 #define SC_OPCODE_CEIL_MS           465
 #define SC_OPCODE_CEIL_ISO          466
 #define SC_OPCODE_FLOOR_MS          467
+#define SC_OPCODE_NETWORKDAYS_MS    468
+#define SC_OPCODE_WORKDAY_MS        469
 
-#define SC_OPCODE_STOP_2_PAR        468     /* last function with two or more parameters' OpCode + 1 */
+#define SC_OPCODE_STOP_2_PAR        470     /* last function with two or more parameters' OpCode + 1 */
 #define SC_OPCODE_STOP_FUNCTION     SC_OPCODE_STOP_2_PAR            /* last function's OpCode + 1 */
 #define SC_OPCODE_LAST_OPCODE_ID    (SC_OPCODE_STOP_FUNCTION - 1)   /* last OpCode */
 
diff --git a/include/formula/opcode.hxx b/include/formula/opcode.hxx
index 13daeff..4239c53 100644
--- a/include/formula/opcode.hxx
+++ b/include/formula/opcode.hxx
@@ -436,6 +436,8 @@ enum OpCodeEnum
     // miscellaneous
         ocWeek              = SC_OPCODE_WEEK,
         ocGetDayOfWeek      = SC_OPCODE_GET_DAY_OF_WEEK,
+        ocNetWorkdays_MS    = SC_OPCODE_NETWORKDAYS_MS,
+        ocWorkday_MS        = SC_OPCODE_WORKDAY_MS,
         ocNoName            = SC_OPCODE_NO_NAME,
         ocStyle             = SC_OPCODE_STYLE,
         ocDde               = SC_OPCODE_DDE,
diff --git a/sc/inc/helpids.h b/sc/inc/helpids.h
index bc28f46..2aa8e60 100644
--- a/sc/inc/helpids.h
+++ b/sc/inc/helpids.h
@@ -702,5 +702,7 @@
 #define HID_FUNC_CEIL_MS                                        "SC_HID_FUNC_CEIL_MS"
 #define HID_FUNC_CEIL_ISO                                       "SC_HID_FUNC_CEIL_ISO"
 #define HID_FUNC_FLOOR_MS                                       "SC_HID_FUNC_FLOOR_MS"
+#define HID_FUNC_NETWORKDAYS_MS                                 "SC_HID_FUNC_NETWORKDAYS_MS"
+#define HID_FUNC_WORKDAY_MS                                     "SC_HID_FUNC_WORKDAY_MS"
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 9d0368d..1e08cf7 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -465,7 +465,7 @@ void ScFiltersTest::testFunctionsExcel2010()
         { 40, true  },
         { 41, true  },
         { 42, true  },
-        { 43, false },
+        { 43, false }, // fdo73147 to be set to true
         { 44, true  },
         { 45, true  },
         { 46, true  },
@@ -494,7 +494,7 @@ void ScFiltersTest::testFunctionsExcel2010()
         { 69, true  },
         { 70, true  },
         { 71, true  },
-        { 72, false },
+        { 72, false }, // fdo73147 to be set to true
         { 73, true  }
     };
 
@@ -505,12 +505,24 @@ void ScFiltersTest::testFunctionsExcel2010()
             // Column A is description, B is formula, C is Excel result, D is
             // comparison.
             SCROW nRow = aTests[i].nRow - 1;    // 0-based
+
+            OString aStr = OString::number( aTests[i].nRow) +
+                ", function name=[ " +
+                OUStringToOString( pDoc->GetString( ScAddress( 0, nRow, 0)), RTL_TEXTENCODING_UTF8 ) +
+                " ], result=" +
+                OString::number( pDoc->GetValue( ScAddress( 1, nRow, 0)) ) +
+                ", expected=" +
+                OString::number( pDoc->GetValue( ScAddress( 2, nRow, 0)) );
+
+            ScFormulaCell* pFC = pDoc->GetFormulaCell( ScAddress( 1, nRow, 0) );
+            if ( pFC && pFC->GetErrCode() != 0 )
+                aStr += ", error code =" + OString::number( pFC->GetErrCode() );
+
             CPPUNIT_ASSERT_MESSAGE( OString( "Expected a formula cell without error at row " +
-                    OString::number( aTests[i].nRow)).getStr(),
-                    isFormulaWithoutError( *pDoc, ScAddress( 1, nRow, 0)));
+                    aStr ).getStr(), isFormulaWithoutError( *pDoc, ScAddress( 1, nRow, 0)));
             CPPUNIT_ASSERT_MESSAGE( OString( "Expected a TRUE value at row " +
-                    OString::number( aTests[i].nRow)).getStr(),
-                    0 != pDoc->GetValue( ScAddress( 3, nRow, 0)));
+                    aStr ).getStr(), 0 != pDoc->GetValue( ScAddress( 3, nRow, 0)));
+
         }
     }
 
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 7bb90ca..f670e9c 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -2374,6 +2374,7 @@ void Test::testFunctionLists()
         "HOUR",
         "MINUTE",
         "MONTH",
+        "NETWORKDAYS.INTL",
         "NOW",
         "SECOND",
         "TIME",
@@ -2381,6 +2382,7 @@ void Test::testFunctionLists()
         "TODAY",
         "WEEKDAY",
         "WEEKNUM",
+        "WORKDAY.INTL",
         "YEAR",
         0
     };
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index bfebfd4..e0e36ed 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -32,6 +32,7 @@
 #include "token.hxx"
 
 #include <map>
+#include <vector>
 
 class ScDocument;
 class SbxVariable;
@@ -589,6 +590,10 @@ void ScGetDay();
 void ScGetDayOfWeek();
 void ScGetWeekOfYear();
 void ScEasterSunday();
+sal_uInt16 GetWeekendAndHolidayMasks( const sal_uInt8 nParamCount, const Date& rNullDate,
+        ::std::vector<double>& rSortArray, OUString& rWeekendDays, bool bWeekendMask[ 7 ] );
+void ScNetWorkdays_MS();
+void ScWorkday_MS();
 void ScGetHour();
 void ScGetMin();
 void ScGetSec();
diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx
index 0c38865..85707a2 100644
--- a/sc/source/core/tool/interpr2.cxx
+++ b/sc/source/core/tool/interpr2.cxx
@@ -50,6 +50,7 @@
 #include <string.h>
 #include <math.h>
 
+using ::std::vector;
 using namespace com::sun::star;
 using namespace formula;
 
@@ -247,6 +248,201 @@ void ScInterpreter::ScEasterSunday()
     }
 }
 
+sal_uInt16 ScInterpreter::GetWeekendAndHolidayMasks(
+    const sal_uInt8 nParamCount, const Date& rNullDate, vector< double >& rSortArray,
+    OUString& rWeekendDays, bool bWeekendMask[ 7 ] )
+{
+    sal_uInt16 nErr = 0;
+    if ( nParamCount == 4 )
+    {
+        GetSortArray( 1, rSortArray );
+        size_t nMax = rSortArray.size();
+        for ( size_t i = 0; i < nMax; i++ )
+        {
+            Date aTempDate( rNullDate );
+            aTempDate += ::rtl::math::approxFloor( rSortArray.at( i ) );
+            rSortArray.at( i ) = aTempDate.GetDate();
+        }
+    }
+
+    if ( nParamCount >= 3 )
+        rWeekendDays = GetString().getString();
+
+    for ( int i = 0; i < 7; i++ )
+        bWeekendMask[ i] = false;
+
+    if ( rWeekendDays.isEmpty() )
+    {
+        bWeekendMask[ SATURDAY ] = true;
+        bWeekendMask[ SUNDAY ]   = true;
+    }
+    else
+    {
+        switch ( rWeekendDays.getLength() )
+        {
+            case 1 :
+                // Weekend days defined by code
+                switch ( rWeekendDays[ 0 ] )
+                {
+                    case '1' : bWeekendMask[ SATURDAY ]  = true; bWeekendMask[ SUNDAY ]    = true; break;
+                    case '2' : bWeekendMask[ SUNDAY ]    = true; bWeekendMask[ MONDAY ]    = true; break;
+                    case '3' : bWeekendMask[ MONDAY ]    = true; bWeekendMask[ TUESDAY ]   = true; break;
+                    case '4' : bWeekendMask[ TUESDAY ]   = true; bWeekendMask[ WEDNESDAY ] = true; break;
+                    case '5' : bWeekendMask[ WEDNESDAY ] = true; bWeekendMask[ THURSDAY ]  = true; break;
+                    case '6' : bWeekendMask[ THURSDAY ]  = true; bWeekendMask[ FRIDAY ]    = true; break;
+                    case '7' : bWeekendMask[ FRIDAY ]    = true; bWeekendMask[ SATURDAY ]  = true; break;
+                    default  : nErr = errIllegalArgument;                                          break;
+                }
+                break;
+            case 2 :
+                // Weekend day defined by code
+                if ( rWeekendDays[ 0 ] == '1' )
+                {
+                    switch ( rWeekendDays[ 1 ] )
+                    {
+                        case '1' : bWeekendMask[ SUNDAY ]    = true; break;
+                        case '2' : bWeekendMask[ MONDAY ]    = true; break;
+                        case '3' : bWeekendMask[ TUESDAY ]   = true; break;
+                        case '4' : bWeekendMask[ WEDNESDAY ] = true; break;
+                        case '5' : bWeekendMask[ THURSDAY ]  = true; break;
+                        case '6' : bWeekendMask[ FRIDAY ]    = true; break;
+                        case '7' : bWeekendMask[ SATURDAY ]  = true; break;
+                        default  : nErr = errIllegalArgument;        break;
+                    }
+                }
+                else
+                    nErr = errIllegalArgument;
+                break;
+            case 7 :
+                // Weekend days defined by string
+                for ( int i = 0; i < 7 && !nErr; i++ )
+                {
+                    switch ( rWeekendDays[ i ] )
+                    {
+                        case '0' : bWeekendMask[ i ] = false; break;
+                        case '1' : bWeekendMask[ i ] = true;  break;
+                        default  : nErr = errIllegalArgument; break;
+                    }
+                }
+                break;
+            default :
+                nErr = errIllegalArgument;
+                break;
+        }
+    }
+    return nErr;
+}
+
+void ScInterpreter::ScNetWorkdays_MS()
+{
+    sal_uInt8 nParamCount = GetByte();
+    if ( MustHaveParamCount( nParamCount, 2, 4 ) )
+    {
+        vector<double> nSortArray;
+        bool bWeekendMask[ 7 ];
+        OUString aWeekendDays;
+        Date aNullDate = *( pFormatter->GetNullDate() );
+        sal_uInt16 nErr = GetWeekendAndHolidayMasks( nParamCount, aNullDate,
+                            nSortArray , aWeekendDays, bWeekendMask );
+        if ( nErr )
+            PushError( nErr );
+        else
+        {
+            double nDate2 = GetDouble();
+            double nDate1 = GetDouble();
+            Date aDate2( aNullDate );
+            aDate2 += ( long )::rtl::math::approxFloor( nDate2 );
+            Date aDate1( aNullDate );
+            aDate1 += ( long )::rtl::math::approxFloor( nDate1 );
+
+            sal_Int32 nCnt = 0;
+            size_t nRef = 0;
+            bool bReverse = ( aDate1 > aDate2 );
+            if ( bReverse )
+            {
+                Date aTempDate( aDate1 );
+                aDate1 = aDate2;
+                aDate2 = aTempDate;
+            }
+            size_t nMax = nSortArray.size();
+            while ( aDate1 <= aDate2 )
+            {
+                if ( !bWeekendMask[ aDate1.GetDayOfWeek() ] )
+                {
+                    while ( nRef < nMax && nSortArray.at( nRef ) < aDate1.GetDate() )
+                        nRef++;
+                    if ( !( nRef < nMax && nSortArray.at( nRef ) == aDate1.GetDate() ) )
+                        nCnt++;
+                }
+                ++aDate1;
+            }
+            PushDouble( ( double ) ( bReverse ? -nCnt : nCnt ) );
+        }
+    }
+}
+
+void ScInterpreter::ScWorkday_MS()
+{
+    sal_uInt8 nParamCount = GetByte();
+    if ( MustHaveParamCount( nParamCount, 2, 4 ) )
+    {
+        nFuncFmtType = NUMBERFORMAT_DATE;
+        vector<double> nSortArray;
+        bool bWeekendMask[ 7 ];
+        OUString aWeekendDays;
+        Date aNullDate = *( pFormatter->GetNullDate() );
+        sal_uInt16 nErr = GetWeekendAndHolidayMasks( nParamCount, aNullDate,
+                            nSortArray , aWeekendDays, bWeekendMask );
+        if ( nErr )
+            PushError( nErr );
+        else
+        {
+            sal_Int32 nDays = ::rtl::math::approxFloor( GetDouble() );
+            double nDate = GetDouble();
+            Date aDate( aNullDate );
+            aDate += ( long )::rtl::math::approxFloor( nDate );
+
+            if ( !nDays )
+                PushDouble( ( double ) ( aDate - aNullDate ) );
+            else
+            {
+                size_t nMax = nSortArray.size();
+                if ( nDays > 0 )
+                {
+                    size_t nRef = 0;
+                    while ( nDays )
+                    {
+                        while ( nRef < nMax && nSortArray.at( nRef ) < aDate.GetDate() )
+                            nRef++;
+                        if ( !( nRef < nMax && nSortArray.at( nRef ) == aDate.GetDate() ) || nRef >= nMax )
+                             nDays--;
+
+                        do
+                            ++aDate;
+                        while ( bWeekendMask[ aDate.GetDayOfWeek() ] ); //jump over weekend day(s)
+                    }
+                }
+                else
+                {
+                    sal_Int16 nRef = nMax - 1;
+                    while ( nDays )
+                    {
+                        while ( nRef >= 0 && nSortArray.at( nRef ) > aDate.GetDate() )
+                            nRef--;
+                        if ( !( nRef >= 0 && nSortArray.at( nRef ) == aDate.GetDate() ) || nRef < 0 )
+                             nDays++;
+
+                        do
+                          --aDate;
+                        while ( bWeekendMask[ aDate.GetDayOfWeek() ] ); //jump over weekend day(s)
+                    }
+                }
+                PushDouble( ( double ) ( aDate - aNullDate ) );
+            }
+        }
+    }
+}
+
 void ScInterpreter::ScGetDate()
 {
     nFuncFmtType = NUMBERFORMAT_DATE;
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index c641b7a..1048c1a 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -3978,6 +3978,8 @@ StackVar ScInterpreter::Interpret()
                 case ocGetDayOfWeek     : ScGetDayOfWeek();             break;
                 case ocWeek             : ScGetWeekOfYear();            break;
                 case ocEasterSunday     : ScEasterSunday();             break;
+                case ocNetWorkdays_MS   : ScNetWorkdays_MS();           break;
+                case ocWorkday_MS       : ScWorkday_MS();               break;
                 case ocGetHour          : ScGetHour();                  break;
                 case ocGetMin           : ScGetMin();                   break;
                 case ocGetSec           : ScGetSec();                   break;
diff --git a/sc/source/core/tool/parclass.cxx b/sc/source/core/tool/parclass.cxx
index 2b74084..b19b361 100644
--- a/sc/source/core/tool/parclass.cxx
+++ b/sc/source/core/tool/parclass.cxx
@@ -208,6 +208,8 @@ const ScParameterClassification::RawData ScParameterClassification::pRawData[] =
     { ocXor,             {{ Reference                                            }, 1 }},
     { ocZTest,           {{ Reference, Value, Value                              }, 0 }},
     { ocZTest_MS,        {{ Reference, Value, Value                              }, 0 }},
+    { ocNetWorkdays_MS,  {{ Value, Value, Value, Reference                       }, 0 }},
+    { ocWorkday_MS,      {{ Value, Value, Value, Reference                       }, 0 }},
     // Excel doubts:
     // ocN, ocT: Excel says (and handles) Reference, error? This means no
     // position dependent SingleRef if DoubleRef, and no array calculation,
diff --git a/sc/source/filter/excel/xlformula.cxx b/sc/source/filter/excel/xlformula.cxx
index c000ff1..e7222a7 100644
--- a/sc/source/filter/excel/xlformula.cxx
+++ b/sc/source/filter/excel/xlformula.cxx
@@ -398,8 +398,11 @@ static const XclFunctionInfo saFuncTable_Oox[] =
     { ocAverageIfs,         255,    4,  MX, V, { RO_E, RO, RO, VR }, EXC_FUNCFLAG_EXPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "AVERAGEIFS" ) },
     { ocIfError,            NOID,   2,  2,  V, { VO, RO }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME( "IFERROR" ) },
     { ocIfError,            255,    3,  3,  V, { RO_E, VO, RO }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME( "IFERROR" ) },
-
-    EXC_FUNCENTRY_V_VR( ocCeil_ISO,         2,  2,  0,  "ISO.CEILING" ),
+    { ocNetWorkdays_MS,     NOID,   2,  4,  V, { VR, VR, VR, RO }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME( "NETWORKDAYS.INTL" ) },
+    { ocNetWorkdays_MS,     255,    3,  5,  V, { RO_E, VR, VR, VR, RO }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME( "NETWORKDAYS.INTL" ) },
+    { ocWorkday_MS,         NOID,   2,  4,  V, { VR, VR, VR, RO }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME( "NETWORKDAYS.INTL" ) },
+    { ocWorkday_MS,         255,    3,  5,  V, { RO_E, VR, VR, VR, RO }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME( "NETWORKDAYS.INTL" ) },
+    EXC_FUNCENTRY_V_VR( ocCeil_ISO,         2,  2,  0,  "ISO.CEILING" )
 };
 
 
@@ -486,7 +489,7 @@ static const XclFunctionInfo saFuncTable_2010[] =
     EXC_FUNCENTRY_V_VR( ocNegBinomDist_MS,  4,  4,  0,  "NEGBINOM.DIST" ),
     EXC_FUNCENTRY_V_VR( ocZTest_MS,         2,  3,  0,  "Z.TEST" ),
     EXC_FUNCENTRY_V_VR( ocCeil_MS,          2,  2,  0,  "CEILING.PRECISE" ),
-    EXC_FUNCENTRY_V_VR( ocFloor_MS,         2,  2,  0,  "FLOOR.PRECISE" )
+    EXC_FUNCENTRY_V_VR( ocFloor_MS,         2,  2,  0,  "FLOOR.PRECISE" ),
 };
 
 /** Functions new in Excel 2013.
diff --git a/sc/source/filter/oox/formulabase.cxx b/sc/source/filter/oox/formulabase.cxx
index b44f605..25021e8 100644
--- a/sc/source/filter/oox/formulabase.cxx
+++ b/sc/source/filter/oox/formulabase.cxx
@@ -726,7 +726,9 @@ static const FunctionData saFuncTableOox[] =
     { "SUMIFS",                 "SUMIFS",               482,    NOID,   3,  MX, V, { RO, RO, VR }, FUNCFLAG_MACROCALL | FUNCFLAG_PARAMPAIRS },
     { "AVERAGEIF",              "AVERAGEIF",            483,    NOID,   2,  3,  V, { RO, VR, RO }, FUNCFLAG_MACROCALL },
     { "AVERAGEIFS",             "AVERAGEIFS",           484,    NOID,   3,  MX, V, { RO, RO, VR }, FUNCFLAG_MACROCALL | FUNCFLAG_PARAMPAIRS },
-    { "COM.MICROSOFT.ISO.CEILING",  "ISO.CEILING",     NOID,    NOID,   2,  2,  V, { VR }, FUNCFLAG_MACROCALL }
+    { "COM.MICROSOFT.ISO.CEILING",  "ISO.CEILING",     NOID,    NOID,   2,  2,  V, { VR }, FUNCFLAG_MACROCALL },
+    { "COM.MICROSOFT.NETWORKDAYS.INTL", "NETWORKDAYS.INTL", NOID, NOID, 2,  4,  V, { VR, VR, VR, RX }, FUNCFLAG_MACROCALL },
+    { "COM.MICROSOFT.WORKDAY.INTL",     "WORKDAY.INTL",     NOID, NOID, 2,  4,  V, { VR, VR, VR, RX }, FUNCFLAG_MACROCALL }
 };
 
 /** Functions new in Excel 2010.
@@ -802,7 +804,7 @@ static const FunctionData saFuncTable2010[] =
     { "COM.MICROSOFT.NEGBINOM.DIST",          "NEGBINOM.DIST",       NOID,   NOID,    4,  4,  V, { VR }, FUNCFLAG_MACROCALL_NEW },
     { "COM.MICROSOFT.Z.TEST",                 "Z.TEST",              NOID,   NOID,    2,  3,  V, { RX, VR }, FUNCFLAG_MACROCALL_NEW },
     { "COM.MICROSOFT.CEILING.PRECISE",        "CEILING.PRECISE",     NOID,   NOID,    2,  2,  V, { VR }, FUNCFLAG_MACROCALL_NEW },
-    { "COM.MICROSOFT.FLOOR.PRECISE",          "FLOOR.PRECISE",       NOID,   NOID,    2,  2,  V, { VR }, FUNCFLAG_MACROCALL_NEW }
+    { "COM.MICROSOFT.FLOOR.PRECISE",          "FLOOR.PRECISE",       NOID,   NOID,    2,  2,  V, { VR }, FUNCFLAG_MACROCALL_NEW },
 };
 
 /** Functions new in Excel 2013.
diff --git a/sc/source/ui/src/scfuncs.src b/sc/source/ui/src/scfuncs.src
index e3d1525..3e35e79 100644
--- a/sc/source/ui/src/scfuncs.src
+++ b/sc/source/ui/src/scfuncs.src
@@ -686,6 +686,102 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1
             Text [ en-US ] = "Method used to form differences: Type = 0 denotes US method (NASD), Type = 1 denotes the European method." ;
         };
     };
+     // -=*# Resource for function NETWORKDAYS.INTL #*=-
+    Resource SC_OPCODE_NETWORKDAYS_MS
+    {
+        String 1 // Description
+        {
+            Text [ en-US ] = "Returns the number of workdays between two dates using arguments to indicate weekenddays and holidays." ;
+        };
+        ExtraData =
+        {
+            0;
+            ID_FUNCTION_GRP_DATETIME;
+            U2S( HID_FUNC_NETWORKDAYS_MS );
+            4;  0;  0;  1;  1;
+            0;
+        };
+        String 2 // Name of Parameter 1
+        {
+            Text [ en-US ] = "Start Date" ;
+        };
+        String 3 // Description of Parameter 1
+        {
+            Text [ en-US ] = "Start date for calculation." ;
+        };
+        String 4 // Name of Parameter 2
+        {
+            Text [ en-US ] = "End Date" ;
+        };
+        String 5 // Description of Parameter 2
+        {
+            Text [ en-US ] = "End date for calculation." ;
+        };
+        String 6 // Name of Parameter 3
+        {
+            Text [ en-US ] = "number or string" ;
+        };
+        String 7 // Description of Parameter 3
+        {
+            Text [ en-US ] = "Optional number or string to indicate to indicate when weekends occur. When omitted, weekend is Saturday and Sunday." ;
+        };
+        String 8 // Name of Parameter 4
+        {
+            Text [ en-US ] = "array" ;
+        };
+        String 9 // Description of Parameter 4
+        {
+            Text [ en-US ] = "Optional set of one or more dates to be considered as holiday." ;
+        };
+    };
+     // -=*# Resource for function WORKDAY.INTL #*=-
+    Resource SC_OPCODE_WORKDAY_MS
+    {
+        String 1 // Description
+        {
+            Text [ en-US ] = "Returns the serial number of the date before or after a number of workdays using arguments to indicate weekenddays and holidays." ;
+        };
+        ExtraData =
+        {
+            0;
+            ID_FUNCTION_GRP_DATETIME;
+            U2S( HID_FUNC_WORKDAY_MS );
+            4;  0;  0;  1;  1;
+            0;
+        };
+        String 2 // Name of Parameter 1
+        {
+            Text [ en-US ] = "Start Date" ;
+        };
+        String 3 // Description of Parameter 1
+        {
+            Text [ en-US ] = "Start date for calculation." ;
+        };
+        String 4 // Name of Parameter 2
+        {
+            Text [ en-US ] = "Days" ;
+        };
+        String 5 // Description of Parameter 2
+        {
+            Text [ en-US ] = "RThe number of workdays before or after start date." ;
+        };
+        String 6 // Name of Parameter 3
+        {
+            Text [ en-US ] = "number or string" ;
+        };
+        String 7 // Description of Parameter 3
+        {
+            Text [ en-US ] = "Optional number or string to indicate to indicate when weekends occur. When omitted, weekend is Saturday and Sunday." ;
+        };
+        String 8 // Name of Parameter 4
+        {
+            Text [ en-US ] = "array" ;
+        };
+        String 9 // Description of Parameter 4
+        {
+            Text [ en-US ] = "Optional set of one or more dates to be considered as holiday." ;
+        };
+    };
      // -=*# Resource for function STUNDE #*=-
     Resource SC_OPCODE_GET_HOUR
     {


More information about the Libreoffice-commits mailing list