mirror of
https://github.com/retailcrm/PHPExcel.git
synced 2024-11-29 08:46:03 +03:00
Refactoring of calculation engine using the multiton pattern to eliminate caching issues when working with multiple workbooks
Refactoring of calculation engine for improved performance and memory usage Refactoring of cell object to eliminate data duplication and reduce memory
This commit is contained in:
parent
6fd6b4d044
commit
3886c47ebe
@ -86,6 +86,11 @@ abstract class PHPExcel_CachedObjectStorage_CacheBase {
|
|||||||
} // function __construct()
|
} // function __construct()
|
||||||
|
|
||||||
|
|
||||||
|
public function getParent()
|
||||||
|
{
|
||||||
|
return $this->_parent;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?
|
* Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?
|
||||||
*
|
*
|
||||||
@ -188,6 +193,23 @@ abstract class PHPExcel_CachedObjectStorage_CacheBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getCurrentAddress()
|
||||||
|
{
|
||||||
|
return $this->_currentObjectID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCurrentColumn()
|
||||||
|
{
|
||||||
|
list($column,$row) = sscanf($this->_currentObjectID, '%[A-Z]%d');
|
||||||
|
return $column;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCurrentRow()
|
||||||
|
{
|
||||||
|
list($column,$row) = sscanf($this->_currentObjectID, '%[A-Z]%d');
|
||||||
|
return $row;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get highest worksheet column
|
* Get highest worksheet column
|
||||||
*
|
*
|
||||||
|
@ -48,11 +48,15 @@ class PHPExcel_CachedObjectStorage_Memory extends PHPExcel_CachedObjectStorage_C
|
|||||||
*
|
*
|
||||||
* @param string $pCoord Coordinate address of the cell to update
|
* @param string $pCoord Coordinate address of the cell to update
|
||||||
* @param PHPExcel_Cell $cell Cell to update
|
* @param PHPExcel_Cell $cell Cell to update
|
||||||
* @return void
|
* @return PHPExcel_Cell
|
||||||
* @throws PHPExcel_Exception
|
* @throws PHPExcel_Exception
|
||||||
*/
|
*/
|
||||||
public function addCacheData($pCoord, PHPExcel_Cell $cell) {
|
public function addCacheData($pCoord, PHPExcel_Cell $cell) {
|
||||||
$this->_cellCache[$pCoord] = $cell;
|
$this->_cellCache[$pCoord] = $cell;
|
||||||
|
|
||||||
|
// Set current entry to the new/updated entry
|
||||||
|
$this->_currentObjectID = $pCoord;
|
||||||
|
|
||||||
return $cell;
|
return $cell;
|
||||||
} // function addCacheData()
|
} // function addCacheData()
|
||||||
|
|
||||||
@ -67,10 +71,14 @@ class PHPExcel_CachedObjectStorage_Memory extends PHPExcel_CachedObjectStorage_C
|
|||||||
public function getCacheData($pCoord) {
|
public function getCacheData($pCoord) {
|
||||||
// Check if the entry that has been requested actually exists
|
// Check if the entry that has been requested actually exists
|
||||||
if (!isset($this->_cellCache[$pCoord])) {
|
if (!isset($this->_cellCache[$pCoord])) {
|
||||||
|
$this->_currentObjectID = NULL;
|
||||||
// Return null if requested entry doesn't exist in cache
|
// Return null if requested entry doesn't exist in cache
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set current entry to the requested entry
|
||||||
|
$this->_currentObjectID = $pCoord;
|
||||||
|
|
||||||
// Return requested entry
|
// Return requested entry
|
||||||
return $this->_cellCache[$pCoord];
|
return $this->_cellCache[$pCoord];
|
||||||
} // function getCacheData()
|
} // function getCacheData()
|
||||||
|
109
Classes/PHPExcel/CalcEngine/Logger.php
Normal file
109
Classes/PHPExcel/CalcEngine/Logger.php
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PHPExcel
|
||||||
|
*
|
||||||
|
* Copyright (c) 2006 - 2012 PHPExcel
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* @category PHPExcel
|
||||||
|
* @package PHPExcel_Calculation
|
||||||
|
* @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||||
|
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||||
|
* @version ##VERSION##, ##DATE##
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHPExcel_Calculation_Logger
|
||||||
|
*
|
||||||
|
* @category PHPExcel
|
||||||
|
* @package PHPExcel_Calculation
|
||||||
|
* @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||||
|
*/
|
||||||
|
class PHPExcel_CalcEngine_Logger {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag to determine whether a debug log should be generated by the calculation engine
|
||||||
|
* If true, then a debug log will be generated
|
||||||
|
* If false, then a debug log will not be generated
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private $_writeDebugLog = FALSE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag to determine whether a debug log should be echoed by the calculation engine
|
||||||
|
* If true, then a debug log will be echoed
|
||||||
|
* If false, then a debug log will not be echoed
|
||||||
|
* A debug log can only be echoed if it is generated
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private $_echoDebugLog = FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The debug log generated by the calculation engine
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private $_debugLog = array();
|
||||||
|
|
||||||
|
|
||||||
|
public function setWriteDebugLog($pValue = FALSE) {
|
||||||
|
$this->_writeDebugLog = $pValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getWriteDebugLog() {
|
||||||
|
return $this->_writeDebugLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setEchoDebugLog($pValue = FALSE) {
|
||||||
|
$this->_echoDebugLog = $pValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEchoDebugLog() {
|
||||||
|
return $this->_echoDebugLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function writeDebugLog(array $cellReferencePath) {
|
||||||
|
// Only write the debug log if logging is enabled
|
||||||
|
if ($this->_writeDebugLog) {
|
||||||
|
$message = func_get_args();
|
||||||
|
array_shift($message);
|
||||||
|
$cellReference = implode(' -> ', $cellReferencePath);
|
||||||
|
$message = implode($message);
|
||||||
|
if ($this->_echoDebugLog) {
|
||||||
|
echo $cellReference, (count($cellReferencePath) > 0 ? ' => ' : ''), $message,PHP_EOL;
|
||||||
|
}
|
||||||
|
$this->_debugLog[] = $cellReference . (count($cellReferencePath) > 0 ? ' => ' : '') . $message;
|
||||||
|
}
|
||||||
|
} // function _writeDebug()
|
||||||
|
|
||||||
|
|
||||||
|
public function clearLog() {
|
||||||
|
$this->_debugLog = array();
|
||||||
|
} // function flushLogger()
|
||||||
|
|
||||||
|
public function getLog() {
|
||||||
|
return $this->_debugLog;
|
||||||
|
} // function flushLogger()
|
||||||
|
|
||||||
|
|
||||||
|
} // class PHPExcel_Calculation_Logger
|
||||||
|
|
@ -156,6 +156,15 @@ class PHPExcel_Calculation {
|
|||||||
'|' => TRUE, ':' => TRUE
|
'|' => TRUE, ':' => TRUE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The debug log generated by the calculation engine
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var PHPExcel_CalcEngine_Logger
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private $debugLog;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag to determine how formula errors should be handled
|
* Flag to determine how formula errors should be handled
|
||||||
* If true, then a user error will be triggered
|
* If true, then a user error will be triggered
|
||||||
@ -176,30 +185,6 @@ class PHPExcel_Calculation {
|
|||||||
*/
|
*/
|
||||||
public $formulaError = NULL;
|
public $formulaError = NULL;
|
||||||
|
|
||||||
/**
|
|
||||||
* Flag to determine whether a debug log should be generated by the calculation engine
|
|
||||||
* If true, then a debug log will be generated
|
|
||||||
* If false, then a debug log will not be generated
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @var boolean
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public $writeDebugLog = FALSE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flag to determine whether a debug log should be echoed by the calculation engine
|
|
||||||
* If true, then a debug log will be echoed
|
|
||||||
* If false, then a debug log will not be echoed
|
|
||||||
* A debug log can only be echoed if it is generated
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @var boolean
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public $echoDebugLog = FALSE;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An array of the nested cell references accessed by the calculation engine, used for the debug log
|
* An array of the nested cell references accessed by the calculation engine, used for the debug log
|
||||||
*
|
*
|
||||||
@ -207,22 +192,14 @@ class PHPExcel_Calculation {
|
|||||||
* @var array of string
|
* @var array of string
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private $debugLogStack = array();
|
private $cyclicReferenceStack = array();
|
||||||
|
|
||||||
/**
|
|
||||||
* The debug log generated by the calculation engine
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @var array of string
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public $debugLog = array();
|
|
||||||
private $_cyclicFormulaCount = 0;
|
private $_cyclicFormulaCount = 0;
|
||||||
private $_cyclicFormulaCell = '';
|
private $_cyclicFormulaCell = '';
|
||||||
public $cyclicFormulaCount = 0;
|
public $cyclicFormulaCount = 0;
|
||||||
|
|
||||||
|
|
||||||
private $_savedPrecision = 12;
|
private $_savedPrecision = 14;
|
||||||
|
|
||||||
|
|
||||||
private static $_localeLanguage = 'en_us'; // US English (default locale)
|
private static $_localeLanguage = 'en_us'; // US English (default locale)
|
||||||
@ -1688,7 +1665,7 @@ class PHPExcel_Calculation {
|
|||||||
|
|
||||||
|
|
||||||
private function __construct(PHPExcel $workbook = NULL) {
|
private function __construct(PHPExcel $workbook = NULL) {
|
||||||
$setPrecision = (PHP_INT_SIZE == 4) ? 12 : 16;
|
$setPrecision = (PHP_INT_SIZE == 4) ? 14 : 16;
|
||||||
$this->_savedPrecision = ini_get('precision');
|
$this->_savedPrecision = ini_get('precision');
|
||||||
if ($this->_savedPrecision < $setPrecision) {
|
if ($this->_savedPrecision < $setPrecision) {
|
||||||
ini_set('precision',$setPrecision);
|
ini_set('precision',$setPrecision);
|
||||||
@ -1699,6 +1676,7 @@ class PHPExcel_Calculation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->_workbook = $workbook;
|
$this->_workbook = $workbook;
|
||||||
|
$this->_debugLog = new PHPExcel_CalcEngine_Logger();
|
||||||
} // function __construct()
|
} // function __construct()
|
||||||
|
|
||||||
|
|
||||||
@ -1759,6 +1737,10 @@ class PHPExcel_Calculation {
|
|||||||
} // function flushInstance()
|
} // function flushInstance()
|
||||||
|
|
||||||
|
|
||||||
|
public function getDebugLog() {
|
||||||
|
return $this->_debugLog;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __clone implementation. Cloning should not be allowed in a Singleton!
|
* __clone implementation. Cloning should not be allowed in a Singleton!
|
||||||
*
|
*
|
||||||
@ -1871,7 +1853,7 @@ class PHPExcel_Calculation {
|
|||||||
if (isset($this->_calculationCache[$worksheetName])) {
|
if (isset($this->_calculationCache[$worksheetName])) {
|
||||||
unset($this->_calculationCache[$worksheetName]);
|
unset($this->_calculationCache[$worksheetName]);
|
||||||
}
|
}
|
||||||
} // function clearCalculationCache()
|
} // function clearCalculationCacheForWorksheet()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rename calculation cache for a specified worksheet
|
* Rename calculation cache for a specified worksheet
|
||||||
@ -1881,7 +1863,7 @@ class PHPExcel_Calculation {
|
|||||||
$this->_calculationCache[$toWorksheetName] = &$this->_calculationCache[$fromWorksheetName];
|
$this->_calculationCache[$toWorksheetName] = &$this->_calculationCache[$fromWorksheetName];
|
||||||
unset($this->_calculationCache[$fromWorksheetName]);
|
unset($this->_calculationCache[$fromWorksheetName]);
|
||||||
}
|
}
|
||||||
} // function clearCalculationCache()
|
} // function renameCalculationCacheForWorksheet()
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2174,15 +2156,14 @@ class PHPExcel_Calculation {
|
|||||||
$returnArrayAsType = self::$returnArrayAsType;
|
$returnArrayAsType = self::$returnArrayAsType;
|
||||||
if ($resetLog) {
|
if ($resetLog) {
|
||||||
// Initialise the logging settings if requested
|
// Initialise the logging settings if requested
|
||||||
$this->formulaError = NULL;
|
$this->formulaError = null;
|
||||||
$this->debugLog = $this->debugLogStack = array();
|
$this->_debugLog->clearLog();
|
||||||
|
$this->cyclicReferenceStack = array();
|
||||||
$this->_cyclicFormulaCount = 1;
|
$this->_cyclicFormulaCount = 1;
|
||||||
|
|
||||||
self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY;
|
self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($resetLog) {
|
|
||||||
}
|
|
||||||
// Execute the calculation for the cell formula
|
// Execute the calculation for the cell formula
|
||||||
try {
|
try {
|
||||||
$result = self::_unwrapResult($this->_calculateFormulaValue($pCell->getValue(), $pCell->getCoordinate(), $pCell));
|
$result = self::_unwrapResult($this->_calculateFormulaValue($pCell->getValue(), $pCell->getCoordinate(), $pCell));
|
||||||
@ -2254,7 +2235,8 @@ class PHPExcel_Calculation {
|
|||||||
public function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = NULL) {
|
public function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = NULL) {
|
||||||
// Initialise the logging settings
|
// Initialise the logging settings
|
||||||
$this->formulaError = null;
|
$this->formulaError = null;
|
||||||
$this->debugLog = $this->debugLogStack = array();
|
$this->_debugLog->clearLog();
|
||||||
|
$this->cyclicReferenceStack = array();
|
||||||
|
|
||||||
// Disable calculation cacheing because it only applies to cell calculations, not straight formulae
|
// Disable calculation cacheing because it only applies to cell calculations, not straight formulae
|
||||||
// But don't actually flush any cache
|
// But don't actually flush any cache
|
||||||
@ -2277,9 +2259,11 @@ class PHPExcel_Calculation {
|
|||||||
public function getValueFromCache($worksheetName, $cellID, &$cellValue) {
|
public function getValueFromCache($worksheetName, $cellID, &$cellValue) {
|
||||||
// Is calculation cacheing enabled?
|
// Is calculation cacheing enabled?
|
||||||
// Is the value present in calculation cache?
|
// Is the value present in calculation cache?
|
||||||
$this->_writeDebug('Testing cache value for cell ', $worksheetName, '!', $cellID);
|
//echo 'Test cache for ',$worksheetName,'!',$cellID,PHP_EOL;
|
||||||
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Testing cache value for cell ', $worksheetName, '!', $cellID);
|
||||||
if (($this->_calculationCacheEnabled) && (isset($this->_calculationCache[$worksheetName][$cellID]))) {
|
if (($this->_calculationCacheEnabled) && (isset($this->_calculationCache[$worksheetName][$cellID]))) {
|
||||||
$this->_writeDebug('Retrieving value for cell ', $worksheetName, '!', $cellID, ' from cache');
|
//echo 'Retrieve from cache',PHP_EOL;
|
||||||
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Retrieving value for cell ', $worksheetName, '!', $cellID, ' from cache');
|
||||||
// Return the cached result
|
// Return the cached result
|
||||||
$cellValue = $this->_calculationCache[$worksheetName][$cellID];
|
$cellValue = $this->_calculationCache[$worksheetName][$cellID];
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -2312,14 +2296,14 @@ class PHPExcel_Calculation {
|
|||||||
$formula = ltrim(substr($formula,1));
|
$formula = ltrim(substr($formula,1));
|
||||||
if (!isset($formula{0})) return self::_wrapResult($formula);
|
if (!isset($formula{0})) return self::_wrapResult($formula);
|
||||||
|
|
||||||
$pCellParent = ($pCell !== NULL) ? $pCell->getParent() : NULL;
|
$pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL;
|
||||||
$wsTitle = ($pCellParent !== NULL) ? $pCellParent->getTitle() : "\x00Wrk";
|
$wsTitle = ($pCellParent !== NULL) ? $pCellParent->getTitle() : "\x00Wrk";
|
||||||
|
|
||||||
if (($cellID !== NULL) && ($this->getValueFromCache($wsTitle, $cellID, $cellValue))) {
|
if (($cellID !== NULL) && ($this->getValueFromCache($wsTitle, $cellID, $cellValue))) {
|
||||||
return $cellValue;
|
return $cellValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($wsTitle{0} !== "\x00") && (in_array($wsTitle.'!'.$cellID,$this->debugLogStack))) {
|
if (($wsTitle{0} !== "\x00") && (in_array($wsTitle.'!'.$cellID,$this->cyclicReferenceStack))) {
|
||||||
if ($this->cyclicFormulaCount <= 0) {
|
if ($this->cyclicFormulaCount <= 0) {
|
||||||
return $this->_raiseFormulaError('Cyclic Reference in Formula');
|
return $this->_raiseFormulaError('Cyclic Reference in Formula');
|
||||||
} elseif (($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) &&
|
} elseif (($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) &&
|
||||||
@ -2337,10 +2321,10 @@ class PHPExcel_Calculation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->debugLogStack[] = $wsTitle.'!'.$cellID;
|
$this->cyclicReferenceStack[] = $wsTitle.'!'.$cellID;
|
||||||
// Parse the formula onto the token stack and calculate the value
|
// Parse the formula onto the token stack and calculate the value
|
||||||
$cellValue = $this->_processTokenStack($this->_parseFormula($formula, $pCell), $cellID, $pCell);
|
$cellValue = $this->_processTokenStack($this->_parseFormula($formula, $pCell), $cellID, $pCell);
|
||||||
array_pop($this->debugLogStack);
|
array_pop($this->cyclicReferenceStack);
|
||||||
|
|
||||||
// Save to calculation cache
|
// Save to calculation cache
|
||||||
if ($cellID !== NULL) {
|
if ($cellID !== NULL) {
|
||||||
@ -2505,7 +2489,7 @@ class PHPExcel_Calculation {
|
|||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
private function _showValue($value) {
|
private function _showValue($value) {
|
||||||
if ($this->writeDebugLog) {
|
if ($this->_debugLog->getWriteDebugLog()) {
|
||||||
$testArray = PHPExcel_Calculation_Functions::flattenArray($value);
|
$testArray = PHPExcel_Calculation_Functions::flattenArray($value);
|
||||||
if (count($testArray) == 1) {
|
if (count($testArray) == 1) {
|
||||||
$value = array_pop($testArray);
|
$value = array_pop($testArray);
|
||||||
@ -2540,7 +2524,7 @@ class PHPExcel_Calculation {
|
|||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
private function _showTypeDetails($value) {
|
private function _showTypeDetails($value) {
|
||||||
if ($this->writeDebugLog) {
|
if ($this->_debugLog->getWriteDebugLog()) {
|
||||||
$testArray = PHPExcel_Calculation_Functions::flattenArray($value);
|
$testArray = PHPExcel_Calculation_Functions::flattenArray($value);
|
||||||
if (count($testArray) == 1) {
|
if (count($testArray) == 1) {
|
||||||
$value = array_pop($testArray);
|
$value = array_pop($testArray);
|
||||||
@ -2665,7 +2649,7 @@ class PHPExcel_Calculation {
|
|||||||
|
|
||||||
// If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet),
|
// If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet),
|
||||||
// so we store the parent worksheet so that we can re-attach it when necessary
|
// so we store the parent worksheet so that we can re-attach it when necessary
|
||||||
$pCellParent = ($pCell !== NULL) ? $pCell->getParent() : NULL;
|
$pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL;
|
||||||
|
|
||||||
$regexpMatchString = '/^('.self::CALCULATION_REGEXP_FUNCTION.
|
$regexpMatchString = '/^('.self::CALCULATION_REGEXP_FUNCTION.
|
||||||
'|'.self::CALCULATION_REGEXP_NUMBER.
|
'|'.self::CALCULATION_REGEXP_NUMBER.
|
||||||
@ -3019,9 +3003,10 @@ class PHPExcel_Calculation {
|
|||||||
private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCell = NULL) {
|
private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCell = NULL) {
|
||||||
if ($tokens == FALSE) return FALSE;
|
if ($tokens == FALSE) return FALSE;
|
||||||
|
|
||||||
// If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet),
|
// If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent cell collection),
|
||||||
// so we store the parent worksheet so that we can re-attach it when necessary
|
// so we store the parent cell collection so that we can re-attach it when necessary
|
||||||
$pCellParent = ($pCell !== NULL) ? $pCell->getParent() : NULL;
|
$pCellWorksheet = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL;
|
||||||
|
$pCellParent = ($pCell !== NULL) ? $pCell->getParent() : null;
|
||||||
$stack = new PHPExcel_Calculation_Token_Stack;
|
$stack = new PHPExcel_Calculation_Token_Stack;
|
||||||
|
|
||||||
// Loop through each token in turn
|
// Loop through each token in turn
|
||||||
@ -3042,9 +3027,9 @@ class PHPExcel_Calculation {
|
|||||||
|
|
||||||
// Log what we're doing
|
// Log what we're doing
|
||||||
if ($token == ':') {
|
if ($token == ':') {
|
||||||
$this->_writeDebug('Evaluating Range ', $this->_showValue($operand1Data['reference']), ' ', $token, ' ', $this->_showValue($operand2Data['reference']));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Range ', $this->_showValue($operand1Data['reference']), ' ', $token, ' ', $this->_showValue($operand2Data['reference']));
|
||||||
} else {
|
} else {
|
||||||
$this->_writeDebug('Evaluating ', $this->_showValue($operand1), ' ', $token, ' ', $this->_showValue($operand2));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating ', $this->_showValue($operand1), ' ', $token, ' ', $this->_showValue($operand2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process the operation in the appropriate manner
|
// Process the operation in the appropriate manner
|
||||||
@ -3064,7 +3049,7 @@ class PHPExcel_Calculation {
|
|||||||
if (strpos($operand1Data['reference'],'!') !== FALSE) {
|
if (strpos($operand1Data['reference'],'!') !== FALSE) {
|
||||||
list($sheet1,$operand1Data['reference']) = explode('!',$operand1Data['reference']);
|
list($sheet1,$operand1Data['reference']) = explode('!',$operand1Data['reference']);
|
||||||
} else {
|
} else {
|
||||||
$sheet1 = ($pCellParent !== NULL) ? $pCellParent->getTitle() : '';
|
$sheet1 = ($pCellParent !== NULL) ? $pCellWorksheet->getTitle() : '';
|
||||||
}
|
}
|
||||||
if (strpos($operand2Data['reference'],'!') !== FALSE) {
|
if (strpos($operand2Data['reference'],'!') !== FALSE) {
|
||||||
list($sheet2,$operand2Data['reference']) = explode('!',$operand2Data['reference']);
|
list($sheet2,$operand2Data['reference']) = explode('!',$operand2Data['reference']);
|
||||||
@ -3145,13 +3130,13 @@ class PHPExcel_Calculation {
|
|||||||
$matrixResult = $matrix->concat($operand2);
|
$matrixResult = $matrix->concat($operand2);
|
||||||
$result = $matrixResult->getArray();
|
$result = $matrixResult->getArray();
|
||||||
} catch (PHPExcel_Exception $ex) {
|
} catch (PHPExcel_Exception $ex) {
|
||||||
$this->_writeDebug('JAMA Matrix Exception: ', $ex->getMessage());
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'JAMA Matrix Exception: ', $ex->getMessage());
|
||||||
$result = '#VALUE!';
|
$result = '#VALUE!';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$result = '"'.str_replace('""','"',self::_unwrapResult($operand1,'"').self::_unwrapResult($operand2,'"')).'"';
|
$result = '"'.str_replace('""','"',self::_unwrapResult($operand1,'"').self::_unwrapResult($operand2,'"')).'"';
|
||||||
}
|
}
|
||||||
$this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails($result));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails($result));
|
||||||
$stack->push('Value',$result);
|
$stack->push('Value',$result);
|
||||||
break;
|
break;
|
||||||
case '|' : // Intersect
|
case '|' : // Intersect
|
||||||
@ -3165,7 +3150,7 @@ class PHPExcel_Calculation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow);
|
$cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow);
|
||||||
$this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails($cellIntersect));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails($cellIntersect));
|
||||||
$stack->push('Value',$cellIntersect,$cellRef);
|
$stack->push('Value',$cellIntersect,$cellRef);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3177,11 +3162,11 @@ class PHPExcel_Calculation {
|
|||||||
$arg = $arg['value'];
|
$arg = $arg['value'];
|
||||||
if ($token === '~') {
|
if ($token === '~') {
|
||||||
// echo 'Token is a negation operator<br />';
|
// echo 'Token is a negation operator<br />';
|
||||||
$this->_writeDebug('Evaluating Negation of ', $this->_showValue($arg));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Negation of ', $this->_showValue($arg));
|
||||||
$multiplier = -1;
|
$multiplier = -1;
|
||||||
} else {
|
} else {
|
||||||
// echo 'Token is a percentile operator<br />';
|
// echo 'Token is a percentile operator<br />';
|
||||||
$this->_writeDebug('Evaluating Percentile of ', $this->_showValue($arg));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Percentile of ', $this->_showValue($arg));
|
||||||
$multiplier = 0.01;
|
$multiplier = 0.01;
|
||||||
}
|
}
|
||||||
if (is_array($arg)) {
|
if (is_array($arg)) {
|
||||||
@ -3191,10 +3176,10 @@ class PHPExcel_Calculation {
|
|||||||
$matrixResult = $matrix1->arrayTimesEquals($multiplier);
|
$matrixResult = $matrix1->arrayTimesEquals($multiplier);
|
||||||
$result = $matrixResult->getArray();
|
$result = $matrixResult->getArray();
|
||||||
} catch (PHPExcel_Exception $ex) {
|
} catch (PHPExcel_Exception $ex) {
|
||||||
$this->_writeDebug('JAMA Matrix Exception: ', $ex->getMessage());
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'JAMA Matrix Exception: ', $ex->getMessage());
|
||||||
$result = '#VALUE!';
|
$result = '#VALUE!';
|
||||||
}
|
}
|
||||||
$this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails($result));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails($result));
|
||||||
$stack->push('Value',$result);
|
$stack->push('Value',$result);
|
||||||
} else {
|
} else {
|
||||||
$this->_executeNumericBinaryOperation($cellID,$multiplier,$arg,'*','arrayTimesEquals',$stack);
|
$this->_executeNumericBinaryOperation($cellID,$multiplier,$arg,'*','arrayTimesEquals',$stack);
|
||||||
@ -3218,23 +3203,23 @@ class PHPExcel_Calculation {
|
|||||||
}
|
}
|
||||||
$matches[2] = trim($matches[2],"\"'");
|
$matches[2] = trim($matches[2],"\"'");
|
||||||
// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />';
|
// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />';
|
||||||
$this->_writeDebug('Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]);
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]);
|
||||||
if ($pCellParent !== NULL) {
|
if ($pCellParent !== NULL) {
|
||||||
$cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE);
|
$cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE);
|
||||||
} else {
|
} else {
|
||||||
return $this->_raiseFormulaError('Unable to access Cell Reference');
|
return $this->_raiseFormulaError('Unable to access Cell Reference');
|
||||||
}
|
}
|
||||||
$this->_writeDebug('Evaluation Result for cells ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for cells ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue));
|
||||||
// $cellRef = $matches[2].'!'.$cellRef;
|
// $cellRef = $matches[2].'!'.$cellRef;
|
||||||
} else {
|
} else {
|
||||||
// echo '$cellRef='.$cellRef.' in current worksheet<br />';
|
// echo '$cellRef='.$cellRef.' in current worksheet<br />';
|
||||||
$this->_writeDebug('Evaluating Cell Range ', $cellRef, ' in current worksheet');
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Cell Range ', $cellRef, ' in current worksheet');
|
||||||
if ($pCellParent !== NULL) {
|
if ($pCellParent !== NULL) {
|
||||||
$cellValue = $this->extractCellRange($cellRef, $pCellParent, FALSE);
|
$cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE);
|
||||||
} else {
|
} else {
|
||||||
return $this->_raiseFormulaError('Unable to access Cell Reference');
|
return $this->_raiseFormulaError('Unable to access Cell Reference');
|
||||||
}
|
}
|
||||||
$this->_writeDebug('Evaluation Result for cells ', $cellRef, ' is ', $this->_showTypeDetails($cellValue));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for cells ', $cellRef, ' is ', $this->_showTypeDetails($cellValue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -3251,7 +3236,7 @@ class PHPExcel_Calculation {
|
|||||||
return $this->_raiseFormulaError('Unable to access External Workbook');
|
return $this->_raiseFormulaError('Unable to access External Workbook');
|
||||||
}
|
}
|
||||||
// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />';
|
// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />';
|
||||||
$this->_writeDebug('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]);
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]);
|
||||||
if ($pCellParent !== NULL) {
|
if ($pCellParent !== NULL) {
|
||||||
if ($this->_workbook->getSheetByName($matches[2])->cellExists($cellRef)) {
|
if ($this->_workbook->getSheetByName($matches[2])->cellExists($cellRef)) {
|
||||||
$cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE);
|
$cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE);
|
||||||
@ -3262,18 +3247,18 @@ class PHPExcel_Calculation {
|
|||||||
} else {
|
} else {
|
||||||
return $this->_raiseFormulaError('Unable to access Cell Reference');
|
return $this->_raiseFormulaError('Unable to access Cell Reference');
|
||||||
}
|
}
|
||||||
$this->_writeDebug('Evaluation Result for cell ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for cell ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue));
|
||||||
// $cellRef = $matches[2].'!'.$cellRef;
|
// $cellRef = $matches[2].'!'.$cellRef;
|
||||||
} else {
|
} else {
|
||||||
// echo '$cellRef='.$cellRef.' in current worksheet<br />';
|
// echo '$cellRef='.$cellRef.' in current worksheet<br />';
|
||||||
$this->_writeDebug('Evaluating Cell ', $cellRef, ' in current worksheet');
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Cell ', $cellRef, ' in current worksheet');
|
||||||
if ($pCellParent->cellExists($cellRef)) {
|
if ($pCellParent->isDataSet($cellRef)) {
|
||||||
$cellValue = $this->extractCellRange($cellRef, $pCellParent, FALSE);
|
$cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE);
|
||||||
$pCell->attach($pCellParent);
|
$pCell->attach($pCellParent);
|
||||||
} else {
|
} else {
|
||||||
$cellValue = NULL;
|
$cellValue = NULL;
|
||||||
}
|
}
|
||||||
$this->_writeDebug('Evaluation Result for cell ', $cellRef, ' is ', $this->_showTypeDetails($cellValue));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for cell ', $cellRef, ' is ', $this->_showTypeDetails($cellValue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3286,7 +3271,7 @@ class PHPExcel_Calculation {
|
|||||||
$argCount = $stack->pop();
|
$argCount = $stack->pop();
|
||||||
$argCount = $argCount['value'];
|
$argCount = $argCount['value'];
|
||||||
if ($functionName != 'MKMATRIX') {
|
if ($functionName != 'MKMATRIX') {
|
||||||
$this->_writeDebug('Evaluating Function ', self::_localeFunc($functionName), '() with ', (($argCount == 0) ? 'no' : $argCount), ' argument', (($argCount == 1) ? '' : 's'));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Function ', self::_localeFunc($functionName), '() with ', (($argCount == 0) ? 'no' : $argCount), ' argument', (($argCount == 1) ? '' : 's'));
|
||||||
}
|
}
|
||||||
if ((isset(self::$_PHPExcelFunctions[$functionName])) || (isset(self::$_controlFunctions[$functionName]))) { // function
|
if ((isset(self::$_PHPExcelFunctions[$functionName])) || (isset(self::$_controlFunctions[$functionName]))) { // function
|
||||||
if (isset(self::$_PHPExcelFunctions[$functionName])) {
|
if (isset(self::$_PHPExcelFunctions[$functionName])) {
|
||||||
@ -3329,30 +3314,30 @@ class PHPExcel_Calculation {
|
|||||||
// print_r($args);
|
// print_r($args);
|
||||||
// echo '<br />';
|
// echo '<br />';
|
||||||
if ($functionName != 'MKMATRIX') {
|
if ($functionName != 'MKMATRIX') {
|
||||||
if ($this->writeDebugLog) {
|
if ($this->_debugLog->getWriteDebugLog()) {
|
||||||
krsort($argArrayVals);
|
krsort($argArrayVals);
|
||||||
$this->_writeDebug('Evaluating ', self::_localeFunc($functionName), '( ', implode(self::$_localeArgumentSeparator.' ',PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )');
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating ', self::_localeFunc($functionName), '( ', implode(self::$_localeArgumentSeparator.' ',PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Process each argument in turn, building the return value as an array
|
// Process each argument in turn, building the return value as an array
|
||||||
// if (($argCount == 1) && (is_array($args[1])) && ($functionName != 'MKMATRIX')) {
|
// if (($argCount == 1) && (is_array($args[1])) && ($functionName != 'MKMATRIX')) {
|
||||||
// $operand1 = $args[1];
|
// $operand1 = $args[1];
|
||||||
// $this->_writeDebug('Argument is a matrix: ', $this->_showValue($operand1));
|
// $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Argument is a matrix: ', $this->_showValue($operand1));
|
||||||
// $result = array();
|
// $result = array();
|
||||||
// $row = 0;
|
// $row = 0;
|
||||||
// foreach($operand1 as $args) {
|
// foreach($operand1 as $args) {
|
||||||
// if (is_array($args)) {
|
// if (is_array($args)) {
|
||||||
// foreach($args as $arg) {
|
// foreach($args as $arg) {
|
||||||
// $this->_writeDebug('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($arg), ' )');
|
// $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($arg), ' )');
|
||||||
// $r = call_user_func_array($functionCall,$arg);
|
// $r = call_user_func_array($functionCall,$arg);
|
||||||
// $this->_writeDebug('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r));
|
// $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r));
|
||||||
// $result[$row][] = $r;
|
// $result[$row][] = $r;
|
||||||
// }
|
// }
|
||||||
// ++$row;
|
// ++$row;
|
||||||
// } else {
|
// } else {
|
||||||
// $this->_writeDebug('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($args), ' )');
|
// $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($args), ' )');
|
||||||
// $r = call_user_func_array($functionCall,$args);
|
// $r = call_user_func_array($functionCall,$args);
|
||||||
// $this->_writeDebug('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r));
|
// $this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r));
|
||||||
// $result[] = $r;
|
// $result[] = $r;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
@ -3372,7 +3357,7 @@ class PHPExcel_Calculation {
|
|||||||
}
|
}
|
||||||
// }
|
// }
|
||||||
if ($functionName != 'MKMATRIX') {
|
if ($functionName != 'MKMATRIX') {
|
||||||
$this->_writeDebug('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($result));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($result));
|
||||||
}
|
}
|
||||||
$stack->push('Value',self::_wrapResult($result));
|
$stack->push('Value',self::_wrapResult($result));
|
||||||
}
|
}
|
||||||
@ -3383,7 +3368,7 @@ class PHPExcel_Calculation {
|
|||||||
$excelConstant = strtoupper($token);
|
$excelConstant = strtoupper($token);
|
||||||
// echo 'Token is a PHPExcel constant: '.$excelConstant.'<br />';
|
// echo 'Token is a PHPExcel constant: '.$excelConstant.'<br />';
|
||||||
$stack->push('Constant Value',self::$_ExcelConstants[$excelConstant]);
|
$stack->push('Constant Value',self::$_ExcelConstants[$excelConstant]);
|
||||||
$this->_writeDebug('Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$_ExcelConstants[$excelConstant]));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$_ExcelConstants[$excelConstant]));
|
||||||
} elseif ((is_numeric($token)) || ($token === NULL) || (is_bool($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) {
|
} elseif ((is_numeric($token)) || ($token === NULL) || (is_bool($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) {
|
||||||
// echo 'Token is a number, boolean, string, null or an Excel error<br />';
|
// echo 'Token is a number, boolean, string, null or an Excel error<br />';
|
||||||
$stack->push('Value',$token);
|
$stack->push('Value',$token);
|
||||||
@ -3392,10 +3377,10 @@ class PHPExcel_Calculation {
|
|||||||
// echo 'Token is a named range<br />';
|
// echo 'Token is a named range<br />';
|
||||||
$namedRange = $matches[6];
|
$namedRange = $matches[6];
|
||||||
// echo 'Named Range is '.$namedRange.'<br />';
|
// echo 'Named Range is '.$namedRange.'<br />';
|
||||||
$this->_writeDebug('Evaluating Named Range ', $namedRange);
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Named Range ', $namedRange);
|
||||||
$cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellParent : NULL), FALSE);
|
$cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellWorksheet : NULL), FALSE);
|
||||||
$pCell->attach($pCellParent);
|
$pCell->attach($pCellParent);
|
||||||
$this->_writeDebug('Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue));
|
||||||
$stack->push('Named Range',$cellValue,$namedRange);
|
$stack->push('Named Range',$cellValue,$namedRange);
|
||||||
} else {
|
} else {
|
||||||
return $this->_raiseFormulaError("undefined variable '$token'");
|
return $this->_raiseFormulaError("undefined variable '$token'");
|
||||||
@ -3425,12 +3410,12 @@ class PHPExcel_Calculation {
|
|||||||
// If not a numeric, test to see if the value is an Excel error, and so can't be used in normal binary operations
|
// If not a numeric, test to see if the value is an Excel error, and so can't be used in normal binary operations
|
||||||
if ($operand > '' && $operand{0} == '#') {
|
if ($operand > '' && $operand{0} == '#') {
|
||||||
$stack->push('Value', $operand);
|
$stack->push('Value', $operand);
|
||||||
$this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails($operand));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails($operand));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} elseif (!PHPExcel_Shared_String::convertToNumberIfFraction($operand)) {
|
} elseif (!PHPExcel_Shared_String::convertToNumberIfFraction($operand)) {
|
||||||
// If not a numeric or a fraction, then it's a text string, and so can't be used in mathematical binary operations
|
// If not a numeric or a fraction, then it's a text string, and so can't be used in mathematical binary operations
|
||||||
$stack->push('Value', '#VALUE!');
|
$stack->push('Value', '#VALUE!');
|
||||||
$this->_writeDebug('Evaluation Result is a ', $this->_showTypeDetails('#VALUE!'));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is a ', $this->_showTypeDetails('#VALUE!'));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3447,14 +3432,14 @@ class PHPExcel_Calculation {
|
|||||||
$result = array();
|
$result = array();
|
||||||
if ((is_array($operand1)) && (!is_array($operand2))) {
|
if ((is_array($operand1)) && (!is_array($operand2))) {
|
||||||
foreach($operand1 as $x => $operandData) {
|
foreach($operand1 as $x => $operandData) {
|
||||||
$this->_writeDebug('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2));
|
||||||
$this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2,$operation,$stack);
|
$this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2,$operation,$stack);
|
||||||
$r = $stack->pop();
|
$r = $stack->pop();
|
||||||
$result[$x] = $r['value'];
|
$result[$x] = $r['value'];
|
||||||
}
|
}
|
||||||
} elseif ((!is_array($operand1)) && (is_array($operand2))) {
|
} elseif ((!is_array($operand1)) && (is_array($operand2))) {
|
||||||
foreach($operand2 as $x => $operandData) {
|
foreach($operand2 as $x => $operandData) {
|
||||||
$this->_writeDebug('Evaluating Comparison ', $this->_showValue($operand1), ' ', $operation, ' ', $this->_showValue($operandData));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Comparison ', $this->_showValue($operand1), ' ', $operation, ' ', $this->_showValue($operandData));
|
||||||
$this->_executeBinaryComparisonOperation($cellID,$operand1,$operandData,$operation,$stack);
|
$this->_executeBinaryComparisonOperation($cellID,$operand1,$operandData,$operation,$stack);
|
||||||
$r = $stack->pop();
|
$r = $stack->pop();
|
||||||
$result[$x] = $r['value'];
|
$result[$x] = $r['value'];
|
||||||
@ -3462,14 +3447,14 @@ class PHPExcel_Calculation {
|
|||||||
} else {
|
} else {
|
||||||
if (!$recursingArrays) { self::_checkMatrixOperands($operand1,$operand2,2); }
|
if (!$recursingArrays) { self::_checkMatrixOperands($operand1,$operand2,2); }
|
||||||
foreach($operand1 as $x => $operandData) {
|
foreach($operand1 as $x => $operandData) {
|
||||||
$this->_writeDebug('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x]));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x]));
|
||||||
$this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2[$x],$operation,$stack,TRUE);
|
$this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2[$x],$operation,$stack,TRUE);
|
||||||
$r = $stack->pop();
|
$r = $stack->pop();
|
||||||
$result[$x] = $r['value'];
|
$result[$x] = $r['value'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Log the result details
|
// Log the result details
|
||||||
$this->_writeDebug('Comparison Evaluation Result is ', $this->_showTypeDetails($result));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Comparison Evaluation Result is ', $this->_showTypeDetails($result));
|
||||||
// And push the result onto the stack
|
// And push the result onto the stack
|
||||||
$stack->push('Array',$result);
|
$stack->push('Array',$result);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -3508,7 +3493,7 @@ class PHPExcel_Calculation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Log the result details
|
// Log the result details
|
||||||
$this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails($result));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails($result));
|
||||||
// And push the result onto the stack
|
// And push the result onto the stack
|
||||||
$stack->push('Value',$result);
|
$stack->push('Value',$result);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -3546,7 +3531,7 @@ class PHPExcel_Calculation {
|
|||||||
$matrixResult = $matrix->$matrixFunction($operand2);
|
$matrixResult = $matrix->$matrixFunction($operand2);
|
||||||
$result = $matrixResult->getArray();
|
$result = $matrixResult->getArray();
|
||||||
} catch (PHPExcel_Exception $ex) {
|
} catch (PHPExcel_Exception $ex) {
|
||||||
$this->_writeDebug('JAMA Matrix Exception: ', $ex->getMessage());
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'JAMA Matrix Exception: ', $ex->getMessage());
|
||||||
$result = '#VALUE!';
|
$result = '#VALUE!';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -3573,7 +3558,7 @@ class PHPExcel_Calculation {
|
|||||||
if ($operand2 == 0) {
|
if ($operand2 == 0) {
|
||||||
// Trap for Divide by Zero error
|
// Trap for Divide by Zero error
|
||||||
$stack->push('Value','#DIV/0!');
|
$stack->push('Value','#DIV/0!');
|
||||||
$this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails('#DIV/0!'));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails('#DIV/0!'));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else {
|
} else {
|
||||||
$result = $operand1/$operand2;
|
$result = $operand1/$operand2;
|
||||||
@ -3588,29 +3573,17 @@ class PHPExcel_Calculation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Log the result details
|
// Log the result details
|
||||||
$this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails($result));
|
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluation Result is ', $this->_showTypeDetails($result));
|
||||||
// And push the result onto the stack
|
// And push the result onto the stack
|
||||||
$stack->push('Value',$result);
|
$stack->push('Value',$result);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} // function _executeNumericBinaryOperation()
|
} // function _executeNumericBinaryOperation()
|
||||||
|
|
||||||
|
|
||||||
private function _writeDebug() {
|
|
||||||
// Only write the debug log if logging is enabled
|
|
||||||
if ($this->writeDebugLog) {
|
|
||||||
$message = implode('',func_get_args());
|
|
||||||
if ($this->echoDebugLog) {
|
|
||||||
echo implode(' -> ',$this->debugLogStack).' -> '.$message,'<br />';
|
|
||||||
}
|
|
||||||
$this->debugLog[] = implode(' -> ',$this->debugLogStack).' -> '.$message;
|
|
||||||
}
|
|
||||||
} // function _writeDebug()
|
|
||||||
|
|
||||||
|
|
||||||
// trigger an error, but nicely, if need be
|
// trigger an error, but nicely, if need be
|
||||||
protected function _raiseFormulaError($errorMessage) {
|
protected function _raiseFormulaError($errorMessage) {
|
||||||
$this->formulaError = $errorMessage;
|
$this->formulaError = $errorMessage;
|
||||||
$this->debugLogStack = array();
|
$this->cyclicReferenceStack = array();
|
||||||
if (!$this->suppressFormulaErrors) throw new PHPExcel_Calculation_Exception($errorMessage);
|
if (!$this->suppressFormulaErrors) throw new PHPExcel_Calculation_Exception($errorMessage);
|
||||||
trigger_error($errorMessage, E_USER_ERROR);
|
trigger_error($errorMessage, E_USER_ERROR);
|
||||||
} // function _raiseFormulaError()
|
} // function _raiseFormulaError()
|
||||||
@ -3628,25 +3601,26 @@ class PHPExcel_Calculation {
|
|||||||
// Return value
|
// Return value
|
||||||
$returnValue = array ();
|
$returnValue = array ();
|
||||||
|
|
||||||
// echo 'extractCellRange('.$pRange.')<br />';
|
// echo 'extractCellRange('.$pRange.')',PHP_EOL;
|
||||||
if ($pSheet !== NULL) {
|
if ($pSheet !== NULL) {
|
||||||
// echo 'Passed sheet name is '.$pSheet->getTitle().'<br />';
|
$pSheetName = $pSheet->getTitle();
|
||||||
// echo 'Range reference is '.$pRange.'<br />';
|
// echo 'Passed sheet name is '.$pSheetName.PHP_EOL;
|
||||||
if (strpos ($pRange, '!') !== FALSE) {
|
// echo 'Range reference is '.$pRange.PHP_EOL;
|
||||||
// echo '$pRange reference includes sheet reference<br />';
|
if (strpos ($pRange, '!') !== false) {
|
||||||
$worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pRange, TRUE);
|
// echo '$pRange reference includes sheet reference',PHP_EOL;
|
||||||
$pSheet = $this->_workbook->getSheetByName($worksheetReference[0]);
|
list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true);
|
||||||
// echo 'New sheet name is '.$pSheet->getTitle().'<br />';
|
// echo 'New sheet name is '.$pSheetName,PHP_EOL;
|
||||||
$pRange = $worksheetReference[1];
|
// echo 'Adjusted Range reference is '.$pRange,PHP_EOL;
|
||||||
// echo 'Adjusted Range reference is '.$pRange.'<br />';
|
$pSheet = $this->_workbook->getSheetByName($pSheetName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract range
|
// Extract range
|
||||||
$aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange);
|
$aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange);
|
||||||
$pRange = $pSheet->getTitle().'!'.$pRange;
|
$pRange = $pSheetName.'!'.$pRange;
|
||||||
if (!isset($aReferences[1])) {
|
if (!isset($aReferences[1])) {
|
||||||
// Single cell in range
|
// Single cell in range
|
||||||
list($currentCol,$currentRow) = sscanf($aReferences[0],'%[A-Z]%d');
|
list($currentCol,$currentRow) = sscanf($aReferences[0],'%[A-Z]%d');
|
||||||
|
$cellValue = NULL;
|
||||||
if ($pSheet->cellExists($aReferences[0])) {
|
if ($pSheet->cellExists($aReferences[0])) {
|
||||||
$returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog);
|
$returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog);
|
||||||
} else {
|
} else {
|
||||||
@ -3657,7 +3631,7 @@ class PHPExcel_Calculation {
|
|||||||
foreach ($aReferences as $reference) {
|
foreach ($aReferences as $reference) {
|
||||||
// Extract range
|
// Extract range
|
||||||
list($currentCol,$currentRow) = sscanf($reference,'%[A-Z]%d');
|
list($currentCol,$currentRow) = sscanf($reference,'%[A-Z]%d');
|
||||||
|
$cellValue = NULL;
|
||||||
if ($pSheet->cellExists($reference)) {
|
if ($pSheet->cellExists($reference)) {
|
||||||
$returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog);
|
$returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog);
|
||||||
} else {
|
} else {
|
||||||
@ -3686,15 +3660,15 @@ class PHPExcel_Calculation {
|
|||||||
|
|
||||||
// echo 'extractNamedRange('.$pRange.')<br />';
|
// echo 'extractNamedRange('.$pRange.')<br />';
|
||||||
if ($pSheet !== NULL) {
|
if ($pSheet !== NULL) {
|
||||||
// echo 'Current sheet name is '.$pSheet->getTitle().'<br />';
|
$pSheetName = $pSheet->getTitle();
|
||||||
|
// echo 'Current sheet name is '.$pSheetName.'<br />';
|
||||||
// echo 'Range reference is '.$pRange.'<br />';
|
// echo 'Range reference is '.$pRange.'<br />';
|
||||||
if (strpos ($pRange, '!') !== FALSE) {
|
if (strpos ($pRange, '!') !== false) {
|
||||||
// echo '$pRange reference includes sheet reference<br />';
|
// echo '$pRange reference includes sheet reference',PHP_EOL;
|
||||||
$worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pRange, TRUE);
|
list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true);
|
||||||
$pSheet = $this->_workbook->getSheetByName($worksheetReference[0]);
|
// echo 'New sheet name is '.$pSheetName,PHP_EOL;
|
||||||
// echo 'New sheet name is '.$pSheet->getTitle().'<br />';
|
// echo 'Adjusted Range reference is '.$pRange,PHP_EOL;
|
||||||
$pRange = $worksheetReference[1];
|
$pSheet = $this->_workbook->getSheetByName($pSheetName);
|
||||||
// echo 'Adjusted Range reference is '.$pRange.'<br />';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Named range?
|
// Named range?
|
||||||
@ -3729,6 +3703,7 @@ class PHPExcel_Calculation {
|
|||||||
if (!isset($aReferences[1])) {
|
if (!isset($aReferences[1])) {
|
||||||
// Single cell (or single column or row) in range
|
// Single cell (or single column or row) in range
|
||||||
list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($aReferences[0]);
|
list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($aReferences[0]);
|
||||||
|
$cellValue = NULL;
|
||||||
if ($pSheet->cellExists($aReferences[0])) {
|
if ($pSheet->cellExists($aReferences[0])) {
|
||||||
$returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog);
|
$returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog);
|
||||||
} else {
|
} else {
|
||||||
@ -3740,6 +3715,7 @@ class PHPExcel_Calculation {
|
|||||||
// Extract range
|
// Extract range
|
||||||
list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($reference);
|
list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($reference);
|
||||||
// echo 'NAMED RANGE: $currentCol='.$currentCol.' $currentRow='.$currentRow.'<br />';
|
// echo 'NAMED RANGE: $currentCol='.$currentCol.' $currentRow='.$currentRow.'<br />';
|
||||||
|
$cellValue = NULL;
|
||||||
if ($pSheet->cellExists($reference)) {
|
if ($pSheet->cellExists($reference)) {
|
||||||
$returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog);
|
$returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog);
|
||||||
} else {
|
} else {
|
||||||
|
@ -67,7 +67,9 @@ class PHPExcel_Calculation_Token_Stack {
|
|||||||
} // function last()
|
} // function last()
|
||||||
|
|
||||||
|
|
||||||
function __construct() {
|
function clear() {
|
||||||
|
$this->_stack = array();
|
||||||
|
$this->_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // class PHPExcel_Calculation_Token_Stack
|
} // class PHPExcel_Calculation_Token_Stack
|
||||||
|
@ -50,13 +50,6 @@ class PHPExcel_Cell
|
|||||||
*/
|
*/
|
||||||
private static $_valueBinder = NULL;
|
private static $_valueBinder = NULL;
|
||||||
|
|
||||||
/**
|
|
||||||
* Cell Address (e.g. A1)
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $_coordinate;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Value of the cell
|
* Value of the cell
|
||||||
*
|
*
|
||||||
@ -86,7 +79,7 @@ class PHPExcel_Cell
|
|||||||
/**
|
/**
|
||||||
* Parent worksheet
|
* Parent worksheet
|
||||||
*
|
*
|
||||||
* @var PHPExcel_Worksheet
|
* @var PHPExcel_CachedObjectStorage_CacheBase
|
||||||
*/
|
*/
|
||||||
private $_parent;
|
private $_parent;
|
||||||
|
|
||||||
@ -110,7 +103,7 @@ class PHPExcel_Cell
|
|||||||
* @return void
|
* @return void
|
||||||
**/
|
**/
|
||||||
public function notifyCacheController() {
|
public function notifyCacheController() {
|
||||||
$this->_parent->getCellCacheController()->updateCacheData($this);
|
$this->_parent->updateCacheData($this);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +111,9 @@ class PHPExcel_Cell
|
|||||||
$this->_parent = NULL;
|
$this->_parent = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function attach($parent) {
|
public function attach(PHPExcel_CachedObjectStorage_CacheBase $parent) {
|
||||||
|
|
||||||
|
|
||||||
$this->_parent = $parent;
|
$this->_parent = $parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,23 +121,18 @@ class PHPExcel_Cell
|
|||||||
/**
|
/**
|
||||||
* Create a new Cell
|
* Create a new Cell
|
||||||
*
|
*
|
||||||
* @param string $pColumn
|
|
||||||
* @param int $pRow
|
|
||||||
* @param mixed $pValue
|
* @param mixed $pValue
|
||||||
* @param string $pDataType
|
* @param string $pDataType
|
||||||
* @param PHPExcel_Worksheet $pSheet
|
* @param PHPExcel_Worksheet $pSheet
|
||||||
* @throws PHPExcel_Exception
|
* @throws PHPExcel_Exception
|
||||||
*/
|
*/
|
||||||
public function __construct($pCoordinate = 'A1', $pValue = NULL, $pDataType = NULL, PHPExcel_Worksheet $pSheet = NULL)
|
public function __construct($pValue = NULL, $pDataType = NULL, PHPExcel_Worksheet $pSheet = NULL)
|
||||||
{
|
{
|
||||||
// Initialise cell coordinate
|
|
||||||
$this->_coordinate = strtoupper($pCoordinate);
|
|
||||||
|
|
||||||
// Initialise cell value
|
// Initialise cell value
|
||||||
$this->_value = $pValue;
|
$this->_value = $pValue;
|
||||||
|
|
||||||
// Set worksheet
|
// Set worksheet cache
|
||||||
$this->_parent = $pSheet;
|
$this->_parent = $pSheet->getCellCacheController();
|
||||||
|
|
||||||
// Set datatype?
|
// Set datatype?
|
||||||
if ($pDataType !== NULL) {
|
if ($pDataType !== NULL) {
|
||||||
@ -166,8 +156,7 @@ class PHPExcel_Cell
|
|||||||
*/
|
*/
|
||||||
public function getColumn()
|
public function getColumn()
|
||||||
{
|
{
|
||||||
list($column) = sscanf($this->_coordinate, '%[A-Z]%d');
|
return $this->_parent->getCurrentColumn();
|
||||||
return $column;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -177,8 +166,7 @@ class PHPExcel_Cell
|
|||||||
*/
|
*/
|
||||||
public function getRow()
|
public function getRow()
|
||||||
{
|
{
|
||||||
list(,$row) = sscanf($this->_coordinate, '%[A-Z]%d');
|
return $this->_parent->getCurrentRow();
|
||||||
return $row;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -188,7 +176,7 @@ class PHPExcel_Cell
|
|||||||
*/
|
*/
|
||||||
public function getCoordinate()
|
public function getCoordinate()
|
||||||
{
|
{
|
||||||
return $this->_coordinate;
|
return $this->_parent->getCurrentAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -210,7 +198,7 @@ class PHPExcel_Cell
|
|||||||
{
|
{
|
||||||
return (string) PHPExcel_Style_NumberFormat::toFormattedString(
|
return (string) PHPExcel_Style_NumberFormat::toFormattedString(
|
||||||
$this->getCalculatedValue(),
|
$this->getCalculatedValue(),
|
||||||
$this->_parent->getParent()->getCellXfByIndex($this->getXfIndex())
|
$this->getWorksheet()->getParent()->getCellXfByIndex($this->getXfIndex())
|
||||||
->getNumberFormat()->getFormatCode()
|
->getNumberFormat()->getFormatCode()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -289,7 +277,7 @@ class PHPExcel_Cell
|
|||||||
try {
|
try {
|
||||||
// echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value<br />';
|
// echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value<br />';
|
||||||
$result = PHPExcel_Calculation::getInstance(
|
$result = PHPExcel_Calculation::getInstance(
|
||||||
$this->getParent()->getParent()
|
$this->getWorksheet()->getParent()
|
||||||
)->calculateCellValue($this,$resetLog);
|
)->calculateCellValue($this,$resetLog);
|
||||||
// $result = $this->getParent()->getParent()->getCalculationEngine()->calculateCellValue($this,$resetLog);
|
// $result = $this->getParent()->getParent()->getCalculationEngine()->calculateCellValue($this,$resetLog);
|
||||||
// echo $this->getCoordinate().' calculation result is '.$result.'<br />';
|
// echo $this->getCoordinate().' calculation result is '.$result.'<br />';
|
||||||
@ -302,7 +290,7 @@ class PHPExcel_Cell
|
|||||||
$result = '#N/A';
|
$result = '#N/A';
|
||||||
throw(
|
throw(
|
||||||
new PHPExcel_Calculation_Exception(
|
new PHPExcel_Calculation_Exception(
|
||||||
$this->getParent()->getTitle().'!'.$this->getCoordinate().' -> '.$ex->getMessage()
|
$this->getWorksheet()->getTitle().'!'.$this->getCoordinate().' -> '.$ex->getMessage()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -391,7 +379,7 @@ class PHPExcel_Cell
|
|||||||
throw new PHPExcel_Exception('Cannot check for data validation when cell is not bound to a worksheet');
|
throw new PHPExcel_Exception('Cannot check for data validation when cell is not bound to a worksheet');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->_parent->dataValidationExists($this->getCoordinate());
|
return $this->getWorksheet()->dataValidationExists($this->getCoordinate());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -406,7 +394,7 @@ class PHPExcel_Cell
|
|||||||
throw new PHPExcel_Exception('Cannot get data validation for cell that is not bound to a worksheet');
|
throw new PHPExcel_Exception('Cannot get data validation for cell that is not bound to a worksheet');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->_parent->getDataValidation($this->getCoordinate());
|
return $this->getWorksheet()->getDataValidation($this->getCoordinate());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -422,7 +410,7 @@ class PHPExcel_Cell
|
|||||||
throw new PHPExcel_Exception('Cannot set data validation for cell that is not bound to a worksheet');
|
throw new PHPExcel_Exception('Cannot set data validation for cell that is not bound to a worksheet');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_parent->setDataValidation($this->getCoordinate(), $pDataValidation);
|
$this->getWorksheet()->setDataValidation($this->getCoordinate(), $pDataValidation);
|
||||||
|
|
||||||
return $this->notifyCacheController();
|
return $this->notifyCacheController();
|
||||||
}
|
}
|
||||||
@ -439,7 +427,7 @@ class PHPExcel_Cell
|
|||||||
throw new PHPExcel_Exception('Cannot check for hyperlink when cell is not bound to a worksheet');
|
throw new PHPExcel_Exception('Cannot check for hyperlink when cell is not bound to a worksheet');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->_parent->hyperlinkExists($this->getCoordinate());
|
return $this->getWorksheet()->hyperlinkExists($this->getCoordinate());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -454,7 +442,7 @@ class PHPExcel_Cell
|
|||||||
throw new PHPExcel_Exception('Cannot get hyperlink for cell that is not bound to a worksheet');
|
throw new PHPExcel_Exception('Cannot get hyperlink for cell that is not bound to a worksheet');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->_parent->getHyperlink($this->getCoordinate());
|
return $this->getWorksheet()->getHyperlink($this->getCoordinate());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -470,7 +458,7 @@ class PHPExcel_Cell
|
|||||||
throw new PHPExcel_Exception('Cannot set hyperlink for cell that is not bound to a worksheet');
|
throw new PHPExcel_Exception('Cannot set hyperlink for cell that is not bound to a worksheet');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_parent->setHyperlink($this->getCoordinate(), $pHyperlink);
|
$this->getWorksheet()->setHyperlink($this->getCoordinate(), $pHyperlink);
|
||||||
|
|
||||||
return $this->notifyCacheController();
|
return $this->notifyCacheController();
|
||||||
}
|
}
|
||||||
@ -484,6 +472,15 @@ class PHPExcel_Cell
|
|||||||
return $this->_parent;
|
return $this->_parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get parent worksheet
|
||||||
|
*
|
||||||
|
* @return PHPExcel_Worksheet
|
||||||
|
*/
|
||||||
|
public function getWorksheet() {
|
||||||
|
return $this->_parent->getParent();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Re-bind parent
|
* Re-bind parent
|
||||||
*
|
*
|
||||||
@ -491,7 +488,7 @@ class PHPExcel_Cell
|
|||||||
* @return PHPExcel_Cell
|
* @return PHPExcel_Cell
|
||||||
*/
|
*/
|
||||||
public function rebindParent(PHPExcel_Worksheet $parent) {
|
public function rebindParent(PHPExcel_Worksheet $parent) {
|
||||||
$this->_parent = $parent;
|
$this->_parent = $parent->getCellCacheController();
|
||||||
|
|
||||||
return $this->notifyCacheController();
|
return $this->notifyCacheController();
|
||||||
}
|
}
|
||||||
|
@ -708,27 +708,22 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable
|
|||||||
// loop through all cells in the worksheet
|
// loop through all cells in the worksheet
|
||||||
foreach ($this->getCellCollection(false) as $cellID) {
|
foreach ($this->getCellCollection(false) as $cellID) {
|
||||||
$cell = $this->getCell($cellID);
|
$cell = $this->getCell($cellID);
|
||||||
if (isset($autoSizes[$cell->getColumn()])) {
|
if (isset($autoSizes[$this->_cellCollection->getCurrentColumn()])) {
|
||||||
// Determine width if cell does not participate in a merge
|
// Determine width if cell does not participate in a merge
|
||||||
if (!isset($isMergeCell[$cell->getCoordinate()])) {
|
if (!isset($isMergeCell[$this->_cellCollection->getCurrentAddress()])) {
|
||||||
// Calculated value
|
// Calculated value
|
||||||
$cellValue = $cell->getCalculatedValue();
|
|
||||||
|
|
||||||
// To formatted string
|
// To formatted string
|
||||||
$cellValue = PHPExcel_Style_NumberFormat::toFormattedString(
|
$cellValue = PHPExcel_Style_NumberFormat::toFormattedString(
|
||||||
$cellValue,
|
$cell->getCalculatedValue(),
|
||||||
$this->_parent->getCellXfByIndex($cell->getXfIndex())
|
$this->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode()
|
||||||
->getNumberFormat()->getFormatCode()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$autoSizes[$cell->getColumn()] = max(
|
$autoSizes[$this->_cellCollection->getCurrentColumn()] = max(
|
||||||
(float)$autoSizes[$cell->getColumn()],
|
(float) $autoSizes[$this->_cellCollection->getCurrentColumn()],
|
||||||
(float)PHPExcel_Shared_Font::calculateColumnWidth(
|
(float)PHPExcel_Shared_Font::calculateColumnWidth(
|
||||||
$this->_parent->getCellXfByIndex($cell->getXfIndex())
|
$this->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont(),
|
||||||
->getFont(),
|
|
||||||
$cellValue,
|
$cellValue,
|
||||||
$this->_parent->getCellXfByIndex($cell->getXfIndex())
|
$this->getParent()->getCellXfByIndex($cell->getXfIndex())->getAlignment()->getTextRotation(),
|
||||||
->getAlignment()->getTextRotation(),
|
|
||||||
$this->getDefaultStyle()->getFont()
|
$this->getDefaultStyle()->getFont()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -1138,7 +1133,7 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable
|
|||||||
// Coordinates
|
// Coordinates
|
||||||
$aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate);
|
$aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate);
|
||||||
|
|
||||||
$cell = $this->_cellCollection->addCacheData($pCoordinate,new PHPExcel_Cell($pCoordinate, NULL, PHPExcel_Cell_DataType::TYPE_NULL, $this));
|
$cell = $this->_cellCollection->addCacheData($pCoordinate,new PHPExcel_Cell(NULL, PHPExcel_Cell_DataType::TYPE_NULL, $this));
|
||||||
$this->_cellCollectionIsSorted = false;
|
$this->_cellCollectionIsSorted = false;
|
||||||
|
|
||||||
if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($aCoordinates[0]))
|
if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($aCoordinates[0]))
|
||||||
@ -1178,7 +1173,7 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable
|
|||||||
$coordinate = $columnLetter . $pRow;
|
$coordinate = $columnLetter . $pRow;
|
||||||
|
|
||||||
if (!$this->_cellCollection->isDataSet($coordinate)) {
|
if (!$this->_cellCollection->isDataSet($coordinate)) {
|
||||||
$cell = $this->_cellCollection->addCacheData($coordinate, new PHPExcel_Cell($coordinate, NULL, PHPExcel_Cell_DataType::TYPE_NULL, $this));
|
$cell = $this->_cellCollection->addCacheData($coordinate, new PHPExcel_Cell(NULL, PHPExcel_Cell_DataType::TYPE_NULL, $this));
|
||||||
$this->_cellCollectionIsSorted = false;
|
$this->_cellCollectionIsSorted = false;
|
||||||
|
|
||||||
if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < $pColumn)
|
if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < $pColumn)
|
||||||
|
@ -102,8 +102,8 @@ class PHPExcel_Writer_CSV extends PHPExcel_Writer_Abstract implements PHPExcel_W
|
|||||||
// Fetch sheet
|
// Fetch sheet
|
||||||
$sheet = $this->_phpExcel->getSheet($this->_sheetIndex);
|
$sheet = $this->_phpExcel->getSheet($this->_sheetIndex);
|
||||||
|
|
||||||
$saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog;
|
$saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog();
|
||||||
PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = FALSE;
|
PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE);
|
||||||
$saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType();
|
$saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType();
|
||||||
PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE);
|
PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE);
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ class PHPExcel_Writer_CSV extends PHPExcel_Writer_Abstract implements PHPExcel_W
|
|||||||
fclose($fileHandle);
|
fclose($fileHandle);
|
||||||
|
|
||||||
PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType);
|
PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType);
|
||||||
PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = $saveDebugLog;
|
PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -179,8 +179,8 @@ class PHPExcel_Writer_Excel2007 extends PHPExcel_Writer_Abstract implements PHPE
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$saveDebugLog = PHPExcel_Calculation::getInstance($this->_spreadSheet)->writeDebugLog;
|
$saveDebugLog = PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->getWriteDebugLog();
|
||||||
PHPExcel_Calculation::getInstance($this->_spreadSheet)->writeDebugLog = false;
|
PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog(FALSE);
|
||||||
$saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType();
|
$saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType();
|
||||||
PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);
|
PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);
|
||||||
|
|
||||||
@ -341,7 +341,7 @@ class PHPExcel_Writer_Excel2007 extends PHPExcel_Writer_Abstract implements PHPE
|
|||||||
}
|
}
|
||||||
|
|
||||||
PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType);
|
PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType);
|
||||||
PHPExcel_Calculation::getInstance($this->_spreadSheet)->writeDebugLog = $saveDebugLog;
|
PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog);
|
||||||
|
|
||||||
// Close file
|
// Close file
|
||||||
if ($objZip->close() === false) {
|
if ($objZip->close() === false) {
|
||||||
|
@ -1074,12 +1074,9 @@ class PHPExcel_Writer_Excel2007_Worksheet extends PHPExcel_Writer_Excel2007_Writ
|
|||||||
$objWriter->writeAttribute('t', $mappedType);
|
$objWriter->writeAttribute('t', $mappedType);
|
||||||
break;
|
break;
|
||||||
case 'f': // Formula
|
case 'f': // Formula
|
||||||
$calculatedValue = null;
|
$calculatedValue = ($this->getParentWriter()->getPreCalculateFormulas()) ?
|
||||||
if ($this->getParentWriter()->getPreCalculateFormulas()) {
|
$pCell->getCalculatedValue() :
|
||||||
$calculatedValue = $pCell->getCalculatedValue();
|
$cellValue;
|
||||||
} else {
|
|
||||||
$calculatedValue = $cellValue;
|
|
||||||
}
|
|
||||||
if (is_string($calculatedValue)) {
|
if (is_string($calculatedValue)) {
|
||||||
$objWriter->writeAttribute('t', 'str');
|
$objWriter->writeAttribute('t', 'str');
|
||||||
}
|
}
|
||||||
@ -1125,7 +1122,7 @@ class PHPExcel_Writer_Excel2007_Worksheet extends PHPExcel_Writer_Excel2007_Writ
|
|||||||
}
|
}
|
||||||
if ($this->getParentWriter()->getOffice2003Compatibility() === false) {
|
if ($this->getParentWriter()->getOffice2003Compatibility() === false) {
|
||||||
if ($this->getParentWriter()->getPreCalculateFormulas()) {
|
if ($this->getParentWriter()->getPreCalculateFormulas()) {
|
||||||
$calculatedValue = $pCell->getCalculatedValue();
|
// $calculatedValue = $pCell->getCalculatedValue();
|
||||||
if (!is_array($calculatedValue) && substr($calculatedValue, 0, 1) != '#') {
|
if (!is_array($calculatedValue) && substr($calculatedValue, 0, 1) != '#') {
|
||||||
$objWriter->writeElement('v', PHPExcel_Shared_String::FormatNumber($calculatedValue));
|
$objWriter->writeElement('v', PHPExcel_Shared_String::FormatNumber($calculatedValue));
|
||||||
} else {
|
} else {
|
||||||
|
@ -120,8 +120,8 @@ class PHPExcel_Writer_Excel5 extends PHPExcel_Writer_Abstract implements PHPExce
|
|||||||
// garbage collect
|
// garbage collect
|
||||||
$this->_phpExcel->garbageCollect();
|
$this->_phpExcel->garbageCollect();
|
||||||
|
|
||||||
$saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog;
|
$saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog();
|
||||||
PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = false;
|
PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE);
|
||||||
$saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType();
|
$saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType();
|
||||||
PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);
|
PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);
|
||||||
|
|
||||||
@ -226,7 +226,7 @@ class PHPExcel_Writer_Excel5 extends PHPExcel_Writer_Abstract implements PHPExce
|
|||||||
$res = $root->save($pFilename);
|
$res = $root->save($pFilename);
|
||||||
|
|
||||||
PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType);
|
PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType);
|
||||||
PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = $saveDebugLog;
|
PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -152,8 +152,8 @@ class PHPExcel_Writer_HTML extends PHPExcel_Writer_Abstract implements PHPExcel_
|
|||||||
// garbage collect
|
// garbage collect
|
||||||
$this->_phpExcel->garbageCollect();
|
$this->_phpExcel->garbageCollect();
|
||||||
|
|
||||||
$saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog;
|
$saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog();
|
||||||
PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = false;
|
PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE);
|
||||||
$saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType();
|
$saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType();
|
||||||
PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE);
|
PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE);
|
||||||
|
|
||||||
@ -184,7 +184,7 @@ class PHPExcel_Writer_HTML extends PHPExcel_Writer_Abstract implements PHPExcel_
|
|||||||
fclose($fileHandle);
|
fclose($fileHandle);
|
||||||
|
|
||||||
PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType);
|
PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType);
|
||||||
PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = $saveDebugLog;
|
PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user