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