summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWinfried Donkers <winfrieddonkers@libreoffice.org>2016-06-21 11:33:36 +0200
committerEike Rathke <erack@redhat.com>2016-07-05 11:32:44 +0000
commit696b515dcfe9e003037370b99e3ba8d2c9c20c28 (patch)
treeca9b7f438b558f2c1d65aec155c21584c40009b6
parentf4c68d3ad80734e15d093eeee211519e97e2a8ec (diff)
tdf#100446 fix compatibilty issues with Excel.
Use cases added to the unit test showed various differences in results between Calc and Excel. The code changes makes Calc now return the same results as Excel, even if the result is somewhat unexpected. Change-Id: I348f7f2cc2c39a30f4db68dbed98b03de48f1ff5 Reviewed-on: https://gerrit.libreoffice.org/26544 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Eike Rathke <erack@redhat.com>
-rw-r--r--sc/source/core/inc/interpre.hxx2
-rw-r--r--sc/source/core/tool/interpr2.cxx54
2 files changed, 51 insertions, 5 deletions
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 1c7baa5c2ac3..3357f6b47a4f 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -686,7 +686,7 @@ void ScEasterSunday();
sal_uInt16 GetWeekendAndHolidayMasks( const sal_uInt8 nParamCount, const sal_uInt32 nNullDate,
::std::vector<double>& rSortArray, bool bWeekendMask[ 7 ] );
sal_uInt16 GetWeekendAndHolidayMasks_MS( const sal_uInt8 nParamCount, const sal_uInt32 nNullDate,
- ::std::vector<double>& rSortArray, bool bWeekendMask[ 7 ] );
+ ::std::vector<double>& rSortArray, bool bWeekendMask[ 7 ], bool bWorkdayFunction );
static inline sal_Int16 GetDayOfWeek( sal_Int32 n );
void ScNetWorkdays( bool bOOXML_Version );
void ScWorkday_MS();
diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx
index 548e842f372b..5a716c7cc163 100644
--- a/sc/source/core/tool/interpr2.cxx
+++ b/sc/source/core/tool/interpr2.cxx
@@ -387,7 +387,7 @@ sal_uInt16 ScInterpreter::GetWeekendAndHolidayMasks(
sal_uInt16 ScInterpreter::GetWeekendAndHolidayMasks_MS(
const sal_uInt8 nParamCount, const sal_uInt32 nNullDate, vector< double >& rSortArray,
- bool bWeekendMask[ 7 ] )
+ bool bWeekendMask[ 7 ], bool bWorkdayFunction )
{
sal_uInt16 nErr = 0;
OUString aWeekendDays;
@@ -400,7 +400,43 @@ sal_uInt16 ScInterpreter::GetWeekendAndHolidayMasks_MS(
}
if ( nParamCount >= 3 )
- aWeekendDays = GetString().getString();
+ {
+ if ( IsMissing() )
+ Pop();
+ else
+ {
+ switch ( GetStackType() )
+ {
+ case svDoubleRef :
+ case svExternalDoubleRef :
+ return errNoValue;
+ break;
+
+ default :
+ {
+ double fDouble;
+ svl::SharedString aSharedString;
+ bool bDouble = GetDoubleOrString( fDouble, aSharedString);
+ if ( bDouble )
+ {
+ if ( fDouble >= 1.0 && fDouble <= 17 )
+ aWeekendDays = OUString::number( fDouble );
+ else
+ return errNoValue;
+ }
+ else
+ {
+ if ( aSharedString.isEmpty() || aSharedString.getLength() != 7 ||
+ ( bWorkdayFunction && aSharedString.getString() == "1111111" ) )
+ return errNoValue;
+ else
+ aWeekendDays = aSharedString.getString();
+ }
+ }
+ break;
+ }
+ }
+ }
for ( int i = 0; i < 7; i++ )
bWeekendMask[ i] = false;
@@ -480,7 +516,7 @@ void ScInterpreter::ScNetWorkdays( bool bOOXML_Version )
if ( bOOXML_Version )
{
nErr = GetWeekendAndHolidayMasks_MS( nParamCount, nNullDate,
- nSortArray, bWeekendMask );
+ nSortArray, bWeekendMask, false );
}
else
{
@@ -538,7 +574,7 @@ void ScInterpreter::ScWorkday_MS()
Date aNullDate = *( pFormatter->GetNullDate() );
sal_uInt32 nNullDate = Date::DateToDays( aNullDate.GetDay(), aNullDate.GetMonth(), aNullDate.GetYear() );
sal_uInt16 nErr = GetWeekendAndHolidayMasks_MS( nParamCount, nNullDate,
- nSortArray, bWeekendMask );
+ nSortArray, bWeekendMask, true );
if ( nErr )
PushError( nErr );
else
@@ -560,10 +596,15 @@ void ScInterpreter::ScWorkday_MS()
if ( nDays > 0 )
{
size_t nRef = 0;
+ //skip holidays before/on start date
+ while ( nRef < nMax && nSortArray.at( nRef ) <= nDate )
+ nRef++;
+
while ( nDays )
{
while ( nRef < nMax && nSortArray.at( nRef ) < nDate )
nRef++;
+
if ( !( nRef < nMax && nSortArray.at( nRef ) == nDate ) || nRef >= nMax )
nDays--;
@@ -575,10 +616,15 @@ void ScInterpreter::ScWorkday_MS()
else
{
sal_Int16 nRef = nMax - 1;
+ //skip holidays after/on start date
+ while ( nRef >= 0 && nSortArray.at( nRef ) >= nDate )
+ nRef--;
+
while ( nDays )
{
while ( nRef >= 0 && nSortArray.at( nRef ) > nDate )
nRef--;
+
if ( !( nRef >= 0 && nSortArray.at( nRef ) == nDate ) || nRef < 0 )
nDays++;