diff options
author | Winfried Donkers <winfrieddonkers@libreoffice.org> | 2016-06-21 11:33:36 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2016-07-05 11:32:44 +0000 |
commit | 696b515dcfe9e003037370b99e3ba8d2c9c20c28 (patch) | |
tree | ca9b7f438b558f2c1d65aec155c21584c40009b6 /sc | |
parent | f4c68d3ad80734e15d093eeee211519e97e2a8ec (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>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/source/core/inc/interpre.hxx | 2 | ||||
-rw-r--r-- | sc/source/core/tool/interpr2.cxx | 54 |
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++; |