ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
PHPExcel_Calculation Class Reference
+ Collaboration diagram for PHPExcel_Calculation:

Public Member Functions

 __destruct ()
 
 flushInstance ()
 Flush the calculation cache for any existing instance of this class but only if a PHPExcel_Calculation instance exists. More...
 
 getDebugLog ()
 Get the debuglog for this claculation engine instance. More...
 
 __clone ()
 __clone implementation. More...
 
 getCalculationCacheEnabled ()
 Is calculation caching enabled? More...
 
 setCalculationCacheEnabled ($pValue=TRUE)
 Enable/disable calculation cache. More...
 
 enableCalculationCache ()
 Enable calculation cache. More...
 
 disableCalculationCache ()
 Disable calculation cache. More...
 
 clearCalculationCache ()
 Clear calculation cache. More...
 
 clearCalculationCacheForWorksheet ($worksheetName)
 Clear calculation cache for a specified worksheet. More...
 
 renameCalculationCacheForWorksheet ($fromWorksheetName, $toWorksheetName)
 Rename calculation cache for a specified worksheet. More...
 
 getLocale ()
 Get the currently defined locale code. More...
 
 setLocale ($locale='en_us')
 Set the locale code. More...
 
 _translateFormulaToLocale ($formula)
 
 _translateFormulaToEnglish ($formula)
 
 calculate (PHPExcel_Cell $pCell=NULL)
 Calculate cell value (using formula from a cell ID) Retained for backward compatibility. More...
 
 calculateCellValue (PHPExcel_Cell $pCell=NULL, $resetLog=TRUE)
 Calculate the value of a cell formula. More...
 
 parseFormula ($formula)
 Validate and parse a formula string. More...
 
 calculateFormula ($formula, $cellID=NULL, PHPExcel_Cell $pCell=NULL)
 Calculate the value of a formula. More...
 
 getValueFromCache ($cellReference, &$cellValue)
 
 saveValueToCache ($cellReference, $cellValue)
 
 _calculateFormulaValue ($formula, $cellID=null, PHPExcel_Cell $pCell=null)
 Parse a cell formula and calculate its value. More...
 
 extractCellRange (&$pRange='A1', PHPExcel_Worksheet $pSheet=NULL, $resetLog=TRUE)
 Extract range values. More...
 
 extractNamedRange (&$pRange='A1', PHPExcel_Worksheet $pSheet=NULL, $resetLog=TRUE)
 Extract range values. More...
 
 isImplemented ($pFunction='')
 Is a specific function implemented? More...
 
 listFunctions ()
 Get a list of all implemented functions as an array of function objects. More...
 
 listAllFunctionNames ()
 Get a list of all Excel function names. More...
 
 listFunctionNames ()
 Get a list of implemented Excel function names. More...
 

Static Public Member Functions

static getInstance (PHPExcel $workbook=NULL)
 Get an instance of this class. More...
 
static unsetInstance (PHPExcel $workbook=NULL)
 Unset an instance of this class. More...
 
static getTRUE ()
 Return the locale-specific translation of TRUE. More...
 
static getFALSE ()
 Return the locale-specific translation of FALSE. More...
 
static setArrayReturnType ($returnType)
 Set the Array Return Type (Array or Value of first element in the array) More...
 
static getArrayReturnType ()
 Return the Array Return Type (Array or Value of first element in the array) More...
 
static _translateSeparator ($fromSeparator, $toSeparator, $formula, &$inBraces)
 
static _localeFunc ($function)
 
static _wrapResult ($value)
 Wrap string values in quotes. More...
 
static _unwrapResult ($value)
 Remove quotes used as a wrapper to identify string values. More...
 
static _getMatrixDimensions (&$matrix)
 Read the dimensions of a matrix, and re-index it with straight numeric keys starting from row 0, column 0. More...
 

Data Fields

const CALCULATION_REGEXP_NUMBER = '[-+]?\d*\.?\d+(e[-+]?\d+)?'
 Constants. More...
 
const CALCULATION_REGEXP_STRING = '"(?:[^"]|"")*"'
 
const CALCULATION_REGEXP_OPENBRACE = '\('
 
const CALCULATION_REGEXP_FUNCTION = '@?([A-Z][A-Z0-9\.]*)[\s]*\('
 
const CALCULATION_REGEXP_CELLREF = CALCULATION_REGEXP_CELLREF
 
const CALCULATION_REGEXP_NAMEDRANGE = CALCULATION_REGEXP_NAMEDRANGE
 
const CALCULATION_REGEXP_ERROR = '\#[A-Z][A-Z0_\/]*[!\?]?'
 
const RETURN_ARRAY_AS_ERROR = 'error'
 constants More...
 
const RETURN_ARRAY_AS_VALUE = 'value'
 
const RETURN_ARRAY_AS_ARRAY = 'array'
 
 $suppressFormulaErrors = FALSE
 
 $formulaError = NULL
 
 $cyclicFormulaCount = 1
 

Static Public Attributes

static $_localeBoolean
 

Protected Member Functions

 _raiseFormulaError ($errorMessage)
 

Private Member Functions

 __construct (PHPExcel $workbook=NULL)
 
 _showValue ($value)
 Format details of an operand for display in the log (based on operand type) More...
 
 _showTypeDetails ($value)
 Format type and details of an operand for display in the log (based on operand type) More...
 
 _convertMatrixReferences ($formula)
 
 _parseFormula ($formula, PHPExcel_Cell $pCell=NULL)
 
 _processTokenStack ($tokens, $cellID=NULL, PHPExcel_Cell $pCell=NULL)
 
 _validateBinaryOperand ($cellID, &$operand, &$stack)
 
 _executeBinaryComparisonOperation ($cellID, $operand1, $operand2, $operation, &$stack, $recursingArrays=FALSE)
 
 strcmpLowercaseFirst ($str1, $str2)
 Compare two strings in the same way as strcmp() except that lowercase come before uppercase letters. More...
 
 _executeNumericBinaryOperation ($cellID, $operand1, $operand2, $operation, $matrixFunction, &$stack)
 

Static Private Member Functions

static _loadLocales ()
 
static _translateFormula ($from, $to, $formula, $fromSeparator, $toSeparator)
 
static _checkMatrixOperands (&$operand1, &$operand2, $resize=1)
 Ensure that paired matrix operands are both matrices and of the same size. More...
 
static _resizeMatricesShrink (&$matrix1, &$matrix2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns)
 Ensure that paired matrix operands are both matrices of the same size. More...
 
static _resizeMatricesExtend (&$matrix1, &$matrix2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns)
 Ensure that paired matrix operands are both matrices of the same size. More...
 
static _mkMatrix ()
 
static _dataTestReference (&$operandData)
 

Private Attributes

 $_workbook
 
 $_calculationCache = array ()
 
 $_calculationCacheEnabled = TRUE
 
 $debugLog
 
 $_cyclicReferenceStack
 
 $_cellStack = array()
 
 $_cyclicFormulaCount = 1
 
 $_cyclicFormulaCell = ''
 
 $_savedPrecision = 14
 

Static Private Attributes

static $returnArrayAsType = self::RETURN_ARRAY_AS_VALUE
 
static $_instance
 
static $_workbookSets
 
static $_operators
 
static $_binaryOperators
 
static $_localeLanguage = 'en_us'
 
static $_validLocaleLanguages
 
static $_localeArgumentSeparator = ','
 
static $_localeFunctions = array()
 
static $_ExcelConstants
 
static $_PHPExcelFunctions
 
static $_controlFunctions
 
static $functionReplaceFromExcel = NULL
 
static $functionReplaceToLocale = NULL
 
static $functionReplaceFromLocale = NULL
 
static $functionReplaceToExcel = NULL
 
static $_operatorAssociativity
 
static $_comparisonOperators = array('>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE)
 
static $_operatorPrecedence
 

Detailed Description

Definition at line 62 of file Calculation.php.

Constructor & Destructor Documentation

◆ __construct()

PHPExcel_Calculation::__construct ( PHPExcel  $workbook = NULL)
private

Definition at line 1723 of file Calculation.php.

1723  {
1724  $setPrecision = (PHP_INT_SIZE == 4) ? 14 : 16;
1725  $this->_savedPrecision = ini_get('precision');
1726  if ($this->_savedPrecision < $setPrecision) {
1727  ini_set('precision',$setPrecision);
1728  }
1729  $this->delta = 1 * pow(10, -$setPrecision);
1730 
1731  if ($workbook !== NULL) {
1732  self::$_workbookSets[$workbook->getID()] = $this;
1733  }
1734 
1735  $this->_workbook = $workbook;
1736  $this->_cyclicReferenceStack = new PHPExcel_CalcEngine_CyclicReferenceStack();
1737  $this->_debugLog = new PHPExcel_CalcEngine_Logger($this->_cyclicReferenceStack);
1738  } // function __construct()
getID()
Return the unique ID value assigned to this spreadsheet workbook.
Definition: PHPExcel.php:1135

◆ __destruct()

PHPExcel_Calculation::__destruct ( )

Definition at line 1741 of file Calculation.php.

1741  {
1742  if ($this->_savedPrecision != ini_get('precision')) {
1743  ini_set('precision',$this->_savedPrecision);
1744  }
1745  }

Member Function Documentation

◆ __clone()

PHPExcel_Calculation::__clone ( )
final

__clone implementation.

Cloning should not be allowed in a Singleton!

public

Exceptions
PHPExcel_Calculation_Exception

Definition at line 1822 of file Calculation.php.

1822  {
1823  throw new PHPExcel_Calculation_Exception ('Cloning the calculation engine is not allowed!');
1824  } // function __clone()

◆ _calculateFormulaValue()

PHPExcel_Calculation::_calculateFormulaValue (   $formula,
  $cellID = null,
PHPExcel_Cell  $pCell = null 
)

Parse a cell formula and calculate its value.

Parameters
string$formulaThe formula to parse and calculate
string$cellIDThe ID (e.g. A3) of the cell that we are calculating
PHPExcel_Cell$pCellCell to calculate
Returns
mixed
Exceptions
PHPExcel_Calculation_Exception

Definition at line 2375 of file Calculation.php.

References $_cyclicFormulaCount, _parseFormula(), _processTokenStack(), _raiseFormulaError(), getValueFromCache(), and saveValueToCache().

Referenced by calculateCellValue(), and calculateFormula().

2375  {
2376  $cellValue = null;
2377 
2378  // Basic validation that this is indeed a formula
2379  // We simply return the cell value if not
2380  $formula = trim($formula);
2381  if ($formula{0} != '=') return self::_wrapResult($formula);
2382  $formula = ltrim(substr($formula, 1));
2383  if (!isset($formula{0})) return self::_wrapResult($formula);
2384 
2385  $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL;
2386  $wsTitle = ($pCellParent !== NULL) ? $pCellParent->getTitle() : "\x00Wrk";
2387  $wsCellReference = $wsTitle . '!' . $cellID;
2388 
2389  if (($cellID !== NULL) && ($this->getValueFromCache($wsCellReference, $cellValue))) {
2390  return $cellValue;
2391  }
2392 
2393  if (($wsTitle{0} !== "\x00") && ($this->_cyclicReferenceStack->onStack($wsCellReference))) {
2394  if ($this->cyclicFormulaCount <= 0) {
2395  $this->_cyclicFormulaCell = '';
2396  return $this->_raiseFormulaError('Cyclic Reference in Formula');
2397  } elseif ($this->_cyclicFormulaCell === $wsCellReference) {
2399  if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) {
2400  $this->_cyclicFormulaCell = '';
2401  return $cellValue;
2402  }
2403  } elseif ($this->_cyclicFormulaCell == '') {
2404  if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) {
2405  return $cellValue;
2406  }
2407  $this->_cyclicFormulaCell = $wsCellReference;
2408  }
2409  }
2410 
2411  // Parse the formula onto the token stack and calculate the value
2412  $this->_cyclicReferenceStack->push($wsCellReference);
2413  $cellValue = $this->_processTokenStack($this->_parseFormula($formula, $pCell), $cellID, $pCell);
2414  $this->_cyclicReferenceStack->pop();
2415 
2416  // Save to calculation cache
2417  if ($cellID !== NULL) {
2418  $this->saveValueToCache($wsCellReference, $cellValue);
2419  }
2420 
2421  // Return the calculated value
2422  return $cellValue;
2423  } // function _calculateFormulaValue()
saveValueToCache($cellReference, $cellValue)
_processTokenStack($tokens, $cellID=NULL, PHPExcel_Cell $pCell=NULL)
_parseFormula($formula, PHPExcel_Cell $pCell=NULL)
_raiseFormulaError($errorMessage)
getValueFromCache($cellReference, &$cellValue)
getWorksheet()
Get parent worksheet.
Definition: Cell.php:488
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _checkMatrixOperands()

static PHPExcel_Calculation::_checkMatrixOperands ( $operand1,
$operand2,
  $resize = 1 
)
staticprivate

Ensure that paired matrix operands are both matrices and of the same size.

Parameters
mixed&$operand1First matrix operand
mixed&$operand2Second matrix operand
integer$resizeFlag indicating whether the matrices should be resized to match and (if so), whether the smaller dimension should grow or the larger should shrink. 0 = no resize 1 = shrink to fit 2 = extend to fit

Definition at line 2438 of file Calculation.php.

References array.

2438  {
2439  // Examine each of the two operands, and turn them into an array if they aren't one already
2440  // Note that this function should only be called if one or both of the operand is already an array
2441  if (!is_array($operand1)) {
2442  list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand2);
2443  $operand1 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand1));
2444  $resize = 0;
2445  } elseif (!is_array($operand2)) {
2446  list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand1);
2447  $operand2 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand2));
2448  $resize = 0;
2449  }
2450 
2451  list($matrix1Rows,$matrix1Columns) = self::_getMatrixDimensions($operand1);
2452  list($matrix2Rows,$matrix2Columns) = self::_getMatrixDimensions($operand2);
2453  if (($matrix1Rows == $matrix2Columns) && ($matrix2Rows == $matrix1Columns)) {
2454  $resize = 1;
2455  }
2456 
2457  if ($resize == 2) {
2458  // Given two matrices of (potentially) unequal size, convert the smaller in each dimension to match the larger
2459  self::_resizeMatricesExtend($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns);
2460  } elseif ($resize == 1) {
2461  // Given two matrices of (potentially) unequal size, convert the larger in each dimension to match the smaller
2462  self::_resizeMatricesShrink($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns);
2463  }
2464  return array( $matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns);
2465  } // function _checkMatrixOperands()
Create styles array
The data for the language used.

◆ _convertMatrixReferences()

PHPExcel_Calculation::_convertMatrixReferences (   $formula)
private

Definition at line 2652 of file Calculation.php.

References _raiseFormulaError(), and array.

Referenced by _parseFormula().

2652  {
2653  static $matrixReplaceFrom = array('{',';','}');
2654  static $matrixReplaceTo = array('MKMATRIX(MKMATRIX(','),MKMATRIX(','))');
2655 
2656  // Convert any Excel matrix references to the MKMATRIX() function
2657  if (strpos($formula,'{') !== FALSE) {
2658  // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators
2659  if (strpos($formula,'"') !== FALSE) {
2660  // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded
2661  // the formula
2662  $temp = explode('"',$formula);
2663  // Open and Closed counts used for trapping mismatched braces in the formula
2664  $openCount = $closeCount = 0;
2665  $i = FALSE;
2666  foreach($temp as &$value) {
2667  // Only count/replace in alternating array entries
2668  if ($i = !$i) {
2669  $openCount += substr_count($value,'{');
2670  $closeCount += substr_count($value,'}');
2671  $value = str_replace($matrixReplaceFrom,$matrixReplaceTo,$value);
2672  }
2673  }
2674  unset($value);
2675  // Then rebuild the formula string
2676  $formula = implode('"',$temp);
2677  } else {
2678  // If there's no quoted strings, then we do a simple count/replace
2679  $openCount = substr_count($formula,'{');
2680  $closeCount = substr_count($formula,'}');
2681  $formula = str_replace($matrixReplaceFrom,$matrixReplaceTo,$formula);
2682  }
2683  // Trap for mismatched braces and trigger an appropriate error
2684  if ($openCount < $closeCount) {
2685  if ($openCount > 0) {
2686  return $this->_raiseFormulaError("Formula Error: Mismatched matrix braces '}'");
2687  } else {
2688  return $this->_raiseFormulaError("Formula Error: Unexpected '}' encountered");
2689  }
2690  } elseif ($openCount > $closeCount) {
2691  if ($closeCount > 0) {
2692  return $this->_raiseFormulaError("Formula Error: Mismatched matrix braces '{'");
2693  } else {
2694  return $this->_raiseFormulaError("Formula Error: Unexpected '{' encountered");
2695  }
2696  }
2697  }
2698 
2699  return $formula;
2700  } // function _convertMatrixReferences()
_raiseFormulaError($errorMessage)
Create styles array
The data for the language used.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _dataTestReference()

static PHPExcel_Calculation::_dataTestReference ( $operandData)
staticprivate

Definition at line 3082 of file Calculation.php.

3083  {
3084  $operand = $operandData['value'];
3085  if (($operandData['reference'] === NULL) && (is_array($operand))) {
3086  $rKeys = array_keys($operand);
3087  $rowKey = array_shift($rKeys);
3088  $cKeys = array_keys(array_keys($operand[$rowKey]));
3089  $colKey = array_shift($cKeys);
3090  if (ctype_upper($colKey)) {
3091  $operandData['reference'] = $colKey.$rowKey;
3092  }
3093  }
3094  return $operand;
3095  }

◆ _executeBinaryComparisonOperation()

PHPExcel_Calculation::_executeBinaryComparisonOperation (   $cellID,
  $operand1,
  $operand2,
  $operation,
$stack,
  $recursingArrays = FALSE 
)
private

Definition at line 3532 of file Calculation.php.

References $r, $result, $x, _showTypeDetails(), _showValue(), array, PHPExcel_Calculation_Functions\COMPATIBILITY_OPENOFFICE, PHPExcel_Calculation_Functions\getCompatibilityMode(), and strcmpLowercaseFirst().

Referenced by _processTokenStack().

3532  {
3533  // If we're dealing with matrix operations, we want a matrix result
3534  if ((is_array($operand1)) || (is_array($operand2))) {
3535  $result = array();
3536  if ((is_array($operand1)) && (!is_array($operand2))) {
3537  foreach($operand1 as $x => $operandData) {
3538  $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2));
3539  $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2,$operation,$stack);
3540  $r = $stack->pop();
3541  $result[$x] = $r['value'];
3542  }
3543  } elseif ((!is_array($operand1)) && (is_array($operand2))) {
3544  foreach($operand2 as $x => $operandData) {
3545  $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operand1), ' ', $operation, ' ', $this->_showValue($operandData));
3546  $this->_executeBinaryComparisonOperation($cellID,$operand1,$operandData,$operation,$stack);
3547  $r = $stack->pop();
3548  $result[$x] = $r['value'];
3549  }
3550  } else {
3551  if (!$recursingArrays) { self::_checkMatrixOperands($operand1,$operand2,2); }
3552  foreach($operand1 as $x => $operandData) {
3553  $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x]));
3554  $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2[$x],$operation,$stack,TRUE);
3555  $r = $stack->pop();
3556  $result[$x] = $r['value'];
3557  }
3558  }
3559  // Log the result details
3560  $this->_debugLog->writeDebugLog('Comparison Evaluation Result is ', $this->_showTypeDetails($result));
3561  // And push the result onto the stack
3562  $stack->push('Array',$result);
3563  return TRUE;
3564  }
3565 
3566  // Simple validate the two operands if they are string values
3567  if (is_string($operand1) && $operand1 > '' && $operand1{0} == '"') { $operand1 = self::_unwrapResult($operand1); }
3568  if (is_string($operand2) && $operand2 > '' && $operand2{0} == '"') { $operand2 = self::_unwrapResult($operand2); }
3569 
3570  // Use case insensitive comparaison if not OpenOffice mode
3572  {
3573  if (is_string($operand1)) {
3574  $operand1 = strtoupper($operand1);
3575  }
3576 
3577  if (is_string($operand2)) {
3578  $operand2 = strtoupper($operand2);
3579  }
3580  }
3581 
3582  $useLowercaseFirstComparison = is_string($operand1) && is_string($operand2) && PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE;
3583 
3584  // execute the necessary operation
3585  switch ($operation) {
3586  // Greater than
3587  case '>':
3588  if ($useLowercaseFirstComparison) {
3589  $result = $this->strcmpLowercaseFirst($operand1, $operand2) > 0;
3590  } else {
3591  $result = ($operand1 > $operand2);
3592  }
3593  break;
3594  // Less than
3595  case '<':
3596  if ($useLowercaseFirstComparison) {
3597  $result = $this->strcmpLowercaseFirst($operand1, $operand2) < 0;
3598  } else {
3599  $result = ($operand1 < $operand2);
3600  }
3601  break;
3602  // Equality
3603  case '=':
3604  if (is_numeric($operand1) && is_numeric($operand2)) {
3605  $result = (abs($operand1 - $operand2) < $this->delta);
3606  } else {
3607  $result = strcmp($operand1, $operand2) == 0;
3608  }
3609  break;
3610  // Greater than or equal
3611  case '>=':
3612  if (is_numeric($operand1) && is_numeric($operand2)) {
3613  $result = ((abs($operand1 - $operand2) < $this->delta) || ($operand1 > $operand2));
3614  } elseif ($useLowercaseFirstComparison) {
3615  $result = $this->strcmpLowercaseFirst($operand1, $operand2) >= 0;
3616  } else {
3617  $result = strcmp($operand1, $operand2) >= 0;
3618  }
3619  break;
3620  // Less than or equal
3621  case '<=':
3622  if (is_numeric($operand1) && is_numeric($operand2)) {
3623  $result = ((abs($operand1 - $operand2) < $this->delta) || ($operand1 < $operand2));
3624  } elseif ($useLowercaseFirstComparison) {
3625  $result = $this->strcmpLowercaseFirst($operand1, $operand2) <= 0;
3626  } else {
3627  $result = strcmp($operand1, $operand2) <= 0;
3628  }
3629  break;
3630  // Inequality
3631  case '<>':
3632  if (is_numeric($operand1) && is_numeric($operand2)) {
3633  $result = (abs($operand1 - $operand2) > 1E-14);
3634  } else {
3635  $result = strcmp($operand1, $operand2) != 0;
3636  }
3637  break;
3638  }
3639 
3640  // Log the result details
3641  $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result));
3642  // And push the result onto the stack
3643  $stack->push('Value',$result);
3644  return true;
3645  }
$result
$x
Definition: example_009.php:98
_showValue($value)
Format details of an operand for display in the log (based on operand type)
_executeBinaryComparisonOperation($cellID, $operand1, $operand2, $operation, &$stack, $recursingArrays=FALSE)
$r
Definition: example_031.php:79
_showTypeDetails($value)
Format type and details of an operand for display in the log (based on operand type) ...
Create styles array
The data for the language used.
strcmpLowercaseFirst($str1, $str2)
Compare two strings in the same way as strcmp() except that lowercase come before uppercase letters...
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _executeNumericBinaryOperation()

PHPExcel_Calculation::_executeNumericBinaryOperation (   $cellID,
  $operand1,
  $operand2,
  $operation,
  $matrixFunction,
$stack 
)
private

Definition at line 3661 of file Calculation.php.

References $result, _showTypeDetails(), _validateBinaryOperand(), PHPExcel_Calculation_Functions\COMPATIBILITY_OPENOFFICE, PHPExcel_Calculation_Functions\getCompatibilityMode(), and PHPExcel_Calculation_Functions\VALUE().

Referenced by _processTokenStack().

3661  {
3662  // Validate the two operands
3663  if (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return FALSE;
3664  if (!$this->_validateBinaryOperand($cellID,$operand2,$stack)) return FALSE;
3665 
3666  // If either of the operands is a matrix, we need to treat them both as matrices
3667  // (converting the other operand to a matrix if need be); then perform the required
3668  // matrix operation
3669  if ((is_array($operand1)) || (is_array($operand2))) {
3670  // Ensure that both operands are arrays/matrices of the same size
3671  self::_checkMatrixOperands($operand1, $operand2, 2);
3672 
3673  try {
3674  // Convert operand 1 from a PHP array to a matrix
3675  $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1);
3676  // Perform the required operation against the operand 1 matrix, passing in operand 2
3677  $matrixResult = $matrix->$matrixFunction($operand2);
3678  $result = $matrixResult->getArray();
3679  } catch (PHPExcel_Exception $ex) {
3680  $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage());
3681  $result = '#VALUE!';
3682  }
3683  } else {
3685  ((is_string($operand1) && !is_numeric($operand1) && strlen($operand1)>0) ||
3686  (is_string($operand2) && !is_numeric($operand2) && strlen($operand2)>0))) {
3688  } else {
3689  // If we're dealing with non-matrix operations, execute the necessary operation
3690  switch ($operation) {
3691  // Addition
3692  case '+':
3693  $result = $operand1 + $operand2;
3694  break;
3695  // Subtraction
3696  case '-':
3697  $result = $operand1 - $operand2;
3698  break;
3699  // Multiplication
3700  case '*':
3701  $result = $operand1 * $operand2;
3702  break;
3703  // Division
3704  case '/':
3705  if ($operand2 == 0) {
3706  // Trap for Divide by Zero error
3707  $stack->push('Value','#DIV/0!');
3708  $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails('#DIV/0!'));
3709  return FALSE;
3710  } else {
3711  $result = $operand1 / $operand2;
3712  }
3713  break;
3714  // Power
3715  case '^':
3716  $result = pow($operand1, $operand2);
3717  break;
3718  }
3719  }
3720  }
3721 
3722  // Log the result details
3723  $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result));
3724  // And push the result onto the stack
3725  $stack->push('Value',$result);
3726  return TRUE;
3727  } // function _executeNumericBinaryOperation()
$result
_validateBinaryOperand($cellID, &$operand, &$stack)
PHPExcel root directory.
Definition: Matrix.php:27
_showTypeDetails($value)
Format type and details of an operand for display in the log (based on operand type) ...
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _getMatrixDimensions()

static PHPExcel_Calculation::_getMatrixDimensions ( $matrix)
static

Read the dimensions of a matrix, and re-index it with straight numeric keys starting from row 0, column 0.

Parameters
mixed&$matrixmatrix operand
Returns
array An array comprising the number of rows, and number of columns

Definition at line 2474 of file Calculation.php.

References array.

Referenced by PHPExcel_Calculation_LookupRef\COLUMNS(), and PHPExcel_Calculation_LookupRef\ROWS().

2474  {
2475  $matrixRows = count($matrix);
2476  $matrixColumns = 0;
2477  foreach($matrix as $rowKey => $rowValue) {
2478  $matrixColumns = max(count($rowValue),$matrixColumns);
2479  if (!is_array($rowValue)) {
2480  $matrix[$rowKey] = array($rowValue);
2481  } else {
2482  $matrix[$rowKey] = array_values($rowValue);
2483  }
2484  }
2485  $matrix = array_values($matrix);
2486  return array($matrixRows,$matrixColumns);
2487  } // function _getMatrixDimensions()
Create styles array
The data for the language used.
+ Here is the caller graph for this function:

◆ _loadLocales()

static PHPExcel_Calculation::_loadLocales ( )
staticprivate

Definition at line 1747 of file Calculation.php.

References $filename.

1747  {
1748  $localeFileDirectory = PHPEXCEL_ROOT.'PHPExcel/locale/';
1749  foreach (glob($localeFileDirectory.'/*',GLOB_ONLYDIR) as $filename) {
1750  $filename = substr($filename,strlen($localeFileDirectory)+1);
1751  if ($filename != 'en') {
1752  self::$_validLocaleLanguages[] = $filename;
1753  }
1754  }
1755  }

◆ _localeFunc()

static PHPExcel_Calculation::_localeFunc (   $function)
static

Definition at line 2142 of file Calculation.php.

Referenced by PHPExcel_Calculation_Token_Stack\push().

2142  {
2143  if (self::$_localeLanguage !== 'en_us') {
2144  $functionName = trim($function,'(');
2145  if (isset(self::$_localeFunctions[$functionName])) {
2146  $brace = ($functionName != $function);
2147  $function = self::$_localeFunctions[$functionName];
2148  if ($brace) { $function .= '('; }
2149  }
2150  }
2151  return $function;
2152  }
+ Here is the caller graph for this function:

◆ _mkMatrix()

static PHPExcel_Calculation::_mkMatrix ( )
staticprivate

Definition at line 2703 of file Calculation.php.

2703  {
2704  return func_get_args();
2705  } // function _mkMatrix()

◆ _parseFormula()

PHPExcel_Calculation::_parseFormula (   $formula,
PHPExcel_Cell  $pCell = NULL 
)
private

Definition at line 2740 of file Calculation.php.

References $d, $output, _convertMatrixReferences(), _raiseFormulaError(), and array.

Referenced by _calculateFormulaValue(), and parseFormula().

2740  {
2741  if (($formula = $this->_convertMatrixReferences(trim($formula))) === FALSE) {
2742  return FALSE;
2743  }
2744 
2745  // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet),
2746  // so we store the parent worksheet so that we can re-attach it when necessary
2747  $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL;
2748 
2749  $regexpMatchString = '/^('.self::CALCULATION_REGEXP_FUNCTION.
2750  '|'.self::CALCULATION_REGEXP_CELLREF.
2751  '|'.self::CALCULATION_REGEXP_NUMBER.
2752  '|'.self::CALCULATION_REGEXP_STRING.
2753  '|'.self::CALCULATION_REGEXP_OPENBRACE.
2754  '|'.self::CALCULATION_REGEXP_NAMEDRANGE.
2755  '|'.self::CALCULATION_REGEXP_ERROR.
2756  ')/si';
2757 
2758  // Start with initialisation
2759  $index = 0;
2760  $stack = new PHPExcel_Calculation_Token_Stack;
2761  $output = array();
2762  $expectingOperator = FALSE; // We use this test in syntax-checking the expression to determine when a
2763  // - is a negation or + is a positive operator rather than an operation
2764  $expectingOperand = FALSE; // We use this test in syntax-checking the expression to determine whether an operand
2765  // should be null in a function call
2766  // The guts of the lexical parser
2767  // Loop through the formula extracting each operator and operand in turn
2768  while(TRUE) {
2769 //echo 'Assessing Expression '.substr($formula, $index),PHP_EOL;
2770  $opCharacter = $formula{$index}; // Get the first character of the value at the current index position
2771 //echo 'Initial character of expression block is '.$opCharacter,PHP_EOL;
2772  if ((isset(self::$_comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset(self::$_comparisonOperators[$formula{$index+1}]))) {
2773  $opCharacter .= $formula{++$index};
2774 //echo 'Initial character of expression block is comparison operator '.$opCharacter.PHP_EOL;
2775  }
2776 
2777  // Find out if we're currently at the beginning of a number, variable, cell reference, function, parenthesis or operand
2778  $isOperandOrFunction = preg_match($regexpMatchString, substr($formula, $index), $match);
2779 //echo '$isOperandOrFunction is '.(($isOperandOrFunction) ? 'True' : 'False').PHP_EOL;
2780 //var_dump($match);
2781 
2782  if ($opCharacter == '-' && !$expectingOperator) { // Is it a negation instead of a minus?
2783 //echo 'Element is a Negation operator',PHP_EOL;
2784  $stack->push('Unary Operator','~'); // Put a negation on the stack
2785  ++$index; // and drop the negation symbol
2786  } elseif ($opCharacter == '%' && $expectingOperator) {
2787 //echo 'Element is a Percentage operator',PHP_EOL;
2788  $stack->push('Unary Operator','%'); // Put a percentage on the stack
2789  ++$index;
2790  } elseif ($opCharacter == '+' && !$expectingOperator) { // Positive (unary plus rather than binary operator plus) can be discarded?
2791 //echo 'Element is a Positive number, not Plus operator',PHP_EOL;
2792  ++$index; // Drop the redundant plus symbol
2793  } elseif ((($opCharacter == '~') || ($opCharacter == '|')) && (!$isOperandOrFunction)) { // We have to explicitly deny a tilde or pipe, because they are legal
2794  return $this->_raiseFormulaError("Formula Error: Illegal character '~'"); // on the stack but not in the input expression
2795 
2796  } elseif ((isset(self::$_operators[$opCharacter]) or $isOperandOrFunction) && $expectingOperator) { // Are we putting an operator on the stack?
2797 //echo 'Element with value '.$opCharacter.' is an Operator',PHP_EOL;
2798  while($stack->count() > 0 &&
2799  ($o2 = $stack->last()) &&
2800  isset(self::$_operators[$o2['value']]) &&
2801  @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) {
2802  $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output
2803  }
2804  $stack->push('Binary Operator',$opCharacter); // Finally put our current operator onto the stack
2805  ++$index;
2806  $expectingOperator = FALSE;
2807 
2808  } elseif ($opCharacter == ')' && $expectingOperator) { // Are we expecting to close a parenthesis?
2809 //echo 'Element is a Closing bracket',PHP_EOL;
2810  $expectingOperand = FALSE;
2811  while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last (
2812  if ($o2 === NULL) return $this->_raiseFormulaError('Formula Error: Unexpected closing brace ")"');
2813  else $output[] = $o2;
2814  }
2815  $d = $stack->last(2);
2816  if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) { // Did this parenthesis just close a function?
2817  $functionName = $matches[1]; // Get the function name
2818 //echo 'Closed Function is '.$functionName,PHP_EOL;
2819  $d = $stack->pop();
2820  $argumentCount = $d['value']; // See how many arguments there were (argument count is the next value stored on the stack)
2821 //if ($argumentCount == 0) {
2822 // echo 'With no arguments',PHP_EOL;
2823 //} elseif ($argumentCount == 1) {
2824 // echo 'With 1 argument',PHP_EOL;
2825 //} else {
2826 // echo 'With '.$argumentCount.' arguments',PHP_EOL;
2827 //}
2828  $output[] = $d; // Dump the argument count on the output
2829  $output[] = $stack->pop(); // Pop the function and push onto the output
2830  if (isset(self::$_controlFunctions[$functionName])) {
2831 //echo 'Built-in function '.$functionName,PHP_EOL;
2832  $expectedArgumentCount = self::$_controlFunctions[$functionName]['argumentCount'];
2833  $functionCall = self::$_controlFunctions[$functionName]['functionCall'];
2834  } elseif (isset(self::$_PHPExcelFunctions[$functionName])) {
2835 //echo 'PHPExcel function '.$functionName,PHP_EOL;
2836  $expectedArgumentCount = self::$_PHPExcelFunctions[$functionName]['argumentCount'];
2837  $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall'];
2838  } else { // did we somehow push a non-function on the stack? this should never happen
2839  return $this->_raiseFormulaError("Formula Error: Internal error, non-function on stack");
2840  }
2841  // Check the argument count
2842  $argumentCountError = FALSE;
2843  if (is_numeric($expectedArgumentCount)) {
2844  if ($expectedArgumentCount < 0) {
2845 //echo '$expectedArgumentCount is between 0 and '.abs($expectedArgumentCount),PHP_EOL;
2846  if ($argumentCount > abs($expectedArgumentCount)) {
2847  $argumentCountError = TRUE;
2848  $expectedArgumentCountString = 'no more than '.abs($expectedArgumentCount);
2849  }
2850  } else {
2851 //echo '$expectedArgumentCount is numeric '.$expectedArgumentCount,PHP_EOL;
2852  if ($argumentCount != $expectedArgumentCount) {
2853  $argumentCountError = TRUE;
2854  $expectedArgumentCountString = $expectedArgumentCount;
2855  }
2856  }
2857  } elseif ($expectedArgumentCount != '*') {
2858  $isOperandOrFunction = preg_match('/(\d*)([-+,])(\d*)/',$expectedArgumentCount,$argMatch);
2859 //print_r($argMatch);
2860 //echo PHP_EOL;
2861  switch ($argMatch[2]) {
2862  case '+' :
2863  if ($argumentCount < $argMatch[1]) {
2864  $argumentCountError = TRUE;
2865  $expectedArgumentCountString = $argMatch[1].' or more ';
2866  }
2867  break;
2868  case '-' :
2869  if (($argumentCount < $argMatch[1]) || ($argumentCount > $argMatch[3])) {
2870  $argumentCountError = TRUE;
2871  $expectedArgumentCountString = 'between '.$argMatch[1].' and '.$argMatch[3];
2872  }
2873  break;
2874  case ',' :
2875  if (($argumentCount != $argMatch[1]) && ($argumentCount != $argMatch[3])) {
2876  $argumentCountError = TRUE;
2877  $expectedArgumentCountString = 'either '.$argMatch[1].' or '.$argMatch[3];
2878  }
2879  break;
2880  }
2881  }
2882  if ($argumentCountError) {
2883  return $this->_raiseFormulaError("Formula Error: Wrong number of arguments for $functionName() function: $argumentCount given, ".$expectedArgumentCountString." expected");
2884  }
2885  }
2886  ++$index;
2887 
2888  } elseif ($opCharacter == ',') { // Is this the separator for function arguments?
2889 //echo 'Element is a Function argument separator',PHP_EOL;
2890  while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last (
2891  if ($o2 === NULL) return $this->_raiseFormulaError("Formula Error: Unexpected ,");
2892  else $output[] = $o2; // pop the argument expression stuff and push onto the output
2893  }
2894  // If we've a comma when we're expecting an operand, then what we actually have is a null operand;
2895  // so push a null onto the stack
2896  if (($expectingOperand) || (!$expectingOperator)) {
2897  $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL);
2898  }
2899  // make sure there was a function
2900  $d = $stack->last(2);
2901  if (!preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches))
2902  return $this->_raiseFormulaError("Formula Error: Unexpected ,");
2903  $d = $stack->pop();
2904  $stack->push($d['type'],++$d['value'],$d['reference']); // increment the argument count
2905  $stack->push('Brace', '('); // put the ( back on, we'll need to pop back to it again
2906  $expectingOperator = FALSE;
2907  $expectingOperand = TRUE;
2908  ++$index;
2909 
2910  } elseif ($opCharacter == '(' && !$expectingOperator) {
2911 // echo 'Element is an Opening Bracket<br />';
2912  $stack->push('Brace', '(');
2913  ++$index;
2914 
2915  } elseif ($isOperandOrFunction && !$expectingOperator) { // do we now have a function/variable/number?
2916  $expectingOperator = TRUE;
2917  $expectingOperand = FALSE;
2918  $val = $match[1];
2919  $length = strlen($val);
2920 // echo 'Element with value '.$val.' is an Operand, Variable, Constant, String, Number, Cell Reference or Function<br />';
2921 
2922  if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $val, $matches)) {
2923  $val = preg_replace('/\s/u','',$val);
2924 // echo 'Element '.$val.' is a Function<br />';
2925  if (isset(self::$_PHPExcelFunctions[strtoupper($matches[1])]) || isset(self::$_controlFunctions[strtoupper($matches[1])])) { // it's a function
2926  $stack->push('Function', strtoupper($val));
2927  $ax = preg_match('/^\s*(\s*\))/ui', substr($formula, $index+$length), $amatch);
2928  if ($ax) {
2929  $stack->push('Operand Count for Function '.strtoupper($val).')', 0);
2930  $expectingOperator = TRUE;
2931  } else {
2932  $stack->push('Operand Count for Function '.strtoupper($val).')', 1);
2933  $expectingOperator = FALSE;
2934  }
2935  $stack->push('Brace', '(');
2936  } else { // it's a var w/ implicit multiplication
2937  $output[] = array('type' => 'Value', 'value' => $matches[1], 'reference' => NULL);
2938  }
2939  } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $val, $matches)) {
2940 // echo 'Element '.$val.' is a Cell reference<br />';
2941  // Watch for this case-change when modifying to allow cell references in different worksheets...
2942  // Should only be applied to the actual cell column, not the worksheet name
2943 
2944  // If the last entry on the stack was a : operator, then we have a cell range reference
2945  $testPrevOp = $stack->last(1);
2946  if ($testPrevOp['value'] == ':') {
2947  // If we have a worksheet reference, then we're playing with a 3D reference
2948  if ($matches[2] == '') {
2949  // Otherwise, we 'inherit' the worksheet reference from the start cell reference
2950  // The start of the cell range reference should be the last entry in $output
2951  $startCellRef = $output[count($output)-1]['value'];
2952  preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $startCellRef, $startMatches);
2953  if ($startMatches[2] > '') {
2954  $val = $startMatches[2].'!'.$val;
2955  }
2956  } else {
2957  return $this->_raiseFormulaError("3D Range references are not yet supported");
2958  }
2959  }
2960 
2961  $output[] = array('type' => 'Cell Reference', 'value' => $val, 'reference' => $val);
2962 // $expectingOperator = FALSE;
2963  } else { // it's a variable, constant, string, number or boolean
2964 // echo 'Element is a Variable, Constant, String, Number or Boolean<br />';
2965  // If the last entry on the stack was a : operator, then we may have a row or column range reference
2966  $testPrevOp = $stack->last(1);
2967  if ($testPrevOp['value'] == ':') {
2968  $startRowColRef = $output[count($output)-1]['value'];
2969  $rangeWS1 = '';
2970  if (strpos('!',$startRowColRef) !== FALSE) {
2971  list($rangeWS1,$startRowColRef) = explode('!',$startRowColRef);
2972  }
2973  if ($rangeWS1 != '') $rangeWS1 .= '!';
2974  $rangeWS2 = $rangeWS1;
2975  if (strpos('!',$val) !== FALSE) {
2976  list($rangeWS2,$val) = explode('!',$val);
2977  }
2978  if ($rangeWS2 != '') $rangeWS2 .= '!';
2979  if ((is_integer($startRowColRef)) && (ctype_digit($val)) &&
2980  ($startRowColRef <= 1048576) && ($val <= 1048576)) {
2981  // Row range
2982  $endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestColumn() : 'XFD'; // Max 16,384 columns for Excel2007
2983  $output[count($output)-1]['value'] = $rangeWS1.'A'.$startRowColRef;
2984  $val = $rangeWS2.$endRowColRef.$val;
2985  } elseif ((ctype_alpha($startRowColRef)) && (ctype_alpha($val)) &&
2986  (strlen($startRowColRef) <= 3) && (strlen($val) <= 3)) {
2987  // Column range
2988  $endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestRow() : 1048576; // Max 1,048,576 rows for Excel2007
2989  $output[count($output)-1]['value'] = $rangeWS1.strtoupper($startRowColRef).'1';
2990  $val = $rangeWS2.$val.$endRowColRef;
2991  }
2992  }
2993 
2994  $localeConstant = FALSE;
2995  if ($opCharacter == '"') {
2996 // echo 'Element is a String<br />';
2997  // UnEscape any quotes within the string
2998  $val = self::_wrapResult(str_replace('""','"',self::_unwrapResult($val)));
2999  } elseif (is_numeric($val)) {
3000 // echo 'Element is a Number<br />';
3001  if ((strpos($val,'.') !== FALSE) || (stripos($val,'e') !== FALSE) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) {
3002 // echo 'Casting '.$val.' to float<br />';
3003  $val = (float) $val;
3004  } else {
3005 // echo 'Casting '.$val.' to integer<br />';
3006  $val = (integer) $val;
3007  }
3008  } elseif (isset(self::$_ExcelConstants[trim(strtoupper($val))])) {
3009  $excelConstant = trim(strtoupper($val));
3010 // echo 'Element '.$excelConstant.' is an Excel Constant<br />';
3011  $val = self::$_ExcelConstants[$excelConstant];
3012  } elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$_localeBoolean)) !== FALSE) {
3013 // echo 'Element '.$localeConstant.' is an Excel Constant<br />';
3014  $val = self::$_ExcelConstants[$localeConstant];
3015  }
3016  $details = array('type' => 'Value', 'value' => $val, 'reference' => NULL);
3017  if ($localeConstant) { $details['localeValue'] = $localeConstant; }
3018  $output[] = $details;
3019  }
3020  $index += $length;
3021 
3022  } elseif ($opCharacter == '$') { // absolute row or column range
3023  ++$index;
3024  } elseif ($opCharacter == ')') { // miscellaneous error checking
3025  if ($expectingOperand) {
3026  $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL);
3027  $expectingOperand = FALSE;
3028  $expectingOperator = TRUE;
3029  } else {
3030  return $this->_raiseFormulaError("Formula Error: Unexpected ')'");
3031  }
3032  } elseif (isset(self::$_operators[$opCharacter]) && !$expectingOperator) {
3033  return $this->_raiseFormulaError("Formula Error: Unexpected operator '$opCharacter'");
3034  } else { // I don't even want to know what you did to get here
3035  return $this->_raiseFormulaError("Formula Error: An unexpected error occured");
3036  }
3037  // Test for end of formula string
3038  if ($index == strlen($formula)) {
3039  // Did we end with an operator?.
3040  // Only valid for the % unary operator
3041  if ((isset(self::$_operators[$opCharacter])) && ($opCharacter != '%')) {
3042  return $this->_raiseFormulaError("Formula Error: Operator '$opCharacter' has no operands");
3043  } else {
3044  break;
3045  }
3046  }
3047  // Ignore white space
3048  while (($formula{$index} == "\n") || ($formula{$index} == "\r")) {
3049  ++$index;
3050  }
3051  if ($formula{$index} == ' ') {
3052  while ($formula{$index} == ' ') {
3053  ++$index;
3054  }
3055  // If we're expecting an operator, but only have a space between the previous and next operands (and both are
3056  // Cell References) then we have an INTERSECTION operator
3057 // echo 'Possible Intersect Operator<br />';
3058  if (($expectingOperator) && (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'.*/Ui', substr($formula, $index), $match)) &&
3059  ($output[count($output)-1]['type'] == 'Cell Reference')) {
3060 // echo 'Element is an Intersect Operator<br />';
3061  while($stack->count() > 0 &&
3062  ($o2 = $stack->last()) &&
3063  isset(self::$_operators[$o2['value']]) &&
3064  @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) {
3065  $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output
3066  }
3067  $stack->push('Binary Operator','|'); // Put an Intersect Operator on the stack
3068  $expectingOperator = FALSE;
3069  }
3070  }
3071  }
3072 
3073  while (($op = $stack->pop()) !== NULL) { // pop everything off the stack and push onto output
3074  if ((is_array($op) && $op['value'] == '(') || ($op === '('))
3075  return $this->_raiseFormulaError("Formula Error: Expecting ')'"); // if there are any opening braces on the stack, then braces were unbalanced
3076  $output[] = $op;
3077  }
3078  return $output;
3079  } // function _parseFormula()
_convertMatrixReferences($formula)
for($col=0; $col< 50; $col++) $d
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\+" &#(? foreach( $entity_files as $file) $output
_raiseFormulaError($errorMessage)
Create styles array
The data for the language used.
getWorksheet()
Get parent worksheet.
Definition: Cell.php:488
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _processTokenStack()

PHPExcel_Calculation::_processTokenStack (   $tokens,
  $cellID = NULL,
PHPExcel_Cell  $pCell = NULL 
)
private

Definition at line 3098 of file Calculation.php.

References $data, $output, $result, $row, _executeBinaryComparisonOperation(), _executeNumericBinaryOperation(), _raiseFormulaError(), _showTypeDetails(), _showValue(), array, PHPExcel_Cell\columnIndexFromString(), PHPExcel_Cell\coordinateFromString(), extractCellRange(), extractNamedRange(), PHPExcel_Calculation_Functions\flattenArray(), PHPExcel_Calculation_Functions\flattenSingleValue(), PHPExcel_Calculation_Functions\REF(), and PHPExcel_Cell\stringFromColumnIndex().

Referenced by _calculateFormulaValue().

3098  {
3099  if ($tokens == FALSE) return FALSE;
3100 
3101  // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent cell collection),
3102  // so we store the parent cell collection so that we can re-attach it when necessary
3103  $pCellWorksheet = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL;
3104  $pCellParent = ($pCell !== NULL) ? $pCell->getParent() : null;
3105  $stack = new PHPExcel_Calculation_Token_Stack;
3106 
3107  // Loop through each token in turn
3108  foreach ($tokens as $tokenData) {
3109 // print_r($tokenData);
3110 // echo '<br />';
3111  $token = $tokenData['value'];
3112 // echo '<b>Token is '.$token.'</b><br />';
3113  // if the token is a binary operator, pop the top two values off the stack, do the operation, and push the result back on the stack
3114  if (isset(self::$_binaryOperators[$token])) {
3115 // echo 'Token is a binary operator<br />';
3116  // We must have two operands, error if we don't
3117  if (($operand2Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack');
3118  if (($operand1Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack');
3119 
3120  $operand1 = self::_dataTestReference($operand1Data);
3121  $operand2 = self::_dataTestReference($operand2Data);
3122 
3123  // Log what we're doing
3124  if ($token == ':') {
3125  $this->_debugLog->writeDebugLog('Evaluating Range ', $this->_showValue($operand1Data['reference']), ' ', $token, ' ', $this->_showValue($operand2Data['reference']));
3126  } else {
3127  $this->_debugLog->writeDebugLog('Evaluating ', $this->_showValue($operand1), ' ', $token, ' ', $this->_showValue($operand2));
3128  }
3129 
3130  // Process the operation in the appropriate manner
3131  switch ($token) {
3132  // Comparison (Boolean) Operators
3133  case '>' : // Greater than
3134  case '<' : // Less than
3135  case '>=' : // Greater than or Equal to
3136  case '<=' : // Less than or Equal to
3137  case '=' : // Equality
3138  case '<>' : // Inequality
3139  $this->_executeBinaryComparisonOperation($cellID,$operand1,$operand2,$token,$stack);
3140  break;
3141  // Binary Operators
3142  case ':' : // Range
3143  $sheet1 = $sheet2 = '';
3144  if (strpos($operand1Data['reference'],'!') !== FALSE) {
3145  list($sheet1,$operand1Data['reference']) = explode('!',$operand1Data['reference']);
3146  } else {
3147  $sheet1 = ($pCellParent !== NULL) ? $pCellWorksheet->getTitle() : '';
3148  }
3149  if (strpos($operand2Data['reference'],'!') !== FALSE) {
3150  list($sheet2,$operand2Data['reference']) = explode('!',$operand2Data['reference']);
3151  } else {
3152  $sheet2 = $sheet1;
3153  }
3154  if ($sheet1 == $sheet2) {
3155  if ($operand1Data['reference'] === NULL) {
3156  if ((trim($operand1Data['value']) != '') && (is_numeric($operand1Data['value']))) {
3157  $operand1Data['reference'] = $pCell->getColumn().$operand1Data['value'];
3158  } elseif (trim($operand1Data['reference']) == '') {
3159  $operand1Data['reference'] = $pCell->getCoordinate();
3160  } else {
3161  $operand1Data['reference'] = $operand1Data['value'].$pCell->getRow();
3162  }
3163  }
3164  if ($operand2Data['reference'] === NULL) {
3165  if ((trim($operand2Data['value']) != '') && (is_numeric($operand2Data['value']))) {
3166  $operand2Data['reference'] = $pCell->getColumn().$operand2Data['value'];
3167  } elseif (trim($operand2Data['reference']) == '') {
3168  $operand2Data['reference'] = $pCell->getCoordinate();
3169  } else {
3170  $operand2Data['reference'] = $operand2Data['value'].$pCell->getRow();
3171  }
3172  }
3173 
3174  $oData = array_merge(explode(':',$operand1Data['reference']),explode(':',$operand2Data['reference']));
3175  $oCol = $oRow = array();
3176  foreach($oData as $oDatum) {
3177  $oCR = PHPExcel_Cell::coordinateFromString($oDatum);
3178  $oCol[] = PHPExcel_Cell::columnIndexFromString($oCR[0]) - 1;
3179  $oRow[] = $oCR[1];
3180  }
3181  $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow);
3182  if ($pCellParent !== NULL) {
3183  $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($sheet1), FALSE);
3184  } else {
3185  return $this->_raiseFormulaError('Unable to access Cell Reference');
3186  }
3187  $stack->push('Cell Reference',$cellValue,$cellRef);
3188  } else {
3189  $stack->push('Error',PHPExcel_Calculation_Functions::REF(),NULL);
3190  }
3191 
3192  break;
3193  case '+' : // Addition
3194  $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'plusEquals',$stack);
3195  break;
3196  case '-' : // Subtraction
3197  $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'minusEquals',$stack);
3198  break;
3199  case '*' : // Multiplication
3200  $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayTimesEquals',$stack);
3201  break;
3202  case '/' : // Division
3203  $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayRightDivide',$stack);
3204  break;
3205  case '^' : // Exponential
3206  $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'power',$stack);
3207  break;
3208  case '&' : // Concatenation
3209  // If either of the operands is a matrix, we need to treat them both as matrices
3210  // (converting the other operand to a matrix if need be); then perform the required
3211  // matrix operation
3212  if (is_bool($operand1)) {
3213  $operand1 = ($operand1) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE'];
3214  }
3215  if (is_bool($operand2)) {
3216  $operand2 = ($operand2) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE'];
3217  }
3218  if ((is_array($operand1)) || (is_array($operand2))) {
3219  // Ensure that both operands are arrays/matrices
3220  self::_checkMatrixOperands($operand1,$operand2,2);
3221  try {
3222  // Convert operand 1 from a PHP array to a matrix
3223  $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1);
3224  // Perform the required operation against the operand 1 matrix, passing in operand 2
3225  $matrixResult = $matrix->concat($operand2);
3226  $result = $matrixResult->getArray();
3227  } catch (PHPExcel_Exception $ex) {
3228  $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage());
3229  $result = '#VALUE!';
3230  }
3231  } else {
3232  $result = '"'.str_replace('""','"',self::_unwrapResult($operand1,'"').self::_unwrapResult($operand2,'"')).'"';
3233  }
3234  $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result));
3235  $stack->push('Value',$result);
3236  break;
3237  case '|' : // Intersect
3238  $rowIntersect = array_intersect_key($operand1,$operand2);
3239  $cellIntersect = $oCol = $oRow = array();
3240  foreach(array_keys($rowIntersect) as $row) {
3241  $oRow[] = $row;
3242  foreach($rowIntersect[$row] as $col => $data) {
3243  $oCol[] = PHPExcel_Cell::columnIndexFromString($col) - 1;
3244  $cellIntersect[$row] = array_intersect_key($operand1[$row],$operand2[$row]);
3245  }
3246  }
3247  $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow);
3248  $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($cellIntersect));
3249  $stack->push('Value',$cellIntersect,$cellRef);
3250  break;
3251  }
3252 
3253  // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on
3254  } elseif (($token === '~') || ($token === '%')) {
3255 // echo 'Token is a unary operator<br />';
3256  if (($arg = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack');
3257  $arg = $arg['value'];
3258  if ($token === '~') {
3259 // echo 'Token is a negation operator<br />';
3260  $this->_debugLog->writeDebugLog('Evaluating Negation of ', $this->_showValue($arg));
3261  $multiplier = -1;
3262  } else {
3263 // echo 'Token is a percentile operator<br />';
3264  $this->_debugLog->writeDebugLog('Evaluating Percentile of ', $this->_showValue($arg));
3265  $multiplier = 0.01;
3266  }
3267  if (is_array($arg)) {
3268  self::_checkMatrixOperands($arg,$multiplier,2);
3269  try {
3270  $matrix1 = new PHPExcel_Shared_JAMA_Matrix($arg);
3271  $matrixResult = $matrix1->arrayTimesEquals($multiplier);
3272  $result = $matrixResult->getArray();
3273  } catch (PHPExcel_Exception $ex) {
3274  $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage());
3275  $result = '#VALUE!';
3276  }
3277  $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result));
3278  $stack->push('Value',$result);
3279  } else {
3280  $this->_executeNumericBinaryOperation($cellID,$multiplier,$arg,'*','arrayTimesEquals',$stack);
3281  }
3282 
3283  } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $token, $matches)) {
3284  $cellRef = NULL;
3285 // echo 'Element '.$token.' is a Cell reference<br />';
3286  if (isset($matches[8])) {
3287 // echo 'Reference is a Range of cells<br />';
3288  if ($pCell === NULL) {
3289 // We can't access the range, so return a REF error
3290  $cellValue = PHPExcel_Calculation_Functions::REF();
3291  } else {
3292  $cellRef = $matches[6].$matches[7].':'.$matches[9].$matches[10];
3293  if ($matches[2] > '') {
3294  $matches[2] = trim($matches[2],"\"'");
3295  if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) {
3296  // It's a Reference to an external workbook (not currently supported)
3297  return $this->_raiseFormulaError('Unable to access External Workbook');
3298  }
3299  $matches[2] = trim($matches[2],"\"'");
3300 // echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />';
3301  $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]);
3302  if ($pCellParent !== NULL) {
3303  $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE);
3304  } else {
3305  return $this->_raiseFormulaError('Unable to access Cell Reference');
3306  }
3307  $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue));
3308 // $cellRef = $matches[2].'!'.$cellRef;
3309  } else {
3310 // echo '$cellRef='.$cellRef.' in current worksheet<br />';
3311  $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in current worksheet');
3312  if ($pCellParent !== NULL) {
3313  $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE);
3314  } else {
3315  return $this->_raiseFormulaError('Unable to access Cell Reference');
3316  }
3317  $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' is ', $this->_showTypeDetails($cellValue));
3318  }
3319  }
3320  } else {
3321 // echo 'Reference is a single Cell<br />';
3322  if ($pCell === NULL) {
3323 // We can't access the cell, so return a REF error
3324  $cellValue = PHPExcel_Calculation_Functions::REF();
3325  } else {
3326  $cellRef = $matches[6].$matches[7];
3327  if ($matches[2] > '') {
3328  $matches[2] = trim($matches[2],"\"'");
3329  if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) {
3330  // It's a Reference to an external workbook (not currently supported)
3331  return $this->_raiseFormulaError('Unable to access External Workbook');
3332  }
3333 // echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />';
3334  $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]);
3335  if ($pCellParent !== NULL) {
3336  $cellSheet = $this->_workbook->getSheetByName($matches[2]);
3337  if ($cellSheet && $cellSheet->cellExists($cellRef)) {
3338  $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE);
3339  $pCell->attach($pCellParent);
3340  } else {
3341  $cellValue = NULL;
3342  }
3343  } else {
3344  return $this->_raiseFormulaError('Unable to access Cell Reference');
3345  }
3346  $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue));
3347 // $cellRef = $matches[2].'!'.$cellRef;
3348  } else {
3349 // echo '$cellRef='.$cellRef.' in current worksheet<br />';
3350  $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in current worksheet');
3351  if ($pCellParent->isDataSet($cellRef)) {
3352  $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE);
3353  $pCell->attach($pCellParent);
3354  } else {
3355  $cellValue = NULL;
3356  }
3357  $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' is ', $this->_showTypeDetails($cellValue));
3358  }
3359  }
3360  }
3361  $stack->push('Value',$cellValue,$cellRef);
3362 
3363  // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on
3364  } elseif (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $token, $matches)) {
3365 // echo 'Token is a function<br />';
3366  $functionName = $matches[1];
3367  $argCount = $stack->pop();
3368  $argCount = $argCount['value'];
3369  if ($functionName != 'MKMATRIX') {
3370  $this->_debugLog->writeDebugLog('Evaluating Function ', self::_localeFunc($functionName), '() with ', (($argCount == 0) ? 'no' : $argCount), ' argument', (($argCount == 1) ? '' : 's'));
3371  }
3372  if ((isset(self::$_PHPExcelFunctions[$functionName])) || (isset(self::$_controlFunctions[$functionName]))) { // function
3373  if (isset(self::$_PHPExcelFunctions[$functionName])) {
3374  $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall'];
3375  $passByReference = isset(self::$_PHPExcelFunctions[$functionName]['passByReference']);
3376  $passCellReference = isset(self::$_PHPExcelFunctions[$functionName]['passCellReference']);
3377  } elseif (isset(self::$_controlFunctions[$functionName])) {
3378  $functionCall = self::$_controlFunctions[$functionName]['functionCall'];
3379  $passByReference = isset(self::$_controlFunctions[$functionName]['passByReference']);
3380  $passCellReference = isset(self::$_controlFunctions[$functionName]['passCellReference']);
3381  }
3382  // get the arguments for this function
3383 // echo 'Function '.$functionName.' expects '.$argCount.' arguments<br />';
3384  $args = $argArrayVals = array();
3385  for ($i = 0; $i < $argCount; ++$i) {
3386  $arg = $stack->pop();
3387  $a = $argCount - $i - 1;
3388  if (($passByReference) &&
3389  (isset(self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) &&
3390  (self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) {
3391  if ($arg['reference'] === NULL) {
3392  $args[] = $cellID;
3393  if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($cellID); }
3394  } else {
3395  $args[] = $arg['reference'];
3396  if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['reference']); }
3397  }
3398  } else {
3399  $args[] = self::_unwrapResult($arg['value']);
3400  if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['value']); }
3401  }
3402  }
3403  // Reverse the order of the arguments
3404  krsort($args);
3405  if (($passByReference) && ($argCount == 0)) {
3406  $args[] = $cellID;
3407  $argArrayVals[] = $this->_showValue($cellID);
3408  }
3409 // echo 'Arguments are: ';
3410 // print_r($args);
3411 // echo '<br />';
3412  if ($functionName != 'MKMATRIX') {
3413  if ($this->_debugLog->getWriteDebugLog()) {
3414  krsort($argArrayVals);
3415  $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', implode(self::$_localeArgumentSeparator.' ',PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )');
3416  }
3417  }
3418  // Process each argument in turn, building the return value as an array
3419 // if (($argCount == 1) && (is_array($args[1])) && ($functionName != 'MKMATRIX')) {
3420 // $operand1 = $args[1];
3421 // $this->_debugLog->writeDebugLog('Argument is a matrix: ', $this->_showValue($operand1));
3422 // $result = array();
3423 // $row = 0;
3424 // foreach($operand1 as $args) {
3425 // if (is_array($args)) {
3426 // foreach($args as $arg) {
3427 // $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($arg), ' )');
3428 // $r = call_user_func_array($functionCall,$arg);
3429 // $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r));
3430 // $result[$row][] = $r;
3431 // }
3432 // ++$row;
3433 // } else {
3434 // $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($args), ' )');
3435 // $r = call_user_func_array($functionCall,$args);
3436 // $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r));
3437 // $result[] = $r;
3438 // }
3439 // }
3440 // } else {
3441  // Process the argument with the appropriate function call
3442  if ($passCellReference) {
3443  $args[] = $pCell;
3444  }
3445  if (strpos($functionCall,'::') !== FALSE) {
3446  $result = call_user_func_array(explode('::',$functionCall),$args);
3447  } else {
3448  foreach($args as &$arg) {
3450  }
3451  unset($arg);
3452  $result = call_user_func_array($functionCall,$args);
3453  }
3454 // }
3455  if ($functionName != 'MKMATRIX') {
3456  $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($result));
3457  }
3458  $stack->push('Value',self::_wrapResult($result));
3459  }
3460 
3461  } else {
3462  // if the token is a number, boolean, string or an Excel error, push it onto the stack
3463  if (isset(self::$_ExcelConstants[strtoupper($token)])) {
3464  $excelConstant = strtoupper($token);
3465 // echo 'Token is a PHPExcel constant: '.$excelConstant.'<br />';
3466  $stack->push('Constant Value',self::$_ExcelConstants[$excelConstant]);
3467  $this->_debugLog->writeDebugLog('Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$_ExcelConstants[$excelConstant]));
3468  } elseif ((is_numeric($token)) || ($token === NULL) || (is_bool($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) {
3469 // echo 'Token is a number, boolean, string, null or an Excel error<br />';
3470  $stack->push('Value',$token);
3471  // if the token is a named range, push the named range name onto the stack
3472  } elseif (preg_match('/^'.self::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $token, $matches)) {
3473 // echo 'Token is a named range<br />';
3474  $namedRange = $matches[6];
3475 // echo 'Named Range is '.$namedRange.'<br />';
3476  $this->_debugLog->writeDebugLog('Evaluating Named Range ', $namedRange);
3477  $cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellWorksheet : NULL), FALSE);
3478  $pCell->attach($pCellParent);
3479  $this->_debugLog->writeDebugLog('Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue));
3480  $stack->push('Named Range',$cellValue,$namedRange);
3481  } else {
3482  return $this->_raiseFormulaError("undefined variable '$token'");
3483  }
3484  }
3485  }
3486  // when we're out of tokens, the stack should have a single element, the final result
3487  if ($stack->count() != 1) return $this->_raiseFormulaError("internal error");
3488  $output = $stack->pop();
3489  $output = $output['value'];
3490 
3491 // if ((is_array($output)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) {
3492 // return array_shift(PHPExcel_Calculation_Functions::flattenArray($output));
3493 // }
3494  return $output;
3495  } // function _processTokenStack()
static flattenSingleValue($value='')
Convert an array to a single scalar value by extracting the first element.
Definition: Functions.php:662
static coordinateFromString($pCoordinateString='A1')
Coordinate from string.
Definition: Cell.php:580
$result
_showValue($value)
Format details of an operand for display in the log (based on operand type)
extractNamedRange(&$pRange='A1', PHPExcel_Worksheet $pSheet=NULL, $resetLog=TRUE)
Extract range values.
_executeBinaryComparisonOperation($cellID, $operand1, $operand2, $operation, &$stack, $recursingArrays=FALSE)
getColumn()
Get cell coordinate column.
Definition: Cell.php:151
static flattenArray($array)
Convert a multi-dimensional array to a simple 1-dimensional array.
Definition: Functions.php:598
getCoordinate()
Get cell coordinate.
Definition: Cell.php:171
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\+" &#(? foreach( $entity_files as $file) $output
_raiseFormulaError($errorMessage)
PHPExcel root directory.
Definition: Matrix.php:27
_showTypeDetails($value)
Format type and details of an operand for display in the log (based on operand type) ...
Create styles array
The data for the language used.
attach(PHPExcel_CachedObjectStorage_CacheBase $parent)
Definition: Cell.php:115
static columnIndexFromString($pString='A')
Column index from string.
Definition: Cell.php:782
static stringFromColumnIndex($pColumnIndex=0)
String from columnindex.
Definition: Cell.php:825
_executeNumericBinaryOperation($cellID, $operand1, $operand2, $operation, $matrixFunction, &$stack)
extractCellRange(&$pRange='A1', PHPExcel_Worksheet $pSheet=NULL, $resetLog=TRUE)
Extract range values.
getParent()
Get parent worksheet.
Definition: Cell.php:479
getWorksheet()
Get parent worksheet.
Definition: Cell.php:488
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _raiseFormulaError()

PHPExcel_Calculation::_raiseFormulaError (   $errorMessage)
protected

Definition at line 3731 of file Calculation.php.

Referenced by _calculateFormulaValue(), _convertMatrixReferences(), _parseFormula(), and _processTokenStack().

3731  {
3732  $this->formulaError = $errorMessage;
3733  $this->_cyclicReferenceStack->clear();
3734  if (!$this->suppressFormulaErrors) throw new PHPExcel_Calculation_Exception($errorMessage);
3735  trigger_error($errorMessage, E_USER_ERROR);
3736  } // function _raiseFormulaError()
+ Here is the caller graph for this function:

◆ _resizeMatricesExtend()

static PHPExcel_Calculation::_resizeMatricesExtend ( $matrix1,
$matrix2,
  $matrix1Rows,
  $matrix1Columns,
  $matrix2Rows,
  $matrix2Columns 
)
staticprivate

Ensure that paired matrix operands are both matrices of the same size.

Parameters
mixed&$matrix1First matrix operand
mixed&$matrix2Second matrix operand
integer$matrix1RowsRow size of first matrix operand
integer$matrix1ColumnsColumn size of first matrix operand
integer$matrix2RowsRow size of second matrix operand
integer$matrix2ColumnsColumn size of second matrix operand

Definition at line 2543 of file Calculation.php.

References $x.

2543  {
2544  if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) {
2545  if ($matrix2Columns < $matrix1Columns) {
2546  for ($i = 0; $i < $matrix2Rows; ++$i) {
2547  $x = $matrix2[$i][$matrix2Columns-1];
2548  for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) {
2549  $matrix2[$i][$j] = $x;
2550  }
2551  }
2552  }
2553  if ($matrix2Rows < $matrix1Rows) {
2554  $x = $matrix2[$matrix2Rows-1];
2555  for ($i = 0; $i < $matrix1Rows; ++$i) {
2556  $matrix2[$i] = $x;
2557  }
2558  }
2559  }
2560 
2561  if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) {
2562  if ($matrix1Columns < $matrix2Columns) {
2563  for ($i = 0; $i < $matrix1Rows; ++$i) {
2564  $x = $matrix1[$i][$matrix1Columns-1];
2565  for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) {
2566  $matrix1[$i][$j] = $x;
2567  }
2568  }
2569  }
2570  if ($matrix1Rows < $matrix2Rows) {
2571  $x = $matrix1[$matrix1Rows-1];
2572  for ($i = 0; $i < $matrix2Rows; ++$i) {
2573  $matrix1[$i] = $x;
2574  }
2575  }
2576  }
2577  } // function _resizeMatricesExtend()
$x
Definition: example_009.php:98

◆ _resizeMatricesShrink()

static PHPExcel_Calculation::_resizeMatricesShrink ( $matrix1,
$matrix2,
  $matrix1Rows,
  $matrix1Columns,
  $matrix2Rows,
  $matrix2Columns 
)
staticprivate

Ensure that paired matrix operands are both matrices of the same size.

Parameters
mixed&$matrix1First matrix operand
mixed&$matrix2Second matrix operand
integer$matrix1RowsRow size of first matrix operand
integer$matrix1ColumnsColumn size of first matrix operand
integer$matrix2RowsRow size of second matrix operand
integer$matrix2ColumnsColumn size of second matrix operand

Definition at line 2500 of file Calculation.php.

2500  {
2501  if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) {
2502  if ($matrix2Rows < $matrix1Rows) {
2503  for ($i = $matrix2Rows; $i < $matrix1Rows; ++$i) {
2504  unset($matrix1[$i]);
2505  }
2506  }
2507  if ($matrix2Columns < $matrix1Columns) {
2508  for ($i = 0; $i < $matrix1Rows; ++$i) {
2509  for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) {
2510  unset($matrix1[$i][$j]);
2511  }
2512  }
2513  }
2514  }
2515 
2516  if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) {
2517  if ($matrix1Rows < $matrix2Rows) {
2518  for ($i = $matrix1Rows; $i < $matrix2Rows; ++$i) {
2519  unset($matrix2[$i]);
2520  }
2521  }
2522  if ($matrix1Columns < $matrix2Columns) {
2523  for ($i = 0; $i < $matrix2Rows; ++$i) {
2524  for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) {
2525  unset($matrix2[$i][$j]);
2526  }
2527  }
2528  }
2529  }
2530  } // function _resizeMatricesShrink()

◆ _showTypeDetails()

PHPExcel_Calculation::_showTypeDetails (   $value)
private

Format type and details of an operand for display in the log (based on operand type)

Parameters
mixed$valueFirst matrix operand
Returns
mixed

Definition at line 2621 of file Calculation.php.

References _showValue(), and PHPExcel_Calculation_Functions\flattenArray().

Referenced by _executeBinaryComparisonOperation(), _executeNumericBinaryOperation(), _processTokenStack(), and _validateBinaryOperand().

2621  {
2622  if ($this->_debugLog->getWriteDebugLog()) {
2623  $testArray = PHPExcel_Calculation_Functions::flattenArray($value);
2624  if (count($testArray) == 1) {
2625  $value = array_pop($testArray);
2626  }
2627 
2628  if ($value === NULL) {
2629  return 'a NULL value';
2630  } elseif (is_float($value)) {
2631  $typeString = 'a floating point number';
2632  } elseif(is_int($value)) {
2633  $typeString = 'an integer number';
2634  } elseif(is_bool($value)) {
2635  $typeString = 'a boolean';
2636  } elseif(is_array($value)) {
2637  $typeString = 'a matrix';
2638  } else {
2639  if ($value == '') {
2640  return 'an empty string';
2641  } elseif ($value{0} == '#') {
2642  return 'a '.$value.' error';
2643  } else {
2644  $typeString = 'a string';
2645  }
2646  }
2647  return $typeString.' with a value of '.$this->_showValue($value);
2648  }
2649  } // function _showTypeDetails()
_showValue($value)
Format details of an operand for display in the log (based on operand type)
static flattenArray($array)
Convert a multi-dimensional array to a simple 1-dimensional array.
Definition: Functions.php:598
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _showValue()

PHPExcel_Calculation::_showValue (   $value)
private

Format details of an operand for display in the log (based on operand type)

Parameters
mixed$valueFirst matrix operand
Returns
mixed

Definition at line 2586 of file Calculation.php.

References $row, array, PHPExcel_Calculation_Functions\flattenArray(), and PHPExcel_Calculation_Functions\flattenSingleValue().

Referenced by _executeBinaryComparisonOperation(), _processTokenStack(), and _showTypeDetails().

2586  {
2587  if ($this->_debugLog->getWriteDebugLog()) {
2588  $testArray = PHPExcel_Calculation_Functions::flattenArray($value);
2589  if (count($testArray) == 1) {
2590  $value = array_pop($testArray);
2591  }
2592 
2593  if (is_array($value)) {
2594  $returnMatrix = array();
2595  $pad = $rpad = ', ';
2596  foreach($value as $row) {
2597  if (is_array($row)) {
2598  $returnMatrix[] = implode($pad,array_map(array($this,'_showValue'),$row));
2599  $rpad = '; ';
2600  } else {
2601  $returnMatrix[] = $this->_showValue($row);
2602  }
2603  }
2604  return '{ '.implode($rpad,$returnMatrix).' }';
2605  } elseif(is_string($value) && (trim($value,'"') == $value)) {
2606  return '"'.$value.'"';
2607  } elseif(is_bool($value)) {
2608  return ($value) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE'];
2609  }
2610  }
2612  } // function _showValue()
static flattenSingleValue($value='')
Convert an array to a single scalar value by extracting the first element.
Definition: Functions.php:662
_showValue($value)
Format details of an operand for display in the log (based on operand type)
static flattenArray($array)
Convert a multi-dimensional array to a simple 1-dimensional array.
Definition: Functions.php:598
Create styles array
The data for the language used.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _translateFormula()

static PHPExcel_Calculation::_translateFormula (   $from,
  $to,
  $formula,
  $fromSeparator,
  $toSeparator 
)
staticprivate

Definition at line 2055 of file Calculation.php.

2055  {
2056  // Convert any Excel function names to the required language
2057  if (self::$_localeLanguage !== 'en_us') {
2058  $inBraces = FALSE;
2059  // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators
2060  if (strpos($formula,'"') !== FALSE) {
2061  // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded
2062  // the formula
2063  $temp = explode('"',$formula);
2064  $i = FALSE;
2065  foreach($temp as &$value) {
2066  // Only count/replace in alternating array entries
2067  if ($i = !$i) {
2068  $value = preg_replace($from,$to,$value);
2069  $value = self::_translateSeparator($fromSeparator,$toSeparator,$value,$inBraces);
2070  }
2071  }
2072  unset($value);
2073  // Then rebuild the formula string
2074  $formula = implode('"',$temp);
2075  } else {
2076  // If there's no quoted strings, then we do a simple count/replace
2077  $formula = preg_replace($from,$to,$formula);
2078  $formula = self::_translateSeparator($fromSeparator,$toSeparator,$formula,$inBraces);
2079  }
2080  }
2081 
2082  return $formula;
2083  }

◆ _translateFormulaToEnglish()

PHPExcel_Calculation::_translateFormulaToEnglish (   $formula)

Definition at line 2117 of file Calculation.php.

References array.

2117  {
2118  if (self::$functionReplaceFromLocale === NULL) {
2119  self::$functionReplaceFromLocale = array();
2120  foreach(array_values(self::$_localeFunctions) as $localeFunctionName) {
2121  self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($localeFunctionName).'([\s]*\()/Ui';
2122  }
2123  foreach(array_values(self::$_localeBoolean) as $excelBoolean) {
2124  self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui';
2125  }
2126  }
2127 
2128  if (self::$functionReplaceToExcel === NULL) {
2129  self::$functionReplaceToExcel = array();
2130  foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) {
2131  self::$functionReplaceToExcel[] = '$1'.trim($excelFunctionName).'$2';
2132  }
2133  foreach(array_keys(self::$_localeBoolean) as $excelBoolean) {
2134  self::$functionReplaceToExcel[] = '$1'.trim($excelBoolean).'$2';
2135  }
2136  }
2137 
2138  return self::_translateFormula(self::$functionReplaceFromLocale,self::$functionReplaceToExcel,$formula,self::$_localeArgumentSeparator,',');
2139  } // function _translateFormulaToEnglish()
Create styles array
The data for the language used.

◆ _translateFormulaToLocale()

PHPExcel_Calculation::_translateFormulaToLocale (   $formula)

Definition at line 2088 of file Calculation.php.

References array.

2088  {
2089  if (self::$functionReplaceFromExcel === NULL) {
2090  self::$functionReplaceFromExcel = array();
2091  foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) {
2092  self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelFunctionName).'([\s]*\()/Ui';
2093  }
2094  foreach(array_keys(self::$_localeBoolean) as $excelBoolean) {
2095  self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui';
2096  }
2097 
2098  }
2099 
2100  if (self::$functionReplaceToLocale === NULL) {
2101  self::$functionReplaceToLocale = array();
2102  foreach(array_values(self::$_localeFunctions) as $localeFunctionName) {
2103  self::$functionReplaceToLocale[] = '$1'.trim($localeFunctionName).'$2';
2104  }
2105  foreach(array_values(self::$_localeBoolean) as $localeBoolean) {
2106  self::$functionReplaceToLocale[] = '$1'.trim($localeBoolean).'$2';
2107  }
2108  }
2109 
2110  return self::_translateFormula(self::$functionReplaceFromExcel,self::$functionReplaceToLocale,$formula,',',self::$_localeArgumentSeparator);
2111  } // function _translateFormulaToLocale()
Create styles array
The data for the language used.

◆ _translateSeparator()

static PHPExcel_Calculation::_translateSeparator (   $fromSeparator,
  $toSeparator,
  $formula,
$inBraces 
)
static

Definition at line 2037 of file Calculation.php.

Referenced by PHPExcel_Reader_OOCalc\loadIntoExisting().

2037  {
2038  $strlen = mb_strlen($formula);
2039  for ($i = 0; $i < $strlen; ++$i) {
2040  $chr = mb_substr($formula,$i,1);
2041  switch ($chr) {
2042  case '{' : $inBraces = TRUE;
2043  break;
2044  case '}' : $inBraces = FALSE;
2045  break;
2046  case $fromSeparator :
2047  if (!$inBraces) {
2048  $formula = mb_substr($formula,0,$i).$toSeparator.mb_substr($formula,$i+1);
2049  }
2050  }
2051  }
2052  return $formula;
2053  }
+ Here is the caller graph for this function:

◆ _unwrapResult()

static PHPExcel_Calculation::_unwrapResult (   $value)
static

Remove quotes used as a wrapper to identify string values.

Parameters
mixed$value
Returns
mixed

Definition at line 2187 of file Calculation.php.

References PHPExcel_Calculation_Functions\NaN().

Referenced by PHPExcel_Reader_SYLK\loadIntoExisting(), and PHPExcel_Chart_DataSeriesValues\refresh().

2187  {
2188  if (is_string($value)) {
2189  if ((isset($value{0})) && ($value{0} == '"') && (substr($value,-1) == '"')) {
2190  return substr($value,1,-1);
2191  }
2192  // Convert numeric errors to NaN error
2193  } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) {
2195  }
2196  return $value;
2197  } // function _unwrapResult()
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _validateBinaryOperand()

PHPExcel_Calculation::_validateBinaryOperand (   $cellID,
$operand,
$stack 
)
private

Definition at line 3498 of file Calculation.php.

References _showTypeDetails(), and PHPExcel_Shared_String\convertToNumberIfFraction().

Referenced by _executeNumericBinaryOperation().

3498  {
3499  if (is_array($operand)) {
3500  if ((count($operand, COUNT_RECURSIVE) - count($operand)) == 1) {
3501  do {
3502  $operand = array_pop($operand);
3503  } while (is_array($operand));
3504  }
3505  }
3506  // Numbers, matrices and booleans can pass straight through, as they're already valid
3507  if (is_string($operand)) {
3508  // We only need special validations for the operand if it is a string
3509  // Start by stripping off the quotation marks we use to identify true excel string values internally
3510  if ($operand > '' && $operand{0} == '"') { $operand = self::_unwrapResult($operand); }
3511  // If the string is a numeric value, we treat it as a numeric, so no further testing
3512  if (!is_numeric($operand)) {
3513  // If not a numeric, test to see if the value is an Excel error, and so can't be used in normal binary operations
3514  if ($operand > '' && $operand{0} == '#') {
3515  $stack->push('Value', $operand);
3516  $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($operand));
3517  return FALSE;
3519  // If not a numeric or a fraction, then it's a text string, and so can't be used in mathematical binary operations
3520  $stack->push('Value', '#VALUE!');
3521  $this->_debugLog->writeDebugLog('Evaluation Result is a ', $this->_showTypeDetails('#VALUE!'));
3522  return FALSE;
3523  }
3524  }
3525  }
3526 
3527  // return a true if the value of the operand is one that we can use in normal binary operations
3528  return TRUE;
3529  } // function _validateBinaryOperand()
static convertToNumberIfFraction(&$operand)
Identify whether a string contains a fractional numeric value, and convert it to a numeric if it is...
Definition: String.php:671
_showTypeDetails($value)
Format type and details of an operand for display in the log (based on operand type) ...
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _wrapResult()

static PHPExcel_Calculation::_wrapResult (   $value)
static

Wrap string values in quotes.

Parameters
mixed$value
Returns
mixed

Definition at line 2163 of file Calculation.php.

References PHPExcel_Calculation_Functions\NaN().

Referenced by PHPExcel_Calculation_Database\__filter(), PHPExcel_Calculation_Functions\_ifCondition(), PHPExcel_Calculation_Statistical\AVERAGEIF(), PHPExcel_Calculation_Statistical\COUNTIF(), PHPExcel_Calculation_Statistical\MAXIF(), PHPExcel_Calculation_Statistical\MINIF(), and PHPExcel_Calculation_MathTrig\SUMIF().

2163  {
2164  if (is_string($value)) {
2165  // Error values cannot be "wrapped"
2166  if (preg_match('/^'.self::CALCULATION_REGEXP_ERROR.'$/i', $value, $match)) {
2167  // Return Excel errors "as is"
2168  return $value;
2169  }
2170  // Return strings wrapped in quotes
2171  return '"'.$value.'"';
2172  // Convert numeric errors to NaN error
2173  } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) {
2175  }
2176 
2177  return $value;
2178  } // function _wrapResult()
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calculate()

PHPExcel_Calculation::calculate ( PHPExcel_Cell  $pCell = NULL)

Calculate cell value (using formula from a cell ID) Retained for backward compatibility.

public

Parameters
PHPExcel_Cell$pCellCell to calculate
Returns
mixed
Exceptions
PHPExcel_Calculation_Exception

Definition at line 2211 of file Calculation.php.

References calculateCellValue().

2211  {
2212  try {
2213  return $this->calculateCellValue($pCell);
2214  } catch (PHPExcel_Exception $e) {
2215  throw new PHPExcel_Calculation_Exception($e->getMessage());
2216  }
2217  } // function calculate()
calculateCellValue(PHPExcel_Cell $pCell=NULL, $resetLog=TRUE)
Calculate the value of a cell formula.
+ Here is the call graph for this function:

◆ calculateCellValue()

PHPExcel_Calculation::calculateCellValue ( PHPExcel_Cell  $pCell = NULL,
  $resetLog = TRUE 
)

Calculate the value of a cell formula.

public

Parameters
PHPExcel_Cell$pCellCell to calculate
Boolean$resetLogFlag indicating whether the debug log should be reset or not
Returns
mixed
Exceptions
PHPExcel_Calculation_Exception

Definition at line 2229 of file Calculation.php.

References $r, $result, $returnArrayAsType, _calculateFormulaValue(), array, PHPExcel_Calculation_Functions\flattenArray(), PHPExcel_Calculation_Functions\NaN(), and PHPExcel_Calculation_Functions\VALUE().

Referenced by calculate().

2229  {
2230  if ($pCell === NULL) {
2231  return NULL;
2232  }
2233 
2234  $returnArrayAsType = self::$returnArrayAsType;
2235  if ($resetLog) {
2236  // Initialise the logging settings if requested
2237  $this->formulaError = null;
2238  $this->_debugLog->clearLog();
2239  $this->_cyclicReferenceStack->clear();
2240  $this->_cyclicFormulaCount = 1;
2241 
2242  self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY;
2243  }
2244 
2245  // Execute the calculation for the cell formula
2246  $this->_cellStack[] = array(
2247  'sheet' => $pCell->getWorksheet()->getTitle(),
2248  'cell' => $pCell->getCoordinate(),
2249  );
2250  try {
2251  $result = self::_unwrapResult($this->_calculateFormulaValue($pCell->getValue(), $pCell->getCoordinate(), $pCell));
2252  $cellAddress = array_pop($this->_cellStack);
2253  $this->_workbook->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']);
2254  } catch (PHPExcel_Exception $e) {
2255  $cellAddress = array_pop($this->_cellStack);
2256  $this->_workbook->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']);
2257  throw new PHPExcel_Calculation_Exception($e->getMessage());
2258  }
2259 
2260  if ((is_array($result)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) {
2261  self::$returnArrayAsType = $returnArrayAsType;
2263  if (self::$returnArrayAsType == self::RETURN_ARRAY_AS_ERROR) {
2265  }
2266  // If there's only a single cell in the array, then we allow it
2267  if (count($testResult) != 1) {
2268  // If keys are numeric, then it's a matrix result rather than a cell range result, so we permit it
2269  $r = array_keys($result);
2270  $r = array_shift($r);
2271  if (!is_numeric($r)) { return PHPExcel_Calculation_Functions::VALUE(); }
2272  if (is_array($result[$r])) {
2273  $c = array_keys($result[$r]);
2274  $c = array_shift($c);
2275  if (!is_numeric($c)) {
2277  }
2278  }
2279  }
2280  $result = array_shift($testResult);
2281  }
2282  self::$returnArrayAsType = $returnArrayAsType;
2283 
2284 
2285  if ($result === NULL) {
2286  return 0;
2287  } elseif((is_float($result)) && ((is_nan($result)) || (is_infinite($result)))) {
2289  }
2290  return $result;
2291  } // function calculateCellValue(
$result
static flattenArray($array)
Convert a multi-dimensional array to a simple 1-dimensional array.
Definition: Functions.php:598
getCoordinate()
Get cell coordinate.
Definition: Cell.php:171
$r
Definition: example_031.php:79
getValue()
Get cell value.
Definition: Cell.php:181
Create styles array
The data for the language used.
_calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pCell=null)
Parse a cell formula and calculate its value.
getWorksheet()
Get parent worksheet.
Definition: Cell.php:488
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calculateFormula()

PHPExcel_Calculation::calculateFormula (   $formula,
  $cellID = NULL,
PHPExcel_Cell  $pCell = NULL 
)

Calculate the value of a formula.

Parameters
string$formulaFormula to parse
string$cellIDAddress of the cell to calculate
PHPExcel_Cell$pCellCell to calculate
Returns
mixed
Exceptions
PHPExcel_Calculation_Exception

Definition at line 2323 of file Calculation.php.

References $result, _calculateFormulaValue(), and getCalculationCacheEnabled().

2323  {
2324  // Initialise the logging settings
2325  $this->formulaError = null;
2326  $this->_debugLog->clearLog();
2327  $this->_cyclicReferenceStack->clear();
2328 
2329  // Disable calculation cacheing because it only applies to cell calculations, not straight formulae
2330  // But don't actually flush any cache
2331  $resetCache = $this->getCalculationCacheEnabled();
2332  $this->_calculationCacheEnabled = FALSE;
2333  // Execute the calculation
2334  try {
2335  $result = self::_unwrapResult($this->_calculateFormulaValue($formula, $cellID, $pCell));
2336  } catch (PHPExcel_Exception $e) {
2337  throw new PHPExcel_Calculation_Exception($e->getMessage());
2338  }
2339 
2340  // Reset calculation cacheing to its previous state
2341  $this->_calculationCacheEnabled = $resetCache;
2342 
2343  return $result;
2344  } // function calculateFormula()
$result
getCalculationCacheEnabled()
Is calculation caching enabled?
_calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pCell=null)
Parse a cell formula and calculate its value.
+ Here is the call graph for this function:

◆ clearCalculationCache()

PHPExcel_Calculation::clearCalculationCache ( )

Clear calculation cache.

Definition at line 1917 of file Calculation.php.

References array.

Referenced by flushInstance(), and setCalculationCacheEnabled().

1917  {
1918  $this->_calculationCache = array();
1919  } // function clearCalculationCache()
Create styles array
The data for the language used.
+ Here is the caller graph for this function:

◆ clearCalculationCacheForWorksheet()

PHPExcel_Calculation::clearCalculationCacheForWorksheet (   $worksheetName)

Clear calculation cache for a specified worksheet.

Parameters
string$worksheetName

Definition at line 1926 of file Calculation.php.

1926  {
1927  if (isset($this->_calculationCache[$worksheetName])) {
1928  unset($this->_calculationCache[$worksheetName]);
1929  }
1930  } // function clearCalculationCacheForWorksheet()

◆ disableCalculationCache()

PHPExcel_Calculation::disableCalculationCache ( )

Disable calculation cache.

Definition at line 1909 of file Calculation.php.

References setCalculationCacheEnabled().

1909  {
1910  $this->setCalculationCacheEnabled(FALSE);
1911  } // function disableCalculationCache()
setCalculationCacheEnabled($pValue=TRUE)
Enable/disable calculation cache.
+ Here is the call graph for this function:

◆ enableCalculationCache()

PHPExcel_Calculation::enableCalculationCache ( )

Enable calculation cache.

Definition at line 1901 of file Calculation.php.

References setCalculationCacheEnabled().

1901  {
1902  $this->setCalculationCacheEnabled(TRUE);
1903  } // function enableCalculationCache()
setCalculationCacheEnabled($pValue=TRUE)
Enable/disable calculation cache.
+ Here is the call graph for this function:

◆ extractCellRange()

PHPExcel_Calculation::extractCellRange ( $pRange = 'A1',
PHPExcel_Worksheet  $pSheet = NULL,
  $resetLog = TRUE 
)

Extract range values.

Parameters
string&$pRangeString based range representation
PHPExcel_Worksheet$pSheetWorksheet
boolean$resetLogFlag indicating whether calculation log should be reset or not
Returns
mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned.
Exceptions
PHPExcel_Calculation_Exception

Definition at line 3748 of file Calculation.php.

References array, PHPExcel_Cell\extractAllCellReferencesInRange(), and PHPExcel_Worksheet\extractSheetTitle().

Referenced by _processTokenStack().

3748  {
3749  // Return value
3750  $returnValue = array ();
3751 
3752 // echo 'extractCellRange('.$pRange.')',PHP_EOL;
3753  if ($pSheet !== NULL) {
3754  $pSheetName = $pSheet->getTitle();
3755 // echo 'Passed sheet name is '.$pSheetName.PHP_EOL;
3756 // echo 'Range reference is '.$pRange.PHP_EOL;
3757  if (strpos ($pRange, '!') !== false) {
3758 // echo '$pRange reference includes sheet reference',PHP_EOL;
3759  list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true);
3760 // echo 'New sheet name is '.$pSheetName,PHP_EOL;
3761 // echo 'Adjusted Range reference is '.$pRange,PHP_EOL;
3762  $pSheet = $this->_workbook->getSheetByName($pSheetName);
3763  }
3764 
3765  // Extract range
3766  $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange);
3767  $pRange = $pSheetName.'!'.$pRange;
3768  if (!isset($aReferences[1])) {
3769  // Single cell in range
3770  sscanf($aReferences[0],'%[A-Z]%d', $currentCol, $currentRow);
3771  $cellValue = NULL;
3772  if ($pSheet->cellExists($aReferences[0])) {
3773  $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog);
3774  } else {
3775  $returnValue[$currentRow][$currentCol] = NULL;
3776  }
3777  } else {
3778  // Extract cell data for all cells in the range
3779  foreach ($aReferences as $reference) {
3780  // Extract range
3781  sscanf($reference,'%[A-Z]%d', $currentCol, $currentRow);
3782  $cellValue = NULL;
3783  if ($pSheet->cellExists($reference)) {
3784  $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog);
3785  } else {
3786  $returnValue[$currentRow][$currentCol] = NULL;
3787  }
3788  }
3789  }
3790  }
3791 
3792  // Return
3793  return $returnValue;
3794  } // function extractCellRange()
getCell($pCoordinate='A1')
Get cell at a specific coordinate.
Definition: Worksheet.php:1153
Create styles array
The data for the language used.
static extractAllCellReferencesInRange($pRange='A1')
Extract all cell references in range.
Definition: Cell.php:854
getTitle()
Get title.
Definition: Worksheet.php:817
static extractSheetTitle($pRange, $returnRange=false)
Extract worksheet title from range.
Definition: Worksheet.php:2654
cellExists($pCoordinate='A1')
Does the cell at a specific coordinate exist?
Definition: Worksheet.php:1256
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ extractNamedRange()

PHPExcel_Calculation::extractNamedRange ( $pRange = 'A1',
PHPExcel_Worksheet  $pSheet = NULL,
  $resetLog = TRUE 
)

Extract range values.

Parameters
string&$pRangeString based range representation
PHPExcel_Worksheet$pSheetWorksheet
Returns
mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned.
Parameters
boolean$resetLogFlag indicating whether calculation log should be reset or not
Exceptions
PHPExcel_Calculation_Exception

Definition at line 3806 of file Calculation.php.

References array, PHPExcel_Cell\coordinateFromString(), PHPExcel_Cell\extractAllCellReferencesInRange(), PHPExcel_Worksheet\extractSheetTitle(), PHPExcel_Calculation_Functions\REF(), PHPExcel_NamedRange\resolveRange(), and PHPExcel_Cell\splitRange().

Referenced by _processTokenStack().

3806  {
3807  // Return value
3808  $returnValue = array ();
3809 
3810 // echo 'extractNamedRange('.$pRange.')<br />';
3811  if ($pSheet !== NULL) {
3812  $pSheetName = $pSheet->getTitle();
3813 // echo 'Current sheet name is '.$pSheetName.'<br />';
3814 // echo 'Range reference is '.$pRange.'<br />';
3815  if (strpos ($pRange, '!') !== false) {
3816 // echo '$pRange reference includes sheet reference',PHP_EOL;
3817  list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true);
3818 // echo 'New sheet name is '.$pSheetName,PHP_EOL;
3819 // echo 'Adjusted Range reference is '.$pRange,PHP_EOL;
3820  $pSheet = $this->_workbook->getSheetByName($pSheetName);
3821  }
3822 
3823  // Named range?
3824  $namedRange = PHPExcel_NamedRange::resolveRange($pRange, $pSheet);
3825  if ($namedRange !== NULL) {
3826  $pSheet = $namedRange->getWorksheet();
3827 // echo 'Named Range '.$pRange.' (';
3828  $pRange = $namedRange->getRange();
3829  $splitRange = PHPExcel_Cell::splitRange($pRange);
3830  // Convert row and column references
3831  if (ctype_alpha($splitRange[0][0])) {
3832  $pRange = $splitRange[0][0] . '1:' . $splitRange[0][1] . $namedRange->getWorksheet()->getHighestRow();
3833  } elseif(ctype_digit($splitRange[0][0])) {
3834  $pRange = 'A' . $splitRange[0][0] . ':' . $namedRange->getWorksheet()->getHighestColumn() . $splitRange[0][1];
3835  }
3836 // echo $pRange.') is in sheet '.$namedRange->getWorksheet()->getTitle().'<br />';
3837 
3838 // if ($pSheet->getTitle() != $namedRange->getWorksheet()->getTitle()) {
3839 // if (!$namedRange->getLocalOnly()) {
3840 // $pSheet = $namedRange->getWorksheet();
3841 // } else {
3842 // return $returnValue;
3843 // }
3844 // }
3845  } else {
3847  }
3848 
3849  // Extract range
3850  $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange);
3851 // var_dump($aReferences);
3852  if (!isset($aReferences[1])) {
3853  // Single cell (or single column or row) in range
3854  list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($aReferences[0]);
3855  $cellValue = NULL;
3856  if ($pSheet->cellExists($aReferences[0])) {
3857  $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog);
3858  } else {
3859  $returnValue[$currentRow][$currentCol] = NULL;
3860  }
3861  } else {
3862  // Extract cell data for all cells in the range
3863  foreach ($aReferences as $reference) {
3864  // Extract range
3865  list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($reference);
3866 // echo 'NAMED RANGE: $currentCol='.$currentCol.' $currentRow='.$currentRow.'<br />';
3867  $cellValue = NULL;
3868  if ($pSheet->cellExists($reference)) {
3869  $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog);
3870  } else {
3871  $returnValue[$currentRow][$currentCol] = NULL;
3872  }
3873  }
3874  }
3875 // print_r($returnValue);
3876 // echo '<br />';
3877  }
3878 
3879  // Return
3880  return $returnValue;
3881  } // function extractNamedRange()
static splitRange($pRange='A1:A1')
Split range into coordinate strings.
Definition: Cell.php:660
static coordinateFromString($pCoordinateString='A1')
Coordinate from string.
Definition: Cell.php:580
getCell($pCoordinate='A1')
Get cell at a specific coordinate.
Definition: Worksheet.php:1153
static resolveRange($pNamedRange='', PHPExcel_Worksheet $pSheet)
Resolve a named range to a regular cell range.
Definition: NamedRange.php:229
Create styles array
The data for the language used.
static extractAllCellReferencesInRange($pRange='A1')
Extract all cell references in range.
Definition: Cell.php:854
getTitle()
Get title.
Definition: Worksheet.php:817
static extractSheetTitle($pRange, $returnRange=false)
Extract worksheet title from range.
Definition: Worksheet.php:2654
cellExists($pCoordinate='A1')
Does the cell at a specific coordinate exist?
Definition: Worksheet.php:1256
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flushInstance()

PHPExcel_Calculation::flushInstance ( )

Flush the calculation cache for any existing instance of this class but only if a PHPExcel_Calculation instance exists.

public

Returns
null

Definition at line 1801 of file Calculation.php.

References clearCalculationCache().

1801  {
1802  $this->clearCalculationCache();
1803  } // function flushInstance()
clearCalculationCache()
Clear calculation cache.
+ Here is the call graph for this function:

◆ getArrayReturnType()

static PHPExcel_Calculation::getArrayReturnType ( )
static

Return the Array Return Type (Array or Value of first element in the array)

public

Returns
string $returnType Array return type

Definition at line 1871 of file Calculation.php.

Referenced by PHPExcel_Writer_PDF_Core\prepareForSave(), PHPExcel_Writer_CSV\save(), and PHPExcel_Writer_HTML\save().

1871  {
1872  return self::$returnArrayAsType;
1873  } // function getArrayReturnType()
+ Here is the caller graph for this function:

◆ getCalculationCacheEnabled()

PHPExcel_Calculation::getCalculationCacheEnabled ( )

Is calculation caching enabled?

public

Returns
boolean

Definition at line 1882 of file Calculation.php.

References $_calculationCacheEnabled.

Referenced by calculateFormula().

1882  {
1884  } // function getCalculationCacheEnabled()
+ Here is the caller graph for this function:

◆ getDebugLog()

PHPExcel_Calculation::getDebugLog ( )

Get the debuglog for this claculation engine instance.

public

Returns
PHPExcel_CalcEngine_Logger

Definition at line 1812 of file Calculation.php.

1812  {
1813  return $this->_debugLog;
1814  }

◆ getFALSE()

◆ getInstance()

static PHPExcel_Calculation::getInstance ( PHPExcel  $workbook = NULL)
static

Get an instance of this class.

public

Parameters
PHPExcel$workbookInjected workbook for working with a PHPExcel object, or NULL to create a standalone claculation engine
Returns
PHPExcel_Calculation

Definition at line 1765 of file Calculation.php.

Referenced by PHPExcel\__construct(), PHPExcel_Worksheet\__destruct(), PHPExcel_Calculation_Database\__filter(), PHPExcel_Calculation_Statistical\AVERAGEIF(), PHPExcel_Shared_String\convertToNumberIfFraction(), PHPExcel_Calculation_Statistical\COUNTIF(), PHPExcel_Cell\getCalculatedValue(), PHPExcel_Calculation_LookupRef\INDIRECT(), PHPExcel_Calculation_Statistical\MAXIF(), PHPExcel_Calculation_Statistical\MINIF(), PHPExcel_Calculation_LookupRef\OFFSET(), PHPExcel_Chart_DataSeriesValues\refresh(), PHPExcel_Writer_CSV\save(), PHPExcel_Writer_Excel5\save(), PHPExcel_Writer_HTML\save(), PHPExcel_Writer_Excel2007\save(), PHPExcel_Settings\setLocale(), PHPExcel_Worksheet\setTitle(), PHPExcel_Worksheet_AutoFilter\showHideRows(), PHPExcel_Calculation_MathTrig\SUMIF(), and CalculationTest\testBinaryComparisonOperation().

1765  {
1766  if ($workbook !== NULL) {
1767  if (isset(self::$_workbookSets[$workbook->getID()])) {
1768  return self::$_workbookSets[$workbook->getID()];
1769  }
1770  return new PHPExcel_Calculation($workbook);
1771  }
1772 
1773  if (!isset(self::$_instance) || (self::$_instance === NULL)) {
1774  self::$_instance = new PHPExcel_Calculation();
1775  }
1776 
1777  return self::$_instance;
1778  } // function getInstance()
getID()
Return the unique ID value assigned to this spreadsheet workbook.
Definition: PHPExcel.php:1135
+ Here is the caller graph for this function:

◆ getLocale()

PHPExcel_Calculation::getLocale ( )

Get the currently defined locale code.

Returns
string

Definition at line 1951 of file Calculation.php.

1951  {
1952  return self::$_localeLanguage;
1953  } // function getLocale()

◆ getTRUE()

◆ getValueFromCache()

PHPExcel_Calculation::getValueFromCache (   $cellReference,
$cellValue 
)

Definition at line 2347 of file Calculation.php.

Referenced by _calculateFormulaValue().

2347  {
2348  // Is calculation cacheing enabled?
2349  // Is the value present in calculation cache?
2350  $this->_debugLog->writeDebugLog('Testing cache value for cell ', $cellReference);
2351  if (($this->_calculationCacheEnabled) && (isset($this->_calculationCache[$cellReference]))) {
2352  $this->_debugLog->writeDebugLog('Retrieving value for cell ', $cellReference, ' from cache');
2353  // Return the cached result
2354  $cellValue = $this->_calculationCache[$cellReference];
2355  return TRUE;
2356  }
2357  return FALSE;
2358  }
+ Here is the caller graph for this function:

◆ isImplemented()

PHPExcel_Calculation::isImplemented (   $pFunction = '')

Is a specific function implemented?

Parameters
string$pFunctionFunction Name
Returns
boolean

Definition at line 3890 of file Calculation.php.

3890  {
3891  $pFunction = strtoupper ($pFunction);
3892  if (isset(self::$_PHPExcelFunctions[$pFunction])) {
3893  return (self::$_PHPExcelFunctions[$pFunction]['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY');
3894  } else {
3895  return FALSE;
3896  }
3897  } // function isImplemented()

◆ listAllFunctionNames()

PHPExcel_Calculation::listAllFunctionNames ( )

Get a list of all Excel function names.

Returns
array

Definition at line 3928 of file Calculation.php.

3928  {
3929  return array_keys(self::$_PHPExcelFunctions);
3930  } // function listAllFunctionNames()

◆ listFunctionNames()

PHPExcel_Calculation::listFunctionNames ( )

Get a list of implemented Excel function names.

Returns
array

Definition at line 3937 of file Calculation.php.

References array.

3937  {
3938  // Return value
3939  $returnValue = array();
3940  // Loop functions
3941  foreach(self::$_PHPExcelFunctions as $functionName => $function) {
3942  if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') {
3943  $returnValue[] = $functionName;
3944  }
3945  }
3946 
3947  // Return
3948  return $returnValue;
3949  } // function listFunctionNames()
Create styles array
The data for the language used.

◆ listFunctions()

PHPExcel_Calculation::listFunctions ( )

Get a list of all implemented functions as an array of function objects.

Returns
array of PHPExcel_Calculation_Function

Definition at line 3905 of file Calculation.php.

References array.

3905  {
3906  // Return value
3907  $returnValue = array();
3908  // Loop functions
3909  foreach(self::$_PHPExcelFunctions as $functionName => $function) {
3910  if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') {
3911  $returnValue[$functionName] = new PHPExcel_Calculation_Function($function['category'],
3912  $functionName,
3913  $function['functionCall']
3914  );
3915  }
3916  }
3917 
3918  // Return
3919  return $returnValue;
3920  } // function listFunctions()
Create styles array
The data for the language used.

◆ parseFormula()

PHPExcel_Calculation::parseFormula (   $formula)

Validate and parse a formula string.

Parameters
string$formulaFormula to parse
Returns
array
Exceptions
PHPExcel_Calculation_Exception

Definition at line 2301 of file Calculation.php.

References _parseFormula(), and array.

2301  {
2302  // Basic validation that this is indeed a formula
2303  // We return an empty array if not
2304  $formula = trim($formula);
2305  if ((!isset($formula{0})) || ($formula{0} != '=')) return array();
2306  $formula = ltrim(substr($formula,1));
2307  if (!isset($formula{0})) return array();
2308 
2309  // Parse the formula and return the token stack
2310  return $this->_parseFormula($formula);
2311  } // function parseFormula()
_parseFormula($formula, PHPExcel_Cell $pCell=NULL)
Create styles array
The data for the language used.
+ Here is the call graph for this function:

◆ renameCalculationCacheForWorksheet()

PHPExcel_Calculation::renameCalculationCacheForWorksheet (   $fromWorksheetName,
  $toWorksheetName 
)

Rename calculation cache for a specified worksheet.

Parameters
string$fromWorksheetName
string$toWorksheetName

Definition at line 1938 of file Calculation.php.

1938  {
1939  if (isset($this->_calculationCache[$fromWorksheetName])) {
1940  $this->_calculationCache[$toWorksheetName] = &$this->_calculationCache[$fromWorksheetName];
1941  unset($this->_calculationCache[$fromWorksheetName]);
1942  }
1943  } // function renameCalculationCacheForWorksheet()

◆ saveValueToCache()

PHPExcel_Calculation::saveValueToCache (   $cellReference,
  $cellValue 
)

Definition at line 2360 of file Calculation.php.

Referenced by _calculateFormulaValue().

2360  {
2361  if ($this->_calculationCacheEnabled) {
2362  $this->_calculationCache[$cellReference] = $cellValue;
2363  }
2364  }
+ Here is the caller graph for this function:

◆ setArrayReturnType()

static PHPExcel_Calculation::setArrayReturnType (   $returnType)
static

Set the Array Return Type (Array or Value of first element in the array)

public

Parameters
string$returnTypeArray return type
Returns
boolean Success or failure

Definition at line 1854 of file Calculation.php.

Referenced by PHPExcel_Writer_PDF_Core\prepareForSave(), PHPExcel_Writer_PDF_Core\restoreStateAfterSave(), PHPExcel_Writer_CSV\save(), PHPExcel_Writer_HTML\save(), and MathTrigTest\testMROUND().

1854  {
1855  if (($returnType == self::RETURN_ARRAY_AS_VALUE) ||
1856  ($returnType == self::RETURN_ARRAY_AS_ERROR) ||
1857  ($returnType == self::RETURN_ARRAY_AS_ARRAY)) {
1858  self::$returnArrayAsType = $returnType;
1859  return TRUE;
1860  }
1861  return FALSE;
1862  } // function setArrayReturnType()
+ Here is the caller graph for this function:

◆ setCalculationCacheEnabled()

PHPExcel_Calculation::setCalculationCacheEnabled (   $pValue = TRUE)

Enable/disable calculation cache.

public

Parameters
boolean$pValue

Definition at line 1892 of file Calculation.php.

References clearCalculationCache().

Referenced by disableCalculationCache(), and enableCalculationCache().

1892  {
1893  $this->_calculationCacheEnabled = $pValue;
1894  $this->clearCalculationCache();
1895  } // function setCalculationCacheEnabled()
clearCalculationCache()
Clear calculation cache.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setLocale()

PHPExcel_Calculation::setLocale (   $locale = 'en_us')

Set the locale code.

Parameters
string$localeThe locale to use for formula translation
Returns
boolean

Definition at line 1962 of file Calculation.php.

References array, and file.

1962  {
1963  // Identify our locale and language
1964  $language = $locale = strtolower($locale);
1965  if (strpos($locale,'_') !== FALSE) {
1966  list($language) = explode('_',$locale);
1967  }
1968 
1969  if (count(self::$_validLocaleLanguages) == 1)
1970  self::_loadLocales();
1971 
1972  // Test whether we have any language data for this language (any locale)
1973  if (in_array($language,self::$_validLocaleLanguages)) {
1974  // initialise language/locale settings
1975  self::$_localeFunctions = array();
1976  self::$_localeArgumentSeparator = ',';
1977  self::$_localeBoolean = array('TRUE' => 'TRUE', 'FALSE' => 'FALSE', 'NULL' => 'NULL');
1978  // Default is English, if user isn't requesting english, then read the necessary data from the locale files
1979  if ($locale != 'en_us') {
1980  // Search for a file with a list of function names for locale
1981  $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'functions';
1982  if (!file_exists($functionNamesFile)) {
1983  // If there isn't a locale specific function file, look for a language specific function file
1984  $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'functions';
1985  if (!file_exists($functionNamesFile)) {
1986  return FALSE;
1987  }
1988  }
1989  // Retrieve the list of locale or language specific function names
1990  $localeFunctions = file($functionNamesFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
1991  foreach ($localeFunctions as $localeFunction) {
1992  list($localeFunction) = explode('##',$localeFunction); // Strip out comments
1993  if (strpos($localeFunction,'=') !== FALSE) {
1994  list($fName,$lfName) = explode('=',$localeFunction);
1995  $fName = trim($fName);
1996  $lfName = trim($lfName);
1997  if ((isset(self::$_PHPExcelFunctions[$fName])) && ($lfName != '') && ($fName != $lfName)) {
1998  self::$_localeFunctions[$fName] = $lfName;
1999  }
2000  }
2001  }
2002  // Default the TRUE and FALSE constants to the locale names of the TRUE() and FALSE() functions
2003  if (isset(self::$_localeFunctions['TRUE'])) { self::$_localeBoolean['TRUE'] = self::$_localeFunctions['TRUE']; }
2004  if (isset(self::$_localeFunctions['FALSE'])) { self::$_localeBoolean['FALSE'] = self::$_localeFunctions['FALSE']; }
2005 
2006  $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'config';
2007  if (!file_exists($configFile)) {
2008  $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'config';
2009  }
2010  if (file_exists($configFile)) {
2011  $localeSettings = file($configFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
2012  foreach ($localeSettings as $localeSetting) {
2013  list($localeSetting) = explode('##',$localeSetting); // Strip out comments
2014  if (strpos($localeSetting,'=') !== FALSE) {
2015  list($settingName,$settingValue) = explode('=',$localeSetting);
2016  $settingName = strtoupper(trim($settingName));
2017  switch ($settingName) {
2018  case 'ARGUMENTSEPARATOR' :
2019  self::$_localeArgumentSeparator = trim($settingValue);
2020  break;
2021  }
2022  }
2023  }
2024  }
2025  }
2026 
2027  self::$functionReplaceFromExcel = self::$functionReplaceToExcel =
2028  self::$functionReplaceFromLocale = self::$functionReplaceToLocale = NULL;
2029  self::$_localeLanguage = $locale;
2030  return TRUE;
2031  }
2032  return FALSE;
2033  } // function setLocale()
Reload workbook from saved file
Create styles array
The data for the language used.

◆ strcmpLowercaseFirst()

PHPExcel_Calculation::strcmpLowercaseFirst (   $str1,
  $str2 
)
private

Compare two strings in the same way as strcmp() except that lowercase come before uppercase letters.

Parameters
string$str1First string value for the comparison
string$str2Second string value for the comparison
Returns
integer

Definition at line 3653 of file Calculation.php.

References PHPExcel_Shared_String\StrCaseReverse().

Referenced by _executeBinaryComparisonOperation().

3654  {
3655  $inversedStr1 = PHPExcel_Shared_String::StrCaseReverse($str1);
3656  $inversedStr2 = PHPExcel_Shared_String::StrCaseReverse($str2);
3657 
3658  return strcmp($inversedStr1, $inversedStr2);
3659  }
static StrCaseReverse($pValue='')
Reverse the case of a string, so that all uppercase characters become lowercase and all lowercase cha...
Definition: String.php:648
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ unsetInstance()

static PHPExcel_Calculation::unsetInstance ( PHPExcel  $workbook = NULL)
static

Unset an instance of this class.

public

Parameters
PHPExcel$workbookInjected workbook identifying the instance to unset

Definition at line 1786 of file Calculation.php.

Referenced by PHPExcel\__destruct().

1786  {
1787  if ($workbook !== NULL) {
1788  if (isset(self::$_workbookSets[$workbook->getID()])) {
1789  unset(self::$_workbookSets[$workbook->getID()]);
1790  }
1791  }
1792  }
getID()
Return the unique ID value assigned to this spreadsheet workbook.
Definition: PHPExcel.php:1135
+ Here is the caller graph for this function:

Field Documentation

◆ $_binaryOperators

PHPExcel_Calculation::$_binaryOperators
staticprivate
Initial value:
= array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE,
'^' => TRUE, '&' => TRUE, '>' => TRUE, '<' => TRUE,
'=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE,
'|' => TRUE, ':' => TRUE
)

Definition at line 153 of file Calculation.php.

◆ $_calculationCache

PHPExcel_Calculation::$_calculationCache = array ()
private

Definition at line 121 of file Calculation.php.

◆ $_calculationCacheEnabled

PHPExcel_Calculation::$_calculationCacheEnabled = TRUE
private

Definition at line 130 of file Calculation.php.

Referenced by getCalculationCacheEnabled().

◆ $_cellStack

PHPExcel_Calculation::$_cellStack = array()
private

Definition at line 197 of file Calculation.php.

◆ $_comparisonOperators

PHPExcel_Calculation::$_comparisonOperators = array('>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE)
staticprivate

Definition at line 2722 of file Calculation.php.

◆ $_controlFunctions

PHPExcel_Calculation::$_controlFunctions
staticprivate
Initial value:
'MKMATRIX' => array('argumentCount' => '*',
'functionCall' => 'self::_mkMatrix'
)
)

Definition at line 1714 of file Calculation.php.

◆ $_cyclicFormulaCell

PHPExcel_Calculation::$_cyclicFormulaCell = ''
private

Definition at line 209 of file Calculation.php.

◆ $_cyclicFormulaCount

PHPExcel_Calculation::$_cyclicFormulaCount = 1
private

Definition at line 207 of file Calculation.php.

Referenced by _calculateFormulaValue().

◆ $_cyclicReferenceStack

PHPExcel_Calculation::$_cyclicReferenceStack
private

Definition at line 195 of file Calculation.php.

◆ $_ExcelConstants

PHPExcel_Calculation::$_ExcelConstants
staticprivate
Initial value:
= array('TRUE' => TRUE,
'FALSE' => FALSE,
'NULL' => NULL
)

Definition at line 273 of file Calculation.php.

◆ $_instance

PHPExcel_Calculation::$_instance
staticprivate

Definition at line 96 of file Calculation.php.

◆ $_localeArgumentSeparator

PHPExcel_Calculation::$_localeArgumentSeparator = ','
staticprivate

Definition at line 251 of file Calculation.php.

◆ $_localeBoolean

PHPExcel_Calculation::$_localeBoolean
static
Initial value:
= array( 'TRUE' => 'TRUE',
'FALSE' => 'FALSE',
'NULL' => 'NULL'
)

Definition at line 260 of file Calculation.php.

◆ $_localeFunctions

PHPExcel_Calculation::$_localeFunctions = array()
staticprivate

Definition at line 252 of file Calculation.php.

◆ $_localeLanguage

PHPExcel_Calculation::$_localeLanguage = 'en_us'
staticprivate

Definition at line 234 of file Calculation.php.

◆ $_operatorAssociativity

PHPExcel_Calculation::$_operatorAssociativity
staticprivate
Initial value:
'^' => 0,
'*' => 0, '/' => 0,
'+' => 0, '-' => 0,
'&' => 0,
'|' => 0, ':' => 0,
'>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0
)

Definition at line 2711 of file Calculation.php.

◆ $_operatorPrecedence

PHPExcel_Calculation::$_operatorPrecedence
staticprivate
Initial value:
':' => 8,
'|' => 7,
'~' => 6,
'%' => 5,
'^' => 4,
'*' => 3, '/' => 3,
'+' => 2, '-' => 2,
'&' => 1,
'>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0
)

Definition at line 2727 of file Calculation.php.

◆ $_operators

PHPExcel_Calculation::$_operators
staticprivate
Initial value:
= array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE,
'^' => TRUE, '&' => TRUE, '%' => FALSE, '~' => FALSE,
'>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE,
'<=' => TRUE, '<>' => TRUE, '|' => TRUE, ':' => TRUE
)

Definition at line 140 of file Calculation.php.

◆ $_PHPExcelFunctions

PHPExcel_Calculation::$_PHPExcelFunctions
staticprivate

Definition at line 279 of file Calculation.php.

◆ $_savedPrecision

PHPExcel_Calculation::$_savedPrecision = 14
private

Definition at line 225 of file Calculation.php.

◆ $_validLocaleLanguages

PHPExcel_Calculation::$_validLocaleLanguages
staticprivate
Initial value:
= array( 'en'
)

Definition at line 243 of file Calculation.php.

◆ $_workbook

PHPExcel_Calculation::$_workbook
private

Definition at line 105 of file Calculation.php.

◆ $_workbookSets

PHPExcel_Calculation::$_workbookSets
staticprivate

Definition at line 113 of file Calculation.php.

◆ $cyclicFormulaCount

PHPExcel_Calculation::$cyclicFormulaCount = 1

Definition at line 217 of file Calculation.php.

◆ $debugLog

PHPExcel_Calculation::$debugLog
private

Definition at line 166 of file Calculation.php.

◆ $formulaError

PHPExcel_Calculation::$formulaError = NULL

Definition at line 186 of file Calculation.php.

◆ $functionReplaceFromExcel

PHPExcel_Calculation::$functionReplaceFromExcel = NULL
staticprivate

Definition at line 2085 of file Calculation.php.

◆ $functionReplaceFromLocale

PHPExcel_Calculation::$functionReplaceFromLocale = NULL
staticprivate

Definition at line 2114 of file Calculation.php.

◆ $functionReplaceToExcel

PHPExcel_Calculation::$functionReplaceToExcel = NULL
staticprivate

Definition at line 2115 of file Calculation.php.

◆ $functionReplaceToLocale

PHPExcel_Calculation::$functionReplaceToLocale = NULL
staticprivate

Definition at line 2086 of file Calculation.php.

◆ $returnArrayAsType

PHPExcel_Calculation::$returnArrayAsType = self::RETURN_ARRAY_AS_VALUE
staticprivate

Definition at line 87 of file Calculation.php.

Referenced by calculateCellValue().

◆ $suppressFormulaErrors

PHPExcel_Calculation::$suppressFormulaErrors = FALSE

Definition at line 177 of file Calculation.php.

◆ CALCULATION_REGEXP_CELLREF

const PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF = CALCULATION_REGEXP_CELLREF

◆ CALCULATION_REGEXP_ERROR

const PHPExcel_Calculation::CALCULATION_REGEXP_ERROR = '\#[A-Z][A-Z0_\/]*[!\?]?'

Definition at line 79 of file Calculation.php.

◆ CALCULATION_REGEXP_FUNCTION

const PHPExcel_Calculation::CALCULATION_REGEXP_FUNCTION = '@?([A-Z][A-Z0-9\.]*)[\s]*\('

Definition at line 73 of file Calculation.php.

◆ CALCULATION_REGEXP_NAMEDRANGE

const PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE = CALCULATION_REGEXP_NAMEDRANGE

◆ CALCULATION_REGEXP_NUMBER

const PHPExcel_Calculation::CALCULATION_REGEXP_NUMBER = '[-+]?\d*\.?\d+(e[-+]?\d+)?'

Constants.

Regular Expressions

Definition at line 67 of file Calculation.php.

Referenced by PHPExcel_Cell_AdvancedValueBinder\bindValue().

◆ CALCULATION_REGEXP_OPENBRACE

const PHPExcel_Calculation::CALCULATION_REGEXP_OPENBRACE = '\('

Definition at line 71 of file Calculation.php.

◆ CALCULATION_REGEXP_STRING

const PHPExcel_Calculation::CALCULATION_REGEXP_STRING = '"(?:[^"]|"")*"'

Definition at line 69 of file Calculation.php.

◆ RETURN_ARRAY_AS_ARRAY

const PHPExcel_Calculation::RETURN_ARRAY_AS_ARRAY = 'array'

Definition at line 85 of file Calculation.php.

Referenced by MathTrigTest\testMROUND().

◆ RETURN_ARRAY_AS_ERROR

const PHPExcel_Calculation::RETURN_ARRAY_AS_ERROR = 'error'

constants

Definition at line 83 of file Calculation.php.

◆ RETURN_ARRAY_AS_VALUE

const PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE = 'value'

The documentation for this class was generated from the following file: