1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #ifndef SC_INTERPRE_HXX 29 #define SC_INTERPRE_HXX 30 31 #include <math.h> 32 #include <rtl/math.hxx> 33 #include "formula/errorcodes.hxx" 34 #include "cell.hxx" 35 #include "scdll.hxx" 36 #include "document.hxx" 37 #include "scmatrix.hxx" 38 39 #include <math.h> 40 #include <map> 41 42 class ScDocument; 43 class SbxVariable; 44 class ScBaseCell; 45 class ScFormulaCell; 46 class SvNumberFormatter; 47 class ScDBRangeBase; 48 struct MatrixDoubleOp; 49 struct ScQueryParam; 50 struct ScDBQueryParamBase; 51 52 struct ScCompare 53 { 54 double nVal[2]; 55 String* pVal[2]; 56 sal_Bool bVal[2]; 57 sal_Bool bEmpty[2]; 58 ScCompare( String* p1, String* p2 ) 59 { 60 pVal[ 0 ] = p1; 61 pVal[ 1 ] = p2; 62 bEmpty[0] = sal_False; 63 bEmpty[1] = sal_False; 64 } 65 }; 66 67 struct ScCompareOptions 68 { 69 ScQueryEntry aQueryEntry; 70 bool bRegEx; 71 bool bMatchWholeCell; 72 bool bIgnoreCase; 73 74 ScCompareOptions( ScDocument* pDoc, const ScQueryEntry& rEntry, bool bReg ); 75 private: 76 // Not implemented, prevent usage. 77 ScCompareOptions(); 78 ScCompareOptions( const ScCompareOptions & ); 79 ScCompareOptions& operator=( const ScCompareOptions & ); 80 }; 81 82 class ScToken; 83 84 #define MAXSTACK (4096 / sizeof(formula::FormulaToken*)) 85 86 class ScTokenStack 87 { 88 public: 89 DECL_FIXEDMEMPOOL_NEWDEL( ScTokenStack ) 90 formula::FormulaToken* pPointer[ MAXSTACK ]; 91 }; 92 93 enum ScIterFunc { 94 ifSUM, // Aufsummieren 95 ifSUMSQ, // Quadratsummen 96 ifPRODUCT, // Multiplizieren 97 ifAVERAGE, // Durchschnitt 98 ifCOUNT, // Anzahl Werte 99 ifCOUNT2, // Anzahl Werte (nichtleer) 100 ifMIN, // Minimum 101 ifMAX // Maximum 102 }; 103 104 struct FormulaTokenRef_less 105 { 106 bool operator () ( const formula::FormulaConstTokenRef& r1, const formula::FormulaConstTokenRef& r2 ) const 107 { return &r1 < &r2; } 108 }; 109 typedef ::std::map< const formula::FormulaConstTokenRef, formula::FormulaTokenRef, FormulaTokenRef_less> ScTokenMatrixMap; 110 111 class ScInterpreter 112 { 113 // distibution function objects need the GetxxxDist methods 114 friend class ScGammaDistFunction; 115 friend class ScBetaDistFunction; 116 friend class ScTDistFunction; 117 friend class ScFDistFunction; 118 friend class ScChiDistFunction; 119 friend class ScChiSqDistFunction; 120 121 public: 122 DECL_FIXEDMEMPOOL_NEWDEL( ScInterpreter ) 123 124 static void GlobalExit(); // aus ScGlobal::Clear() gerufen 125 126 /// Could string be a regular expression? 127 /// If pDoc!=NULL the document options are taken into account and if 128 /// RegularExpressions are disabled the function returns sal_False regardless 129 /// of the string content. 130 static sal_Bool MayBeRegExp( const String& rStr, const ScDocument* pDoc ); 131 132 /// Fail safe division, returning an errDivisionByZero coded into a double 133 /// if denominator is 0.0 134 static inline double div( const double& fNumerator, const double& fDenominator ); 135 136 ScMatrixRef GetNewMat(SCSIZE nC, SCSIZE nR); 137 private: 138 static ScTokenStack* pGlobalStack; 139 static sal_Bool bGlobalStackInUse; 140 141 formula::FormulaTokenIterator aCode; 142 ScAddress aPos; 143 ScTokenArray& rArr; 144 ScDocument* pDok; 145 formula::FormulaTokenRef xResult; 146 ScJumpMatrix* pJumpMatrix; // currently active array condition, if any 147 ScTokenMatrixMap* pTokenMatrixMap; // map ScToken* to formula::FormulaTokenRef if in array condition 148 ScFormulaCell* pMyFormulaCell; // the cell of this formula expression 149 SvNumberFormatter* pFormatter; 150 151 const formula::FormulaToken* 152 pCur; // current token 153 String aTempStr; // for GetString() 154 ScTokenStack* pStackObj; // contains the stacks 155 formula::FormulaToken** pStack; // the current stack 156 sal_uInt16 nGlobalError; // global (local to this formula expression) error 157 sal_uInt16 sp; // stack pointer 158 sal_uInt16 maxsp; // the maximal used stack pointer 159 sal_uLong nFuncFmtIndex; // NumberFormatIndex of a function 160 sal_uLong nCurFmtIndex; // current NumberFormatIndex 161 sal_uLong nRetFmtIndex; // NumberFormatIndex of an expression, if any 162 short nFuncFmtType; // NumberFormatType of a function 163 short nCurFmtType; // current NumberFormatType 164 short nRetFmtType; // NumberFormatType of an expression 165 sal_uInt16 mnStringNoValueError; // the error set in ConvertStringToValue() if no value 166 sal_Bool glSubTotal; // flag for subtotal functions 167 sal_uInt8 cPar; // current count of parameters 168 sal_Bool bCalcAsShown; // precision as shown 169 sal_Bool bMatrixFormula; // formula cell is a matrix formula 170 171 //---------------------------------Funktionen in interpre.cxx--------- 172 // nMust <= nAct <= nMax ? ok : PushError 173 inline sal_Bool MustHaveParamCount( short nAct, short nMust ); 174 inline sal_Bool MustHaveParamCount( short nAct, short nMust, short nMax ); 175 inline sal_Bool MustHaveParamCountMin( short nAct, short nMin ); 176 void PushParameterExpected(); 177 void PushIllegalParameter(); 178 void PushIllegalArgument(); 179 void PushNoValue(); 180 void PushNA(); 181 //------------------------------------------------------------------------- 182 // Funktionen fuer den Zugriff auf das Document 183 //------------------------------------------------------------------------- 184 void ReplaceCell( ScAddress& ); // for TableOp 185 void ReplaceCell( SCCOL& rCol, SCROW& rRow, SCTAB& rTab ); // for TableOp 186 sal_Bool IsTableOpInRange( const ScRange& ); 187 sal_uLong GetCellNumberFormat( const ScAddress&, const ScBaseCell* ); 188 double ConvertStringToValue( const String& ); 189 double GetCellValue( const ScAddress&, const ScBaseCell* ); 190 double GetCellValueOrZero( const ScAddress&, const ScBaseCell* ); 191 double GetValueCellValue( const ScAddress&, const ScValueCell* ); 192 ScBaseCell* GetCell( const ScAddress& rPos ) 193 { return pDok->GetCell( rPos ); } 194 void GetCellString( String& rStr, const ScBaseCell* pCell ); 195 inline sal_uInt16 GetCellErrCode( const ScBaseCell* pCell ) 196 { return pCell ? pCell->GetErrorCode() : 0; } 197 inline CellType GetCellType( const ScBaseCell* pCell ) 198 { return pCell ? pCell->GetCellType() : CELLTYPE_NONE; } 199 /// Really empty or inherited emptiness. 200 inline sal_Bool HasCellEmptyData( const ScBaseCell* pCell ) 201 { return pCell ? pCell->HasEmptyData() : sal_True; } 202 /// This includes inherited emptiness, which usually is regarded as value! 203 inline sal_Bool HasCellValueData( const ScBaseCell* pCell ) 204 { return pCell ? pCell->HasValueData() : sal_False; } 205 /// Not empty and not value. 206 inline sal_Bool HasCellStringData( const ScBaseCell* pCell ) 207 { return pCell ? pCell->HasStringData() : sal_False; } 208 209 sal_Bool CreateDoubleArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, 210 SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8* pCellArr); 211 sal_Bool CreateStringArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, 212 SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8* pCellArr); 213 sal_Bool CreateCellArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, 214 SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8* pCellArr); 215 216 //----------------------------------------------------------------------------- 217 // Stack operations 218 //----------------------------------------------------------------------------- 219 220 /** Does substitute with formula::FormulaErrorToken in case nGlobalError is set and the token 221 passed is not formula::FormulaErrorToken. 222 Increments RefCount of the original token if not substituted. */ 223 void Push( formula::FormulaToken& r ); 224 225 /** Does not substitute with formula::FormulaErrorToken in case nGlobalError is set. 226 Used to push RPN tokens or from within Push() or tokens that are already 227 explicit formula::FormulaErrorToken. Increments RefCount. */ 228 void PushWithoutError( formula::FormulaToken& r ); 229 230 /** Clones the token to be pushed or substitutes with formula::FormulaErrorToken if 231 nGlobalError is set and the token passed is not formula::FormulaErrorToken. */ 232 void PushTempToken( const formula::FormulaToken& ); 233 234 /** Does substitute with formula::FormulaErrorToken in case nGlobalError is set and the token 235 passed is not formula::FormulaErrorToken. 236 Increments RefCount of the original token if not substituted. 237 ATTENTION! The token had to be allocated with `new' and must not be used 238 after this call if no RefCount was set because possibly it gets immediately 239 deleted in case of an errStackOverflow or if substituted with formula::FormulaErrorToken! */ 240 void PushTempToken( formula::FormulaToken* ); 241 242 /** Does not substitute with formula::FormulaErrorToken in case nGlobalError is set. 243 Used to push tokens from within PushTempToken() or tokens that are already 244 explicit formula::FormulaErrorToken. Increments RefCount. 245 ATTENTION! The token had to be allocated with `new' and must not be used 246 after this call if no RefCount was set because possibly it gets immediately 247 decremented again and thus deleted in case of an errStackOverflow! */ 248 void PushTempTokenWithoutError( formula::FormulaToken* ); 249 250 /** If nGlobalError is set push formula::FormulaErrorToken. 251 If nGlobalError is not set do nothing. 252 Used in PushTempToken() and alike to simplify handling. 253 @return: <TRUE/> if nGlobalError. */ 254 inline bool IfErrorPushError() 255 { 256 if (nGlobalError) 257 { 258 PushTempTokenWithoutError( new formula::FormulaErrorToken( nGlobalError)); 259 return true; 260 } 261 return false; 262 } 263 264 /** Obtain cell result / content from address and push as temp token. 265 bDisplayEmptyAsString is passed to ScEmptyCell in case of an empty cell 266 result. Also obtain number format and type if _both_, type and index 267 pointer, are not NULL. */ 268 void PushCellResultToken( bool bDisplayEmptyAsString, const ScAddress & rAddress, 269 short * pRetTypeExpr, sal_uLong * pRetIndexExpr ); 270 271 formula::FormulaTokenRef PopToken(); 272 void Pop(); 273 void PopError(); 274 double PopDouble(); 275 const String& PopString(); 276 void ValidateRef( const ScSingleRefData & rRef ); 277 void ValidateRef( const ScComplexRefData & rRef ); 278 void ValidateRef( const ScRefList & rRefList ); 279 void SingleRefToVars( const ScSingleRefData & rRef, SCCOL & rCol, SCROW & rRow, SCTAB & rTab ); 280 void PopSingleRef( ScAddress& ); 281 void PopSingleRef(SCCOL& rCol, SCROW &rRow, SCTAB& rTab); 282 void DoubleRefToRange( const ScComplexRefData&, ScRange&, sal_Bool bDontCheckForTableOp = sal_False ); 283 /** If formula::StackVar formula::svDoubleRef pop ScDoubleRefToken and return values of 284 ScComplexRefData. 285 Else if StackVar svRefList return values of the ScComplexRefData where 286 rRefInList is pointing to. rRefInList is incremented. If rRefInList was the 287 last element in list pop ScRefListToken and set rRefInList to 0, else 288 rParam is incremented (!) to allow usage as in 289 while(nParamCount--) PopDoubleRef(aRange,nParamCount,nRefInList); 290 */ 291 void PopDoubleRef( ScRange & rRange, short & rParam, size_t & rRefInList ); 292 void PopDoubleRef( ScRange&, sal_Bool bDontCheckForTableOp = sal_False ); 293 void DoubleRefToVars( const ScToken* p, 294 SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1, 295 SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2, 296 sal_Bool bDontCheckForTableOp = sal_False ); 297 ScDBRangeBase* PopDoubleRef(); 298 void PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1, 299 SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2, 300 sal_Bool bDontCheckForTableOp = sal_False ); 301 sal_Bool PopDoubleRefOrSingleRef( ScAddress& rAdr ); 302 void PopDoubleRefPushMatrix(); 303 // If MatrixFormula: convert formula::svDoubleRef to svMatrix, create JumpMatrix. 304 // Else convert area reference parameters marked as ForceArray to array. 305 // Returns sal_True if JumpMatrix created. 306 bool ConvertMatrixParameters(); 307 inline void MatrixDoubleRefToMatrix(); // if MatrixFormula: PopDoubleRefPushMatrix 308 // If MatrixFormula or ForceArray: ConvertMatrixParameters() 309 inline bool MatrixParameterConversion(); 310 ScMatrixRef PopMatrix(); 311 //void PushByte(sal_uInt8 nVal); 312 void PushDouble(double nVal); 313 void PushInt( int nVal ); 314 void PushStringBuffer( const sal_Unicode* pString ); 315 void PushString( const String& rString ); 316 void PushSingleRef(SCCOL nCol, SCROW nRow, SCTAB nTab); 317 void PushDoubleRef(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, 318 SCCOL nCol2, SCROW nRow2, SCTAB nTab2); 319 void PushMatrix(ScMatrix* pMat); 320 void PushError( sal_uInt16 nError ); 321 /// Raw stack type without default replacements. 322 formula::StackVar GetRawStackType(); 323 /// Stack type with replacement of defaults, e.g. svMissing and formula::svEmptyCell will result in formula::svDouble. 324 formula::StackVar GetStackType(); 325 // peek StackType of Parameter, Parameter 1 == TOS, 2 == TOS-1, ... 326 formula::StackVar GetStackType( sal_uInt8 nParam ); 327 sal_uInt8 GetByte() { return cPar; } 328 // generiert aus DoubleRef positionsabhaengige SingleRef 329 sal_Bool DoubleRefToPosSingleRef( const ScRange& rRange, ScAddress& rAdr ); 330 double GetDouble(); 331 double GetDoubleWithDefault(double nDefault); 332 sal_Bool IsMissing(); 333 sal_Bool GetBool() { return GetDouble() != 0.0; } 334 const String& GetString(); 335 // pop matrix and obtain one element, upper left or according to jump matrix 336 ScMatValType GetDoubleOrStringFromMatrix( double& rDouble, String& rString ); 337 ScMatrixRef CreateMatrixFromDoubleRef( const formula::FormulaToken* pToken, 338 SCCOL nCol1, SCROW nRow1, SCTAB nTab1, 339 SCCOL nCol2, SCROW nRow2, SCTAB nTab2 ); 340 inline ScTokenMatrixMap& GetTokenMatrixMap(); 341 ScTokenMatrixMap* CreateTokenMatrixMap(); 342 ScMatrixRef GetMatrix(); 343 void ScTableOp(); // Mehrfachoperationen 344 void ScErrCell(); // Sonderbehandlung 345 // Fehlerzelle 346 //-----------------------------allgemeine Hilfsfunktionen 347 void SetMaxIterationCount(sal_uInt16 n); 348 inline void CurFmtToFuncFmt() 349 { nFuncFmtType = nCurFmtType; nFuncFmtIndex = nCurFmtIndex; } 350 // Check for String overflow of rResult+rAdd and set error and erase rResult 351 // if so. Return sal_True if ok, sal_False if overflow 352 inline sal_Bool CheckStringResultLen( String& rResult, const String& rAdd ); 353 // Set error according to rVal, and set rVal to 0.0 if there was an error. 354 inline void TreatDoubleError( double& rVal ); 355 // Lookup using ScLookupCache, @returns sal_True if found and result address 356 bool LookupQueryWithCache( ScAddress & o_rResultPos, 357 const ScQueryParam & rParam ) const; 358 359 //---------------------------------Funktionen in interpr1.cxx--------- 360 void ScIfJump(); 361 void ScChoseJump(); 362 363 // Be sure to only call this if pStack[sp-nStackLevel] really contains a 364 // ScJumpMatrixToken, no further checks are applied! 365 // Returns true if last jump was executed and result matrix pushed. 366 bool JumpMatrix( short nStackLevel ); 367 368 /** @param pOptions 369 NULL means case sensitivity document option is to be used! 370 */ 371 double CompareFunc( const ScCompare& rComp, ScCompareOptions* pOptions = NULL ); 372 double Compare(); 373 /** @param pOptions 374 NULL means case sensitivity document option is to be used! 375 */ 376 ScMatrixRef CompareMat( ScCompareOptions* pOptions = NULL ); 377 ScMatrixRef QueryMat( ScMatrix* pMat, ScCompareOptions& rOptions ); 378 void ScEqual(); 379 void ScNotEqual(); 380 void ScLess(); 381 void ScGreater(); 382 void ScLessEqual(); 383 void ScGreaterEqual(); 384 void ScAnd(); 385 void ScOr(); 386 void ScNot(); 387 void ScNeg(); 388 void ScPercentSign(); 389 void ScIntersect(); 390 void ScRangeFunc(); 391 void ScUnionFunc(); 392 void ScPi(); 393 void ScRandom(); 394 void ScTrue(); 395 void ScFalse(); 396 void ScDeg(); 397 void ScRad(); 398 void ScSin(); 399 void ScCos(); 400 void ScTan(); 401 void ScCot(); 402 void ScArcSin(); 403 void ScArcCos(); 404 void ScArcTan(); 405 void ScArcCot(); 406 void ScSinHyp(); 407 void ScCosHyp(); 408 void ScTanHyp(); 409 void ScCotHyp(); 410 void ScArcSinHyp(); 411 void ScArcCosHyp(); 412 void ScArcTanHyp(); 413 void ScArcCotHyp(); 414 void ScCosecant(); 415 void ScSecant(); 416 void ScCosecantHyp(); 417 void ScSecantHyp(); 418 void ScExp(); 419 void ScLn(); 420 void ScLog10(); 421 void ScSqrt(); 422 void ScIsEmpty(); 423 short IsString(); 424 void ScIsString(); 425 void ScIsNonString(); 426 void ScIsLogical(); 427 void ScType(); 428 void ScCell(); 429 void ScIsRef(); 430 void ScIsValue(); 431 void ScIsFormula(); 432 void ScFormula(); 433 void ScRoman(); 434 void ScArabic(); 435 void ScIsNV(); 436 void ScIsErr(); 437 void ScIsError(); 438 short IsEven(); 439 void ScIsEven(); 440 void ScIsOdd(); 441 void ScN(); 442 void ScCode(); 443 void ScTrim(); 444 void ScUpper(); 445 void ScPropper(); 446 void ScLower(); 447 void ScLen(); 448 void ScT(); 449 void ScValue(); 450 void ScClean(); 451 void ScChar(); 452 void ScJis(); 453 void ScAsc(); 454 void ScUnicode(); 455 void ScUnichar(); 456 void ScMin( sal_Bool bTextAsZero = sal_False ); 457 void ScMax( sal_Bool bTextAsZero = sal_False ); 458 double IterateParameters( ScIterFunc, sal_Bool bTextAsZero = sal_False ); 459 void ScSumSQ(); 460 void ScSum(); 461 void ScProduct(); 462 void ScAverage( sal_Bool bTextAsZero = sal_False ); 463 void ScCount(); 464 void ScCount2(); 465 void GetStVarParams( double& rVal, double& rValCount, sal_Bool bTextAsZero = sal_False ); 466 void ScVar( sal_Bool bTextAsZero = sal_False ); 467 void ScVarP( sal_Bool bTextAsZero = sal_False ); 468 void ScStDev( sal_Bool bTextAsZero = sal_False ); 469 void ScStDevP( sal_Bool bTextAsZero = sal_False ); 470 void ScColumns(); 471 void ScRows(); 472 void ScTables(); 473 void ScColumn(); 474 void ScRow(); 475 void ScTable(); 476 void ScMatch(); 477 void ScCountIf(); 478 void ScSumIf(); 479 void ScCountEmptyCells(); 480 void ScLookup(); 481 void ScHLookup(); 482 void ScVLookup(); 483 void ScSubTotal(); 484 485 // If upon call rMissingField==sal_True then the database field parameter may be 486 // missing (Xcl DCOUNT() syntax), or may be faked as missing by having the 487 // value 0.0 or being exactly the entire database range reference (old SO 488 // compatibility). If this was the case then rMissingField is set to sal_True upon 489 // return. If rMissingField==sal_False upon call all "missing cases" are considered 490 // to be an error. 491 ScDBQueryParamBase* GetDBParams( sal_Bool& rMissingField ); 492 493 void DBIterator( ScIterFunc ); 494 void ScDBSum(); 495 void ScDBCount(); 496 void ScDBCount2(); 497 void ScDBAverage(); 498 void ScDBGet(); 499 void ScDBMax(); 500 void ScDBMin(); 501 void ScDBProduct(); 502 void GetDBStVarParams( double& rVal, double& rValCount ); 503 void ScDBStdDev(); 504 void ScDBStdDevP(); 505 void ScDBVar(); 506 void ScDBVarP(); 507 void ScIndirect(); 508 void ScAddressFunc(); 509 void ScOffset(); 510 void ScIndex(); 511 void ScMultiArea(); 512 void ScAreas(); 513 void ScCurrency(); 514 void ScReplace(); 515 void ScFixed(); 516 void ScFind(); 517 void ScExact(); 518 void ScLeft(); 519 void ScRight(); 520 void ScSearch(); 521 void ScMid(); 522 void ScText(); 523 void ScSubstitute(); 524 void ScRept(); 525 void ScConcat(); 526 void ScExternal(); 527 void ScMissing(); 528 void ScMacro(); 529 sal_Bool SetSbxVariable( SbxVariable* pVar, const ScAddress& ); 530 sal_Bool SetSbxVariable( SbxVariable* pVar, SCCOL nCol, SCROW nRow, SCTAB nTab ); 531 void ScErrorType(); 532 void ScDBArea(); 533 void ScColRowNameAuto(); 534 void ScExternalRef(); 535 void ScGetPivotData(); 536 void ScHyperLink(); 537 void ScBahtText(); 538 void ScTTT(); 539 540 //----------------Funktionen in interpr2.cxx--------------- 541 542 /** Obtain the date serial number for a given date. 543 @param bStrict 544 If sal_False, nYear < 100 takes the two-digit year setting into account, 545 and rollover of invalid calendar dates takes place, e.g. 1999-02-31 => 546 1999-03-03. 547 If sal_True, the date passed must be a valid Gregorian calendar date. No 548 two-digit expanding or rollover is done. 549 */ 550 double GetDateSerial( sal_Int16 nYear, sal_Int16 nMonth, sal_Int16 nDay, bool bStrict ); 551 552 void ScGetActDate(); 553 void ScGetActTime(); 554 void ScGetYear(); 555 void ScGetMonth(); 556 void ScGetDay(); 557 void ScGetDayOfWeek(); 558 void ScGetWeekOfYear(); 559 void ScEasterSunday(); 560 void ScGetHour(); 561 void ScGetMin(); 562 void ScGetSec(); 563 void ScPlusMinus(); 564 void ScAbs(); 565 void ScInt(); 566 void ScEven(); 567 void ScOdd(); 568 void ScCeil(); 569 void ScFloor(); 570 void RoundNumber( rtl_math_RoundingMode eMode ); 571 void ScRound(); 572 void ScRoundUp(); 573 void ScRoundDown(); 574 void ScGetDateValue(); 575 void ScGetTimeValue(); 576 void ScArcTan2(); 577 void ScLog(); 578 void ScGetDate(); 579 void ScGetTime(); 580 void ScGetDiffDate(); 581 void ScGetDiffDate360(); 582 void ScPower(); 583 void ScAmpersand(); 584 void ScAdd(); 585 void ScSub(); 586 void ScMul(); 587 void ScDiv(); 588 void ScPow(); 589 void ScCurrent(); 590 void ScStyle(); 591 void ScDde(); 592 void ScBase(); 593 void ScDecimal(); 594 void ScConvert(); 595 void ScEuroConvert(); 596 597 //----------------------- Finanzfunktionen ------------------------------------ 598 void ScNPV(); 599 void ScIRR(); 600 void ScMIRR(); 601 void ScISPMT(); 602 603 double ScGetBw(double fZins, double fZzr, double fRmz, 604 double fZw, double fF); 605 void ScBW(); 606 void ScDIA(); 607 double ScGetGDA(double fWert, double fRest, double fDauer, 608 double fPeriode, double fFaktor); 609 void ScGDA(); 610 void ScGDA2(); 611 double ScInterVDB(double fWert,double fRest,double fDauer,double fDauer1, 612 double fPeriode,double fFaktor); 613 void ScVDB(); 614 void ScLaufz(); 615 void ScLIA(); 616 double ScGetRmz(double fZins, double fZzr, double fBw, 617 double fZw, double fF); 618 void ScRMZ(); 619 void ScZGZ(); 620 double ScGetZw(double fZins, double fZzr, double fRmz, 621 double fBw, double fF); 622 void ScZW(); 623 void ScZZR(); 624 bool RateIteration(double fNper, double fPayment, double fPv, 625 double fFv, double fPayType, double& fGuess); 626 void ScZins(); 627 double ScGetZinsZ(double fZins, double fZr, double fZzr, double fBw, 628 double fZw, double fF, double& fRmz); 629 void ScZinsZ(); 630 void ScKapz(); 631 void ScKumZinsZ(); 632 void ScKumKapZ(); 633 void ScEffektiv(); 634 void ScNominal(); 635 void ScMod(); 636 void ScBackSolver(); 637 void ScIntercept(); 638 //-------------------------Funktionen in interpr5.cxx-------------------------- 639 double ScGetGCD(double fx, double fy); 640 void ScGCD(); 641 void ScLCM(); 642 //-------------------------- Matrixfunktionen --------------------------------- 643 644 void ScMatValue(); 645 void MEMat(ScMatrix* mM, SCSIZE n); 646 void ScMatDet(); 647 void ScMatInv(); 648 void ScMatMult(); 649 void ScMatTrans(); 650 void ScEMat(); 651 void ScMatRef(); 652 ScMatrixRef MatConcat(ScMatrix* pMat1, ScMatrix* pMat2); 653 void ScSumProduct(); 654 void ScSumX2MY2(); 655 void ScSumX2DY2(); 656 void ScSumXMY2(); 657 void ScGrowth(); 658 bool CalculateSkew(double& fSum,double& fCount,double& vSum,std::vector<double>& values); 659 void CalculateSlopeIntercept(sal_Bool bSlope); 660 void CalculateSmallLarge(sal_Bool bSmall); 661 void CalculatePearsonCovar(sal_Bool _bPearson,sal_Bool _bStexy); 662 bool CalculateTest( sal_Bool _bTemplin 663 ,const SCSIZE nC1, const SCSIZE nC2,const SCSIZE nR1,const SCSIZE nR2 664 ,const ScMatrixRef& pMat1,const ScMatrixRef& pMat2 665 ,double& fT,double& fF); 666 void CalculateLookup(sal_Bool HLookup); 667 bool FillEntry(ScQueryEntry& rEntry); 668 void CalculateAddSub(sal_Bool _bSub); 669 void CalculateTrendGrowth(bool _bGrowth); 670 void CalulateRGPRKP(bool _bRKP); 671 void CalculateSumX2MY2SumX2DY2(sal_Bool _bSumX2DY2); 672 void CalculateMatrixValue(const ScMatrix* pMat,SCSIZE nC,SCSIZE nR); 673 bool CheckMatrix(bool _bLOG,sal_uInt8& nCase,SCSIZE& nCX,SCSIZE& nCY,SCSIZE& nRX,SCSIZE& nRY,SCSIZE& M,SCSIZE& N,ScMatrixRef& pMatX,ScMatrixRef& pMatY); 674 void ScRGP(); 675 void ScRKP(); 676 void ScForecast(); 677 //------------------------- Functions in interpr3.cxx ------------------------- 678 void ScNoName(); 679 void ScBadName(); 680 // Statistik: 681 double phi(double x); 682 double integralPhi(double x); 683 double taylor(double* pPolynom, sal_uInt16 nMax, double x); 684 double gauss(double x); 685 double gaussinv(double x); 686 double GetBetaDist(double x, double alpha, double beta); //cumulative distribution function 687 double GetBetaDistPDF(double fX, double fA, double fB); //probability density function) 688 double GetChiDist(double fChi, double fDF); // for LEGACY.CHIDIST, returns right tail 689 double GetChiSqDistCDF(double fX, double fDF); // for CHISQDIST, returns left tail 690 double GetChiSqDistPDF(double fX, double fDF); // probability density function 691 double GetFDist(double x, double fF1, double fF2); 692 double GetTDist(double T, double fDF); 693 double Fakultaet(double x); 694 double BinomKoeff(double n, double k); 695 double GetGamma(double x); 696 double GetLogGamma(double x); 697 double GetBeta(double fAlpha, double fBeta); 698 double GetLogBeta(double fAlpha, double fBeta); 699 double GetBinomDistPMF(double x, double n, double p); //probability mass function 700 void ScLogGamma(); 701 void ScGamma(); 702 void ScPhi(); 703 void ScGauss(); 704 void ScStdNormDist(); 705 void ScFisher(); 706 void ScFisherInv(); 707 void ScFact(); 708 void ScNormDist(); 709 void ScGammaDist(); 710 void ScGammaInv(); 711 void ScExpDist(); 712 void ScBinomDist(); 713 void ScPoissonDist(); 714 void ScKombin(); 715 void ScKombin2(); 716 void ScVariationen(); 717 void ScVariationen2(); 718 void ScB(); 719 void ScHypGeomDist(); 720 void ScLogNormDist(); 721 void ScLogNormInv(); 722 void ScTDist(); 723 void ScFDist(); 724 void ScChiDist(); // for LEGACY.CHIDIST, returns right tail 725 void ScChiSqDist(); // returns left tail or density 726 void ScChiSqInv(); //invers to CHISQDIST 727 void ScWeibull(); 728 void ScBetaDist(); 729 void ScFInv(); 730 void ScTInv(); 731 void ScChiInv(); 732 void ScBetaInv(); 733 void ScCritBinom(); 734 void ScNegBinomDist(); 735 void ScKurt(); 736 void ScHarMean(); 737 void ScGeoMean(); 738 void ScStandard(); 739 void ScSkew(); 740 void ScMedian(); 741 double GetMedian( ::std::vector<double> & rArray ); 742 double GetPercentile( ::std::vector<double> & rArray, double fPercentile ); 743 void GetNumberSequenceArray( sal_uInt8 nParamCount, ::std::vector<double>& rArray ); 744 void GetSortArray(sal_uInt8 nParamCount, ::std::vector<double>& rSortArray, ::std::vector<long>* pIndexOrder = NULL); 745 void QuickSort(::std::vector<double>& rSortArray, ::std::vector<long>* pIndexOrder = NULL); 746 void ScModalValue(); 747 void ScAveDev(); 748 void ScDevSq(); 749 void ScZTest(); 750 void ScTTest(); 751 void ScFTest(); 752 void ScChiTest(); 753 void ScRank(); 754 void ScPercentile(); 755 void ScPercentrank(); 756 void ScLarge(); 757 void ScSmall(); 758 void ScFrequency(); 759 void ScQuartile(); 760 void ScNormInv(); 761 void ScSNormInv(); 762 void ScConfidence(); 763 void ScTrimMean(); 764 void ScProbability(); 765 void ScCorrel(); 766 void ScCovar(); 767 void ScPearson(); 768 void ScRSQ(); 769 void ScSTEXY(); 770 void ScSlope(); 771 void ScTrend(); 772 void ScInfo(); 773 774 //------------------------ Functions in interpr6.cxx ------------------------- 775 776 static const double fMaxGammaArgument; // defined in interpr3.cxx 777 778 double GetGammaContFraction(double fA,double fX); 779 double GetGammaSeries(double fA,double fX); 780 double GetLowRegIGamma(double fA,double fX); // lower regularized incomplete gamma function, GAMMAQ 781 double GetUpRegIGamma(double fA,double fX); // upper regularized incomplete gamma function, GAMMAP 782 // probability density function; fLambda is "scale" parameter 783 double GetGammaDistPDF(double fX, double fAlpha, double fLambda); 784 // cumulative distribution function; fLambda is "scale" parameter 785 double GetGammaDist(double fX, double fAlpha, double fLambda); 786 787 //---------------------------------------------------------------------------- 788 public: 789 ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc, 790 const ScAddress&, ScTokenArray& ); 791 ~ScInterpreter(); 792 793 formula::StackVar Interpret(); 794 795 void SetError(sal_uInt16 nError) 796 { if (nError && !nGlobalError) nGlobalError = nError; } 797 798 sal_uInt16 GetError() const { return nGlobalError; } 799 formula::StackVar GetResultType() const { return xResult->GetType(); } 800 const String& GetStringResult() const { return xResult->GetString(); } 801 double GetNumResult() const { return xResult->GetDouble(); } 802 formula::FormulaTokenRef 803 GetResultToken() const { return xResult; } 804 short GetRetFormatType() const { return nRetFmtType; } 805 sal_uLong GetRetFormatIndex() const { return nRetFmtIndex; } 806 }; 807 808 809 inline void ScInterpreter::MatrixDoubleRefToMatrix() 810 { 811 if ( bMatrixFormula && GetStackType() == formula::svDoubleRef ) 812 { 813 GetTokenMatrixMap(); // make sure it exists, create if not. 814 PopDoubleRefPushMatrix(); 815 } 816 } 817 818 819 inline bool ScInterpreter::MatrixParameterConversion() 820 { 821 if ( (bMatrixFormula || pCur->HasForceArray()) && !pJumpMatrix && sp > 0 ) 822 return ConvertMatrixParameters(); 823 return false; 824 } 825 826 827 inline ScTokenMatrixMap& ScInterpreter::GetTokenMatrixMap() 828 { 829 if (!pTokenMatrixMap) 830 pTokenMatrixMap = CreateTokenMatrixMap(); 831 return *pTokenMatrixMap; 832 } 833 834 835 inline sal_Bool ScInterpreter::MustHaveParamCount( short nAct, short nMust ) 836 { 837 if ( nAct == nMust ) 838 return sal_True; 839 if ( nAct < nMust ) 840 PushParameterExpected(); 841 else 842 PushIllegalParameter(); 843 return sal_False; 844 } 845 846 847 inline sal_Bool ScInterpreter::MustHaveParamCount( short nAct, short nMust, short nMax ) 848 { 849 if ( nMust <= nAct && nAct <= nMax ) 850 return sal_True; 851 if ( nAct < nMust ) 852 PushParameterExpected(); 853 else 854 PushIllegalParameter(); 855 return sal_False; 856 } 857 858 859 inline sal_Bool ScInterpreter::MustHaveParamCountMin( short nAct, short nMin ) 860 { 861 if ( nAct >= nMin ) 862 return sal_True; 863 PushParameterExpected(); 864 return sal_False; 865 } 866 867 868 inline sal_Bool ScInterpreter::CheckStringResultLen( String& rResult, const String& rAdd ) 869 { 870 if ( (sal_uLong) rResult.Len() + rAdd.Len() > STRING_MAXLEN ) 871 { 872 SetError( errStringOverflow ); 873 rResult.Erase(); 874 return sal_False; 875 } 876 return sal_True; 877 } 878 879 880 inline void ScInterpreter::TreatDoubleError( double& rVal ) 881 { 882 if ( !::rtl::math::isFinite( rVal ) ) 883 { 884 sal_uInt16 nErr = GetDoubleErrorValue( rVal ); 885 if ( nErr ) 886 SetError( nErr ); 887 else 888 SetError( errNoValue ); 889 rVal = 0.0; 890 } 891 } 892 893 894 // static 895 inline double ScInterpreter::div( const double& fNumerator, const double& fDenominator ) 896 { 897 return (fDenominator != 0.0) ? (fNumerator / fDenominator) : 898 CreateDoubleError( errDivisionByZero); 899 } 900 901 #endif 902