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>
This commit is contained in:
Winfried Donkers
2016-06-21 11:33:36 +02:00
committed by Eike Rathke
parent f4c68d3ad8
commit 696b515dcf
2 changed files with 51 additions and 5 deletions

View File

@@ -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();

View File

@@ -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++;