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& rSortArray, bool bWeekendMask[ 7 ] ); sal_uInt16 GetWeekendAndHolidayMasks_MS( const sal_uInt8 nParamCount, const sal_uInt32 nNullDate, - ::std::vector& rSortArray, bool bWeekendMask[ 7 ] ); + ::std::vector& 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++;