mirror of
https://github.com/retailcrm/PHPExcel.git
synced 2024-11-25 23:06: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
@ -70,7 +70,7 @@ class PHPExcel
|
||||
*/
|
||||
private $_workSheetCollection = array();
|
||||
|
||||
/**
|
||||
/**
|
||||
* Calculation Engine
|
||||
*
|
||||
* @var PHPExcel_Calculation
|
||||
@ -878,7 +878,7 @@ class PHPExcel
|
||||
$columnDimension->setXfIndex( $map[$columnDimension->getXfIndex()] );
|
||||
}
|
||||
|
||||
// also do garbage collection for all the sheets
|
||||
// also do garbage collection for all the sheets
|
||||
$sheet->garbageCollect();
|
||||
}
|
||||
}
|
||||
|
@ -86,6 +86,11 @@ abstract class PHPExcel_CachedObjectStorage_CacheBase {
|
||||
} // function __construct()
|
||||
|
||||
|
||||
public function getParent()
|
||||
{
|
||||
return $this->_parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
@ -48,11 +48,15 @@ class PHPExcel_CachedObjectStorage_Memory extends PHPExcel_CachedObjectStorage_C
|
||||
*
|
||||
* @param string $pCoord Coordinate address of the cell to update
|
||||
* @param PHPExcel_Cell $cell Cell to update
|
||||
* @return void
|
||||
* @return PHPExcel_Cell
|
||||
* @throws PHPExcel_Exception
|
||||
*/
|
||||
public function addCacheData($pCoord, PHPExcel_Cell $cell) {
|
||||
$this->_cellCache[$pCoord] = $cell;
|
||||
|
||||
// Set current entry to the new/updated entry
|
||||
$this->_currentObjectID = $pCoord;
|
||||
|
||||
return $cell;
|
||||
} // function addCacheData()
|
||||
|
||||
@ -67,10 +71,14 @@ class PHPExcel_CachedObjectStorage_Memory extends PHPExcel_CachedObjectStorage_C
|
||||
public function getCacheData($pCoord) {
|
||||
// Check if the entry that has been requested actually exists
|
||||
if (!isset($this->_cellCache[$pCoord])) {
|
||||
$this->_currentObjectID = NULL;
|
||||
// Return null if requested entry doesn't exist in cache
|
||||
return null;
|
||||
}
|
||||
|
||||
// Set current entry to the requested entry
|
||||
$this->_currentObjectID = $pCoord;
|
||||
|
||||
// Return requested entry
|
||||
return $this->_cellCache[$pCoord];
|
||||
} // 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
|
||||
);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* If true, then a user error will be triggered
|
||||
@ -176,30 +185,6 @@ class PHPExcel_Calculation {
|
||||
*/
|
||||
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
|
||||
*
|
||||
@ -207,22 +192,14 @@ class PHPExcel_Calculation {
|
||||
* @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 $_cyclicFormulaCell = '';
|
||||
public $cyclicFormulaCount = 0;
|
||||
|
||||
|
||||
private $_savedPrecision = 12;
|
||||
private $_savedPrecision = 14;
|
||||
|
||||
|
||||
private static $_localeLanguage = 'en_us'; // US English (default locale)
|
||||
@ -1688,7 +1665,7 @@ class PHPExcel_Calculation {
|
||||
|
||||
|
||||
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');
|
||||
if ($this->_savedPrecision < $setPrecision) {
|
||||
ini_set('precision',$setPrecision);
|
||||
@ -1699,6 +1676,7 @@ class PHPExcel_Calculation {
|
||||
}
|
||||
|
||||
$this->_workbook = $workbook;
|
||||
$this->_debugLog = new PHPExcel_CalcEngine_Logger();
|
||||
} // function __construct()
|
||||
|
||||
|
||||
@ -1759,6 +1737,10 @@ class PHPExcel_Calculation {
|
||||
} // function flushInstance()
|
||||
|
||||
|
||||
public function getDebugLog() {
|
||||
return $this->_debugLog;
|
||||
}
|
||||
|
||||
/**
|
||||
* __clone implementation. Cloning should not be allowed in a Singleton!
|
||||
*
|
||||
@ -1871,7 +1853,7 @@ class PHPExcel_Calculation {
|
||||
if (isset($this->_calculationCache[$worksheetName])) {
|
||||
unset($this->_calculationCache[$worksheetName]);
|
||||
}
|
||||
} // function clearCalculationCache()
|
||||
} // function clearCalculationCacheForWorksheet()
|
||||
|
||||
/**
|
||||
* Rename calculation cache for a specified worksheet
|
||||
@ -1881,7 +1863,7 @@ class PHPExcel_Calculation {
|
||||
$this->_calculationCache[$toWorksheetName] = &$this->_calculationCache[$fromWorksheetName];
|
||||
unset($this->_calculationCache[$fromWorksheetName]);
|
||||
}
|
||||
} // function clearCalculationCache()
|
||||
} // function renameCalculationCacheForWorksheet()
|
||||
|
||||
|
||||
/**
|
||||
@ -2174,15 +2156,14 @@ class PHPExcel_Calculation {
|
||||
$returnArrayAsType = self::$returnArrayAsType;
|
||||
if ($resetLog) {
|
||||
// Initialise the logging settings if requested
|
||||
$this->formulaError = NULL;
|
||||
$this->debugLog = $this->debugLogStack = array();
|
||||
$this->formulaError = null;
|
||||
$this->_debugLog->clearLog();
|
||||
$this->cyclicReferenceStack = array();
|
||||
$this->_cyclicFormulaCount = 1;
|
||||
|
||||
self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY;
|
||||
}
|
||||
|
||||
if ($resetLog) {
|
||||
}
|
||||
// Execute the calculation for the cell formula
|
||||
try {
|
||||
$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) {
|
||||
// Initialise the logging settings
|
||||
$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
|
||||
// But don't actually flush any cache
|
||||
@ -2277,9 +2259,11 @@ class PHPExcel_Calculation {
|
||||
public function getValueFromCache($worksheetName, $cellID, &$cellValue) {
|
||||
// Is calculation cacheing enabled?
|
||||
// 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]))) {
|
||||
$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
|
||||
$cellValue = $this->_calculationCache[$worksheetName][$cellID];
|
||||
return TRUE;
|
||||
@ -2312,14 +2296,14 @@ class PHPExcel_Calculation {
|
||||
$formula = ltrim(substr($formula,1));
|
||||
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";
|
||||
|
||||
if (($cellID !== NULL) && ($this->getValueFromCache($wsTitle, $cellID, $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) {
|
||||
return $this->_raiseFormulaError('Cyclic Reference in Formula');
|
||||
} 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
|
||||
$cellValue = $this->_processTokenStack($this->_parseFormula($formula, $pCell), $cellID, $pCell);
|
||||
array_pop($this->debugLogStack);
|
||||
array_pop($this->cyclicReferenceStack);
|
||||
|
||||
// Save to calculation cache
|
||||
if ($cellID !== NULL) {
|
||||
@ -2505,7 +2489,7 @@ class PHPExcel_Calculation {
|
||||
* @return mixed
|
||||
*/
|
||||
private function _showValue($value) {
|
||||
if ($this->writeDebugLog) {
|
||||
if ($this->_debugLog->getWriteDebugLog()) {
|
||||
$testArray = PHPExcel_Calculation_Functions::flattenArray($value);
|
||||
if (count($testArray) == 1) {
|
||||
$value = array_pop($testArray);
|
||||
@ -2540,7 +2524,7 @@ class PHPExcel_Calculation {
|
||||
* @return mixed
|
||||
*/
|
||||
private function _showTypeDetails($value) {
|
||||
if ($this->writeDebugLog) {
|
||||
if ($this->_debugLog->getWriteDebugLog()) {
|
||||
$testArray = PHPExcel_Calculation_Functions::flattenArray($value);
|
||||
if (count($testArray) == 1) {
|
||||
$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),
|
||||
// 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.
|
||||
'|'.self::CALCULATION_REGEXP_NUMBER.
|
||||
@ -3019,9 +3003,10 @@ class PHPExcel_Calculation {
|
||||
private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCell = NULL) {
|
||||
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),
|
||||
// so we store the parent worksheet so that we can re-attach it when necessary
|
||||
$pCellParent = ($pCell !== NULL) ? $pCell->getParent() : NULL;
|
||||
// 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 cell collection so that we can re-attach it when necessary
|
||||
$pCellWorksheet = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL;
|
||||
$pCellParent = ($pCell !== NULL) ? $pCell->getParent() : null;
|
||||
$stack = new PHPExcel_Calculation_Token_Stack;
|
||||
|
||||
// Loop through each token in turn
|
||||
@ -3042,9 +3027,9 @@ class PHPExcel_Calculation {
|
||||
|
||||
// Log what we're doing
|
||||
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 {
|
||||
$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
|
||||
@ -3064,7 +3049,7 @@ class PHPExcel_Calculation {
|
||||
if (strpos($operand1Data['reference'],'!') !== FALSE) {
|
||||
list($sheet1,$operand1Data['reference']) = explode('!',$operand1Data['reference']);
|
||||
} else {
|
||||
$sheet1 = ($pCellParent !== NULL) ? $pCellParent->getTitle() : '';
|
||||
$sheet1 = ($pCellParent !== NULL) ? $pCellWorksheet->getTitle() : '';
|
||||
}
|
||||
if (strpos($operand2Data['reference'],'!') !== FALSE) {
|
||||
list($sheet2,$operand2Data['reference']) = explode('!',$operand2Data['reference']);
|
||||
@ -3145,13 +3130,13 @@ class PHPExcel_Calculation {
|
||||
$matrixResult = $matrix->concat($operand2);
|
||||
$result = $matrixResult->getArray();
|
||||
} catch (PHPExcel_Exception $ex) {
|
||||
$this->_writeDebug('JAMA Matrix Exception: ', $ex->getMessage());
|
||||
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'JAMA Matrix Exception: ', $ex->getMessage());
|
||||
$result = '#VALUE!';
|
||||
}
|
||||
} else {
|
||||
$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);
|
||||
break;
|
||||
case '|' : // Intersect
|
||||
@ -3165,7 +3150,7 @@ class PHPExcel_Calculation {
|
||||
}
|
||||
}
|
||||
$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);
|
||||
break;
|
||||
}
|
||||
@ -3177,11 +3162,11 @@ class PHPExcel_Calculation {
|
||||
$arg = $arg['value'];
|
||||
if ($token === '~') {
|
||||
// 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;
|
||||
} else {
|
||||
// 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;
|
||||
}
|
||||
if (is_array($arg)) {
|
||||
@ -3191,10 +3176,10 @@ class PHPExcel_Calculation {
|
||||
$matrixResult = $matrix1->arrayTimesEquals($multiplier);
|
||||
$result = $matrixResult->getArray();
|
||||
} catch (PHPExcel_Exception $ex) {
|
||||
$this->_writeDebug('JAMA Matrix Exception: ', $ex->getMessage());
|
||||
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'JAMA Matrix Exception: ', $ex->getMessage());
|
||||
$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);
|
||||
} else {
|
||||
$this->_executeNumericBinaryOperation($cellID,$multiplier,$arg,'*','arrayTimesEquals',$stack);
|
||||
@ -3218,23 +3203,23 @@ class PHPExcel_Calculation {
|
||||
}
|
||||
$matches[2] = trim($matches[2],"\"'");
|
||||
// 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) {
|
||||
$cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE);
|
||||
} else {
|
||||
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;
|
||||
} else {
|
||||
// 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) {
|
||||
$cellValue = $this->extractCellRange($cellRef, $pCellParent, FALSE);
|
||||
$cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE);
|
||||
} else {
|
||||
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 {
|
||||
@ -3251,7 +3236,7 @@ class PHPExcel_Calculation {
|
||||
return $this->_raiseFormulaError('Unable to access External Workbook');
|
||||
}
|
||||
// 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 ($this->_workbook->getSheetByName($matches[2])->cellExists($cellRef)) {
|
||||
$cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE);
|
||||
@ -3262,18 +3247,18 @@ class PHPExcel_Calculation {
|
||||
} else {
|
||||
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;
|
||||
} else {
|
||||
// echo '$cellRef='.$cellRef.' in current worksheet<br />';
|
||||
$this->_writeDebug('Evaluating Cell ', $cellRef, ' in current worksheet');
|
||||
if ($pCellParent->cellExists($cellRef)) {
|
||||
$cellValue = $this->extractCellRange($cellRef, $pCellParent, FALSE);
|
||||
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Cell ', $cellRef, ' in current worksheet');
|
||||
if ($pCellParent->isDataSet($cellRef)) {
|
||||
$cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE);
|
||||
$pCell->attach($pCellParent);
|
||||
} else {
|
||||
$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 = $argCount['value'];
|
||||
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])) {
|
||||
@ -3329,30 +3314,30 @@ class PHPExcel_Calculation {
|
||||
// print_r($args);
|
||||
// echo '<br />';
|
||||
if ($functionName != 'MKMATRIX') {
|
||||
if ($this->writeDebugLog) {
|
||||
if ($this->_debugLog->getWriteDebugLog()) {
|
||||
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
|
||||
// if (($argCount == 1) && (is_array($args[1])) && ($functionName != 'MKMATRIX')) {
|
||||
// $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();
|
||||
// $row = 0;
|
||||
// foreach($operand1 as $args) {
|
||||
// if (is_array($args)) {
|
||||
// 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);
|
||||
// $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;
|
||||
// }
|
||||
// ++$row;
|
||||
// } 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);
|
||||
// $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;
|
||||
// }
|
||||
// }
|
||||
@ -3372,7 +3357,7 @@ class PHPExcel_Calculation {
|
||||
}
|
||||
// }
|
||||
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));
|
||||
}
|
||||
@ -3383,7 +3368,7 @@ class PHPExcel_Calculation {
|
||||
$excelConstant = strtoupper($token);
|
||||
// echo 'Token is a PHPExcel constant: '.$excelConstant.'<br />';
|
||||
$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} == '#')) {
|
||||
// echo 'Token is a number, boolean, string, null or an Excel error<br />';
|
||||
$stack->push('Value',$token);
|
||||
@ -3392,10 +3377,10 @@ class PHPExcel_Calculation {
|
||||
// echo 'Token is a named range<br />';
|
||||
$namedRange = $matches[6];
|
||||
// echo 'Named Range is '.$namedRange.'<br />';
|
||||
$this->_writeDebug('Evaluating Named Range ', $namedRange);
|
||||
$cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellParent : NULL), FALSE);
|
||||
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'Evaluating Named Range ', $namedRange);
|
||||
$cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellWorksheet : NULL), FALSE);
|
||||
$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);
|
||||
} else {
|
||||
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 ($operand > '' && $operand{0} == '#') {
|
||||
$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;
|
||||
} 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
|
||||
$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;
|
||||
}
|
||||
}
|
||||
@ -3447,14 +3432,14 @@ class PHPExcel_Calculation {
|
||||
$result = array();
|
||||
if ((is_array($operand1)) && (!is_array($operand2))) {
|
||||
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);
|
||||
$r = $stack->pop();
|
||||
$result[$x] = $r['value'];
|
||||
}
|
||||
} elseif ((!is_array($operand1)) && (is_array($operand2))) {
|
||||
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);
|
||||
$r = $stack->pop();
|
||||
$result[$x] = $r['value'];
|
||||
@ -3462,14 +3447,14 @@ class PHPExcel_Calculation {
|
||||
} else {
|
||||
if (!$recursingArrays) { self::_checkMatrixOperands($operand1,$operand2,2); }
|
||||
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);
|
||||
$r = $stack->pop();
|
||||
$result[$x] = $r['value'];
|
||||
}
|
||||
}
|
||||
// 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
|
||||
$stack->push('Array',$result);
|
||||
return TRUE;
|
||||
@ -3508,7 +3493,7 @@ class PHPExcel_Calculation {
|
||||
}
|
||||
|
||||
// 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
|
||||
$stack->push('Value',$result);
|
||||
return TRUE;
|
||||
@ -3546,7 +3531,7 @@ class PHPExcel_Calculation {
|
||||
$matrixResult = $matrix->$matrixFunction($operand2);
|
||||
$result = $matrixResult->getArray();
|
||||
} catch (PHPExcel_Exception $ex) {
|
||||
$this->_writeDebug('JAMA Matrix Exception: ', $ex->getMessage());
|
||||
$this->_debugLog->writeDebugLog($this->cyclicReferenceStack, 'JAMA Matrix Exception: ', $ex->getMessage());
|
||||
$result = '#VALUE!';
|
||||
}
|
||||
} else {
|
||||
@ -3573,7 +3558,7 @@ class PHPExcel_Calculation {
|
||||
if ($operand2 == 0) {
|
||||
// Trap for Divide by Zero error
|
||||
$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;
|
||||
} else {
|
||||
$result = $operand1/$operand2;
|
||||
@ -3588,29 +3573,17 @@ class PHPExcel_Calculation {
|
||||
}
|
||||
|
||||
// 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
|
||||
$stack->push('Value',$result);
|
||||
return TRUE;
|
||||
} // 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
|
||||
protected function _raiseFormulaError($errorMessage) {
|
||||
$this->formulaError = $errorMessage;
|
||||
$this->debugLogStack = array();
|
||||
$this->cyclicReferenceStack = array();
|
||||
if (!$this->suppressFormulaErrors) throw new PHPExcel_Calculation_Exception($errorMessage);
|
||||
trigger_error($errorMessage, E_USER_ERROR);
|
||||
} // function _raiseFormulaError()
|
||||
@ -3628,25 +3601,26 @@ class PHPExcel_Calculation {
|
||||
// Return value
|
||||
$returnValue = array ();
|
||||
|
||||
// echo 'extractCellRange('.$pRange.')<br />';
|
||||
// echo 'extractCellRange('.$pRange.')',PHP_EOL;
|
||||
if ($pSheet !== NULL) {
|
||||
// echo 'Passed sheet name is '.$pSheet->getTitle().'<br />';
|
||||
// echo 'Range reference is '.$pRange.'<br />';
|
||||
if (strpos ($pRange, '!') !== FALSE) {
|
||||
// echo '$pRange reference includes sheet reference<br />';
|
||||
$worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pRange, TRUE);
|
||||
$pSheet = $this->_workbook->getSheetByName($worksheetReference[0]);
|
||||
// echo 'New sheet name is '.$pSheet->getTitle().'<br />';
|
||||
$pRange = $worksheetReference[1];
|
||||
// echo 'Adjusted Range reference is '.$pRange.'<br />';
|
||||
$pSheetName = $pSheet->getTitle();
|
||||
// echo 'Passed sheet name is '.$pSheetName.PHP_EOL;
|
||||
// echo 'Range reference is '.$pRange.PHP_EOL;
|
||||
if (strpos ($pRange, '!') !== false) {
|
||||
// echo '$pRange reference includes sheet reference',PHP_EOL;
|
||||
list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true);
|
||||
// echo 'New sheet name is '.$pSheetName,PHP_EOL;
|
||||
// echo 'Adjusted Range reference is '.$pRange,PHP_EOL;
|
||||
$pSheet = $this->_workbook->getSheetByName($pSheetName);
|
||||
}
|
||||
|
||||
// Extract range
|
||||
$aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange);
|
||||
$pRange = $pSheet->getTitle().'!'.$pRange;
|
||||
$pRange = $pSheetName.'!'.$pRange;
|
||||
if (!isset($aReferences[1])) {
|
||||
// Single cell in range
|
||||
list($currentCol,$currentRow) = sscanf($aReferences[0],'%[A-Z]%d');
|
||||
$cellValue = NULL;
|
||||
if ($pSheet->cellExists($aReferences[0])) {
|
||||
$returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog);
|
||||
} else {
|
||||
@ -3657,7 +3631,7 @@ class PHPExcel_Calculation {
|
||||
foreach ($aReferences as $reference) {
|
||||
// Extract range
|
||||
list($currentCol,$currentRow) = sscanf($reference,'%[A-Z]%d');
|
||||
|
||||
$cellValue = NULL;
|
||||
if ($pSheet->cellExists($reference)) {
|
||||
$returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog);
|
||||
} else {
|
||||
@ -3686,15 +3660,15 @@ class PHPExcel_Calculation {
|
||||
|
||||
// echo 'extractNamedRange('.$pRange.')<br />';
|
||||
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 />';
|
||||
if (strpos ($pRange, '!') !== FALSE) {
|
||||
// echo '$pRange reference includes sheet reference<br />';
|
||||
$worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pRange, TRUE);
|
||||
$pSheet = $this->_workbook->getSheetByName($worksheetReference[0]);
|
||||
// echo 'New sheet name is '.$pSheet->getTitle().'<br />';
|
||||
$pRange = $worksheetReference[1];
|
||||
// echo 'Adjusted Range reference is '.$pRange.'<br />';
|
||||
if (strpos ($pRange, '!') !== false) {
|
||||
// echo '$pRange reference includes sheet reference',PHP_EOL;
|
||||
list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true);
|
||||
// echo 'New sheet name is '.$pSheetName,PHP_EOL;
|
||||
// echo 'Adjusted Range reference is '.$pRange,PHP_EOL;
|
||||
$pSheet = $this->_workbook->getSheetByName($pSheetName);
|
||||
}
|
||||
|
||||
// Named range?
|
||||
@ -3729,6 +3703,7 @@ class PHPExcel_Calculation {
|
||||
if (!isset($aReferences[1])) {
|
||||
// Single cell (or single column or row) in range
|
||||
list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($aReferences[0]);
|
||||
$cellValue = NULL;
|
||||
if ($pSheet->cellExists($aReferences[0])) {
|
||||
$returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog);
|
||||
} else {
|
||||
@ -3740,6 +3715,7 @@ class PHPExcel_Calculation {
|
||||
// Extract range
|
||||
list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($reference);
|
||||
// echo 'NAMED RANGE: $currentCol='.$currentCol.' $currentRow='.$currentRow.'<br />';
|
||||
$cellValue = NULL;
|
||||
if ($pSheet->cellExists($reference)) {
|
||||
$returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog);
|
||||
} else {
|
||||
|
@ -67,7 +67,9 @@ class PHPExcel_Calculation_Token_Stack {
|
||||
} // function last()
|
||||
|
||||
|
||||
function __construct() {
|
||||
function clear() {
|
||||
$this->_stack = array();
|
||||
$this->_count = 0;
|
||||
}
|
||||
|
||||
} // class PHPExcel_Calculation_Token_Stack
|
||||
|
@ -50,13 +50,6 @@ class PHPExcel_Cell
|
||||
*/
|
||||
private static $_valueBinder = NULL;
|
||||
|
||||
/**
|
||||
* Cell Address (e.g. A1)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_coordinate;
|
||||
|
||||
/**
|
||||
* Value of the cell
|
||||
*
|
||||
@ -86,7 +79,7 @@ class PHPExcel_Cell
|
||||
/**
|
||||
* Parent worksheet
|
||||
*
|
||||
* @var PHPExcel_Worksheet
|
||||
* @var PHPExcel_CachedObjectStorage_CacheBase
|
||||
*/
|
||||
private $_parent;
|
||||
|
||||
@ -110,7 +103,7 @@ class PHPExcel_Cell
|
||||
* @return void
|
||||
**/
|
||||
public function notifyCacheController() {
|
||||
$this->_parent->getCellCacheController()->updateCacheData($this);
|
||||
$this->_parent->updateCacheData($this);
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -118,7 +111,9 @@ class PHPExcel_Cell
|
||||
$this->_parent = NULL;
|
||||
}
|
||||
|
||||
public function attach($parent) {
|
||||
public function attach(PHPExcel_CachedObjectStorage_CacheBase $parent) {
|
||||
|
||||
|
||||
$this->_parent = $parent;
|
||||
}
|
||||
|
||||
@ -126,23 +121,18 @@ class PHPExcel_Cell
|
||||
/**
|
||||
* Create a new Cell
|
||||
*
|
||||
* @param string $pColumn
|
||||
* @param int $pRow
|
||||
* @param mixed $pValue
|
||||
* @param string $pDataType
|
||||
* @param PHPExcel_Worksheet $pSheet
|
||||
* @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
|
||||
$this->_value = $pValue;
|
||||
|
||||
// Set worksheet
|
||||
$this->_parent = $pSheet;
|
||||
// Set worksheet cache
|
||||
$this->_parent = $pSheet->getCellCacheController();
|
||||
|
||||
// Set datatype?
|
||||
if ($pDataType !== NULL) {
|
||||
@ -166,8 +156,7 @@ class PHPExcel_Cell
|
||||
*/
|
||||
public function getColumn()
|
||||
{
|
||||
list($column) = sscanf($this->_coordinate, '%[A-Z]%d');
|
||||
return $column;
|
||||
return $this->_parent->getCurrentColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -177,8 +166,7 @@ class PHPExcel_Cell
|
||||
*/
|
||||
public function getRow()
|
||||
{
|
||||
list(,$row) = sscanf($this->_coordinate, '%[A-Z]%d');
|
||||
return $row;
|
||||
return $this->_parent->getCurrentRow();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -188,7 +176,7 @@ class PHPExcel_Cell
|
||||
*/
|
||||
public function getCoordinate()
|
||||
{
|
||||
return $this->_coordinate;
|
||||
return $this->_parent->getCurrentAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -210,7 +198,7 @@ class PHPExcel_Cell
|
||||
{
|
||||
return (string) PHPExcel_Style_NumberFormat::toFormattedString(
|
||||
$this->getCalculatedValue(),
|
||||
$this->_parent->getParent()->getCellXfByIndex($this->getXfIndex())
|
||||
$this->getWorksheet()->getParent()->getCellXfByIndex($this->getXfIndex())
|
||||
->getNumberFormat()->getFormatCode()
|
||||
);
|
||||
}
|
||||
@ -289,7 +277,7 @@ class PHPExcel_Cell
|
||||
try {
|
||||
// echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value<br />';
|
||||
$result = PHPExcel_Calculation::getInstance(
|
||||
$this->getParent()->getParent()
|
||||
$this->getWorksheet()->getParent()
|
||||
)->calculateCellValue($this,$resetLog);
|
||||
// $result = $this->getParent()->getParent()->getCalculationEngine()->calculateCellValue($this,$resetLog);
|
||||
// echo $this->getCoordinate().' calculation result is '.$result.'<br />';
|
||||
@ -302,7 +290,7 @@ class PHPExcel_Cell
|
||||
$result = '#N/A';
|
||||
throw(
|
||||
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');
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
$this->_parent->setDataValidation($this->getCoordinate(), $pDataValidation);
|
||||
$this->getWorksheet()->setDataValidation($this->getCoordinate(), $pDataValidation);
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
$this->_parent->setHyperlink($this->getCoordinate(), $pHyperlink);
|
||||
$this->getWorksheet()->setHyperlink($this->getCoordinate(), $pHyperlink);
|
||||
|
||||
return $this->notifyCacheController();
|
||||
}
|
||||
@ -484,6 +472,15 @@ class PHPExcel_Cell
|
||||
return $this->_parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parent worksheet
|
||||
*
|
||||
* @return PHPExcel_Worksheet
|
||||
*/
|
||||
public function getWorksheet() {
|
||||
return $this->_parent->getParent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-bind parent
|
||||
*
|
||||
@ -491,7 +488,7 @@ class PHPExcel_Cell
|
||||
* @return PHPExcel_Cell
|
||||
*/
|
||||
public function rebindParent(PHPExcel_Worksheet $parent) {
|
||||
$this->_parent = $parent;
|
||||
$this->_parent = $parent->getCellCacheController();
|
||||
|
||||
return $this->notifyCacheController();
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -102,8 +102,8 @@ class PHPExcel_Writer_CSV extends PHPExcel_Writer_Abstract implements PHPExcel_W
|
||||
// Fetch sheet
|
||||
$sheet = $this->_phpExcel->getSheet($this->_sheetIndex);
|
||||
|
||||
$saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog;
|
||||
PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = FALSE;
|
||||
$saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog();
|
||||
PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE);
|
||||
$saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType();
|
||||
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);
|
||||
|
||||
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;
|
||||
PHPExcel_Calculation::getInstance($this->_spreadSheet)->writeDebugLog = false;
|
||||
$saveDebugLog = PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->getWriteDebugLog();
|
||||
PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog(FALSE);
|
||||
$saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType();
|
||||
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::getInstance($this->_spreadSheet)->writeDebugLog = $saveDebugLog;
|
||||
PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog);
|
||||
|
||||
// Close file
|
||||
if ($objZip->close() === false) {
|
||||
|
@ -1074,12 +1074,9 @@ class PHPExcel_Writer_Excel2007_Worksheet extends PHPExcel_Writer_Excel2007_Writ
|
||||
$objWriter->writeAttribute('t', $mappedType);
|
||||
break;
|
||||
case 'f': // Formula
|
||||
$calculatedValue = null;
|
||||
if ($this->getParentWriter()->getPreCalculateFormulas()) {
|
||||
$calculatedValue = $pCell->getCalculatedValue();
|
||||
} else {
|
||||
$calculatedValue = $cellValue;
|
||||
}
|
||||
$calculatedValue = ($this->getParentWriter()->getPreCalculateFormulas()) ?
|
||||
$pCell->getCalculatedValue() :
|
||||
$cellValue;
|
||||
if (is_string($calculatedValue)) {
|
||||
$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()->getPreCalculateFormulas()) {
|
||||
$calculatedValue = $pCell->getCalculatedValue();
|
||||
// $calculatedValue = $pCell->getCalculatedValue();
|
||||
if (!is_array($calculatedValue) && substr($calculatedValue, 0, 1) != '#') {
|
||||
$objWriter->writeElement('v', PHPExcel_Shared_String::FormatNumber($calculatedValue));
|
||||
} else {
|
||||
|
@ -120,13 +120,13 @@ class PHPExcel_Writer_Excel5 extends PHPExcel_Writer_Abstract implements PHPExce
|
||||
// garbage collect
|
||||
$this->_phpExcel->garbageCollect();
|
||||
|
||||
$saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog;
|
||||
PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = false;
|
||||
$saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog();
|
||||
PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE);
|
||||
$saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType();
|
||||
PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);
|
||||
|
||||
// initialize colors array
|
||||
$this->_colors = array();
|
||||
$this->_colors = array();
|
||||
|
||||
// Initialise workbook writer
|
||||
$this->_writerWorkbook = new PHPExcel_Writer_Excel5_Workbook($this->_phpExcel,
|
||||
@ -226,7 +226,7 @@ class PHPExcel_Writer_Excel5 extends PHPExcel_Writer_Abstract implements PHPExce
|
||||
$res = $root->save($pFilename);
|
||||
|
||||
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
|
||||
$this->_phpExcel->garbageCollect();
|
||||
|
||||
$saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog;
|
||||
PHPExcel_Calculation::getInstance($this->_phpExcel)->writeDebugLog = false;
|
||||
$saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog();
|
||||
PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE);
|
||||
$saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType();
|
||||
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);
|
||||
|
||||
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