Kaydet (Commit) 696b515d authored tarafından Winfried Donkers's avatar Winfried Donkers Kaydeden (comit) Eike Rathke

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/26544Reviewed-by: 's avatarEike Rathke <erack@redhat.com>
Tested-by: 's avatarEike Rathke <erack@redhat.com>
üst f4c68d3a
...@@ -686,7 +686,7 @@ void ScEasterSunday(); ...@@ -686,7 +686,7 @@ void ScEasterSunday();
sal_uInt16 GetWeekendAndHolidayMasks( const sal_uInt8 nParamCount, const sal_uInt32 nNullDate, sal_uInt16 GetWeekendAndHolidayMasks( const sal_uInt8 nParamCount, const sal_uInt32 nNullDate,
::std::vector<double>& rSortArray, bool bWeekendMask[ 7 ] ); ::std::vector<double>& rSortArray, bool bWeekendMask[ 7 ] );
sal_uInt16 GetWeekendAndHolidayMasks_MS( const sal_uInt8 nParamCount, const sal_uInt32 nNullDate, 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 ); static inline sal_Int16 GetDayOfWeek( sal_Int32 n );
void ScNetWorkdays( bool bOOXML_Version ); void ScNetWorkdays( bool bOOXML_Version );
void ScWorkday_MS(); void ScWorkday_MS();
......
...@@ -387,7 +387,7 @@ sal_uInt16 ScInterpreter::GetWeekendAndHolidayMasks( ...@@ -387,7 +387,7 @@ sal_uInt16 ScInterpreter::GetWeekendAndHolidayMasks(
sal_uInt16 ScInterpreter::GetWeekendAndHolidayMasks_MS( sal_uInt16 ScInterpreter::GetWeekendAndHolidayMasks_MS(
const sal_uInt8 nParamCount, const sal_uInt32 nNullDate, vector< double >& rSortArray, const sal_uInt8 nParamCount, const sal_uInt32 nNullDate, vector< double >& rSortArray,
bool bWeekendMask[ 7 ] ) bool bWeekendMask[ 7 ], bool bWorkdayFunction )
{ {
sal_uInt16 nErr = 0; sal_uInt16 nErr = 0;
OUString aWeekendDays; OUString aWeekendDays;
...@@ -400,7 +400,43 @@ sal_uInt16 ScInterpreter::GetWeekendAndHolidayMasks_MS( ...@@ -400,7 +400,43 @@ sal_uInt16 ScInterpreter::GetWeekendAndHolidayMasks_MS(
} }
if ( nParamCount >= 3 ) 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++ ) for ( int i = 0; i < 7; i++ )
bWeekendMask[ i] = false; bWeekendMask[ i] = false;
...@@ -480,7 +516,7 @@ void ScInterpreter::ScNetWorkdays( bool bOOXML_Version ) ...@@ -480,7 +516,7 @@ void ScInterpreter::ScNetWorkdays( bool bOOXML_Version )
if ( bOOXML_Version ) if ( bOOXML_Version )
{ {
nErr = GetWeekendAndHolidayMasks_MS( nParamCount, nNullDate, nErr = GetWeekendAndHolidayMasks_MS( nParamCount, nNullDate,
nSortArray, bWeekendMask ); nSortArray, bWeekendMask, false );
} }
else else
{ {
...@@ -538,7 +574,7 @@ void ScInterpreter::ScWorkday_MS() ...@@ -538,7 +574,7 @@ void ScInterpreter::ScWorkday_MS()
Date aNullDate = *( pFormatter->GetNullDate() ); Date aNullDate = *( pFormatter->GetNullDate() );
sal_uInt32 nNullDate = Date::DateToDays( aNullDate.GetDay(), aNullDate.GetMonth(), aNullDate.GetYear() ); sal_uInt32 nNullDate = Date::DateToDays( aNullDate.GetDay(), aNullDate.GetMonth(), aNullDate.GetYear() );
sal_uInt16 nErr = GetWeekendAndHolidayMasks_MS( nParamCount, nNullDate, sal_uInt16 nErr = GetWeekendAndHolidayMasks_MS( nParamCount, nNullDate,
nSortArray, bWeekendMask ); nSortArray, bWeekendMask, true );
if ( nErr ) if ( nErr )
PushError( nErr ); PushError( nErr );
else else
...@@ -560,10 +596,15 @@ void ScInterpreter::ScWorkday_MS() ...@@ -560,10 +596,15 @@ void ScInterpreter::ScWorkday_MS()
if ( nDays > 0 ) if ( nDays > 0 )
{ {
size_t nRef = 0; size_t nRef = 0;
//skip holidays before/on start date
while ( nRef < nMax && nSortArray.at( nRef ) <= nDate )
nRef++;
while ( nDays ) while ( nDays )
{ {
while ( nRef < nMax && nSortArray.at( nRef ) < nDate ) while ( nRef < nMax && nSortArray.at( nRef ) < nDate )
nRef++; nRef++;
if ( !( nRef < nMax && nSortArray.at( nRef ) == nDate ) || nRef >= nMax ) if ( !( nRef < nMax && nSortArray.at( nRef ) == nDate ) || nRef >= nMax )
nDays--; nDays--;
...@@ -575,10 +616,15 @@ void ScInterpreter::ScWorkday_MS() ...@@ -575,10 +616,15 @@ void ScInterpreter::ScWorkday_MS()
else else
{ {
sal_Int16 nRef = nMax - 1; sal_Int16 nRef = nMax - 1;
//skip holidays after/on start date
while ( nRef >= 0 && nSortArray.at( nRef ) >= nDate )
nRef--;
while ( nDays ) while ( nDays )
{ {
while ( nRef >= 0 && nSortArray.at( nRef ) > nDate ) while ( nRef >= 0 && nSortArray.at( nRef ) > nDate )
nRef--; nRef--;
if ( !( nRef >= 0 && nSortArray.at( nRef ) == nDate ) || nRef < 0 ) if ( !( nRef >= 0 && nSortArray.at( nRef ) == nDate ) || nRef < 0 )
nDays++; nDays++;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment