30 #include <osl/diagnose.h>
36 #include <document.hxx>
38 #include <unitconv.hxx>
41 #include <tokenarray.hxx>
43 #include <stlsheet.hxx>
46 #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
54 #define SCdEpsilon 1.0E-7
61 if ( nYear < 100 && !bStrict )
62 nYear = pFormatter->ExpandTwoDigitYear( nYear );
76 nY = nYear + (nMonth-1) / 12;
77 nM = ((nMonth-1) % 12) + 1;
81 nY = nYear + (nMonth-12) / 12;
82 nM = 12 - (-nMonth) % 12;
86 Date aDate( nD, nM, nY);
90 return static_cast<double>(aDate - pFormatter->GetNullDate());
100 nFuncFmtType = SvNumFormatType::DATE;
102 tools::Long nDiff = aActDate - pFormatter->GetNullDate();
103 PushDouble(static_cast<double>(nDiff));
108 nFuncFmtType = SvNumFormatType::DATETIME;
110 tools::Long nDiff = aActTime - pFormatter->GetNullDate();
115 PushDouble( static_cast<double>(nDiff) + fTime );
120 Date aDate = pFormatter->GetNullDate();
122 PushDouble( static_cast<double>(aDate.
GetYear()) );
127 Date aDate = pFormatter->GetNullDate();
129 PushDouble( static_cast<double>(aDate.
GetMonth()) );
134 Date aDate = pFormatter->GetNullDate();
136 PushDouble(static_cast<double>(aDate.
GetDay()));
141 sal_uInt16 nHour, nMinute, nSecond;
142 double fFractionOfSecond;
144 PushDouble( nMinute);
149 sal_uInt16 nHour, nMinute, nSecond;
150 double fFractionOfSecond;
152 if ( fFractionOfSecond >= 0.5 )
153 nSecond = ( nSecond + 1 ) % 60;
154 PushDouble( nSecond );
160 sal_uInt16 nHour, nMinute, nSecond;
161 double fFractionOfSecond;
168 OUString aInputString =
GetString().getString();
169 sal_uInt32 nFIndex = 0;
171 if (pFormatter->IsNumberFormat(aInputString, nFIndex, fVal))
174 if (eType == SvNumFormatType::DATE || eType == SvNumFormatType::DATETIME)
176 nFuncFmtType = SvNumFormatType::DATE;
177 PushDouble(::rtl::math::approxFloor(fVal));
180 PushIllegalArgument();
183 PushIllegalArgument();
189 if ( !MustHaveParamCount( nParamCount, 1, 2 ) )
193 if (nParamCount == 2)
198 Date aDate = pFormatter->GetNullDate();
222 if (nVal < nFlag - 11)
228 SetError( FormulaError::IllegalArgument);
235 if ( MustHaveParamCount( GetByte(), 2 ) )
237 sal_Int16 nFlag = GetInt16();
239 Date aDate = pFormatter->GetNullDate();
248 if ( !MustHaveParamCount( nParamCount, 1, 2 ) )
252 if (nParamCount == 1)
257 Date aDate = pFormatter->GetNullDate();
260 sal_Int32 nMinimumNumberOfDaysInWeek;
266 nMinimumNumberOfDaysInWeek = 1;
270 nMinimumNumberOfDaysInWeek = 1;
279 eFirstDayOfWeek =
static_cast<DayOfWeek>( nFlag - 11 );
280 nMinimumNumberOfDaysInWeek = 1;
286 nMinimumNumberOfDaysInWeek = 4;
289 PushIllegalArgument();
292 PushInt( static_cast<int>(aDate.
GetWeekOfYear( eFirstDayOfWeek, nMinimumNumberOfDaysInWeek )) );
297 if ( MustHaveParamCount( GetByte(), 1 ) )
299 Date aDate = pFormatter->GetNullDate();
307 nFuncFmtType = SvNumFormatType::DATE;
308 if ( !MustHaveParamCount( GetByte(), 1 ) )
311 sal_Int16 nDay, nMonth, nYear;
313 if (nGlobalError != FormulaError::NONE)
315 PushError( nGlobalError);
319 nYear = pFormatter->ExpandTwoDigitYear( nYear );
320 if (nYear < 1583 || nYear > 9956)
323 PushIllegalArgument();
327 int B,
C,
D,
E,
F,G,
H,I,K,L,
M,
N,O;
329 B =
int(nYear / 100);
333 F =
int((B + 8) / 25);
334 G =
int((B - F + 1) / 3);
335 H = (19 * N + B - D - G + 15) % 30;
338 L = (32 + 2 * E + 2 * I - H - K) % 7;
339 M =
int((N + 11 * H + 22 * L) / 451);
340 O = H + L - 7 * M + 114;
341 nDay = sal::static_int_cast<sal_Int16>( O % 31 + 1 );
342 nMonth = sal::static_int_cast<sal_Int16>(
int(O / 31) );
343 PushDouble( GetDateSerial( nYear, nMonth, nDay,
true ) );
348 bool bWeekendMask[ 7 ] )
350 if ( nParamCount == 4 )
352 vector< double > nWeekendDays;
353 GetNumberSequenceArray( 1, nWeekendDays,
false );
354 if ( nGlobalError != FormulaError::NONE )
358 if ( nWeekendDays.size() != 7 )
359 return FormulaError::IllegalArgument;
362 for (
int i = 0;
i < 7;
i++ )
363 bWeekendMask[
i ] = static_cast<bool>(nWeekendDays[ (
i == 6 ? 0 :
i + 1 ) ]);
368 for (
int i = 0;
i < 7;
i++ )
369 bWeekendMask[
i] =
false;
372 bWeekendMask[
SUNDAY ] =
true;
375 if ( nParamCount >= 3 )
377 GetSortArray( 1, rSortArray,
nullptr,
true,
true );
378 size_t nMax = rSortArray.size();
379 for (
size_t i = 0;
i < nMax;
i++ )
380 rSortArray.at(
i ) = ::rtl::math::approxFloor( rSortArray.at(
i ) ) + nNullDate;
388 bool bWeekendMask[ 7 ],
bool bWorkdayFunction )
391 OUString aWeekendDays;
392 if ( nParamCount == 4 )
394 GetSortArray( 1, rSortArray,
nullptr,
true,
true );
395 size_t nMax = rSortArray.size();
396 for (
size_t i = 0;
i < nMax;
i++ )
397 rSortArray.at(
i ) = ::rtl::math::approxFloor( rSortArray.at(
i ) ) + nNullDate;
400 if ( nParamCount >= 3 )
406 switch ( GetStackType() )
410 return FormulaError::NoValue;
416 bool bDouble = GetDoubleOrString( fDouble, aSharedString);
419 if ( fDouble >= 1.0 && fDouble <= 17 )
420 aWeekendDays = OUString::number( fDouble );
422 return FormulaError::NoValue;
427 ( bWorkdayFunction && aSharedString.
getString() ==
"1111111" ) )
428 return FormulaError::NoValue;
430 aWeekendDays = aSharedString.
getString();
438 for (
int i = 0;
i < 7;
i++ )
439 bWeekendMask[
i] =
false;
441 if ( aWeekendDays.isEmpty() )
444 bWeekendMask[
SUNDAY ] =
true;
448 switch ( aWeekendDays.getLength() )
452 switch ( aWeekendDays[ 0 ] )
454 case '1' : bWeekendMask[
SATURDAY ] =
true; bWeekendMask[
SUNDAY ] =
true;
break;
455 case '2' : bWeekendMask[
SUNDAY ] =
true; bWeekendMask[
MONDAY ] =
true;
break;
456 case '3' : bWeekendMask[
MONDAY ] =
true; bWeekendMask[
TUESDAY ] =
true;
break;
457 case '4' : bWeekendMask[
TUESDAY ] =
true; bWeekendMask[
WEDNESDAY ] =
true;
break;
458 case '5' : bWeekendMask[
WEDNESDAY ] =
true; bWeekendMask[
THURSDAY ] =
true;
break;
459 case '6' : bWeekendMask[
THURSDAY ] =
true; bWeekendMask[
FRIDAY ] =
true;
break;
460 case '7' : bWeekendMask[
FRIDAY ] =
true; bWeekendMask[
SATURDAY ] =
true;
break;
461 default : nErr = FormulaError::IllegalArgument;
break;
466 if ( aWeekendDays[ 0 ] ==
'1' )
468 switch ( aWeekendDays[ 1 ] )
470 case '1' : bWeekendMask[
SUNDAY ] =
true;
break;
471 case '2' : bWeekendMask[
MONDAY ] =
true;
break;
472 case '3' : bWeekendMask[
TUESDAY ] =
true;
break;
473 case '4' : bWeekendMask[
WEDNESDAY ] =
true;
break;
474 case '5' : bWeekendMask[
THURSDAY ] =
true;
break;
475 case '6' : bWeekendMask[
FRIDAY ] =
true;
break;
476 case '7' : bWeekendMask[
SATURDAY ] =
true;
break;
477 default : nErr = FormulaError::IllegalArgument;
break;
481 nErr = FormulaError::IllegalArgument;
485 for (
int i = 0;
i < 7 && nErr == FormulaError::NONE;
i++ )
487 switch ( aWeekendDays[
i ] )
489 case '0' : bWeekendMask[ i ] =
false;
break;
490 case '1' : bWeekendMask[ i ] =
true;
break;
491 default : nErr = FormulaError::IllegalArgument;
break;
496 nErr = FormulaError::IllegalArgument;
506 if ( !MustHaveParamCount( nParamCount, 2, 4 ) )
509 vector<double> nSortArray;
510 bool bWeekendMask[ 7 ];
511 const Date& rNullDate = pFormatter->GetNullDate();
514 if ( bOOXML_Version )
516 nErr = GetWeekendAndHolidayMasks_MS( nParamCount, nNullDate,
517 nSortArray, bWeekendMask,
false );
521 nErr = GetWeekendAndHolidayMasks( nParamCount, nNullDate,
522 nSortArray, bWeekendMask );
524 if ( nErr != FormulaError::NONE )
528 sal_uInt32 nDate2 = GetUInt32();
529 sal_uInt32 nDate1 = GetUInt32();
532 PushIllegalArgument();
540 bool bReverse = ( nDate1 > nDate2 );
543 sal_uInt32 nTemp = nDate1;
547 size_t nMax = nSortArray.size();
548 while ( nDate1 <= nDate2 )
552 while ( nRef < nMax && nSortArray.at( nRef ) < nDate1 )
554 if ( nRef >= nMax || nSortArray.at( nRef ) != nDate1 )
559 PushDouble( static_cast<double>( bReverse ? -nCnt : nCnt ) );
566 if ( !MustHaveParamCount( nParamCount, 2, 4 ) )
569 nFuncFmtType = SvNumFormatType::DATE;
570 vector<double> nSortArray;
571 bool bWeekendMask[ 7 ];
572 const Date& rNullDate = pFormatter->GetNullDate();
574 FormulaError nErr = GetWeekendAndHolidayMasks_MS( nParamCount, nNullDate,
575 nSortArray, bWeekendMask,
true );
576 if ( nErr != FormulaError::NONE )
580 sal_Int32 nDays = GetInt32();
581 sal_uInt32 nDate = GetUInt32();
582 if (nGlobalError != FormulaError::NONE || (nDate >
SAL_MAX_UINT32 - nNullDate))
584 PushIllegalArgument();
590 PushDouble( static_cast<double>( nDate - nNullDate ) );
593 size_t nMax = nSortArray.size();
605 while ( nRef < nMax && nSortArray.at( nRef ) < nDate )
608 if ( nRef >= nMax || nSortArray.at( nRef ) != nDate || nRef >= nMax )
614 sal_Int16
nRef = nMax - 1;
623 while ( nRef >= 0 && nSortArray.at( nRef ) > nDate )
626 if (nRef < 0 || nSortArray.at(nRef) != nDate)
630 PushDouble( static_cast<double>( nDate - nNullDate ) );
637 nFuncFmtType = SvNumFormatType::DATE;
638 if ( !MustHaveParamCount( GetByte(), 3 ) )
641 sal_Int16 nDay = GetInt16();
642 sal_Int16 nMonth = GetInt16();
644 SetError( FormulaError::ParameterExpected);
645 sal_Int16 nYear = GetInt16();
646 if (nGlobalError != FormulaError::NONE || nYear < 0)
647 PushIllegalArgument();
650 PushDouble(GetDateSerial(nYear, nMonth, nDay,
false));
656 nFuncFmtType = SvNumFormatType::TIME;
657 if ( MustHaveParamCount( GetByte(), 3 ) )
659 double fSec = GetDouble();
660 double fMin = GetDouble();
661 double fHour = GetDouble();
664 PushIllegalArgument();
672 if ( MustHaveParamCount( GetByte(), 2 ) )
674 double fDate2 = GetDouble();
675 double fDate1 = GetDouble();
676 PushDouble(fDate1 - fDate2);
708 if ( !MustHaveParamCount( nParamCount, 2, 3 ) )
712 if (nParamCount == 3)
716 sal_Int32 nDate2 = GetInt32();
717 sal_Int32 nDate1 = GetInt32();
718 if (nGlobalError != FormulaError::NONE)
719 PushError( nGlobalError);
725 if (bFlag && (nDate2 < nDate1))
734 Date aDate1 = pFormatter->GetNullDate();
736 Date aDate2 = pFormatter->GetNullDate();
738 if (aDate1.
GetDay() == 31)
744 switch ( aDate1.
GetDay() )
756 if (aDate2.
GetDay() == 31)
760 if (aDate1.
GetDay() == 30)
766 PushDouble( static_cast<double>(nSign) *
767 ( static_cast<double>(aDate2.
GetDay()) + static_cast<double>(aDate2.
GetMonth()) * 30.0 +
768 static_cast<double>(aDate2.
GetYear()) * 360.0
769 - static_cast<double>(aDate1.
GetDay()) - static_cast<double>(aDate1.
GetMonth()) * 30.0
770 - static_cast<double>(aDate1.
GetYear()) * 360.0) );
777 if ( !MustHaveParamCount( GetByte(), 3 ) )
780 OUString aInterval =
GetString().getString();
781 sal_Int32 nDate2 = GetInt32();
782 sal_Int32 nDate1 = GetInt32();
784 if (nGlobalError != FormulaError::NONE)
786 PushError( nGlobalError);
793 PushIllegalArgument();
797 double dd = nDate2 - nDate1;
799 if (dd == 0.0 || aInterval.equalsIgnoreAsciiCase(
"d" ))
806 sal_uInt16 d1, m1, d2, m2;
808 Date aDate1( pFormatter->GetNullDate());
810 y1 = aDate1.GetYear();
811 m1 = aDate1.GetMonth();
812 d1 = aDate1.GetDay();
813 Date aDate2( pFormatter->GetNullDate());
815 y2 = aDate2.GetYear();
816 m2 = aDate2.GetMonth();
817 d2 = aDate2.GetDay();
820 if (y1 < 0 && y2 > 0)
822 else if (y1 > 0 && y2 < 0)
825 if ( aInterval.equalsIgnoreAsciiCase(
"m" ) )
828 int md = m2 - m1 + 12 * (y2 - y1);
833 else if ( aInterval.equalsIgnoreAsciiCase(
"y" ) )
839 if (m2 > m1 || (m2 == m1 && d2 >= d1))
852 else if ( aInterval.equalsIgnoreAsciiCase(
"md" ) )
877 aDate1.SetYear( y2 == 1 ? -1 : y2 - 1 );
878 aDate1.SetMonth( 12 );
882 aDate1.SetYear( y2 );
883 aDate1.SetMonth( m2 - 1 );
886 nd = aDate2 - aDate1;
890 else if ( aInterval.equalsIgnoreAsciiCase(
"ym" ) )
893 int md = m2 - m1 + 12 * (y2 - y1);
899 else if ( aInterval.equalsIgnoreAsciiCase(
"yd" ) )
904 if (m2 > m1 || (m2 == m1 && d2 >= d1))
905 aDate1.SetYear( y2 );
907 aDate1.SetYear( y2 - 1 );
917 double fd = aDate2 - aDate1;
921 PushIllegalArgument();
926 OUString aInputString =
GetString().getString();
927 sal_uInt32 nFIndex = 0;
929 if (pFormatter->IsNumberFormat(aInputString, nFIndex, fVal, SvNumInputOptions::LAX_TIME))
932 if (eType == SvNumFormatType::TIME || eType == SvNumFormatType::DATETIME)
934 nFuncFmtType = SvNumFormatType::TIME;
935 double fDateVal = rtl::math::approxFloor(fVal);
936 double fTimeVal = fVal - fDateVal;
937 PushDouble(fTimeVal);
940 PushIllegalArgument();
943 PushIllegalArgument();
948 double fVal = GetDouble();
959 PushDouble(fabs(GetDouble()));
964 PushDouble(::rtl::math::approxFloor(GetDouble()));
970 if ( !MustHaveParamCount( nParamCount, 1, 2 ) )
974 if (nParamCount == 1)
975 fVal = ::rtl::math::round( GetDouble(), 0, eMode );
978 sal_Int16 nDec = GetInt16();
979 double fX = GetDouble();
980 if ( nGlobalError != FormulaError::NONE || nDec < -20 || nDec > 20 )
981 PushIllegalArgument();
984 if ( ( eMode == rtl_math_RoundingMode_Down ||
985 eMode == rtl_math_RoundingMode_Up ) &&
986 nDec < 12 && fmod( fX, 1.0 ) != 0.0 )
992 RoundSignificant( fX, 12, fRes );
993 fVal = ::rtl::math::round( fRes, nDec, eMode );
996 fVal = ::rtl::math::round( fX, nDec, eMode );
1004 RoundNumber( rtl_math_RoundingMode_Corrected );
1009 RoundNumber( rtl_math_RoundingMode_Down );
1014 RoundNumber( rtl_math_RoundingMode_Up );
1019 bool bNegVal = ( fX < 0 );
1022 double fTemp = ::rtl::math::approxFloor( log10( fX ) ) + 1.0 - fDigits;
1023 fRes = ::rtl::math::round( pow(10.0, -fTemp ) * fX ) * pow( 10.0, fTemp );
1031 if ( !MustHaveParamCount( GetByte(), 2 ) )
1034 double fDigits = ::rtl::math::approxFloor( GetDouble() );
1035 double fX = GetDouble();
1036 if ( nGlobalError != FormulaError::NONE || fDigits < 1.0 )
1038 PushIllegalArgument();
1047 RoundSignificant( fX, fDigits, fRes );
1062 if ( !MustHaveParamCount( nParamCount, 1, 3 ) )
1065 bool bAbs = nParamCount == 3 && GetBool();
1067 if ( nParamCount == 1 )
1070 fDec = ( fVal < 0 ? -1 : 1 );
1074 bool bArgumentMissing = IsMissing();
1077 if ( bArgumentMissing )
1078 fDec = ( fVal < 0 ? -1 : 1 );
1080 if ( fVal == 0 || fDec == 0.0 )
1084 if ( bODFF && fVal * fDec < 0 )
1085 PushIllegalArgument();
1088 if ( fVal * fDec < 0.0 )
1091 if ( !bAbs && fVal < 0.0 )
1092 PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec );
1094 PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec );
1102 if ( !MustHaveParamCount( nParamCount, 2 ) )
1105 double fDec = GetDouble();
1106 double fVal = GetDouble();
1107 if ( fVal == 0 || fDec == 0.0 )
1109 else if ( fVal * fDec > 0 )
1110 PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec );
1111 else if ( fVal < 0.0 )
1112 PushDouble(::rtl::math::approxFloor( fVal / -fDec ) * -fDec );
1114 PushIllegalArgument();
1120 if ( !MustHaveParamCount( nParamCount, 1, 2 ) )
1124 if ( nParamCount == 1 )
1131 fDec = fabs( GetDoubleWithDefault( 1.0 ));
1134 if ( fDec == 0.0 || fVal == 0.0 )
1137 PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec );
1150 if ( !MustHaveParamCount( nParamCount, 1, 3 ) )
1153 bool bAbs = ( nParamCount == 3 && GetBool() );
1155 if ( nParamCount == 1 )
1158 fDec = ( fVal < 0 ? -1 : 1 );
1162 bool bArgumentMissing = IsMissing();
1165 if ( bArgumentMissing )
1166 fDec = ( fVal < 0 ? -1 : 1 );
1168 if ( fDec == 0.0 || fVal == 0.0 )
1172 if ( bODFF && ( fVal * fDec < 0.0 ) )
1173 PushIllegalArgument();
1176 if ( fVal * fDec < 0.0 )
1179 if ( !bAbs && fVal < 0.0 )
1180 PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec );
1182 PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec );
1190 if ( !MustHaveParamCount( nParamCount, 2 ) )
1193 double fDec = GetDouble();
1194 double fVal = GetDouble();
1198 else if ( fVal * fDec > 0 )
1199 PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec );
1200 else if ( fDec == 0 )
1201 PushIllegalArgument();
1202 else if ( fVal < 0.0 )
1203 PushDouble(::rtl::math::approxCeil( fVal / -fDec ) * -fDec );
1205 PushIllegalArgument();
1211 if ( !MustHaveParamCount( nParamCount, 1, 2 ) )
1215 if ( nParamCount == 1 )
1222 fDec = fabs( GetDoubleWithDefault( 1.0 ) );
1225 if ( fDec == 0.0 || fVal == 0.0 )
1228 PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec );
1233 double fVal = GetDouble();
1235 PushDouble(::rtl::math::approxFloor(fVal/2.0) * 2.0);
1237 PushDouble(::rtl::math::approxCeil(fVal/2.0) * 2.0);
1242 double fVal = GetDouble();
1245 fVal = ::rtl::math::approxCeil(fVal);
1246 if (fmod(fVal, 2.0) == 0.0)
1251 fVal = ::rtl::math::approxFloor(fVal);
1252 if (fmod(fVal, 2.0) == 0.0)
1260 if ( MustHaveParamCount( GetByte(), 2 ) )
1262 double fVal2 = GetDouble();
1263 double fVal1 = GetDouble();
1264 PushDouble(atan2(fVal2, fVal1));
1271 if ( !MustHaveParamCount( nParamCount, 1, 2 ) )
1275 if (nParamCount == 2)
1276 fBase = GetDouble();
1279 double fVal = GetDouble();
1280 if (fVal > 0.0 && fBase > 0.0 && fBase != 1.0)
1281 PushDouble(
log(fVal) /
log(fBase));
1283 PushIllegalArgument();
1288 double fVal = GetDouble();
1290 PushDouble(
log(fVal));
1292 PushIllegalArgument();
1297 double fVal = GetDouble();
1299 PushDouble(log10(fVal));
1301 PushIllegalArgument();
1306 nFuncFmtType = SvNumFormatType::CURRENCY;
1308 if ( !MustHaveParamCountMin( nParamCount, 2) )
1313 ReverseStack( nParamCount);
1314 if (nGlobalError == FormulaError::NONE)
1316 double fCount = 1.0;
1317 double fRate = GetDouble();
1319 size_t nRefInList = 0;
1321 while (nParamCount-- > 0)
1323 switch (GetStackType())
1327 fVal += (GetDouble() / pow(1.0 + fRate, fCount));
1334 PopSingleRef( aAdr );
1338 double fCellVal = GetCellValue(aAdr, aCell);
1339 fVal += (fCellVal / pow(1.0 + fRate, fCount));
1349 PopDoubleRef( aRange, nParamCount, nRefInList);
1351 while ((nErr == FormulaError::NONE) && aValIter.
GetNext(fCellVal, nErr))
1353 fVal += (fCellVal / pow(1.0 + fRate, fCount));
1356 if ( nErr != FormulaError::NONE )
1368 pMat->GetDimensions(nC, nR);
1369 if (nC == 0 || nR == 0)
1371 PushIllegalArgument();
1377 for (
SCSIZE j = 0; j < nC; j++ )
1379 for (
SCSIZE k = 0; k < nR; ++k)
1381 if (!pMat->IsValue(j,k))
1383 PushIllegalArgument();
1386 fx = pMat->GetDouble(j,k);
1387 fVal += (fx / pow(1.0 + fRate, fCount));
1395 default :
SetError(FormulaError::IllegalParameter);
break;
1405 nFuncFmtType = SvNumFormatType::PERCENT;
1407 if ( !MustHaveParamCount( nParamCount, 1, 2 ) )
1409 if (nParamCount == 2)
1410 fEstimated = GetDouble();
1413 sal_uInt16 sPos = sp;
1416 if (fEstimated == -1.0)
1420 switch (GetStackType())
1426 PushIllegalParameter();
1430 const sal_uInt16 nIterationsMax = 20;
1431 sal_uInt16 nItCount = 0;
1433 while (fEps >
SCdEpsilon && nItCount < nIterationsMax)
1437 double fDenom = 0.0;
1439 PopDoubleRef( aRange );
1441 if (aValIter.
GetFirst(fValue, nErr))
1443 double fCount = 0.0;
1444 fNom += fValue / pow(1.0+x,fCount);
1445 fDenom += -fCount * fValue / pow(1.0+x,fCount+1.0);
1447 while ((nErr == FormulaError::NONE) && aValIter.
GetNext(fValue, nErr))
1449 fNom += fValue / pow(1.0+x,fCount);
1450 fDenom += -fCount * fValue / pow(1.0+x,fCount+1.0);
1455 double xNew = x - fNom / fDenom;
1457 fEps = fabs(xNew - x);
1460 if (fEstimated == 0.0 && fabs(x) <
SCdEpsilon)
1465 PushError( FormulaError::NoConvergence);
1470 nFuncFmtType = SvNumFormatType::PERCENT;
1471 if ( !MustHaveParamCount( GetByte(), 3 ) )
1474 double fRate1_reinvest = GetDouble() + 1;
1475 double fRate1_invest = GetDouble() + 1;
1481 bool bIsMatrix =
false;
1482 switch ( GetStackType() )
1485 PopDoubleRef( aRange );
1494 pMat->GetDimensions( nC, nR );
1495 if ( nC == 0 || nR == 0 )
1496 SetError( FormulaError::IllegalArgument );
1500 SetError( FormulaError::IllegalArgument );
1504 SetError( FormulaError::IllegalParameter );
1508 if ( nGlobalError != FormulaError::NONE )
1509 PushError( nGlobalError );
1512 double fNPV_reinvest = 0.0;
1513 double fPow_reinvest = 1.0;
1514 double fNPV_invest = 0.0;
1515 double fPow_invest = 1.0;
1517 bool bHasPosValue =
false;
1518 bool bHasNegValue =
false;
1523 for (
SCSIZE j = 0; j < nC; j++ )
1525 for (
SCSIZE k = 0; k < nR; ++k )
1527 if ( !pMat->IsValue( j, k ) )
1529 fX = pMat->GetDouble( j, k );
1530 if ( nGlobalError != FormulaError::NONE )
1535 bHasPosValue =
true;
1536 fNPV_reinvest += fX * fPow_reinvest;
1538 else if ( fX < 0.0 )
1540 bHasNegValue =
true;
1541 fNPV_invest += fX * fPow_invest;
1543 fPow_reinvest /= fRate1_reinvest;
1544 fPow_invest /= fRate1_invest;
1555 bool bLoop = aValIter.
GetFirst( fCellValue, nIterError );
1558 if( fCellValue > 0.0 )
1560 bHasPosValue =
true;
1561 fNPV_reinvest += fCellValue * fPow_reinvest;
1563 else if( fCellValue < 0.0 )
1565 bHasNegValue =
true;
1566 fNPV_invest += fCellValue * fPow_invest;
1568 fPow_reinvest /= fRate1_reinvest;
1569 fPow_invest /= fRate1_invest;
1572 bLoop = aValIter.
GetNext( fCellValue, nIterError );
1575 if ( nIterError != FormulaError::NONE )
1578 if ( !( bHasPosValue && bHasNegValue ) )
1579 SetError( FormulaError::IllegalArgument );
1581 if ( nGlobalError != FormulaError::NONE )
1582 PushError( nGlobalError );
1585 double fResult = -fNPV_reinvest / fNPV_invest;
1586 fResult *= pow( fRate1_reinvest, static_cast<double>( nCount - 1 ) );
1587 fResult = pow( fResult,
div( 1.0, (nCount - 1)) );
1588 PushDouble( fResult - 1.0 );
1595 if( MustHaveParamCount( GetByte(), 4 ) )
1597 double fInvest = GetDouble();
1598 double fTotal = GetDouble();
1599 double fPeriod = GetDouble();
1600 double fRate = GetDouble();
1602 if( nGlobalError != FormulaError::NONE )
1603 PushError( nGlobalError);
1605 PushDouble( fInvest * fRate * (fPeriod / fTotal - 1.0) );
1611 double fFv,
bool bPayInAdvance)
1615 fPv = fFv + fPmt * fNper;
1619 fPv = (fFv * pow(1.0 + fRate, -fNper))
1620 + (fPmt * (1.0 - pow(1.0 + fRate, -fNper + 1.0)) / fRate)
1623 fPv = (fFv * pow(1.0 + fRate, -fNper))
1624 + (fPmt * (1.0 - pow(1.0 + fRate, -fNper)) / fRate);
1631 nFuncFmtType = SvNumFormatType::CURRENCY;
1632 double fPmt, fNper, fRate, fFv = 0;
1633 bool bPayInAdvance =
false;
1635 if ( !MustHaveParamCount( nParamCount, 3, 5 ) )
1637 if (nParamCount == 5)
1638 bPayInAdvance = GetBool();
1639 if (nParamCount >= 4)
1642 fNper = GetDouble();
1643 fRate = GetDouble();
1644 PushDouble(ScGetPV(fRate, fNper, fPmt, fFv, bPayInAdvance));
1649 nFuncFmtType = SvNumFormatType::CURRENCY;
1650 if ( MustHaveParamCount( GetByte(), 4 ) )
1652 double fPer = GetDouble();
1653 double fLife = GetDouble();
1654 double fSalvage = GetDouble();
1655 double fCost = GetDouble();
1656 double fSyd = ((fCost - fSalvage) * (fLife - fPer + 1.0)) /
1657 ((fLife * (fLife + 1.0)) / 2.0);
1663 double fPeriod,
double fFactor)
1665 double fDdb, fRate, fOldValue, fNewValue;
1666 fRate = fFactor / fLife;
1676 fOldValue = fCost * pow(1.0 - fRate, fPeriod - 1.0);
1677 fNewValue = fCost * pow(1.0 - fRate, fPeriod);
1679 if (fNewValue < fSalvage)
1680 fDdb = fOldValue - fSalvage;
1682 fDdb = fOldValue - fNewValue;
1690 nFuncFmtType = SvNumFormatType::CURRENCY;
1692 if ( !MustHaveParamCount( nParamCount, 4, 5 ) )
1696 if (nParamCount == 5)
1697 fFactor = GetDouble();
1700 double fPeriod = GetDouble();
1701 double fLife = GetDouble();
1702 double fSalvage = GetDouble();
1703 double fCost = GetDouble();
1704 if (fCost < 0.0 || fSalvage < 0.0 || fFactor <= 0.0 || fSalvage > fCost
1705 || fPeriod < 1.0 || fPeriod > fLife)
1706 PushIllegalArgument();
1708 PushDouble(
ScGetDDB(fCost, fSalvage, fLife, fPeriod, fFactor));
1713 nFuncFmtType = SvNumFormatType::CURRENCY;
1715 if ( !MustHaveParamCount( nParamCount, 4, 5 ) )
1718 if (nParamCount == 4)
1721 fMonths = ::rtl::math::approxFloor(GetDouble());
1722 double fPeriod = GetDouble();
1723 double fLife = GetDouble();
1724 double fSalvage = GetDouble();
1725 double fCost = GetDouble();
1726 if (fMonths < 1.0 || fMonths > 12.0 || fLife > 1200.0 || fSalvage < 0.0 ||
1727 fPeriod > (fLife + 1.0) || fSalvage > fCost || fCost <= 0.0 ||
1728 fLife <= 0 || fPeriod <= 0 )
1730 PushIllegalArgument();
1733 double fOffRate = 1.0 - pow(fSalvage / fCost, 1.0 / fLife);
1734 fOffRate = ::rtl::math::approxFloor((fOffRate * 1000.0) + 0.5) / 1000.0;
1735 double fFirstOffRate = fCost * fOffRate * fMonths / 12.0;
1737 if (::rtl::math::approxFloor(fPeriod) == 1)
1738 fDb = fFirstOffRate;
1741 double fSumOffRate = fFirstOffRate;
1742 double fMin = fLife;
1743 if (fMin > fPeriod) fMin = fPeriod;
1744 sal_uInt16 iMax =
static_cast<sal_uInt16
>(::rtl::math::approxFloor(fMin));
1745 for (sal_uInt16
i = 2;
i <= iMax;
i++)
1747 fDb = (fCost - fSumOffRate) * fOffRate;
1750 if (fPeriod > fLife)
1751 fDb = ((fCost - fSumOffRate) * fOffRate * (12.0 - fMonths)) / 12.0;
1757 double fLife1,
double fPeriod,
double fFactor)
1760 double fIntEnd = ::rtl::math::approxCeil(fPeriod);
1764 double fSalvageValue = fCost - fSalvage;
1765 bool bNowSln =
false;
1770 for ( i = 1; i <= nLoopEnd; i++)
1774 fDdb =
ScGetDDB(fCost, fSalvage, fLife, static_cast<double>(i), fFactor);
1775 fSln = fSalvageValue/ (fLife1 -
static_cast<double>(i-1));
1785 fSalvageValue -= fDdb;
1794 fTerm *= ( fPeriod + 1.0 - fIntEnd );
1803 nFuncFmtType = SvNumFormatType::CURRENCY;
1805 if ( !MustHaveParamCount( nParamCount, 5, 7 ) )
1808 double fCost, fSalvage, fLife, fStart, fEnd, fFactor, fVdb = 0.0;
1810 if (nParamCount == 7)
1811 bNoSwitch = GetBool();
1814 if (nParamCount >= 6)
1815 fFactor = GetDouble();
1819 fStart = GetDouble();
1820 fLife = GetDouble();
1821 fSalvage = GetDouble();
1822 fCost = GetDouble();
1823 if (fStart < 0.0 || fEnd < fStart || fEnd > fLife || fCost < 0.0
1824 || fSalvage > fCost || fFactor <= 0.0)
1825 PushIllegalArgument();
1828 double fIntStart = ::rtl::math::approxFloor(fStart);
1829 double fIntEnd = ::rtl::math::approxCeil(fEnd);
1838 double fTerm =
ScGetDDB(fCost, fSalvage, fLife, static_cast<double>(
i), fFactor);
1841 if (
i == nLoopStart+1 )
1842 fTerm *= ( std::min( fEnd, fIntStart + 1.0 ) - fStart );
1843 else if (
i == nLoopEnd )
1844 fTerm *= ( fEnd + 1.0 - fIntEnd );
1853 if ( !::rtl::math::approxEqual( fStart, fIntStart ) ||
1854 !::rtl::math::approxEqual( fEnd, fIntEnd ) )
1856 if ( !::rtl::math::approxEqual( fStart, fIntStart ) )
1859 double fTempIntEnd = fIntStart + 1.0;
1860 double fTempValue = fCost -
1861 ScInterVDB( fCost, fSalvage, fLife, fLife, fIntStart, fFactor );
1862 fPart += ( fStart - fIntStart ) *
1863 ScInterVDB( fTempValue, fSalvage, fLife, fLife - fIntStart,
1864 fTempIntEnd - fIntStart, fFactor);
1866 if ( !::rtl::math::approxEqual( fEnd, fIntEnd ) )
1869 double fTempIntStart = fIntEnd - 1.0;
1870 double fTempValue = fCost -
1871 ScInterVDB( fCost, fSalvage, fLife, fLife, fTempIntStart, fFactor );
1872 fPart += ( fIntEnd - fEnd ) *
1873 ScInterVDB( fTempValue, fSalvage, fLife, fLife - fTempIntStart,
1874 fIntEnd - fTempIntStart, fFactor);
1878 fCost -=
ScInterVDB( fCost, fSalvage, fLife, fLife, fIntStart, fFactor );
1879 fVdb =
ScInterVDB( fCost, fSalvage, fLife, fLife - fIntStart,
1880 fIntEnd - fIntStart, fFactor);
1889 if ( MustHaveParamCount( GetByte(), 3 ) )
1891 double fFuture = GetDouble();
1892 double fPresent = GetDouble();
1893 double fRate = GetDouble();
1894 if ( fFuture <= 0.0 || fPresent <= 0.0 || fRate <= 0.0 )
1895 PushIllegalArgument();
1897 PushDouble(
log( fFuture / fPresent ) / rtl::math::log1p( fRate ) );
1903 nFuncFmtType = SvNumFormatType::CURRENCY;
1904 if ( MustHaveParamCount( GetByte(), 3 ) )
1906 double fLife = GetDouble();
1907 double fSalvage = GetDouble();
1908 double fCost = GetDouble();
1909 PushDouble(
div( fCost - fSalvage, fLife ) );
1914 double fFv,
bool bPayInAdvance)
1918 fPayment = (fPv + fFv) / fNper;
1922 fPayment = (fFv + fPv * exp( fNper * ::rtl::math::log1p(fRate) ) ) * fRate /
1923 (::rtl::math::expm1( (fNper + 1) * ::rtl::math::log1p(fRate) ) - fRate);
1925 fPayment = (fFv + fPv * exp(fNper * ::rtl::math::log1p(fRate) ) ) * fRate /
1926 ::rtl::math::expm1( fNper * ::rtl::math::log1p(fRate) );
1933 double fRate, fNper, fPv, fFv = 0;
1934 bool bPayInAdvance =
false;
1935 nFuncFmtType = SvNumFormatType::CURRENCY;
1937 if ( !MustHaveParamCount( nParamCount, 3, 5 ) )
1939 if (nParamCount == 5)
1940 bPayInAdvance = GetBool();
1941 if (nParamCount >= 4)
1944 fNper = GetDouble();
1945 fRate = GetDouble();
1946 PushDouble(ScGetPMT(fRate, fNper, fPv, fFv, bPayInAdvance));
1951 nFuncFmtType = SvNumFormatType::PERCENT;
1952 if ( MustHaveParamCount( GetByte(), 3 ) )
1954 double fFutureValue = GetDouble();
1955 double fPresentValue = GetDouble();
1956 double fNrOfPeriods = GetDouble();
1957 if ( fNrOfPeriods <= 0.0 || fPresentValue == 0.0 )
1958 PushIllegalArgument();
1960 PushDouble(pow(fFutureValue / fPresentValue, 1.0 / fNrOfPeriods) - 1.0);
1965 double fPv,
bool bPayInAdvance)
1969 fFv = fPv + fPmt * fNper;
1972 double fTerm = pow(1.0 + fRate, fNper);
1974 fFv = fPv * fTerm + fPmt*(1.0 + fRate)*(fTerm - 1.0)/fRate;
1976 fFv = fPv * fTerm + fPmt*(fTerm - 1.0)/fRate;
1983 double fRate, fNper, fPmt, fPv = 0;
1984 bool bPayInAdvance =
false;
1985 nFuncFmtType = SvNumFormatType::CURRENCY;
1987 if ( !MustHaveParamCount( nParamCount, 3, 5 ) )
1989 if (nParamCount == 5)
1990 bPayInAdvance = GetBool();
1991 if (nParamCount >= 4)
1994 fNper = GetDouble();
1995 fRate = GetDouble();
1996 PushDouble(ScGetFV(fRate, fNper, fPmt, fPv, bPayInAdvance));
2001 double fRate, fPmt, fPV, fFV = 0;
2002 bool bPayInAdvance =
false;
2004 if ( !MustHaveParamCount( nParamCount, 3, 5 ) )
2006 if (nParamCount == 5)
2007 bPayInAdvance = GetBool();
2008 if (nParamCount >= 4)
2012 fRate = GetDouble();
2015 if ( fPV + fFV == 0.0 )
2017 else if (fRate == 0.0)
2018 PushDouble(-(fPV + fFV)/fPmt);
2019 else if (bPayInAdvance)
2020 PushDouble(
log(-(fRate*fFV-fPmt*(1.0+fRate))/(fRate*fPV+fPmt*(1.0+fRate)))
2021 / rtl::math::log1p(fRate));
2023 PushDouble(
log(-(fRate*fFV-fPmt)/(fRate*fPV+fPmt)) / rtl::math::log1p(fRate));
2027 double fFv,
bool bPayType,
double & fGuess )
2034 bool bValid =
true, bFound =
false;
2035 double fX, fXnew, fTerm, fTermDerivation;
2036 double fGeoSeries, fGeoSeriesDerivation;
2037 const sal_uInt16 nIterationsMax = 150;
2039 const double fEpsilonSmall = 1.0E-14;
2043 fFv = fFv - fPayment;
2044 fPv = fPv + fPayment;
2046 if (fNper == ::rtl::math::round( fNper ))
2049 while (!bFound && nCount < nIterationsMax)
2051 double fPowN, fPowNminus1;
2052 fPowNminus1 = pow( 1.0+fX, fNper-1.0);
2053 fPowN = fPowNminus1 * (1.0+fX);
2057 fGeoSeriesDerivation = fNper * (fNper-1.0)/2.0;
2061 fGeoSeries = (fPowN-1.0)/fX;
2062 fGeoSeriesDerivation = fNper * fPowNminus1 / fX - fGeoSeries / fX;
2064 fTerm = fFv + fPv *fPowN+ fPayment * fGeoSeries;
2065 fTermDerivation = fPv * fNper * fPowNminus1 + fPayment * fGeoSeriesDerivation;
2066 if (fabs(fTerm) < fEpsilonSmall)
2070 if (fTermDerivation == 0.0)
2073 fXnew = fX - fTerm / fTermDerivation;
2086 bValid = (fX > -1.0);
2090 fX = (fGuess < -1.0) ? -1.0 : fGuess;
2091 while (bValid && !bFound && nCount < nIterationsMax)
2096 fGeoSeriesDerivation = fNper * (fNper-1.0)/2.0;
2100 fGeoSeries = (pow( 1.0+fX, fNper) - 1.0) / fX;
2101 fGeoSeriesDerivation = fNper * pow( 1.0+fX, fNper-1.0) / fX - fGeoSeries / fX;
2103 fTerm = fFv + fPv *pow(1.0 + fX,fNper)+ fPayment * fGeoSeries;
2104 fTermDerivation = fPv * fNper * pow( 1.0+fX, fNper-1.0) + fPayment * fGeoSeriesDerivation;
2105 if (fabs(fTerm) < fEpsilonSmall)
2109 if (fTermDerivation == 0.0)
2112 fXnew = fX - fTerm / fTermDerivation;
2117 bValid = (fX >= -1.0);
2122 return bValid && bFound;
2128 double fPv, fPayment, fNper;
2130 double fFv = 0, fGuess = 0.1, fOrigGuess = 0.1;
2131 bool bPayType =
false, bValid =
true;
2132 bool bDefaultGuess =
true;
2133 nFuncFmtType = SvNumFormatType::PERCENT;
2135 if ( !MustHaveParamCount( nParamCount, 3, 6 ) )
2137 if (nParamCount == 6)
2139 fOrigGuess = fGuess = GetDouble();
2140 bDefaultGuess =
false;
2142 if (nParamCount >= 5)
2143 bPayType = GetBool();
2144 if (nParamCount >= 4)
2147 fPayment = GetDouble();
2148 fNper = GetDouble();
2151 PushIllegalArgument();
2154 bValid = RateIteration(fNper, fPayment, fPv, fFv, bPayType, fGuess);
2168 double fX = fOrigGuess;
2169 for (
int nStep = 2; nStep <= 10 && !bValid; ++nStep)
2171 fGuess = fX * nStep;
2172 bValid = RateIteration( fNper, fPayment, fPv, fFv, bPayType, fGuess);
2175 fGuess = fX / nStep;
2176 bValid = RateIteration( fNper, fPayment, fPv, fFv, bPayType, fGuess);
2181 SetError(FormulaError::NoConvergence);
2187 double fFv,
bool bPayInAdvance,
double& fPmt)
2189 fPmt = ScGetPMT(fRate, fNper, fPv, fFv, bPayInAdvance);
2191 nFuncFmtType = SvNumFormatType::CURRENCY;
2202 fIpmt = ScGetFV(fRate, fPer-2.0, fPmt, fPv,
true) - fPmt;
2204 fIpmt = ScGetFV(fRate, fPer-1.0, fPmt, fPv,
false);
2206 return fIpmt * fRate;
2211 double fRate, fPer, fNper, fPv, fFv = 0;
2212 bool bPayInAdvance =
false;
2213 nFuncFmtType = SvNumFormatType::CURRENCY;
2215 if ( !MustHaveParamCount( nParamCount, 4, 6 ) )
2217 if (nParamCount == 6)
2218 bPayInAdvance = GetBool();
2219 if (nParamCount >= 5)
2222 fNper = GetDouble();
2224 fRate = GetDouble();
2225 if (fPer < 1.0 || fPer > fNper)
2226 PushIllegalArgument();
2230 PushDouble(ScGetIpmt(fRate, fPer, fNper, fPv, fFv, bPayInAdvance, fPmt));
2236 double fRate, fPer, fNper, fPv, fFv = 0;
2237 bool bPayInAdvance =
false;
2238 nFuncFmtType = SvNumFormatType::CURRENCY;
2240 if ( !MustHaveParamCount( nParamCount, 4, 6 ) )
2242 if (nParamCount == 6)
2243 bPayInAdvance = GetBool();
2244 if (nParamCount >= 5)
2247 fNper = GetDouble();
2249 fRate = GetDouble();
2250 if (fPer < 1.0 || fPer > fNper)
2251 PushIllegalArgument();
2255 double fInterestPer = ScGetIpmt(fRate, fPer, fNper, fPv, fFv, bPayInAdvance, fPmt);
2256 PushDouble(fPmt - fInterestPer);
2262 nFuncFmtType = SvNumFormatType::CURRENCY;
2263 if ( !MustHaveParamCount( GetByte(), 6 ) )
2266 double fRate, fNper, fPv, fStart, fEnd;
2267 double fFlag = GetDoubleWithDefault( -1.0 );
2268 fEnd = ::rtl::math::approxFloor(GetDouble());
2269 fStart = ::rtl::math::approxFloor(GetDouble());
2271 fNper = GetDouble();
2272 fRate = GetDouble();
2273 if (fStart < 1.0 || fEnd < fStart || fRate <= 0.0 ||
2274 fEnd > fNper || fNper <= 0.0 || fPv <= 0.0 ||
2275 ( fFlag != 0.0 && fFlag != 1.0 ))
2276 PushIllegalArgument();
2279 bool bPayInAdvance =
static_cast<bool>(fFlag);
2282 double fPmt = ScGetPMT(fRate, fNper, fPv, 0.0, bPayInAdvance);
2293 fIpmt += ScGetFV(fRate, static_cast<double>(
i-2), fPmt, fPv,
true) - fPmt;
2295 fIpmt += ScGetFV(fRate, static_cast<double>(
i-1), fPmt, fPv,
false);
2304 nFuncFmtType = SvNumFormatType::CURRENCY;
2305 if ( !MustHaveParamCount( GetByte(), 6 ) )
2308 double fRate, fNper, fPv, fStart, fEnd;
2309 double fFlag = GetDoubleWithDefault( -1.0 );
2310 fEnd = ::rtl::math::approxFloor(GetDouble());
2311 fStart = ::rtl::math::approxFloor(GetDouble());
2313 fNper = GetDouble();
2314 fRate = GetDouble();
2315 if (fStart < 1.0 || fEnd < fStart || fRate <= 0.0 ||
2316 fEnd > fNper || fNper <= 0.0 || fPv <= 0.0 ||
2317 ( fFlag != 0.0 && fFlag != 1.0 ))
2318 PushIllegalArgument();
2321 bool bPayInAdvance =
static_cast<bool>(fFlag);
2322 double fPmt = ScGetPMT(fRate, fNper, fPv, 0.0, bPayInAdvance);
2331 fPpmt = fPmt + fPv * fRate;
2337 fPpmt += fPmt - (ScGetFV(fRate, static_cast<double>(
i-2), fPmt, fPv,
true) - fPmt) * fRate;
2339 fPpmt += fPmt - ScGetFV(fRate, static_cast<double>(
i-1), fPmt, fPv,
false) * fRate;
2347 nFuncFmtType = SvNumFormatType::PERCENT;
2348 if ( !MustHaveParamCount( GetByte(), 2 ) )
2351 double fPeriods = GetDouble();
2352 double fNominal = GetDouble();
2353 if (fPeriods < 1.0 || fNominal < 0.0)
2354 PushIllegalArgument();
2355 else if ( fNominal == 0.0 )
2359 fPeriods = ::rtl::math::approxFloor(fPeriods);
2360 PushDouble(pow(1.0 + fNominal/fPeriods, fPeriods) - 1.0);
2366 nFuncFmtType = SvNumFormatType::PERCENT;
2367 if ( MustHaveParamCount( GetByte(), 2 ) )
2369 double fPeriods = GetDouble();
2370 double fEffective = GetDouble();
2371 if (fPeriods < 1.0 || fEffective <= 0.0)
2372 PushIllegalArgument();
2375 fPeriods = ::rtl::math::approxFloor(fPeriods);
2376 PushDouble( (pow(fEffective + 1.0, 1.0 / fPeriods) - 1.0) * fPeriods );
2383 if ( !MustHaveParamCount( GetByte(), 2 ) )
2386 double fDenom = GetDouble();
2387 if ( fDenom == 0.0 )
2389 PushError(FormulaError::DivisionByZero);
2392 double fNum = GetDouble();
2393 double fRes = ::rtl::math::approxSub( fNum,
2394 ::rtl::math::approxFloor( fNum / fDenom ) * fDenom );
2395 if ( ( fDenom > 0 && fRes >= 0 && fRes < fDenom ) ||
2396 ( fDenom < 0 && fRes <= 0 && fRes > fDenom ) )
2399 PushError( FormulaError::NoValue );
2407 if (nGlobalError != FormulaError::NONE || !p2nd || !p1st)
2409 PushIllegalArgument();
2418 PushIllegalArgument();
2433 std::unique_ptr<formula::FormulaToken>
p;
2434 for (
size_t i=0;
i<2; ++
i)
2441 p->GetRefList()->push_back( aRef);
2448 p->GetRefList()->push_back( aRef);
2459 const ScAddress& r11 = rRef1.Ref1.toAbs(mrDoc, aPos);
2460 const ScAddress& r12 = rRef1.Ref2.toAbs(mrDoc, aPos);
2463 const ScAddress& r21 = rRef2.Ref1.toAbs(mrDoc, aPos);
2464 const ScAddress& r22 = rRef2.Ref2.toAbs(mrDoc, aPos);
2471 if (nCol2 < nCol1 || nRow2 < nRow1 || nTab2 < nTab1)
2476 aRef.
InitRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
2477 pRefList->push_back( aRef);
2481 size_t n = pRefList->size();
2483 PushError( FormulaError::NoRef);
2493 PushTokenRef( xRes);
2499 SCCOL nC1[2], nC2[2];
2500 SCROW nR1[2], nR2[2];
2501 SCTAB nT1[2], nT2[2];
2502 for (
size_t i=0;
i<2; ++
i)
2534 SCCOL nCol1 = ::std::max( nC1[0], nC1[1]);
2535 SCROW nRow1 = ::std::max( nR1[0], nR1[1]);
2536 SCTAB nTab1 = ::std::max( nT1[0], nT1[1]);
2537 SCCOL nCol2 = ::std::min( nC2[0], nC2[1]);
2538 SCROW nRow2 = ::std::min( nR2[0], nR2[1]);
2539 SCTAB nTab2 = ::std::min( nT2[0], nT2[1]);
2540 if (nCol2 < nCol1 || nRow2 < nRow1 || nTab2 < nTab1)
2541 PushError( FormulaError::NoRef);
2542 else if (nCol2 == nCol1 && nRow2 == nRow1 && nTab2 == nTab1)
2543 PushSingleRef( nCol1, nRow1, nTab1);
2545 PushDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
2554 if (nGlobalError != FormulaError::NONE || !x2 || !x1)
2556 PushIllegalArgument();
2564 PushIllegalArgument();
2566 PushTokenRef( xRes);
2574 if (nGlobalError != FormulaError::NONE || !p2nd || !p1st)
2576 PushIllegalArgument();
2585 PushIllegalArgument();
2609 for (
size_t i=0;
i<2; ++
i)
2619 pRes->push_back( aRef);
2623 pRes->push_back( *pt[i]->GetDoubleRef());
2628 for (
const auto& rRef : *p)
2630 pRes->push_back( rRef);
2638 ValidateRef( *pRes);
2639 PushTokenRef( xRes);
2647 PushTokenRef( xTok);
2648 PushTokenRef( xTok);
2651 PushError( FormulaError::UnknownStackVariable);
2657 if (nParamCount >= 1 && nParamCount <= 3)
2660 if (nParamCount >= 3)
2663 if (nParamCount >= 2)
2664 nTimeOut =
static_cast<tools::Long>(GetDouble()*1000.0);
2665 OUString aStyle1 =
GetString().getString();
2671 if ( !mrDoc.IsClipOrUndo() )
2677 bool bNotify =
true;
2678 if (aStyle2.isEmpty())
2680 const ScStyleSheet* pStyle = mrDoc.GetStyle(aPos.Col(), aPos.Row(), aPos.Tab());
2682 if (pStyle && pStyle->
GetName() == aStyle1)
2690 pShell->Broadcast( aHint );
2698 PushIllegalParameter();
2702 std::u16string_view rA, std::u16string_view rT, std::u16string_view rI,
sal_uInt8 nM )
2705 for (
size_t i=0;
i<nCount;
i++ )
2710 if (
pLink->GetAppl() == rA &&
2711 pLink->GetTopic() == rT &&
2712 pLink->GetItem() == rI &&
2713 pLink->GetMode() == nM )
2727 if ( !MustHaveParamCount( nParamCount, 3, 4 ) )
2731 if (nParamCount == 4)
2733 sal_uInt32 nTmp = GetUInt32();
2734 if (nGlobalError != FormulaError::NONE || nTmp >
SAL_MAX_UINT8)
2736 PushIllegalArgument();
2741 OUString aItem =
GetString().getString();
2742 OUString aTopic =
GetString().getString();
2743 OUString aAppl =
GetString().getString();
2759 pArr->AddRecalcMode( ScRecalcMode::ONLOAD_LENIENT );
2763 bool bOldEnabled = mrDoc.IsIdleEnabled();
2764 mrDoc.EnableIdle(
false);
2773 bool bWasError = ( pMyFormulaCell && pMyFormulaCell->GetRawError() != FormulaError::NONE );
2777 pLink =
new ScDdeLink( mrDoc, aAppl, aTopic, aItem, nMode );
2778 mpLinkManager->InsertDDELink( pLink, aAppl, aTopic, aItem );
2779 if ( mpLinkManager->GetLinks().size() == 1 )
2789 if (!mrDoc.HasLinkFormulaNeedingCheck())
2798 pMyFormulaCell->StartListening( *pLink );
2804 pMyFormulaCell->StartListening( *pLink );
2810 if ( pMyFormulaCell && pMyFormulaCell->GetRawError() != FormulaError::NONE && !bWasError )
2811 pMyFormulaCell->SetErrCode(FormulaError::NONE);
2824 PushMatrix( pNewMat );
2827 PushIllegalArgument();
2832 mrDoc.EnableIdle(bOldEnabled);
2833 mpLinkManager->CloseCachedComps();
2839 if ( !MustHaveParamCount( nParamCount, 2, 3 ) )
2843 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
2844 'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
2845 'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
2850 if ( nParamCount == 3 )
2852 double fLen = ::rtl::math::approxFloor( GetDouble() );
2854 nMinLen =
static_cast<sal_Int32
>(fLen);
2855 else if ( fLen == 0.0 )
2862 double fBase = ::rtl::math::approxFloor( GetDouble() );
2863 double fVal = ::rtl::math::approxFloor( GetDouble() );
2864 double fChars = ((fVal > 0.0 && fBase > 0.0) ?
2865 (ceil(
log( fVal ) /
log( fBase ) ) + 2.0) :
2870 if ( nGlobalError == FormulaError::NONE && nMinLen && 2 <= fBase && fBase <= nDigits && 0 <= fVal )
2872 const sal_Int32 nConstBuf = 128;
2874 sal_Int32 nBuf = std::max<sal_Int32>( fChars, nMinLen + 1 );
2876 for ( sal_Int32 j = 0; j < nBuf; ++j )
2886 while ( nVal && p > pBuf )
2888 *--p = pDigits[ nVal % nBase ];
2891 fVal =
static_cast<double>(nVal);
2896 while ( fVal && p > pBuf )
2901 double fInt = ::rtl::math::approxFloor( fVal / fBase );
2902 double fMult = fInt * fBase;
2907 double fDebug1 = fVal - fMult;
2912 double fDebug2 = ::rtl::math::approxSub( fVal, fMult );
2914 double fDebug3 = ( fInt ? fVal / fInt : 0.0 );
2930 double fDig = ::rtl::math::approxFloor( ::rtl::math::approxSub( fVal, fMult ) );
2938 else if ( fDig >= fBase )
2939 nDig =
static_cast<size_t>(fBase) - 1;
2941 nDig =
static_cast<size_t>(fDig);
2943 *--p = pDigits[ nDig ];
2948 PushError( FormulaError::StringOverflow );
2951 if ( nBuf - (p - pBuf) <= nMinLen )
2952 p = pBuf + nBuf - 1 - nMinLen;
2953 PushStringBuffer( p );
2959 PushIllegalArgument();
2964 if ( !MustHaveParamCount( GetByte(), 2 ) )
2967 double fBase = ::rtl::math::approxFloor( GetDouble() );
2969 if ( nGlobalError == FormulaError::NONE && 2 <= fBase && fBase <= 36 )
2972 int nBase =
static_cast<int>(fBase);
2974 while ( *p ==
' ' || *p ==
'\t' )
2978 if ( *p ==
'x' || *p ==
'X' )
2980 else if ( *p ==
'0' && (*(p+1) ==
'x' || *(p+1) ==
'X') )
2986 if (
'0' <= *p && *p <=
'9' )
2988 else if (
'A' <= *p && *p <=
'Z' )
2989 n = 10 + (*p -
'A');
2990 else if (
'a' <= *p && *p <=
'z' )
2991 n = 10 + (*p -
'a');
2997 ( (nBase == 2 && (*p ==
'b' || *p ==
'B'))
2998 ||(nBase == 16 && (*p ==
'h' || *p ==
'H')) )
3003 PushIllegalArgument();
3008 fVal = fVal * fBase + n;
3015 PushIllegalArgument();
3020 if ( !MustHaveParamCount( GetByte(), 3 ) )
3023 OUString aToUnit =
GetString().getString();
3024 OUString aFromUnit =
GetString().getString();
3025 double fVal = GetDouble();
3026 if ( nGlobalError != FormulaError::NONE )
3027 PushError( nGlobalError);
3033 PushDouble( fVal * fConv );
3035 PushDouble( fVal / fConv );
3044 if( !MustHaveParamCount( nParamCount, 1, 2 ) )
3047 double fMode = (nParamCount == 2) ? ::rtl::math::approxFloor( GetDouble() ) : 0.0;
3048 double fVal = ::rtl::math::approxFloor( GetDouble() );
3049 if( nGlobalError != FormulaError::NONE )
3050 PushError( nGlobalError);
3051 else if( (fMode >= 0.0) && (fMode < 5.0) && (fVal >= 0.0) && (fVal < 4000.0) )
3053 static const sal_Unicode pChars[] = {
'M',
'D',
'C',
'L',
'X',
'V',
'I' };
3054 static const sal_uInt16
pValues[] = { 1000, 500, 100, 50, 10, 5, 1 };
3055 static const sal_uInt16 nMaxIndex = sal_uInt16(
SAL_N_ELEMENTS(pValues) - 1);
3057 OUStringBuffer aRoman;
3058 sal_uInt16 nVal =
static_cast<sal_uInt16
>(fVal);
3059 sal_uInt16 nMode =
static_cast<sal_uInt16
>(fMode);
3061 for( sal_uInt16
i = 0;
i <= nMaxIndex / 2;
i++ )
3064 sal_uInt16 nDigit = nVal / pValues[ nIndex ];
3066 if( (nDigit % 5) == 4 )
3069 assert( ((nDigit == 4) ? (nIndex >= 1) : (nIndex >= 2)));
3071 sal_uInt16 nIndex2 = (nDigit == 4) ? nIndex - 1 : nIndex - 2;
3072 sal_uInt16 nSteps = 0;
3073 while( (nSteps < nMode) && (nIndex < nMaxIndex) )
3076 if( pValues[ nIndex2 ] - pValues[ nIndex + 1 ] <= nVal )
3081 aRoman.append( pChars[ nIndex ] ).append( pChars[ nIndex2 ] );
3082 nVal = sal::static_int_cast<sal_uInt16>( nVal + pValues[ nIndex ] );
3083 nVal = sal::static_int_cast<sal_uInt16>( nVal - pValues[ nIndex2 ] );
3091 aRoman.append( pChars[ nIndex - 1 ] );
3093 sal_Int32 nPad = nDigit % 5;
3096 OUStringBuffer
aBuf(aRoman);
3099 aRoman = aBuf.makeStringAndClear();
3101 nVal %= pValues[ nIndex ];
3105 PushString( aRoman.makeStringAndClear() );
3108 PushIllegalArgument();
3115 case 'M': rnValue = 1000; rbIsDec =
true;
break;
3116 case 'D': rnValue = 500; rbIsDec =
false;
break;
3117 case 'C': rnValue = 100; rbIsDec =
true;
break;
3118 case 'L': rnValue = 50; rbIsDec =
false;
break;
3119 case 'X': rnValue = 10; rbIsDec =
true;
break;
3120 case 'V': rnValue = 5; rbIsDec =
false;
break;
3121 case 'I': rnValue = 1; rbIsDec =
true;
break;
3122 default:
return false;
3129 OUString aRoman =
GetString().getString();
3130 if( nGlobalError != FormulaError::NONE )
3131 PushError( nGlobalError);
3134 aRoman = aRoman.toAsciiUpperCase();
3137 sal_uInt16 nValidRest = 3999;
3138 sal_Int32 nCharIndex = 0;
3139 sal_Int32 nCharCount = aRoman.getLength();
3142 while( bValid && (nCharIndex < nCharCount) )
3144 sal_uInt16 nDigit1 = 0;
3145 sal_uInt16 nDigit2 = 0;
3146 bool bIsDec1 =
false;
3148 if( bValid && (nCharIndex + 1 < nCharCount) )
3150 bool bIsDec2 =
false;
3155 if( nDigit1 >= nDigit2 )
3157 nValue = sal::static_int_cast<sal_uInt16>( nValue + nDigit1 );
3158 nValidRest %= (nDigit1 * (bIsDec1 ? 5 : 2));
3159 bValid = (nValidRest >= nDigit1);
3161 nValidRest = sal::static_int_cast<sal_uInt16>( nValidRest - nDigit1 );
3164 else if( nDigit1 * 2 != nDigit2 )
3166 sal_uInt16 nDiff = nDigit2 - nDigit1;
3167 nValue = sal::static_int_cast<sal_uInt16>( nValue + nDiff );
3168 bValid = (nValidRest >= nDiff);
3170 nValidRest = nDigit1 - 1;
3180 PushIllegalArgument();
3187 if ( !MustHaveParamCount( nParamCount, 1, 2 ) )
3194 if ( nParamCount == 2 )
3196 switch ( GetStackType() )
3209 if ( !PopDoubleRefOrSingleRef( aAdr ) )
3218 if (nErr != FormulaError::NONE)
3222 fVal = GetCellValue(aAdr, aCell);
3226 GetCellString(aStr, aCell);
3231 nResultType = GetDoubleOrStringFromMatrix( fVal, aStr);
3242 SetError( FormulaError::IllegalArgument);
3247 if (nGlobalError != FormulaError::NONE)
3252 if (nParamCount == 2 || nGlobalError != FormulaError::NONE)
3255 pResMat->PutDouble( fVal, 0);
3257 pResMat->PutString(aStr, 0);
3259 pResMat->PutDouble( 0.0, 0 );
3262 pResMat->PutString(aUrl, 0);
3263 pResMat->PutString(aUrl, 1);
3264 bMatrixFormula =
true;
3265 PushMatrix(pResMat);
3276 const char* pCurrText;
3280 static const ConvertInfo aConvertTable[] = {
3282 {
"ATS", 13.7603, 2 },
3283 {
"BEF", 40.3399, 0 },
3284 {
"DEM", 1.95583, 2 },
3285 {
"ESP", 166.386, 0 },
3286 {
"FIM", 5.94573, 2 },
3287 {
"FRF", 6.55957, 2 },
3288 {
"IEP", 0.787564, 2 },
3289 {
"ITL", 1936.27, 0 },
3290 {
"LUF", 40.3399, 0 },
3291 {
"NLG", 2.20371, 2 },
3292 {
"PTE", 200.482, 2 },
3293 {
"GRD", 340.750, 2 },
3294 {
"SIT", 239.640, 2 },
3295 {
"MTL", 0.429300, 2 },
3296 {
"CYP", 0.585274, 2 },
3297 {
"SKK", 30.1260, 2 },
3298 {
"EEK", 15.6466, 2 },
3299 {
"LVL", 0.702804, 2 },
3300 {
"LTL", 3.45280, 2 }
3303 for (
const auto &
i : aConvertTable)
3304 if ( aSearchUnit.equalsIgnoreAsciiCaseAscii(
i.pCurrText ) )
3316 if ( !MustHaveParamCount( nParamCount, 3, 5 ) )
3319 double fPrecision = 0.0;
3320 if ( nParamCount == 5 )
3322 fPrecision = ::rtl::math::approxFloor(GetDouble());
3323 if ( fPrecision < 3 )
3325 PushIllegalArgument();
3329 bool bFullPrecision =
false;
3330 if ( nParamCount >= 4 )
3331 bFullPrecision = GetBool();
3332 OUString aToUnit =
GetString().getString();
3333 OUString aFromUnit =
GetString().getString();
3334 double fVal = GetDouble();
3335 if ( nGlobalError != FormulaError::NONE )
3336 PushError( nGlobalError);
3347 if ( aFromUnit.equalsIgnoreAsciiCase( aToUnit ) )
3351 if ( aFromUnit.equalsIgnoreAsciiCase(
"EUR" ) )
3352 fRes = fVal * fToRate;
3355 double fIntermediate = fVal / fFromRate;
3357 fIntermediate = ::rtl::math::round( fIntermediate,
3358 static_cast<int>(fPrecision) );
3359 fRes = fIntermediate * fToRate;
3361 if ( !bFullPrecision )
3362 fRes = ::rtl::math::round( fRes, nToDec );
3367 PushIllegalArgument();
3372 #define UTF8_TH_0 "\340\270\250\340\270\271\340\270\231\340\270\242\340\271\214"
3373 #define UTF8_TH_1 "\340\270\253\340\270\231\340\270\266\340\271\210\340\270\207"
3374 #define UTF8_TH_2 "\340\270\252\340\270\255\340\270\207"
3375 #define UTF8_TH_3 "\340\270\252\340\270\262\340\270\241"
3376 #define UTF8_TH_4 "\340\270\252\340\270\265\340\271\210"
3377 #define UTF8_TH_5 "\340\270\253\340\271\211\340\270\262"
3378 #define UTF8_TH_6 "\340\270\253\340\270\201"
3379 #define UTF8_TH_7 "\340\271\200\340\270\210\340\271\207\340\270\224"
3380 #define UTF8_TH_8 "\340\271\201\340\270\233\340\270\224"
3381 #define UTF8_TH_9 "\340\271\200\340\270\201\340\271\211\340\270\262"
3382 #define UTF8_TH_10 "\340\270\252\340\270\264\340\270\232"
3383 #define UTF8_TH_11 "\340\271\200\340\270\255\340\271\207\340\270\224"
3384 #define UTF8_TH_20 "\340\270\242\340\270\265\340\271\210"
3385 #define UTF8_TH_1E2 "\340\270\243\340\271\211\340\270\255\340\270\242"
3386 #define UTF8_TH_1E3 "\340\270\236\340\270\261\340\270\231"
3387 #define UTF8_TH_1E4 "\340\270\253\340\270\241\340\270\267\340\271\210\340\270\231"
3388 #define UTF8_TH_1E5 "\340\271\201\340\270\252\340\270\231"
3389 #define UTF8_TH_1E6 "\340\270\245\340\271\211\340\270\262\340\270\231"
3390 #define UTF8_TH_DOT0 "\340\270\226\340\271\211\340\270\247\340\270\231"
3391 #define UTF8_TH_BAHT "\340\270\232\340\270\262\340\270\227"
3392 #define UTF8_TH_SATANG "\340\270\252\340\270\225\340\270\262\340\270\207\340\270\204\340\271\214"
3393 #define UTF8_TH_MINUS "\340\270\245\340\270\232"
3398 void lclSplitBlock(
double& rfInt, sal_Int32& rnBlock,
double fValue,
double fSize )
3400 rnBlock =
static_cast< sal_Int32
>( modf( (fValue + 0.1) / fSize, &rfInt ) * fSize + 0.1 );
3404 void lclAppendDigit( OStringBuffer& rText, sal_Int32 nDigit )
3408 case 0: rText.append(
UTF8_TH_0 );
break;
3409 case 1: rText.append(
UTF8_TH_1 );
break;
3410 case 2: rText.append(
UTF8_TH_2 );
break;
3411 case 3: rText.append(
UTF8_TH_3 );
break;
3412 case 4: rText.append(
UTF8_TH_4 );
break;
3413 case 5: rText.append(
UTF8_TH_5 );
break;
3414 case 6: rText.append(
UTF8_TH_6 );
break;
3415 case 7: rText.append(
UTF8_TH_7 );
break;
3416 case 8: rText.append(
UTF8_TH_8 );
break;
3417 case 9: rText.append(
UTF8_TH_9 );
break;
3418 default: OSL_FAIL(
"lclAppendDigit - illegal digit" );
3426 void lclAppendPow10( OStringBuffer& rText, sal_Int32 nDigit, sal_Int32 nPow10 )
3428 OSL_ENSURE( (1 <= nDigit) && (nDigit <= 9),
"lclAppendPow10 - illegal digit" );
3429 lclAppendDigit( rText, nDigit );
3436 default: OSL_FAIL(
"lclAppendPow10 - illegal power" );
3441 void lclAppendBlock( OStringBuffer& rText, sal_Int32
nValue )
3443 OSL_ENSURE( (1 <= nValue) && (nValue <= 999999),
"lclAppendBlock - illegal value" );
3444 if( nValue >= 100000 )
3446 lclAppendPow10( rText, nValue / 100000, 5 );
3449 if( nValue >= 10000 )
3451 lclAppendPow10( rText, nValue / 10000, 4 );
3454 if( nValue >= 1000 )
3456 lclAppendPow10( rText, nValue / 1000, 3 );
3461 lclAppendPow10( rText, nValue / 100, 2 );
3467 sal_Int32 nTen = nValue / 10;
3468 sal_Int32 nOne = nValue % 10;
3472 lclAppendDigit( rText, nTen );
3473 else if( nTen == 2 )
3477 if( (nTen > 0) && (nOne == 1) )
3480 lclAppendDigit( rText, nOne );
3488 if ( !MustHaveParamCount( nParamCount, 1 ) )
3491 double fValue = GetDouble();
3492 if( nGlobalError != FormulaError::NONE )
3494 PushError( nGlobalError);
3499 bool bMinus = fValue < 0.0;
3500 fValue = fabs( fValue );
3503 fValue = ::rtl::math::approxFloor( fValue * 100.0 + 0.5 );
3507 sal_Int32 nSatang = 0;
3508 lclSplitBlock( fBaht, nSatang, fValue, 100.0 );
3510 OStringBuffer aText;
3518 else while( fBaht > 0.0 )
3520 OStringBuffer aBlock;
3521 sal_Int32 nBlock = 0;
3522 lclSplitBlock( fBaht, nBlock, fBaht, 1.0e6 );
3524 lclAppendBlock( aBlock, nBlock );
3529 aText.insert(0, aBlock.makeStringAndClear());
3531 if (!aText.isEmpty())
3541 lclAppendBlock( aText, nSatang );
3549 PushString( OStringToOUString(aText.makeStringAndClear(), RTL_TEXTENCODING_UTF8) );
3556 if (!MustHaveParamCountMin(nParamCount, 2) || (nParamCount % 2) == 1)
3558 PushError(FormulaError::NoRef);
3562 bool bOldSyntax =
false;
3563 if (nParamCount == 2)
3566 StackVar eFirstType = GetStackType(2);
3571 std::vector<sheet::DataPilotFieldFilter> aFilters;
3572 OUString aDataFieldName;
3577 aDataFieldName =
GetString().getString();
3579 switch (GetStackType())
3582 PopDoubleRef(aBlock);
3587 PopSingleRef(aAddr);
3592 PushError(FormulaError::NoRef);
3600 sal_uInt16 nFilterCount = nParamCount / 2 - 1;
3601 aFilters.resize(nFilterCount);
3603 sal_uInt16
i = nFilterCount;
3610 bool bEvaluateFormatIndex;
3611 switch (GetRawStackType())
3615 bEvaluateFormatIndex =
true;
3618 bEvaluateFormatIndex =
false;
3623 bool bDouble = GetDoubleOrString( fDouble, aSharedString);
3624 if (nGlobalError != FormulaError::NONE)
3626 PushError( nGlobalError);
3632 sal_uInt32 nNumFormat;
3633 if (bEvaluateFormatIndex && nCurFmtIndex)
3634 nNumFormat = nCurFmtIndex;
3637 if (nCurFmtType == SvNumFormatType::UNDEFINED)
3640 nNumFormat = pFormatter->GetStandardFormat( nCurFmtType,
ScGlobal::eLnge);
3642 const Color* pColor;
3643 pFormatter->GetOutputString( fDouble, nNumFormat, aFilters[i].MatchValueName, &pColor);
3645 fDouble, *pFormatter, nNumFormat);
3649 aFilters[i].MatchValueName = aSharedString.
getString();
3653 sal_uInt32 nNumFormat = 0;
3655 if (pFormatter->IsNumberFormat( aFilters[i].MatchValueName, nNumFormat, fValue))
3657 fValue, *pFormatter, nNumFormat);
3659 aFilters[i].MatchValue = aFilters[i].MatchValueName;
3662 aFilters[i].FieldName =
GetString().getString();
3665 switch (GetStackType())
3668 PopDoubleRef(aBlock);
3673 PopSingleRef(aAddr);
3678 PushError(FormulaError::NoRef);
3682 aDataFieldName =
GetString().getString();
3686 if (nGlobalError != FormulaError::NONE)
3688 PushError( nGlobalError);
3695 ScDPObject* pDPObj = mrDoc.GetDPAtBlock(aBlock);
3698 PushError(FormulaError::NoRef);
3704 OUString aFilterStr = aDataFieldName;
3705 std::vector<sal_Int16> aFilterFuncs;
3706 if (!pDPObj->
ParseFilters(aDataFieldName, aFilters, aFilterFuncs, aFilterStr))
3708 PushError(FormulaError::NoRef);
3717 double fVal = pDPObj->
GetPivotData(aDataFieldName, aFilters);
3718 if (std::isnan(fVal))
3720 PushError(FormulaError::NoRef);
Matrix data type that can store values of mixed types.
void ScRoundSignificant()
constexpr sal_Int64 md(Length i, Length j)
static void RoundSignificant(double fX, double fDigits, double &fRes)
OUString getString() const
DayOfWeek GetDayOfWeek() const
static OUString GetLocaleIndependentFormattedString(double fValue, SvNumberFormatter &rFormatter, sal_uInt32 nNumFormat)
ScAddress toAbs(const ScSheetLimits &rLimits, const ScAddress &rPos) const
const sal_uInt8 SC_DDE_DEFAULT
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
FormulaError GetWeekendAndHolidayMasks_MS(const sal_uInt8 nParamCount, const sal_uInt32 nNullDate,::std::vector< double > &rSortArray, bool bWeekendMask[7], bool bWorkdayFunction)
void ScCeil(bool bODFF)
tdf69552 ODFF1.2 function CEILING and Excel function CEILING.MATH In essence, the difference between ...
void MatCopy(const ScMatrix &mRes) const
static sal_Int32 DateToDays(sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear)
This is very similar to ScCellValue, except that it references the original value instead of copying ...
void Invalidate(sal_uInt16 nId)
sal_uInt16 GetWeekOfYear(DayOfWeek eStartDay=MONDAY, sal_Int16 nMinimumNumberOfDaysInWeek=4) const
const sal_uInt8 SC_DDE_TEXT
OUString GetString(int nId)
bool IsValidAndGregorian() const
const OUString & GetName() const
FormulaTokenRef extendRangeReference(ScSheetLimits &rLimits, FormulaToken &rTok1, FormulaToken &rTok2, const ScAddress &rPos, bool bReuseDoubleRef)
If rTok1 and rTok2 both are SingleRef or DoubleRef tokens, extend/merge ranges as needed for ocRange...
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
sal_uInt16 GetMonth() const
static double ScGetPMT(double fRate, double fNper, double fPv, double fFv, bool bPayInAdvance)
static double ScGetFV(double fRate, double fNper, double fPmt, double fPv, bool bPayInAdvance)
::boost::intrusive_ptr< ScMatrix > ScMatrixRef
void ScNetWorkdays(bool bOOXML_Version)
bool GetNext(double &rValue, FormulaError &rErr)
Does NOT reset rValue if no value found!
#define SAL_N_ELEMENTS(arr)
sal_Int16 GetYear() const
static bool lcl_GetArabicValue(sal_Unicode cChar, sal_uInt16 &rnValue, bool &rbIsDec)
static ScDdeLink * lcl_GetDdeLink(const sfx2::LinkManager *pLinkMgr, std::u16string_view rA, std::u16string_view rT, std::u16string_view rI, sal_uInt8 nM)
bool ParseFilters(OUString &rDataFieldName, std::vector< css::sheet::DataPilotFieldFilter > &rFilters, std::vector< sal_Int16 > &rFilterFuncs, const OUString &rFilterList)
const SvBaseLinks & GetLinks() const
void SetDay(sal_uInt16 nNewDay)
void ScGetIsoWeekOfYear()
sal_Int32 getLength() const
void GetDimensions(SCSIZE &rC, SCSIZE &rR) const
double ScGetIpmt(double fRate, double fPer, double fNper, double fPv, double fFv, bool bPayInAdvance, double &fPmt)
virtual const ScRefList * GetRefList() const override
static bool IsValueType(ScMatValType nType)
Value or boolean.
sal_uInt16 GetDay() const
std::enable_if_t< std::is_floating_point_v< F > &&std::is_integral_v< I >, bool > convertsToAtMost(F value, I max)
void AddDays(sal_Int32 nAddDays)
static ScUnitConverter * GetUnitConverter()
static SC_DLLPUBLIC LanguageType eLnge
double GetDateSerial(sal_Int16 nYear, sal_Int16 nMonth, sal_Int16 nDay, bool bStrict)
Obtain the date serial number for a given date.
void ScFloor(bool bODFF)
tdf69552 ODFF1.2 function FLOOR and Excel function FLOOR.MATH In essence, the difference between the ...
FormulaError GetWeekendAndHolidayMasks(const sal_uInt8 nParamCount, const sal_uInt32 nNullDate,::std::vector< double > &rSortArray, bool bWeekendMask[7])
static bool IsRealStringType(ScMatValType nType)
String, but not empty or empty path or any other type.
const ScMatrix * GetResult() const
const PropertyValue * pValues
double CreateDoubleError(FormulaError nErr)
static bool RateIteration(double fNper, double fPayment, double fPv, double fFv, bool bPayType, double &fGuess)
static double ScGetDDB(double fCost, double fSalvage, double fLife, double fPeriod, double fFactor)
static bool lclConvertMoney(const OUString &aSearchUnit, double &rfRate, int &rnDec)
Resources at the website of the European Commission: http://ec.europa.eu/economy_finance/euro/adoptio...
bool GetFirst(double &rValue, FormulaError &rErr)
Does NOT reset rValue if no value found!
static double ScInterVDB(double fCost, double fSalvage, double fLife, double fLife1, double fPeriod, double fFactor)
void InitRange(const ScRange &rRange)
::boost::intrusive_ptr< formula::FormulaToken > ScTokenRef
void RoundNumber(rtl_math_RoundingMode eMode)
bool GetNext(double &rValue, FormulaError &rErr)
Does NOT reset rValue if no value found!
Complex reference (a range) into the sheet.
double GetPivotData(const OUString &rDataFieldName, std::vector< css::sheet::DataPilotFieldFilter > &rFilters)
::std::vector< ScComplexRefData > ScRefList
static double ScGetPV(double fRate, double fNper, double fPmt, double fFv, bool bPayInAdvance)
move ScAutoStyleHint to a different file?
double div(const double &fNumerator, const double &fDenominator)
Return fNumerator/fDenominator if fDenominator!=0 else #DIV/0! error coded into double.
sal_Int16 GetDayOfWeek(sal_Int32 nDate)
OStringBuffer & padToLength(OStringBuffer &rBuffer, sal_Int32 nLength, char cFill= '\0')