PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.0.10
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.0.10
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
← All changes | vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation.php +3676 -4115 3.1.23.0.10 View file →
@@ -1,34 +1,9 @@
1 1 <?php
2 -
3 -/** PHPExcel root directory */
4 -if (!defined('PHPEXCEL_ROOT')) {
5 - /**
6 - * @ignore
7 - */
8 - define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../');
9 - require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');
10 -}
11 -
12 -if (!defined('CALCULATION_REGEXP_CELLREF')) {
13 - // Test for support of \P (multibyte options) in PCRE
14 - if (defined('PREG_BAD_UTF8_ERROR')) {
15 - // Cell reference (cell or range of cells, with or without a sheet reference)
16 - define('CALCULATION_REGEXP_CELLREF', '((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d{1,7})');
17 - // Named Range of cells
18 - define('CALCULATION_REGEXP_NAMEDRANGE', '((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?([_A-Z][_A-Z0-9\.]*)');
19 - } else {
20 - // Cell reference (cell or range of cells, with or without a sheet reference)
21 - define('CALCULATION_REGEXP_CELLREF', '(((\w*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d+)');
22 - // Named Range of cells
23 - define('CALCULATION_REGEXP_NAMEDRANGE', '(((\w*)|(\'.*\')|(\".*\"))!)?([_A-Z][_A-Z0-9\.]*)');
24 - }
25 -}
26 -
27 2 /**
28 - * PHPExcel_Calculation (Multiton)
3 + * PHPExcel
29 4 *
30 - * Copyright (c) 2006 - 2015 PHPExcel
5 + * Copyright (c) 2006 - 2014 PHPExcel
31 6 *
32 7 * This library is free software; you can redistribute it and/or
33 8 * modify it under the terms of the GNU Lesser General Public
34 9 * License as published by the Free Software Foundation; either
@@ -44,4348 +19,3934 @@
44 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
45 20 *
46 21 * @category PHPExcel
47 22 * @package PHPExcel_Calculation
48 - * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
49 - * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
50 - * @version ##VERSION##, ##DATE##
23 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
24 + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
25 + * @version ##VERSION##, ##DATE##
51 26 */
52 -class PHPExcel_Calculation
53 -{
54 - /** Constants */
55 - /** Regular Expressions */
56 - // Numeric operand
57 - const CALCULATION_REGEXP_NUMBER = '[-+]?\d*\.?\d+(e[-+]?\d+)?';
58 - // String operand
59 - const CALCULATION_REGEXP_STRING = '"(?:[^"]|"")*"';
60 - // Opening bracket
61 - const CALCULATION_REGEXP_OPENBRACE = '\(';
62 - // Function (allow for the old @ symbol that could be used to prefix a function, but we'll ignore it)
63 - const CALCULATION_REGEXP_FUNCTION = '@?([A-Z][A-Z0-9\.]*)[\s]*\(';
64 - // Cell reference (cell or range of cells, with or without a sheet reference)
65 - const CALCULATION_REGEXP_CELLREF = CALCULATION_REGEXP_CELLREF;
66 - // Named Range of cells
67 - const CALCULATION_REGEXP_NAMEDRANGE = CALCULATION_REGEXP_NAMEDRANGE;
68 - // Error
69 - const CALCULATION_REGEXP_ERROR = '\#[A-Z][A-Z0_\/]*[!\?]?';
70 27
71 28
72 - /** constants */
73 - const RETURN_ARRAY_AS_ERROR = 'error';
74 - const RETURN_ARRAY_AS_VALUE = 'value';
75 - const RETURN_ARRAY_AS_ARRAY = 'array';
29 +/** PHPExcel root directory */
30 +if (!defined('PHPEXCEL_ROOT')) {
31 + /**
32 + * @ignore
33 + */
34 + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../');
35 + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');
36 +}
76 37
77 - private static $returnArrayAsType = self::RETURN_ARRAY_AS_VALUE;
78 38
39 +if (!defined('CALCULATION_REGEXP_CELLREF')) {
40 + // Test for support of \P (multibyte options) in PCRE
41 + if(defined('PREG_BAD_UTF8_ERROR')) {
42 + // Cell reference (cell or range of cells, with or without a sheet reference)
43 + define('CALCULATION_REGEXP_CELLREF','((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d{1,7})');
44 + // Named Range of cells
45 + define('CALCULATION_REGEXP_NAMEDRANGE','((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?([_A-Z][_A-Z0-9\.]*)');
46 + } else {
47 + // Cell reference (cell or range of cells, with or without a sheet reference)
48 + define('CALCULATION_REGEXP_CELLREF','(((\w*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d+)');
49 + // Named Range of cells
50 + define('CALCULATION_REGEXP_NAMEDRANGE','(((\w*)|(\'.*\')|(\".*\"))!)?([_A-Z][_A-Z0-9\.]*)');
51 + }
52 +}
79 53
80 - /**
81 - * Instance of this class
82 - *
83 - * @access private
84 - * @var PHPExcel_Calculation
85 - */
86 - private static $instance;
87 54
55 +/**
56 + * PHPExcel_Calculation (Multiton)
57 + *
58 + * @category PHPExcel
59 + * @package PHPExcel_Calculation
60 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
61 + */
62 +class PHPExcel_Calculation {
88 63
89 - /**
90 - * Instance of the workbook this Calculation Engine is using
91 - *
92 - * @access private
93 - * @var PHPExcel
94 - */
95 - private $workbook;
64 + /** Constants */
65 + /** Regular Expressions */
66 + // Numeric operand
67 + const CALCULATION_REGEXP_NUMBER = '[-+]?\d*\.?\d+(e[-+]?\d+)?';
68 + // String operand
69 + const CALCULATION_REGEXP_STRING = '"(?:[^"]|"")*"';
70 + // Opening bracket
71 + const CALCULATION_REGEXP_OPENBRACE = '\(';
72 + // Function (allow for the old @ symbol that could be used to prefix a function, but we'll ignore it)
73 + const CALCULATION_REGEXP_FUNCTION = '@?([A-Z][A-Z0-9\.]*)[\s]*\(';
74 + // Cell reference (cell or range of cells, with or without a sheet reference)
75 + const CALCULATION_REGEXP_CELLREF = CALCULATION_REGEXP_CELLREF;
76 + // Named Range of cells
77 + const CALCULATION_REGEXP_NAMEDRANGE = CALCULATION_REGEXP_NAMEDRANGE;
78 + // Error
79 + const CALCULATION_REGEXP_ERROR = '\#[A-Z][A-Z0_\/]*[!\?]?';
96 80
97 - /**
98 - * List of instances of the calculation engine that we've instantiated for individual workbooks
99 - *
100 - * @access private
101 - * @var PHPExcel_Calculation[]
102 - */
103 - private static $workbookSets;
104 81
105 - /**
106 - * Calculation cache
107 - *
108 - * @access private
109 - * @var array
110 - */
111 - private $calculationCache = array ();
82 + /** constants */
83 + const RETURN_ARRAY_AS_ERROR = 'error';
84 + const RETURN_ARRAY_AS_VALUE = 'value';
85 + const RETURN_ARRAY_AS_ARRAY = 'array';
112 86
87 + private static $returnArrayAsType = self::RETURN_ARRAY_AS_VALUE;
113 88
114 - /**
115 - * Calculation cache enabled
116 - *
117 - * @access private
118 - * @var boolean
119 - */
120 - private $calculationCacheEnabled = true;
121 89
90 + /**
91 + * Instance of this class
92 + *
93 + * @access private
94 + * @var PHPExcel_Calculation
95 + */
96 + private static $_instance;
122 97
123 - /**
124 - * List of operators that can be used within formulae
125 - * The true/false value indicates whether it is a binary operator or a unary operator
126 - *
127 - * @access private
128 - * @var array
129 - */
130 - private static $operators = array(
131 - '+' => true, '-' => true, '*' => true, '/' => true,
132 - '^' => true, '&' => true, '%' => false, '~' => false,
133 - '>' => true, '<' => true, '=' => true, '>=' => true,
134 - '<=' => true, '<>' => true, '|' => true, ':' => true
135 - );
136 98
137 - /**
138 - * List of binary operators (those that expect two operands)
139 - *
140 - * @access private
141 - * @var array
142 - */
143 - private static $binaryOperators = array(
144 - '+' => true, '-' => true, '*' => true, '/' => true,
145 - '^' => true, '&' => true, '>' => true, '<' => true,
146 - '=' => true, '>=' => true, '<=' => true, '<>' => true,
147 - '|' => true, ':' => true
148 - );
99 + /**
100 + * Instance of the workbook this Calculation Engine is using
101 + *
102 + * @access private
103 + * @var PHPExcel
104 + */
105 + private $_workbook;
149 106
150 - /**
151 - * The debug log generated by the calculation engine
152 - *
153 - * @access private
154 - * @var PHPExcel_CalcEngine_Logger
155 - *
156 - */
157 - private $debugLog;
107 + /**
108 + * List of instances of the calculation engine that we've instantiated for individual workbooks
109 + *
110 + * @access private
111 + * @var PHPExcel_Calculation[]
112 + */
113 + private static $_workbookSets;
158 114
159 - /**
160 - * Flag to determine how formula errors should be handled
161 - * If true, then a user error will be triggered
162 - * If false, then an exception will be thrown
163 - *
164 - * @access public
165 - * @var boolean
166 - *
167 - */
168 - public $suppressFormulaErrors = false;
115 + /**
116 + * Calculation cache
117 + *
118 + * @access private
119 + * @var array
120 + */
121 + private $_calculationCache = array ();
169 122
170 - /**
171 - * Error message for any error that was raised/thrown by the calculation engine
172 - *
173 - * @access public
174 - * @var string
175 - *
176 - */
177 - public $formulaError = null;
178 123
179 - /**
180 - * An array of the nested cell references accessed by the calculation engine, used for the debug log
181 - *
182 - * @access private
183 - * @var array of string
184 - *
185 - */
186 - private $cyclicReferenceStack;
124 + /**
125 + * Calculation cache enabled
126 + *
127 + * @access private
128 + * @var boolean
129 + */
130 + private $_calculationCacheEnabled = TRUE;
187 131
188 - private $cellStack = array();
189 132
190 - /**
191 - * Current iteration counter for cyclic formulae
192 - * If the value is 0 (or less) then cyclic formulae will throw an exception,
193 - * otherwise they will iterate to the limit defined here before returning a result
194 - *
195 - * @var integer
196 - *
197 - */
198 - private $cyclicFormulaCounter = 1;
133 + /**
134 + * List of operators that can be used within formulae
135 + * The true/false value indicates whether it is a binary operator or a unary operator
136 + *
137 + * @access private
138 + * @var array
139 + */
140 + private static $_operators = array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE,
141 + '^' => TRUE, '&' => TRUE, '%' => FALSE, '~' => FALSE,
142 + '>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE,
143 + '<=' => TRUE, '<>' => TRUE, '|' => TRUE, ':' => TRUE
144 + );
199 145
200 - private $cyclicFormulaCell = '';
201 146
202 - /**
203 - * Number of iterations for cyclic formulae
204 - *
205 - * @var integer
206 - *
207 - */
208 - public $cyclicFormulaCount = 1;
147 + /**
148 + * List of binary operators (those that expect two operands)
149 + *
150 + * @access private
151 + * @var array
152 + */
153 + private static $_binaryOperators = array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE,
154 + '^' => TRUE, '&' => TRUE, '>' => TRUE, '<' => TRUE,
155 + '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE,
156 + '|' => TRUE, ':' => TRUE
157 + );
209 158
210 - /**
211 - * Epsilon Precision used for comparisons in calculations
212 - *
213 - * @var float
214 - *
215 - */
216 - private $delta = 0.1e-12;
159 + /**
160 + * The debug log generated by the calculation engine
161 + *
162 + * @access private
163 + * @var PHPExcel_CalcEngine_Logger
164 + *
165 + */
166 + private $debugLog;
217 167
168 + /**
169 + * Flag to determine how formula errors should be handled
170 + * If true, then a user error will be triggered
171 + * If false, then an exception will be thrown
172 + *
173 + * @access public
174 + * @var boolean
175 + *
176 + */
177 + public $suppressFormulaErrors = FALSE;
218 178
219 - /**
220 - * The current locale setting
221 - *
222 - * @var string
223 - *
224 - */
225 - private static $localeLanguage = 'en_us'; // US English (default locale)
179 + /**
180 + * Error message for any error that was raised/thrown by the calculation engine
181 + *
182 + * @access public
183 + * @var string
184 + *
185 + */
186 + public $formulaError = NULL;
226 187
227 - /**
228 - * List of available locale settings
229 - * Note that this is read for the locale subdirectory only when requested
230 - *
231 - * @var string[]
232 - *
233 - */
234 - private static $validLocaleLanguages = array(
235 - 'en' // English (default language)
236 - );
188 + /**
189 + * An array of the nested cell references accessed by the calculation engine, used for the debug log
190 + *
191 + * @access private
192 + * @var array of string
193 + *
194 + */
195 + private $_cyclicReferenceStack;
237 196
238 - /**
239 - * Locale-specific argument separator for function arguments
240 - *
241 - * @var string
242 - *
243 - */
244 - private static $localeArgumentSeparator = ',';
245 - private static $localeFunctions = array();
197 + private $_cellStack = array();
246 198
247 - /**
248 - * Locale-specific translations for Excel constants (True, False and Null)
249 - *
250 - * @var string[]
251 - *
252 - */
253 - public static $localeBoolean = array(
254 - 'TRUE' => 'TRUE',
255 - 'FALSE' => 'FALSE',
256 - 'NULL' => 'NULL'
257 - );
199 + /**
200 + * Current iteration counter for cyclic formulae
201 + * If the value is 0 (or less) then cyclic formulae will throw an exception,
202 + * otherwise they will iterate to the limit defined here before returning a result
203 + *
204 + * @var integer
205 + *
206 + */
207 + private $_cyclicFormulaCount = 1;
258 208
259 - /**
260 - * Excel constant string translations to their PHP equivalents
261 - * Constant conversion from text name/value to actual (datatyped) value
262 - *
263 - * @var string[]
264 - *
265 - */
266 - private static $excelConstants = array(
267 - 'TRUE' => true,
268 - 'FALSE' => false,
269 - 'NULL' => null
270 - );
209 + private $_cyclicFormulaCell = '';
271 210
272 - // PHPExcel functions
273 - private static $PHPExcelFunctions = array(
274 - 'ABS' => array(
275 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
276 - 'functionCall' => 'abs',
277 - 'argumentCount' => '1'
278 - ),
279 - 'ACCRINT' => array(
280 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
281 - 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINT',
282 - 'argumentCount' => '4-7'
283 - ),
284 - 'ACCRINTM' => array(
285 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
286 - 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINTM',
287 - 'argumentCount' => '3-5'
288 - ),
289 - 'ACOS' => array(
290 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
291 - 'functionCall' => 'acos',
292 - 'argumentCount' => '1'
293 - ),
294 - 'ACOSH' => array(
295 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
296 - 'functionCall' => 'acosh',
297 - 'argumentCount' => '1'
298 - ),
299 - 'ADDRESS' => array(
300 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
301 - 'functionCall' => 'PHPExcel_Calculation_LookupRef::CELL_ADDRESS',
302 - 'argumentCount' => '2-5'
303 - ),
304 - 'AMORDEGRC' => array(
305 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
306 - 'functionCall' => 'PHPExcel_Calculation_Financial::AMORDEGRC',
307 - 'argumentCount' => '6,7'
308 - ),
309 - 'AMORLINC' => array(
310 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
311 - 'functionCall' => 'PHPExcel_Calculation_Financial::AMORLINC',
312 - 'argumentCount' => '6,7'
313 - ),
314 - 'AND' => array(
315 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL,
316 - 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_AND',
317 - 'argumentCount' => '1+'
318 - ),
319 - 'AREAS' => array(
320 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
321 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
322 - 'argumentCount' => '1'
323 - ),
324 - 'ASC' => array(
325 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
326 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
327 - 'argumentCount' => '1'
328 - ),
329 - 'ASIN' => array(
330 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
331 - 'functionCall' => 'asin',
332 - 'argumentCount' => '1'
333 - ),
334 - 'ASINH' => array(
335 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
336 - 'functionCall' => 'asinh',
337 - 'argumentCount' => '1'
338 - ),
339 - 'ATAN' => array(
340 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
341 - 'functionCall' => 'atan',
342 - 'argumentCount' => '1'
343 - ),
344 - 'ATAN2' => array(
345 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
346 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ATAN2',
347 - 'argumentCount' => '2'
348 - ),
349 - 'ATANH' => array(
350 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
351 - 'functionCall' => 'atanh',
352 - 'argumentCount' => '1'
353 - ),
354 - 'AVEDEV' => array(
355 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
356 - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVEDEV',
357 - 'argumentCount' => '1+'
358 - ),
359 - 'AVERAGE' => array(
360 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
361 - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGE',
362 - 'argumentCount' => '1+'
363 - ),
364 - 'AVERAGEA' => array(
365 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
366 - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEA',
367 - 'argumentCount' => '1+'
368 - ),
369 - 'AVERAGEIF' => array(
370 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
371 - 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEIF',
372 - 'argumentCount' => '2,3'
373 - ),
374 - 'AVERAGEIFS' => array(
375 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
376 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
377 - 'argumentCount' => '3+'
378 - ),
379 - 'BAHTTEXT' => array(
380 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
381 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
382 - 'argumentCount' => '1'
383 - ),
384 - 'BESSELI' => array(
385 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
386 - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELI',
387 - 'argumentCount' => '2'
388 - ),
389 - 'BESSELJ' => array(
390 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
391 - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELJ',
392 - 'argumentCount' => '2'
393 - ),
394 - 'BESSELK' => array(
395 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
396 - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELK',
397 - 'argumentCount' => '2'
398 - ),
399 - 'BESSELY' => array(
400 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
401 - 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELY',
402 - 'argumentCount' => '2'
403 - ),
404 - 'BETADIST' => array(
405 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
406 - 'functionCall' => 'PHPExcel_Calculation_Statistical::BETADIST',
407 - 'argumentCount' => '3-5'
408 - ),
409 - 'BETAINV' => array(
410 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
411 - 'functionCall' => 'PHPExcel_Calculation_Statistical::BETAINV',
412 - 'argumentCount' => '3-5'
413 - ),
414 - 'BIN2DEC' => array(
415 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
416 - 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTODEC',
417 - 'argumentCount' => '1'
418 - ),
419 - 'BIN2HEX' => array(
420 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
421 - 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOHEX',
422 - 'argumentCount' => '1,2'
423 - ),
424 - 'BIN2OCT' => array(
425 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
426 - 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOOCT',
427 - 'argumentCount' => '1,2'
428 - ),
429 - 'BINOMDIST' => array(
430 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
431 - 'functionCall' => 'PHPExcel_Calculation_Statistical::BINOMDIST',
432 - 'argumentCount' => '4'
433 - ),
434 - 'CEILING' => array(
435 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
436 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::CEILING',
437 - 'argumentCount' => '2'
438 - ),
439 - 'CELL' => array(
440 - 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
441 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
442 - 'argumentCount' => '1,2'
443 - ),
444 - 'CHAR' => array(
445 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
446 - 'functionCall' => 'PHPExcel_Calculation_TextData::CHARACTER',
447 - 'argumentCount' => '1'
448 - ),
449 - 'CHIDIST' => array(
450 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
451 - 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIDIST',
452 - 'argumentCount' => '2'
453 - ),
454 - 'CHIINV' => array(
455 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
456 - 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIINV',
457 - 'argumentCount' => '2'
458 - ),
459 - 'CHITEST' => array(
460 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
461 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
462 - 'argumentCount' => '2'
463 - ),
464 - 'CHOOSE' => array(
465 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
466 - 'functionCall' => 'PHPExcel_Calculation_LookupRef::CHOOSE',
467 - 'argumentCount' => '2+'
468 - ),
469 - 'CLEAN' => array(
470 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
471 - 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMNONPRINTABLE',
472 - 'argumentCount' => '1'
473 - ),
474 - 'CODE' => array(
475 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
476 - 'functionCall' => 'PHPExcel_Calculation_TextData::ASCIICODE',
477 - 'argumentCount' => '1'
478 - ),
479 - 'COLUMN' => array(
480 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
481 - 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMN',
482 - 'argumentCount' => '-1',
483 - 'passByReference' => array(true)
484 - ),
485 - 'COLUMNS' => array(
486 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
487 - 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMNS',
488 - 'argumentCount' => '1'
489 - ),
490 - 'COMBIN' => array(
491 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
492 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::COMBIN',
493 - 'argumentCount' => '2'
494 - ),
495 - 'COMPLEX' => array(
496 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
497 - 'functionCall' => 'PHPExcel_Calculation_Engineering::COMPLEX',
498 - 'argumentCount' => '2,3'
499 - ),
500 - 'CONCATENATE' => array(
501 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
502 - 'functionCall' => 'PHPExcel_Calculation_TextData::CONCATENATE',
503 - 'argumentCount' => '1+'
504 - ),
505 - 'CONFIDENCE' => array(
506 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
507 - 'functionCall' => 'PHPExcel_Calculation_Statistical::CONFIDENCE',
508 - 'argumentCount' => '3'
509 - ),
510 - 'CONVERT' => array(
511 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
512 - 'functionCall' => 'PHPExcel_Calculation_Engineering::CONVERTUOM',
513 - 'argumentCount' => '3'
514 - ),
515 - 'CORREL' => array(
516 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
517 - 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL',
518 - 'argumentCount' => '2'
519 - ),
520 - 'COS' => array(
521 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
522 - 'functionCall' => 'cos',
523 - 'argumentCount' => '1'
524 - ),
525 - 'COSH' => array(
526 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
527 - 'functionCall' => 'cosh',
528 - 'argumentCount' => '1'
529 - ),
530 - 'COUNT' => array(
531 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
532 - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNT',
533 - 'argumentCount' => '1+'
534 - ),
535 - 'COUNTA' => array(
536 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
537 - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTA',
538 - 'argumentCount' => '1+'
539 - ),
540 - 'COUNTBLANK' => array(
541 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
542 - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTBLANK',
543 - 'argumentCount' => '1'
544 - ),
545 - 'COUNTIF' => array(
546 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
547 - 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTIF',
548 - 'argumentCount' => '2'
549 - ),
550 - 'COUNTIFS' => array(
551 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
552 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
553 - 'argumentCount' => '2'
554 - ),
555 - 'COUPDAYBS' => array(
556 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
557 - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYBS',
558 - 'argumentCount' => '3,4'
559 - ),
560 - 'COUPDAYS' => array(
561 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
562 - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYS',
563 - 'argumentCount' => '3,4'
564 - ),
565 - 'COUPDAYSNC' => array(
566 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
567 - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYSNC',
568 - 'argumentCount' => '3,4'
569 - ),
570 - 'COUPNCD' => array(
571 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
572 - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNCD',
573 - 'argumentCount' => '3,4'
574 - ),
575 - 'COUPNUM' => array(
576 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
577 - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNUM',
578 - 'argumentCount' => '3,4'
579 - ),
580 - 'COUPPCD' => array(
581 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
582 - 'functionCall' => 'PHPExcel_Calculation_Financial::COUPPCD',
583 - 'argumentCount' => '3,4'
584 - ),
585 - 'COVAR' => array(
586 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
587 - 'functionCall' => 'PHPExcel_Calculation_Statistical::COVAR',
588 - 'argumentCount' => '2'
589 - ),
590 - 'CRITBINOM' => array(
591 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
592 - 'functionCall' => 'PHPExcel_Calculation_Statistical::CRITBINOM',
593 - 'argumentCount' => '3'
594 - ),
595 - 'CUBEKPIMEMBER' => array(
596 - 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE,
597 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
598 - 'argumentCount' => '?'
599 - ),
600 - 'CUBEMEMBER' => array(
601 - 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE,
602 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
603 - 'argumentCount' => '?'
604 - ),
605 - 'CUBEMEMBERPROPERTY' => array(
606 - 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE,
607 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
608 - 'argumentCount' => '?'
609 - ),
610 - 'CUBERANKEDMEMBER' => array(
611 - 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE,
612 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
613 - 'argumentCount' => '?'
614 - ),
615 - 'CUBESET' => array(
616 - 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE,
617 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
618 - 'argumentCount' => '?'
619 - ),
620 - 'CUBESETCOUNT' => array(
621 - 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE,
622 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
623 - 'argumentCount' => '?'
624 - ),
625 - 'CUBEVALUE' => array(
626 - 'category' => PHPExcel_Calculation_Function::CATEGORY_CUBE,
627 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
628 - 'argumentCount' => '?'
629 - ),
630 - 'CUMIPMT' => array(
631 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
632 - 'functionCall' => 'PHPExcel_Calculation_Financial::CUMIPMT',
633 - 'argumentCount' => '6'
634 - ),
635 - 'CUMPRINC' => array(
636 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
637 - 'functionCall' => 'PHPExcel_Calculation_Financial::CUMPRINC',
638 - 'argumentCount' => '6'
639 - ),
640 - 'DATE' => array(
641 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
642 - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATE',
643 - 'argumentCount' => '3'
644 - ),
645 - 'DATEDIF' => array(
646 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
647 - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEDIF',
648 - 'argumentCount' => '2,3'
649 - ),
650 - 'DATEVALUE' => array(
651 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
652 - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEVALUE',
653 - 'argumentCount' => '1'
654 - ),
655 - 'DAVERAGE' => array(
656 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
657 - 'functionCall' => 'PHPExcel_Calculation_Database::DAVERAGE',
658 - 'argumentCount' => '3'
659 - ),
660 - 'DAY' => array(
661 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
662 - 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFMONTH',
663 - 'argumentCount' => '1'
664 - ),
665 - 'DAYS360' => array(
666 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
667 - 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYS360',
668 - 'argumentCount' => '2,3'
669 - ),
670 - 'DB' => array(
671 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
672 - 'functionCall' => 'PHPExcel_Calculation_Financial::DB',
673 - 'argumentCount' => '4,5'
674 - ),
675 - 'DCOUNT' => array(
676 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
677 - 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNT',
678 - 'argumentCount' => '3'
679 - ),
680 - 'DCOUNTA' => array(
681 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
682 - 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNTA',
683 - 'argumentCount' => '3'
684 - ),
685 - 'DDB' => array(
686 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
687 - 'functionCall' => 'PHPExcel_Calculation_Financial::DDB',
688 - 'argumentCount' => '4,5'
689 - ),
690 - 'DEC2BIN' => array(
691 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
692 - 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOBIN',
693 - 'argumentCount' => '1,2'
694 - ),
695 - 'DEC2HEX' => array(
696 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
697 - 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOHEX',
698 - 'argumentCount' => '1,2'
699 - ),
700 - 'DEC2OCT' => array(
701 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
702 - 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOOCT',
703 - 'argumentCount' => '1,2'
704 - ),
705 - 'DEGREES' => array(
706 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
707 - 'functionCall' => 'rad2deg',
708 - 'argumentCount' => '1'
709 - ),
710 - 'DELTA' => array(
711 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
712 - 'functionCall' => 'PHPExcel_Calculation_Engineering::DELTA',
713 - 'argumentCount' => '1,2'
714 - ),
715 - 'DEVSQ' => array(
716 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
717 - 'functionCall' => 'PHPExcel_Calculation_Statistical::DEVSQ',
718 - 'argumentCount' => '1+'
719 - ),
720 - 'DGET' => array(
721 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
722 - 'functionCall' => 'PHPExcel_Calculation_Database::DGET',
723 - 'argumentCount' => '3'
724 - ),
725 - 'DISC' => array(
726 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
727 - 'functionCall' => 'PHPExcel_Calculation_Financial::DISC',
728 - 'argumentCount' => '4,5'
729 - ),
730 - 'DMAX' => array(
731 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
732 - 'functionCall' => 'PHPExcel_Calculation_Database::DMAX',
733 - 'argumentCount' => '3'
734 - ),
735 - 'DMIN' => array(
736 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
737 - 'functionCall' => 'PHPExcel_Calculation_Database::DMIN',
738 - 'argumentCount' => '3'
739 - ),
740 - 'DOLLAR' => array(
741 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
742 - 'functionCall' => 'PHPExcel_Calculation_TextData::DOLLAR',
743 - 'argumentCount' => '1,2'
744 - ),
745 - 'DOLLARDE' => array(
746 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
747 - 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARDE',
748 - 'argumentCount' => '2'
749 - ),
750 - 'DOLLARFR' => array(
751 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
752 - 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARFR',
753 - 'argumentCount' => '2'
754 - ),
755 - 'DPRODUCT' => array(
756 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
757 - 'functionCall' => 'PHPExcel_Calculation_Database::DPRODUCT',
758 - 'argumentCount' => '3'
759 - ),
760 - 'DSTDEV' => array(
761 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
762 - 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEV',
763 - 'argumentCount' => '3'
764 - ),
765 - 'DSTDEVP' => array(
766 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
767 - 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEVP',
768 - 'argumentCount' => '3'
769 - ),
770 - 'DSUM' => array(
771 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
772 - 'functionCall' => 'PHPExcel_Calculation_Database::DSUM',
773 - 'argumentCount' => '3'
774 - ),
775 - 'DURATION' => array(
776 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
777 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
778 - 'argumentCount' => '5,6'
779 - ),
780 - 'DVAR' => array(
781 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
782 - 'functionCall' => 'PHPExcel_Calculation_Database::DVAR',
783 - 'argumentCount' => '3'
784 - ),
785 - 'DVARP' => array(
786 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
787 - 'functionCall' => 'PHPExcel_Calculation_Database::DVARP',
788 - 'argumentCount' => '3'
789 - ),
790 - 'EDATE' => array(
791 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
792 - 'functionCall' => 'PHPExcel_Calculation_DateTime::EDATE',
793 - 'argumentCount' => '2'
794 - ),
795 - 'EFFECT' => array(
796 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
797 - 'functionCall' => 'PHPExcel_Calculation_Financial::EFFECT',
798 - 'argumentCount' => '2'
799 - ),
800 - 'EOMONTH' => array(
801 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
802 - 'functionCall' => 'PHPExcel_Calculation_DateTime::EOMONTH',
803 - 'argumentCount' => '2'
804 - ),
805 - 'ERF' => array(
806 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
807 - 'functionCall' => 'PHPExcel_Calculation_Engineering::ERF',
808 - 'argumentCount' => '1,2'
809 - ),
810 - 'ERFC' => array(
811 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
812 - 'functionCall' => 'PHPExcel_Calculation_Engineering::ERFC',
813 - 'argumentCount' => '1'
814 - ),
815 - 'ERROR.TYPE' => array(
816 - 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
817 - 'functionCall' => 'PHPExcel_Calculation_Functions::ERROR_TYPE',
818 - 'argumentCount' => '1'
819 - ),
820 - 'EVEN' => array(
821 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
822 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::EVEN',
823 - 'argumentCount' => '1'
824 - ),
825 - 'EXACT' => array(
826 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
827 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
828 - 'argumentCount' => '2'
829 - ),
830 - 'EXP' => array(
831 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
832 - 'functionCall' => 'exp',
833 - 'argumentCount' => '1'
834 - ),
835 - 'EXPONDIST' => array(
836 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
837 - 'functionCall' => 'PHPExcel_Calculation_Statistical::EXPONDIST',
838 - 'argumentCount' => '3'
839 - ),
840 - 'FACT' => array(
841 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
842 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACT',
843 - 'argumentCount' => '1'
844 - ),
845 - 'FACTDOUBLE' => array(
846 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
847 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACTDOUBLE',
848 - 'argumentCount' => '1'
849 - ),
850 - 'FALSE' => array(
851 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL,
852 - 'functionCall' => 'PHPExcel_Calculation_Logical::FALSE',
853 - 'argumentCount' => '0'
854 - ),
855 - 'FDIST' => array(
856 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
857 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
858 - 'argumentCount' => '3'
859 - ),
860 - 'FIND' => array(
861 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
862 - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE',
863 - 'argumentCount' => '2,3'
864 - ),
865 - 'FINDB' => array(
866 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
867 - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE',
868 - 'argumentCount' => '2,3'
869 - ),
870 - 'FINV' => array(
871 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
872 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
873 - 'argumentCount' => '3'
874 - ),
875 - 'FISHER' => array(
876 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
877 - 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHER',
878 - 'argumentCount' => '1'
879 - ),
880 - 'FISHERINV' => array(
881 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
882 - 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHERINV',
883 - 'argumentCount' => '1'
884 - ),
885 - 'FIXED' => array(
886 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
887 - 'functionCall' => 'PHPExcel_Calculation_TextData::FIXEDFORMAT',
888 - 'argumentCount' => '1-3'
889 - ),
890 - 'FLOOR' => array(
891 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
892 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::FLOOR',
893 - 'argumentCount' => '2'
894 - ),
895 - 'FORECAST' => array(
896 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
897 - 'functionCall' => 'PHPExcel_Calculation_Statistical::FORECAST',
898 - 'argumentCount' => '3'
899 - ),
900 - 'FREQUENCY' => array(
901 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
902 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
903 - 'argumentCount' => '2'
904 - ),
905 - 'FTEST' => array(
906 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
907 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
908 - 'argumentCount' => '2'
909 - ),
910 - 'FV' => array(
911 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
912 - 'functionCall' => 'PHPExcel_Calculation_Financial::FV',
913 - 'argumentCount' => '3-5'
914 - ),
915 - 'FVSCHEDULE' => array(
916 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
917 - 'functionCall' => 'PHPExcel_Calculation_Financial::FVSCHEDULE',
918 - 'argumentCount' => '2'
919 - ),
920 - 'GAMMADIST' => array(
921 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
922 - 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMADIST',
923 - 'argumentCount' => '4'
924 - ),
925 - 'GAMMAINV' => array(
926 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
927 - 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMAINV',
928 - 'argumentCount' => '3'
929 - ),
930 - 'GAMMALN' => array(
931 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
932 - 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMALN',
933 - 'argumentCount' => '1'
934 - ),
935 - 'GCD' => array(
936 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
937 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::GCD',
938 - 'argumentCount' => '1+'
939 - ),
940 - 'GEOMEAN' => array(
941 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
942 - 'functionCall' => 'PHPExcel_Calculation_Statistical::GEOMEAN',
943 - 'argumentCount' => '1+'
944 - ),
945 - 'GESTEP' => array(
946 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
947 - 'functionCall' => 'PHPExcel_Calculation_Engineering::GESTEP',
948 - 'argumentCount' => '1,2'
949 - ),
950 - 'GETPIVOTDATA' => array(
951 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
952 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
953 - 'argumentCount' => '2+'
954 - ),
955 - 'GROWTH' => array(
956 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
957 - 'functionCall' => 'PHPExcel_Calculation_Statistical::GROWTH',
958 - 'argumentCount' => '1-4'
959 - ),
960 - 'HARMEAN' => array(
961 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
962 - 'functionCall' => 'PHPExcel_Calculation_Statistical::HARMEAN',
963 - 'argumentCount' => '1+'
964 - ),
965 - 'HEX2BIN' => array(
966 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
967 - 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOBIN',
968 - 'argumentCount' => '1,2'
969 - ),
970 - 'HEX2DEC' => array(
971 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
972 - 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTODEC',
973 - 'argumentCount' => '1'
974 - ),
975 - 'HEX2OCT' => array(
976 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
977 - 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOOCT',
978 - 'argumentCount' => '1,2'
979 - ),
980 - 'HLOOKUP' => array(
981 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
982 - 'functionCall' => 'PHPExcel_Calculation_LookupRef::HLOOKUP',
983 - 'argumentCount' => '3,4'
984 - ),
985 - 'HOUR' => array(
986 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
987 - 'functionCall' => 'PHPExcel_Calculation_DateTime::HOUROFDAY',
988 - 'argumentCount' => '1'
989 - ),
990 - 'HYPERLINK' => array(
991 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
992 - 'functionCall' => 'PHPExcel_Calculation_LookupRef::HYPERLINK',
993 - 'argumentCount' => '1,2',
994 - 'passCellReference' => true
995 - ),
996 - 'HYPGEOMDIST' => array(
997 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
998 - 'functionCall' => 'PHPExcel_Calculation_Statistical::HYPGEOMDIST',
999 - 'argumentCount' => '4'
1000 - ),
1001 - 'IF' => array(
1002 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL,
1003 - 'functionCall' => 'PHPExcel_Calculation_Logical::STATEMENT_IF',
1004 - 'argumentCount' => '1-3'
1005 - ),
1006 - 'IFERROR' => array(
1007 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL,
1008 - 'functionCall' => 'PHPExcel_Calculation_Logical::IFERROR',
1009 - 'argumentCount' => '2'
1010 - ),
1011 - 'IMABS' => array(
1012 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1013 - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMABS',
1014 - 'argumentCount' => '1'
1015 - ),
1016 - 'IMAGINARY' => array(
1017 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1018 - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMAGINARY',
1019 - 'argumentCount' => '1'
1020 - ),
1021 - 'IMARGUMENT' => array(
1022 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1023 - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMARGUMENT',
1024 - 'argumentCount' => '1'
1025 - ),
1026 - 'IMCONJUGATE' => array(
1027 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1028 - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCONJUGATE',
1029 - 'argumentCount' => '1'
1030 - ),
1031 - 'IMCOS' => array(
1032 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1033 - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCOS',
1034 - 'argumentCount' => '1'
1035 - ),
1036 - 'IMDIV' => array(
1037 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1038 - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMDIV',
1039 - 'argumentCount' => '2'
1040 - ),
1041 - 'IMEXP' => array(
1042 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1043 - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMEXP',
1044 - 'argumentCount' => '1'
1045 - ),
1046 - 'IMLN' => array(
1047 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1048 - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLN',
1049 - 'argumentCount' => '1'
1050 - ),
1051 - 'IMLOG10' => array(
1052 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1053 - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG10',
1054 - 'argumentCount' => '1'
1055 - ),
1056 - 'IMLOG2' => array(
1057 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1058 - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG2',
1059 - 'argumentCount' => '1'
1060 - ),
1061 - 'IMPOWER' => array(
1062 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1063 - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPOWER',
1064 - 'argumentCount' => '2'
1065 - ),
1066 - 'IMPRODUCT' => array(
1067 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1068 - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPRODUCT',
1069 - 'argumentCount' => '1+'
1070 - ),
1071 - 'IMREAL' => array(
1072 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1073 - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMREAL',
1074 - 'argumentCount' => '1'
1075 - ),
1076 - 'IMSIN' => array(
1077 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1078 - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSIN',
1079 - 'argumentCount' => '1'
1080 - ),
1081 - 'IMSQRT' => array(
1082 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1083 - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSQRT',
1084 - 'argumentCount' => '1'
1085 - ),
1086 - 'IMSUB' => array(
1087 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1088 - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUB',
1089 - 'argumentCount' => '2'
1090 - ),
1091 - 'IMSUM' => array(
1092 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1093 - 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUM',
1094 - 'argumentCount' => '1+'
1095 - ),
1096 - 'INDEX' => array(
1097 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
1098 - 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDEX',
1099 - 'argumentCount' => '1-4'
1100 - ),
1101 - 'INDIRECT' => array(
1102 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
1103 - 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDIRECT',
1104 - 'argumentCount' => '1,2',
1105 - 'passCellReference' => true
1106 - ),
1107 - 'INFO' => array(
1108 - 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1109 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1110 - 'argumentCount' => '1'
1111 - ),
1112 - 'INT' => array(
1113 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1114 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::INT',
1115 - 'argumentCount' => '1'
1116 - ),
1117 - 'INTERCEPT' => array(
1118 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1119 - 'functionCall' => 'PHPExcel_Calculation_Statistical::INTERCEPT',
1120 - 'argumentCount' => '2'
1121 - ),
1122 - 'INTRATE' => array(
1123 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1124 - 'functionCall' => 'PHPExcel_Calculation_Financial::INTRATE',
1125 - 'argumentCount' => '4,5'
1126 - ),
1127 - 'IPMT' => array(
1128 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1129 - 'functionCall' => 'PHPExcel_Calculation_Financial::IPMT',
1130 - 'argumentCount' => '4-6'
1131 - ),
1132 - 'IRR' => array(
1133 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1134 - 'functionCall' => 'PHPExcel_Calculation_Financial::IRR',
1135 - 'argumentCount' => '1,2'
1136 - ),
1137 - 'ISBLANK' => array(
1138 - 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1139 - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_BLANK',
1140 - 'argumentCount' => '1'
1141 - ),
1142 - 'ISERR' => array(
1143 - 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1144 - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERR',
1145 - 'argumentCount' => '1'
1146 - ),
1147 - 'ISERROR' => array(
1148 - 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1149 - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERROR',
1150 - 'argumentCount' => '1'
1151 - ),
1152 - 'ISEVEN' => array(
1153 - 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1154 - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_EVEN',
1155 - 'argumentCount' => '1'
1156 - ),
1157 - 'ISLOGICAL' => array(
1158 - 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1159 - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_LOGICAL',
1160 - 'argumentCount' => '1'
1161 - ),
1162 - 'ISNA' => array(
1163 - 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1164 - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NA',
1165 - 'argumentCount' => '1'
1166 - ),
1167 - 'ISNONTEXT' => array(
1168 - 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1169 - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NONTEXT',
1170 - 'argumentCount' => '1'
1171 - ),
1172 - 'ISNUMBER' => array(
1173 - 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1174 - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NUMBER',
1175 - 'argumentCount' => '1'
1176 - ),
1177 - 'ISODD' => array(
1178 - 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1179 - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ODD',
1180 - 'argumentCount' => '1'
1181 - ),
1182 - 'ISPMT' => array(
1183 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1184 - 'functionCall' => 'PHPExcel_Calculation_Financial::ISPMT',
1185 - 'argumentCount' => '4'
1186 - ),
1187 - 'ISREF' => array(
1188 - 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1189 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1190 - 'argumentCount' => '1'
1191 - ),
1192 - 'ISTEXT' => array(
1193 - 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1194 - 'functionCall' => 'PHPExcel_Calculation_Functions::IS_TEXT',
1195 - 'argumentCount' => '1'
1196 - ),
1197 - 'JIS' => array(
1198 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1199 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1200 - 'argumentCount' => '1'
1201 - ),
1202 - 'KURT' => array(
1203 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1204 - 'functionCall' => 'PHPExcel_Calculation_Statistical::KURT',
1205 - 'argumentCount' => '1+'
1206 - ),
1207 - 'LARGE' => array(
1208 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1209 - 'functionCall' => 'PHPExcel_Calculation_Statistical::LARGE',
1210 - 'argumentCount' => '2'
1211 - ),
1212 - 'LCM' => array(
1213 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1214 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::LCM',
1215 - 'argumentCount' => '1+'
1216 - ),
1217 - 'LEFT' => array(
1218 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1219 - 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT',
1220 - 'argumentCount' => '1,2'
1221 - ),
1222 - 'LEFTB' => array(
1223 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1224 - 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT',
1225 - 'argumentCount' => '1,2'
1226 - ),
1227 - 'LEN' => array(
1228 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1229 - 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH',
1230 - 'argumentCount' => '1'
1231 - ),
1232 - 'LENB' => array(
1233 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1234 - 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH',
1235 - 'argumentCount' => '1'
1236 - ),
1237 - 'LINEST' => array(
1238 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1239 - 'functionCall' => 'PHPExcel_Calculation_Statistical::LINEST',
1240 - 'argumentCount' => '1-4'
1241 - ),
1242 - 'LN' => array(
1243 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1244 - 'functionCall' => 'log',
1245 - 'argumentCount' => '1'
1246 - ),
1247 - 'LOG' => array(
1248 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1249 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::LOG_BASE',
1250 - 'argumentCount' => '1,2'
1251 - ),
1252 - 'LOG10' => array(
1253 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1254 - 'functionCall' => 'log10',
1255 - 'argumentCount' => '1'
1256 - ),
1257 - 'LOGEST' => array(
1258 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1259 - 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGEST',
1260 - 'argumentCount' => '1-4'
1261 - ),
1262 - 'LOGINV' => array(
1263 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1264 - 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGINV',
1265 - 'argumentCount' => '3'
1266 - ),
1267 - 'LOGNORMDIST' => array(
1268 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1269 - 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGNORMDIST',
1270 - 'argumentCount' => '3'
1271 - ),
1272 - 'LOOKUP' => array(
1273 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
1274 - 'functionCall' => 'PHPExcel_Calculation_LookupRef::LOOKUP',
1275 - 'argumentCount' => '2,3'
1276 - ),
1277 - 'LOWER' => array(
1278 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1279 - 'functionCall' => 'PHPExcel_Calculation_TextData::LOWERCASE',
1280 - 'argumentCount' => '1'
1281 - ),
1282 - 'MATCH' => array(
1283 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
1284 - 'functionCall' => 'PHPExcel_Calculation_LookupRef::MATCH',
1285 - 'argumentCount' => '2,3'
1286 - ),
1287 - 'MAX' => array(
1288 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1289 - 'functionCall' => 'PHPExcel_Calculation_Statistical::MAX',
1290 - 'argumentCount' => '1+'
1291 - ),
1292 - 'MAXA' => array(
1293 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1294 - 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXA',
1295 - 'argumentCount' => '1+'
1296 - ),
1297 - 'MAXIF' => array(
1298 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1299 - 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXIF',
1300 - 'argumentCount' => '2+'
1301 - ),
1302 - 'MDETERM' => array(
1303 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1304 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MDETERM',
1305 - 'argumentCount' => '1'
1306 - ),
1307 - 'MDURATION' => array(
1308 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1309 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1310 - 'argumentCount' => '5,6'
1311 - ),
1312 - 'MEDIAN' => array(
1313 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1314 - 'functionCall' => 'PHPExcel_Calculation_Statistical::MEDIAN',
1315 - 'argumentCount' => '1+'
1316 - ),
1317 - 'MEDIANIF' => array(
1318 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1319 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1320 - 'argumentCount' => '2+'
1321 - ),
1322 - 'MID' => array(
1323 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1324 - 'functionCall' => 'PHPExcel_Calculation_TextData::MID',
1325 - 'argumentCount' => '3'
1326 - ),
1327 - 'MIDB' => array(
1328 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1329 - 'functionCall' => 'PHPExcel_Calculation_TextData::MID',
1330 - 'argumentCount' => '3'
1331 - ),
1332 - 'MIN' => array(
1333 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1334 - 'functionCall' => 'PHPExcel_Calculation_Statistical::MIN',
1335 - 'argumentCount' => '1+'
1336 - ),
1337 - 'MINA' => array(
1338 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1339 - 'functionCall' => 'PHPExcel_Calculation_Statistical::MINA',
1340 - 'argumentCount' => '1+'
1341 - ),
1342 - 'MINIF' => array(
1343 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1344 - 'functionCall' => 'PHPExcel_Calculation_Statistical::MINIF',
1345 - 'argumentCount' => '2+'
1346 - ),
1347 - 'MINUTE' => array(
1348 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1349 - 'functionCall' => 'PHPExcel_Calculation_DateTime::MINUTEOFHOUR',
1350 - 'argumentCount' => '1'
1351 - ),
1352 - 'MINVERSE' => array(
1353 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1354 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MINVERSE',
1355 - 'argumentCount' => '1'
1356 - ),
1357 - 'MIRR' => array(
1358 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1359 - 'functionCall' => 'PHPExcel_Calculation_Financial::MIRR',
1360 - 'argumentCount' => '3'
1361 - ),
1362 - 'MMULT' => array(
1363 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1364 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MMULT',
1365 - 'argumentCount' => '2'
1366 - ),
1367 - 'MOD' => array(
1368 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1369 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MOD',
1370 - 'argumentCount' => '2'
1371 - ),
1372 - 'MODE' => array(
1373 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1374 - 'functionCall' => 'PHPExcel_Calculation_Statistical::MODE',
1375 - 'argumentCount' => '1+'
1376 - ),
1377 - 'MONTH' => array(
1378 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1379 - 'functionCall' => 'PHPExcel_Calculation_DateTime::MONTHOFYEAR',
1380 - 'argumentCount' => '1'
1381 - ),
1382 - 'MROUND' => array(
1383 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1384 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MROUND',
1385 - 'argumentCount' => '2'
1386 - ),
1387 - 'MULTINOMIAL' => array(
1388 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1389 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::MULTINOMIAL',
1390 - 'argumentCount' => '1+'
1391 - ),
1392 - 'N' => array(
1393 - 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1394 - 'functionCall' => 'PHPExcel_Calculation_Functions::N',
1395 - 'argumentCount' => '1'
1396 - ),
1397 - 'NA' => array(
1398 - 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1399 - 'functionCall' => 'PHPExcel_Calculation_Functions::NA',
1400 - 'argumentCount' => '0'
1401 - ),
1402 - 'NEGBINOMDIST' => array(
1403 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1404 - 'functionCall' => 'PHPExcel_Calculation_Statistical::NEGBINOMDIST',
1405 - 'argumentCount' => '3'
1406 - ),
1407 - 'NETWORKDAYS' => array(
1408 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1409 - 'functionCall' => 'PHPExcel_Calculation_DateTime::NETWORKDAYS',
1410 - 'argumentCount' => '2+'
1411 - ),
1412 - 'NOMINAL' => array(
1413 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1414 - 'functionCall' => 'PHPExcel_Calculation_Financial::NOMINAL',
1415 - 'argumentCount' => '2'
1416 - ),
1417 - 'NORMDIST' => array(
1418 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1419 - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMDIST',
1420 - 'argumentCount' => '4'
1421 - ),
1422 - 'NORMINV' => array(
1423 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1424 - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMINV',
1425 - 'argumentCount' => '3'
1426 - ),
1427 - 'NORMSDIST' => array(
1428 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1429 - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSDIST',
1430 - 'argumentCount' => '1'
1431 - ),
1432 - 'NORMSINV' => array(
1433 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1434 - 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSINV',
1435 - 'argumentCount' => '1'
1436 - ),
1437 - 'NOT' => array(
1438 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL,
1439 - 'functionCall' => 'PHPExcel_Calculation_Logical::NOT',
1440 - 'argumentCount' => '1'
1441 - ),
1442 - 'NOW' => array(
1443 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1444 - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATETIMENOW',
1445 - 'argumentCount' => '0'
1446 - ),
1447 - 'NPER' => array(
1448 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1449 - 'functionCall' => 'PHPExcel_Calculation_Financial::NPER',
1450 - 'argumentCount' => '3-5'
1451 - ),
1452 - 'NPV' => array(
1453 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1454 - 'functionCall' => 'PHPExcel_Calculation_Financial::NPV',
1455 - 'argumentCount' => '2+'
1456 - ),
1457 - 'OCT2BIN' => array(
1458 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1459 - 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOBIN',
1460 - 'argumentCount' => '1,2'
1461 - ),
1462 - 'OCT2DEC' => array(
1463 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1464 - 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTODEC',
1465 - 'argumentCount' => '1'
1466 - ),
1467 - 'OCT2HEX' => array(
1468 - 'category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1469 - 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOHEX',
1470 - 'argumentCount' => '1,2'
1471 - ),
1472 - 'ODD' => array(
1473 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1474 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ODD',
1475 - 'argumentCount' => '1'
1476 - ),
1477 - 'ODDFPRICE' => array(
1478 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1479 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1480 - 'argumentCount' => '8,9'
1481 - ),
1482 - 'ODDFYIELD' => array(
1483 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1484 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1485 - 'argumentCount' => '8,9'
1486 - ),
1487 - 'ODDLPRICE' => array(
1488 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1489 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1490 - 'argumentCount' => '7,8'
1491 - ),
1492 - 'ODDLYIELD' => array(
1493 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1494 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1495 - 'argumentCount' => '7,8'
1496 - ),
1497 - 'OFFSET' => array(
1498 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
1499 - 'functionCall' => 'PHPExcel_Calculation_LookupRef::OFFSET',
1500 - 'argumentCount' => '3-5',
1501 - 'passCellReference' => true,
1502 - 'passByReference' => array(true)
1503 - ),
1504 - 'OR' => array(
1505 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL,
1506 - 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_OR',
1507 - 'argumentCount' => '1+'
1508 - ),
1509 - 'PEARSON' => array(
1510 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1511 - 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL',
1512 - 'argumentCount' => '2'
1513 - ),
1514 - 'PERCENTILE' => array(
1515 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1516 - 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTILE',
1517 - 'argumentCount' => '2'
1518 - ),
1519 - 'PERCENTRANK' => array(
1520 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1521 - 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTRANK',
1522 - 'argumentCount' => '2,3'
1523 - ),
1524 - 'PERMUT' => array(
1525 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1526 - 'functionCall' => 'PHPExcel_Calculation_Statistical::PERMUT',
1527 - 'argumentCount' => '2'
1528 - ),
1529 - 'PHONETIC' => array(
1530 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1531 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1532 - 'argumentCount' => '1'
1533 - ),
1534 - 'PI' => array(
1535 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1536 - 'functionCall' => 'pi',
1537 - 'argumentCount' => '0'
1538 - ),
1539 - 'PMT' => array(
1540 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1541 - 'functionCall' => 'PHPExcel_Calculation_Financial::PMT',
1542 - 'argumentCount' => '3-5'
1543 - ),
1544 - 'POISSON' => array(
1545 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1546 - 'functionCall' => 'PHPExcel_Calculation_Statistical::POISSON',
1547 - 'argumentCount' => '3'
1548 - ),
1549 - 'POWER' => array(
1550 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1551 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::POWER',
1552 - 'argumentCount' => '2'
1553 - ),
1554 - 'PPMT' => array(
1555 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1556 - 'functionCall' => 'PHPExcel_Calculation_Financial::PPMT',
1557 - 'argumentCount' => '4-6'
1558 - ),
1559 - 'PRICE' => array(
1560 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1561 - 'functionCall' => 'PHPExcel_Calculation_Financial::PRICE',
1562 - 'argumentCount' => '6,7'
1563 - ),
1564 - 'PRICEDISC' => array(
1565 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1566 - 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEDISC',
1567 - 'argumentCount' => '4,5'
1568 - ),
1569 - 'PRICEMAT' => array(
1570 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1571 - 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEMAT',
1572 - 'argumentCount' => '5,6'
1573 - ),
1574 - 'PROB' => array(
1575 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1576 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1577 - 'argumentCount' => '3,4'
1578 - ),
1579 - 'PRODUCT' => array(
1580 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1581 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::PRODUCT',
1582 - 'argumentCount' => '1+'
1583 - ),
1584 - 'PROPER' => array(
1585 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1586 - 'functionCall' => 'PHPExcel_Calculation_TextData::PROPERCASE',
1587 - 'argumentCount' => '1'
1588 - ),
1589 - 'PV' => array(
1590 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1591 - 'functionCall' => 'PHPExcel_Calculation_Financial::PV',
1592 - 'argumentCount' => '3-5'
1593 - ),
1594 - 'QUARTILE' => array(
1595 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1596 - 'functionCall' => 'PHPExcel_Calculation_Statistical::QUARTILE',
1597 - 'argumentCount' => '2'
1598 - ),
1599 - 'QUOTIENT' => array(
1600 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1601 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::QUOTIENT',
1602 - 'argumentCount' => '2'
1603 - ),
1604 - 'RADIANS' => array(
1605 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1606 - 'functionCall' => 'deg2rad',
1607 - 'argumentCount' => '1'
1608 - ),
1609 - 'RAND' => array(
1610 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1611 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND',
1612 - 'argumentCount' => '0'
1613 - ),
1614 - 'RANDBETWEEN' => array(
1615 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1616 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND',
1617 - 'argumentCount' => '2'
1618 - ),
1619 - 'RANK' => array(
1620 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1621 - 'functionCall' => 'PHPExcel_Calculation_Statistical::RANK',
1622 - 'argumentCount' => '2,3'
1623 - ),
1624 - 'RATE' => array(
1625 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1626 - 'functionCall' => 'PHPExcel_Calculation_Financial::RATE',
1627 - 'argumentCount' => '3-6'
1628 - ),
1629 - 'RECEIVED' => array(
1630 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1631 - 'functionCall' => 'PHPExcel_Calculation_Financial::RECEIVED',
1632 - 'argumentCount' => '4-5'
1633 - ),
1634 - 'REPLACE' => array(
1635 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1636 - 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE',
1637 - 'argumentCount' => '4'
1638 - ),
1639 - 'REPLACEB' => array(
1640 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1641 - 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE',
1642 - 'argumentCount' => '4'
1643 - ),
1644 - 'REPT' => array(
1645 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1646 - 'functionCall' => 'str_repeat',
1647 - 'argumentCount' => '2'
1648 - ),
1649 - 'RIGHT' => array(
1650 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1651 - 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT',
1652 - 'argumentCount' => '1,2'
1653 - ),
1654 - 'RIGHTB' => array(
1655 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1656 - 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT',
1657 - 'argumentCount' => '1,2'
1658 - ),
1659 - 'ROMAN' => array(
1660 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1661 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROMAN',
1662 - 'argumentCount' => '1,2'
1663 - ),
1664 - 'ROUND' => array(
1665 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1666 - 'functionCall' => 'round',
1667 - 'argumentCount' => '2'
1668 - ),
1669 - 'ROUNDDOWN' => array(
1670 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1671 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDDOWN',
1672 - 'argumentCount' => '2'
1673 - ),
1674 - 'ROUNDUP' => array(
1675 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1676 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDUP',
1677 - 'argumentCount' => '2'
1678 - ),
1679 - 'ROW' => array(
1680 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
1681 - 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROW',
1682 - 'argumentCount' => '-1',
1683 - 'passByReference' => array(true)
1684 - ),
1685 - 'ROWS' => array(
1686 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
1687 - 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROWS',
1688 - 'argumentCount' => '1'
1689 - ),
1690 - 'RSQ' => array(
1691 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1692 - 'functionCall' => 'PHPExcel_Calculation_Statistical::RSQ',
1693 - 'argumentCount' => '2'
1694 - ),
1695 - 'RTD' => array(
1696 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
1697 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1698 - 'argumentCount' => '1+'
1699 - ),
1700 - 'SEARCH' => array(
1701 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1702 - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE',
1703 - 'argumentCount' => '2,3'
1704 - ),
1705 - 'SEARCHB' => array(
1706 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1707 - 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE',
1708 - 'argumentCount' => '2,3'
1709 - ),
1710 - 'SECOND' => array(
1711 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1712 - 'functionCall' => 'PHPExcel_Calculation_DateTime::SECONDOFMINUTE',
1713 - 'argumentCount' => '1'
1714 - ),
1715 - 'SERIESSUM' => array(
1716 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1717 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SERIESSUM',
1718 - 'argumentCount' => '4'
1719 - ),
1720 - 'SIGN' => array(
1721 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1722 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SIGN',
1723 - 'argumentCount' => '1'
1724 - ),
1725 - 'SIN' => array(
1726 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1727 - 'functionCall' => 'sin',
1728 - 'argumentCount' => '1'
1729 - ),
1730 - 'SINH' => array(
1731 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1732 - 'functionCall' => 'sinh',
1733 - 'argumentCount' => '1'
1734 - ),
1735 - 'SKEW' => array(
1736 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1737 - 'functionCall' => 'PHPExcel_Calculation_Statistical::SKEW',
1738 - 'argumentCount' => '1+'
1739 - ),
1740 - 'SLN' => array(
1741 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1742 - 'functionCall' => 'PHPExcel_Calculation_Financial::SLN',
1743 - 'argumentCount' => '3'
1744 - ),
1745 - 'SLOPE' => array(
1746 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1747 - 'functionCall' => 'PHPExcel_Calculation_Statistical::SLOPE',
1748 - 'argumentCount' => '2'
1749 - ),
1750 - 'SMALL' => array(
1751 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1752 - 'functionCall' => 'PHPExcel_Calculation_Statistical::SMALL',
1753 - 'argumentCount' => '2'
1754 - ),
1755 - 'SQRT' => array(
1756 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1757 - 'functionCall' => 'sqrt',
1758 - 'argumentCount' => '1'
1759 - ),
1760 - 'SQRTPI' => array(
1761 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1762 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SQRTPI',
1763 - 'argumentCount' => '1'
1764 - ),
1765 - 'STANDARDIZE' => array(
1766 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1767 - 'functionCall' => 'PHPExcel_Calculation_Statistical::STANDARDIZE',
1768 - 'argumentCount' => '3'
1769 - ),
1770 - 'STDEV' => array(
1771 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1772 - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEV',
1773 - 'argumentCount' => '1+'
1774 - ),
1775 - 'STDEVA' => array(
1776 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1777 - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVA',
1778 - 'argumentCount' => '1+'
1779 - ),
1780 - 'STDEVP' => array(
1781 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1782 - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVP',
1783 - 'argumentCount' => '1+'
1784 - ),
1785 - 'STDEVPA' => array(
1786 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1787 - 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVPA',
1788 - 'argumentCount' => '1+'
1789 - ),
1790 - 'STEYX' => array(
1791 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1792 - 'functionCall' => 'PHPExcel_Calculation_Statistical::STEYX',
1793 - 'argumentCount' => '2'
1794 - ),
1795 - 'SUBSTITUTE' => array(
1796 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1797 - 'functionCall' => 'PHPExcel_Calculation_TextData::SUBSTITUTE',
1798 - 'argumentCount' => '3,4'
1799 - ),
1800 - 'SUBTOTAL' => array(
1801 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1802 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUBTOTAL',
1803 - 'argumentCount' => '2+'
1804 - ),
1805 - 'SUM' => array(
1806 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1807 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUM',
1808 - 'argumentCount' => '1+'
1809 - ),
1810 - 'SUMIF' => array(
1811 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1812 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMIF',
1813 - 'argumentCount' => '2,3'
1814 - ),
1815 - 'SUMIFS' => array(
1816 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1817 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMIFS',
1818 - 'argumentCount' => '3+'
1819 - ),
1820 - 'SUMPRODUCT' => array(
1821 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1822 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMPRODUCT',
1823 - 'argumentCount' => '1+'
1824 - ),
1825 - 'SUMSQ' => array(
1826 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1827 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMSQ',
1828 - 'argumentCount' => '1+'
1829 - ),
1830 - 'SUMX2MY2' => array(
1831 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1832 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2MY2',
1833 - 'argumentCount' => '2'
1834 - ),
1835 - 'SUMX2PY2' => array(
1836 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1837 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2PY2',
1838 - 'argumentCount' => '2'
1839 - ),
1840 - 'SUMXMY2' => array(
1841 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1842 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMXMY2',
1843 - 'argumentCount' => '2'
1844 - ),
1845 - 'SYD' => array(
1846 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1847 - 'functionCall' => 'PHPExcel_Calculation_Financial::SYD',
1848 - 'argumentCount' => '4'
1849 - ),
1850 - 'T' => array(
1851 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1852 - 'functionCall' => 'PHPExcel_Calculation_TextData::RETURNSTRING',
1853 - 'argumentCount' => '1'
1854 - ),
1855 - 'TAN' => array(
1856 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1857 - 'functionCall' => 'tan',
1858 - 'argumentCount' => '1'
1859 - ),
1860 - 'TANH' => array(
1861 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1862 - 'functionCall' => 'tanh',
1863 - 'argumentCount' => '1'
1864 - ),
1865 - 'TBILLEQ' => array(
1866 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1867 - 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLEQ',
1868 - 'argumentCount' => '3'
1869 - ),
1870 - 'TBILLPRICE' => array(
1871 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1872 - 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLPRICE',
1873 - 'argumentCount' => '3'
1874 - ),
1875 - 'TBILLYIELD' => array(
1876 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1877 - 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLYIELD',
1878 - 'argumentCount' => '3'
1879 - ),
1880 - 'TDIST' => array(
1881 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1882 - 'functionCall' => 'PHPExcel_Calculation_Statistical::TDIST',
1883 - 'argumentCount' => '3'
1884 - ),
1885 - 'TEXT' => array(
1886 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1887 - 'functionCall' => 'PHPExcel_Calculation_TextData::TEXTFORMAT',
1888 - 'argumentCount' => '2'
1889 - ),
1890 - 'TIME' => array(
1891 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1892 - 'functionCall' => 'PHPExcel_Calculation_DateTime::TIME',
1893 - 'argumentCount' => '3'
1894 - ),
1895 - 'TIMEVALUE' => array(
1896 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1897 - 'functionCall' => 'PHPExcel_Calculation_DateTime::TIMEVALUE',
1898 - 'argumentCount' => '1'
1899 - ),
1900 - 'TINV' => array(
1901 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1902 - 'functionCall' => 'PHPExcel_Calculation_Statistical::TINV',
1903 - 'argumentCount' => '2'
1904 - ),
1905 - 'TODAY' => array(
1906 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1907 - 'functionCall' => 'PHPExcel_Calculation_DateTime::DATENOW',
1908 - 'argumentCount' => '0'
1909 - ),
1910 - 'TRANSPOSE' => array(
1911 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
1912 - 'functionCall' => 'PHPExcel_Calculation_LookupRef::TRANSPOSE',
1913 - 'argumentCount' => '1'
1914 - ),
1915 - 'TREND' => array(
1916 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1917 - 'functionCall' => 'PHPExcel_Calculation_Statistical::TREND',
1918 - 'argumentCount' => '1-4'
1919 - ),
1920 - 'TRIM' => array(
1921 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1922 - 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMSPACES',
1923 - 'argumentCount' => '1'
1924 - ),
1925 - 'TRIMMEAN' => array(
1926 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1927 - 'functionCall' => 'PHPExcel_Calculation_Statistical::TRIMMEAN',
1928 - 'argumentCount' => '2'
1929 - ),
1930 - 'TRUE' => array(
1931 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL,
1932 - 'functionCall' => 'PHPExcel_Calculation_Logical::TRUE',
1933 - 'argumentCount' => '0'
1934 - ),
1935 - 'TRUNC' => array(
1936 - 'category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1937 - 'functionCall' => 'PHPExcel_Calculation_MathTrig::TRUNC',
1938 - 'argumentCount' => '1,2'
1939 - ),
1940 - 'TTEST' => array(
1941 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1942 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1943 - 'argumentCount' => '4'
1944 - ),
1945 - 'TYPE' => array(
1946 - 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1947 - 'functionCall' => 'PHPExcel_Calculation_Functions::TYPE',
1948 - 'argumentCount' => '1'
1949 - ),
1950 - 'UPPER' => array(
1951 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1952 - 'functionCall' => 'PHPExcel_Calculation_TextData::UPPERCASE',
1953 - 'argumentCount' => '1'
1954 - ),
1955 - 'USDOLLAR' => array(
1956 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1957 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1958 - 'argumentCount' => '2'
1959 - ),
1960 - 'VALUE' => array(
1961 - 'category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1962 - 'functionCall' => 'PHPExcel_Calculation_TextData::VALUE',
1963 - 'argumentCount' => '1'
1964 - ),
1965 - 'VAR' => array(
1966 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1967 - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARFunc',
1968 - 'argumentCount' => '1+'
1969 - ),
1970 - 'VARA' => array(
1971 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1972 - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARA',
1973 - 'argumentCount' => '1+'
1974 - ),
1975 - 'VARP' => array(
1976 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1977 - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARP',
1978 - 'argumentCount' => '1+'
1979 - ),
1980 - 'VARPA' => array(
1981 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1982 - 'functionCall' => 'PHPExcel_Calculation_Statistical::VARPA',
1983 - 'argumentCount' => '1+'
1984 - ),
1985 - 'VDB' => array(
1986 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1987 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1988 - 'argumentCount' => '5-7'
1989 - ),
1990 - 'VERSION' => array(
1991 - 'category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1992 - 'functionCall' => 'PHPExcel_Calculation_Functions::VERSION',
1993 - 'argumentCount' => '0'
1994 - ),
1995 - 'VLOOKUP' => array(
1996 - 'category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
1997 - 'functionCall' => 'PHPExcel_Calculation_LookupRef::VLOOKUP',
1998 - 'argumentCount' => '3,4'
1999 - ),
2000 - 'WEEKDAY' => array(
2001 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
2002 - 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFWEEK',
2003 - 'argumentCount' => '1,2'
2004 - ),
2005 - 'WEEKNUM' => array(
2006 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
2007 - 'functionCall' => 'PHPExcel_Calculation_DateTime::WEEKOFYEAR',
2008 - 'argumentCount' => '1,2'
2009 - ),
2010 - 'WEIBULL' => array(
2011 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
2012 - 'functionCall' => 'PHPExcel_Calculation_Statistical::WEIBULL',
2013 - 'argumentCount' => '4'
2014 - ),
2015 - 'WORKDAY' => array(
2016 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
2017 - 'functionCall' => 'PHPExcel_Calculation_DateTime::WORKDAY',
2018 - 'argumentCount' => '2+'
2019 - ),
2020 - 'XIRR' => array(
2021 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
2022 - 'functionCall' => 'PHPExcel_Calculation_Financial::XIRR',
2023 - 'argumentCount' => '2,3'
2024 - ),
2025 - 'XNPV' => array(
2026 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
2027 - 'functionCall' => 'PHPExcel_Calculation_Financial::XNPV',
2028 - 'argumentCount' => '3'
2029 - ),
2030 - 'YEAR' => array(
2031 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
2032 - 'functionCall' => 'PHPExcel_Calculation_DateTime::YEAR',
2033 - 'argumentCount' => '1'
2034 - ),
2035 - 'YEARFRAC' => array(
2036 - 'category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
2037 - 'functionCall' => 'PHPExcel_Calculation_DateTime::YEARFRAC',
2038 - 'argumentCount' => '2,3'
2039 - ),
2040 - 'YIELD' => array(
2041 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
2042 - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
2043 - 'argumentCount' => '6,7'
2044 - ),
2045 - 'YIELDDISC' => array(
2046 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
2047 - 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDDISC',
2048 - 'argumentCount' => '4,5'
2049 - ),
2050 - 'YIELDMAT' => array(
2051 - 'category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
2052 - 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDMAT',
2053 - 'argumentCount' => '5,6'
2054 - ),
2055 - 'ZTEST' => array(
2056 - 'category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
2057 - 'functionCall' => 'PHPExcel_Calculation_Statistical::ZTEST',
2058 - 'argumentCount' => '2-3'
2059 - )
2060 - );
211 + /**
212 + * Number of iterations for cyclic formulae
213 + *
214 + * @var integer
215 + *
216 + */
217 + public $cyclicFormulaCount = 1;
2061 218
2062 - // Internal functions used for special control purposes
2063 - private static $controlFunctions = array(
2064 - 'MKMATRIX' => array(
2065 - 'argumentCount' => '*',
2066 - 'functionCall' => 'self::mkMatrix'
2067 - )
2068 - );
219 + /**
220 + * Precision used for calculations
221 + *
222 + * @var integer
223 + *
224 + */
225 + private $_savedPrecision = 14;
2069 226
2070 227
2071 - public function __construct(PHPExcel $workbook = null)
2072 - {
2073 - $this->delta = 1 * pow(10, 0 - ini_get('precision'));
228 + /**
229 + * The current locale setting
230 + *
231 + * @var string
232 + *
233 + */
234 + private static $_localeLanguage = 'en_us'; // US English (default locale)
2074 235
2075 - $this->workbook = $workbook;
2076 - $this->cyclicReferenceStack = new PHPExcel_CalcEngine_CyclicReferenceStack();
2077 - $this->_debugLog = new PHPExcel_CalcEngine_Logger($this->cyclicReferenceStack);
2078 - }
236 + /**
237 + * List of available locale settings
238 + * Note that this is read for the locale subdirectory only when requested
239 + *
240 + * @var string[]
241 + *
242 + */
243 + private static $_validLocaleLanguages = array( 'en' // English (default language)
244 + );
245 + /**
246 + * Locale-specific argument separator for function arguments
247 + *
248 + * @var string
249 + *
250 + */
251 + private static $_localeArgumentSeparator = ',';
252 + private static $_localeFunctions = array();
2079 253
254 + /**
255 + * Locale-specific translations for Excel constants (True, False and Null)
256 + *
257 + * @var string[]
258 + *
259 + */
260 + public static $_localeBoolean = array( 'TRUE' => 'TRUE',
261 + 'FALSE' => 'FALSE',
262 + 'NULL' => 'NULL'
263 + );
2080 264
2081 - private static function loadLocales()
2082 - {
2083 - $localeFileDirectory = PHPEXCEL_ROOT.'PHPExcel/locale/';
2084 - foreach (glob($localeFileDirectory.'/*', GLOB_ONLYDIR) as $filename) {
2085 - $filename = substr($filename, strlen($localeFileDirectory)+1);
2086 - if ($filename != 'en') {
2087 - self::$validLocaleLanguages[] = $filename;
2088 - }
2089 - }
2090 - }
2091 265
2092 - /**
2093 - * Get an instance of this class
2094 - *
2095 - * @access public
2096 - * @param PHPExcel $workbook Injected workbook for working with a PHPExcel object,
2097 - * or NULL to create a standalone claculation engine
2098 - * @return PHPExcel_Calculation
2099 - */
2100 - public static function getInstance(PHPExcel $workbook = null)
2101 - {
2102 - if ($workbook !== null) {
2103 - $instance = $workbook->getCalculationEngine();
2104 - if (isset($instance)) {
2105 - return $instance;
2106 - }
2107 - }
266 + /**
267 + * Excel constant string translations to their PHP equivalents
268 + * Constant conversion from text name/value to actual (datatyped) value
269 + *
270 + * @var string[]
271 + *
272 + */
273 + private static $_ExcelConstants = array('TRUE' => TRUE,
274 + 'FALSE' => FALSE,
275 + 'NULL' => NULL
276 + );
2108 277
2109 - if (!isset(self::$instance) || (self::$instance === null)) {
2110 - self::$instance = new PHPExcel_Calculation();
2111 - }
2112 - return self::$instance;
278 + // PHPExcel functions
279 + private static $_PHPExcelFunctions = array( // PHPExcel functions
280 + 'ABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
281 + 'functionCall' => 'abs',
282 + 'argumentCount' => '1'
283 + ),
284 + 'ACCRINT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
285 + 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINT',
286 + 'argumentCount' => '4-7'
287 + ),
288 + 'ACCRINTM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
289 + 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINTM',
290 + 'argumentCount' => '3-5'
291 + ),
292 + 'ACOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
293 + 'functionCall' => 'acos',
294 + 'argumentCount' => '1'
295 + ),
296 + 'ACOSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
297 + 'functionCall' => 'acosh',
298 + 'argumentCount' => '1'
299 + ),
300 + 'ADDRESS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
301 + 'functionCall' => 'PHPExcel_Calculation_LookupRef::CELL_ADDRESS',
302 + 'argumentCount' => '2-5'
303 + ),
304 + 'AMORDEGRC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
305 + 'functionCall' => 'PHPExcel_Calculation_Financial::AMORDEGRC',
306 + 'argumentCount' => '6,7'
307 + ),
308 + 'AMORLINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
309 + 'functionCall' => 'PHPExcel_Calculation_Financial::AMORLINC',
310 + 'argumentCount' => '6,7'
311 + ),
312 + 'AND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL,
313 + 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_AND',
314 + 'argumentCount' => '1+'
315 + ),
316 + 'AREAS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
317 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
318 + 'argumentCount' => '1'
319 + ),
320 + 'ASC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
321 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
322 + 'argumentCount' => '1'
323 + ),
324 + 'ASIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
325 + 'functionCall' => 'asin',
326 + 'argumentCount' => '1'
327 + ),
328 + 'ASINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
329 + 'functionCall' => 'asinh',
330 + 'argumentCount' => '1'
331 + ),
332 + 'ATAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
333 + 'functionCall' => 'atan',
334 + 'argumentCount' => '1'
335 + ),
336 + 'ATAN2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
337 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ATAN2',
338 + 'argumentCount' => '2'
339 + ),
340 + 'ATANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
341 + 'functionCall' => 'atanh',
342 + 'argumentCount' => '1'
343 + ),
344 + 'AVEDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
345 + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVEDEV',
346 + 'argumentCount' => '1+'
347 + ),
348 + 'AVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
349 + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGE',
350 + 'argumentCount' => '1+'
351 + ),
352 + 'AVERAGEA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
353 + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEA',
354 + 'argumentCount' => '1+'
355 + ),
356 + 'AVERAGEIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
357 + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEIF',
358 + 'argumentCount' => '2,3'
359 + ),
360 + 'AVERAGEIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
361 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
362 + 'argumentCount' => '3+'
363 + ),
364 + 'BAHTTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
365 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
366 + 'argumentCount' => '1'
367 + ),
368 + 'BESSELI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
369 + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELI',
370 + 'argumentCount' => '2'
371 + ),
372 + 'BESSELJ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
373 + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELJ',
374 + 'argumentCount' => '2'
375 + ),
376 + 'BESSELK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
377 + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELK',
378 + 'argumentCount' => '2'
379 + ),
380 + 'BESSELY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
381 + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELY',
382 + 'argumentCount' => '2'
383 + ),
384 + 'BETADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
385 + 'functionCall' => 'PHPExcel_Calculation_Statistical::BETADIST',
386 + 'argumentCount' => '3-5'
387 + ),
388 + 'BETAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
389 + 'functionCall' => 'PHPExcel_Calculation_Statistical::BETAINV',
390 + 'argumentCount' => '3-5'
391 + ),
392 + 'BIN2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
393 + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTODEC',
394 + 'argumentCount' => '1'
395 + ),
396 + 'BIN2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
397 + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOHEX',
398 + 'argumentCount' => '1,2'
399 + ),
400 + 'BIN2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
401 + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOOCT',
402 + 'argumentCount' => '1,2'
403 + ),
404 + 'BINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
405 + 'functionCall' => 'PHPExcel_Calculation_Statistical::BINOMDIST',
406 + 'argumentCount' => '4'
407 + ),
408 + 'CEILING' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
409 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::CEILING',
410 + 'argumentCount' => '2'
411 + ),
412 + 'CELL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
413 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
414 + 'argumentCount' => '1,2'
415 + ),
416 + 'CHAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
417 + 'functionCall' => 'PHPExcel_Calculation_TextData::CHARACTER',
418 + 'argumentCount' => '1'
419 + ),
420 + 'CHIDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
421 + 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIDIST',
422 + 'argumentCount' => '2'
423 + ),
424 + 'CHIINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
425 + 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIINV',
426 + 'argumentCount' => '2'
427 + ),
428 + 'CHITEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
429 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
430 + 'argumentCount' => '2'
431 + ),
432 + 'CHOOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
433 + 'functionCall' => 'PHPExcel_Calculation_LookupRef::CHOOSE',
434 + 'argumentCount' => '2+'
435 + ),
436 + 'CLEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
437 + 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMNONPRINTABLE',
438 + 'argumentCount' => '1'
439 + ),
440 + 'CODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
441 + 'functionCall' => 'PHPExcel_Calculation_TextData::ASCIICODE',
442 + 'argumentCount' => '1'
443 + ),
444 + 'COLUMN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
445 + 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMN',
446 + 'argumentCount' => '-1',
447 + 'passByReference' => array(TRUE)
448 + ),
449 + 'COLUMNS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
450 + 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMNS',
451 + 'argumentCount' => '1'
452 + ),
453 + 'COMBIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
454 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::COMBIN',
455 + 'argumentCount' => '2'
456 + ),
457 + 'COMPLEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
458 + 'functionCall' => 'PHPExcel_Calculation_Engineering::COMPLEX',
459 + 'argumentCount' => '2,3'
460 + ),
461 + 'CONCATENATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
462 + 'functionCall' => 'PHPExcel_Calculation_TextData::CONCATENATE',
463 + 'argumentCount' => '1+'
464 + ),
465 + 'CONFIDENCE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
466 + 'functionCall' => 'PHPExcel_Calculation_Statistical::CONFIDENCE',
467 + 'argumentCount' => '3'
468 + ),
469 + 'CONVERT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
470 + 'functionCall' => 'PHPExcel_Calculation_Engineering::CONVERTUOM',
471 + 'argumentCount' => '3'
472 + ),
473 + 'CORREL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
474 + 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL',
475 + 'argumentCount' => '2'
476 + ),
477 + 'COS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
478 + 'functionCall' => 'cos',
479 + 'argumentCount' => '1'
480 + ),
481 + 'COSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
482 + 'functionCall' => 'cosh',
483 + 'argumentCount' => '1'
484 + ),
485 + 'COUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
486 + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNT',
487 + 'argumentCount' => '1+'
488 + ),
489 + 'COUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
490 + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTA',
491 + 'argumentCount' => '1+'
492 + ),
493 + 'COUNTBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
494 + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTBLANK',
495 + 'argumentCount' => '1'
496 + ),
497 + 'COUNTIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
498 + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTIF',
499 + 'argumentCount' => '2'
500 + ),
501 + 'COUNTIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
502 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
503 + 'argumentCount' => '2'
504 + ),
505 + 'COUPDAYBS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
506 + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYBS',
507 + 'argumentCount' => '3,4'
508 + ),
509 + 'COUPDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
510 + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYS',
511 + 'argumentCount' => '3,4'
512 + ),
513 + 'COUPDAYSNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
514 + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYSNC',
515 + 'argumentCount' => '3,4'
516 + ),
517 + 'COUPNCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
518 + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNCD',
519 + 'argumentCount' => '3,4'
520 + ),
521 + 'COUPNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
522 + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNUM',
523 + 'argumentCount' => '3,4'
524 + ),
525 + 'COUPPCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
526 + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPPCD',
527 + 'argumentCount' => '3,4'
528 + ),
529 + 'COVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
530 + 'functionCall' => 'PHPExcel_Calculation_Statistical::COVAR',
531 + 'argumentCount' => '2'
532 + ),
533 + 'CRITBINOM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
534 + 'functionCall' => 'PHPExcel_Calculation_Statistical::CRITBINOM',
535 + 'argumentCount' => '3'
536 + ),
537 + 'CUBEKPIMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE,
538 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
539 + 'argumentCount' => '?'
540 + ),
541 + 'CUBEMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE,
542 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
543 + 'argumentCount' => '?'
544 + ),
545 + 'CUBEMEMBERPROPERTY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE,
546 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
547 + 'argumentCount' => '?'
548 + ),
549 + 'CUBERANKEDMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE,
550 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
551 + 'argumentCount' => '?'
552 + ),
553 + 'CUBESET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE,
554 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
555 + 'argumentCount' => '?'
556 + ),
557 + 'CUBESETCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE,
558 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
559 + 'argumentCount' => '?'
560 + ),
561 + 'CUBEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE,
562 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
563 + 'argumentCount' => '?'
564 + ),
565 + 'CUMIPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
566 + 'functionCall' => 'PHPExcel_Calculation_Financial::CUMIPMT',
567 + 'argumentCount' => '6'
568 + ),
569 + 'CUMPRINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
570 + 'functionCall' => 'PHPExcel_Calculation_Financial::CUMPRINC',
571 + 'argumentCount' => '6'
572 + ),
573 + 'DATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
574 + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATE',
575 + 'argumentCount' => '3'
576 + ),
577 + 'DATEDIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
578 + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEDIF',
579 + 'argumentCount' => '2,3'
580 + ),
581 + 'DATEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
582 + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEVALUE',
583 + 'argumentCount' => '1'
584 + ),
585 + 'DAVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
586 + 'functionCall' => 'PHPExcel_Calculation_Database::DAVERAGE',
587 + 'argumentCount' => '3'
588 + ),
589 + 'DAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
590 + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFMONTH',
591 + 'argumentCount' => '1'
592 + ),
593 + 'DAYS360' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
594 + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYS360',
595 + 'argumentCount' => '2,3'
596 + ),
597 + 'DB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
598 + 'functionCall' => 'PHPExcel_Calculation_Financial::DB',
599 + 'argumentCount' => '4,5'
600 + ),
601 + 'DCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
602 + 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNT',
603 + 'argumentCount' => '3'
604 + ),
605 + 'DCOUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
606 + 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNTA',
607 + 'argumentCount' => '3'
608 + ),
609 + 'DDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
610 + 'functionCall' => 'PHPExcel_Calculation_Financial::DDB',
611 + 'argumentCount' => '4,5'
612 + ),
613 + 'DEC2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
614 + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOBIN',
615 + 'argumentCount' => '1,2'
616 + ),
617 + 'DEC2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
618 + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOHEX',
619 + 'argumentCount' => '1,2'
620 + ),
621 + 'DEC2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
622 + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOOCT',
623 + 'argumentCount' => '1,2'
624 + ),
625 + 'DEGREES' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
626 + 'functionCall' => 'rad2deg',
627 + 'argumentCount' => '1'
628 + ),
629 + 'DELTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
630 + 'functionCall' => 'PHPExcel_Calculation_Engineering::DELTA',
631 + 'argumentCount' => '1,2'
632 + ),
633 + 'DEVSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
634 + 'functionCall' => 'PHPExcel_Calculation_Statistical::DEVSQ',
635 + 'argumentCount' => '1+'
636 + ),
637 + 'DGET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
638 + 'functionCall' => 'PHPExcel_Calculation_Database::DGET',
639 + 'argumentCount' => '3'
640 + ),
641 + 'DISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
642 + 'functionCall' => 'PHPExcel_Calculation_Financial::DISC',
643 + 'argumentCount' => '4,5'
644 + ),
645 + 'DMAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
646 + 'functionCall' => 'PHPExcel_Calculation_Database::DMAX',
647 + 'argumentCount' => '3'
648 + ),
649 + 'DMIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
650 + 'functionCall' => 'PHPExcel_Calculation_Database::DMIN',
651 + 'argumentCount' => '3'
652 + ),
653 + 'DOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
654 + 'functionCall' => 'PHPExcel_Calculation_TextData::DOLLAR',
655 + 'argumentCount' => '1,2'
656 + ),
657 + 'DOLLARDE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
658 + 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARDE',
659 + 'argumentCount' => '2'
660 + ),
661 + 'DOLLARFR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
662 + 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARFR',
663 + 'argumentCount' => '2'
664 + ),
665 + 'DPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
666 + 'functionCall' => 'PHPExcel_Calculation_Database::DPRODUCT',
667 + 'argumentCount' => '3'
668 + ),
669 + 'DSTDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
670 + 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEV',
671 + 'argumentCount' => '3'
672 + ),
673 + 'DSTDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
674 + 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEVP',
675 + 'argumentCount' => '3'
676 + ),
677 + 'DSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
678 + 'functionCall' => 'PHPExcel_Calculation_Database::DSUM',
679 + 'argumentCount' => '3'
680 + ),
681 + 'DURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
682 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
683 + 'argumentCount' => '5,6'
684 + ),
685 + 'DVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
686 + 'functionCall' => 'PHPExcel_Calculation_Database::DVAR',
687 + 'argumentCount' => '3'
688 + ),
689 + 'DVARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE,
690 + 'functionCall' => 'PHPExcel_Calculation_Database::DVARP',
691 + 'argumentCount' => '3'
692 + ),
693 + 'EDATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
694 + 'functionCall' => 'PHPExcel_Calculation_DateTime::EDATE',
695 + 'argumentCount' => '2'
696 + ),
697 + 'EFFECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
698 + 'functionCall' => 'PHPExcel_Calculation_Financial::EFFECT',
699 + 'argumentCount' => '2'
700 + ),
701 + 'EOMONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
702 + 'functionCall' => 'PHPExcel_Calculation_DateTime::EOMONTH',
703 + 'argumentCount' => '2'
704 + ),
705 + 'ERF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
706 + 'functionCall' => 'PHPExcel_Calculation_Engineering::ERF',
707 + 'argumentCount' => '1,2'
708 + ),
709 + 'ERFC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
710 + 'functionCall' => 'PHPExcel_Calculation_Engineering::ERFC',
711 + 'argumentCount' => '1'
712 + ),
713 + 'ERROR.TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
714 + 'functionCall' => 'PHPExcel_Calculation_Functions::ERROR_TYPE',
715 + 'argumentCount' => '1'
716 + ),
717 + 'EVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
718 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::EVEN',
719 + 'argumentCount' => '1'
720 + ),
721 + 'EXACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
722 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
723 + 'argumentCount' => '2'
724 + ),
725 + 'EXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
726 + 'functionCall' => 'exp',
727 + 'argumentCount' => '1'
728 + ),
729 + 'EXPONDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
730 + 'functionCall' => 'PHPExcel_Calculation_Statistical::EXPONDIST',
731 + 'argumentCount' => '3'
732 + ),
733 + 'FACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
734 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACT',
735 + 'argumentCount' => '1'
736 + ),
737 + 'FACTDOUBLE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
738 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACTDOUBLE',
739 + 'argumentCount' => '1'
740 + ),
741 + 'FALSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL,
742 + 'functionCall' => 'PHPExcel_Calculation_Logical::FALSE',
743 + 'argumentCount' => '0'
744 + ),
745 + 'FDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
746 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
747 + 'argumentCount' => '3'
748 + ),
749 + 'FIND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
750 + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE',
751 + 'argumentCount' => '2,3'
752 + ),
753 + 'FINDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
754 + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE',
755 + 'argumentCount' => '2,3'
756 + ),
757 + 'FINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
758 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
759 + 'argumentCount' => '3'
760 + ),
761 + 'FISHER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
762 + 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHER',
763 + 'argumentCount' => '1'
764 + ),
765 + 'FISHERINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
766 + 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHERINV',
767 + 'argumentCount' => '1'
768 + ),
769 + 'FIXED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
770 + 'functionCall' => 'PHPExcel_Calculation_TextData::FIXEDFORMAT',
771 + 'argumentCount' => '1-3'
772 + ),
773 + 'FLOOR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
774 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FLOOR',
775 + 'argumentCount' => '2'
776 + ),
777 + 'FORECAST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
778 + 'functionCall' => 'PHPExcel_Calculation_Statistical::FORECAST',
779 + 'argumentCount' => '3'
780 + ),
781 + 'FREQUENCY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
782 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
783 + 'argumentCount' => '2'
784 + ),
785 + 'FTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
786 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
787 + 'argumentCount' => '2'
788 + ),
789 + 'FV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
790 + 'functionCall' => 'PHPExcel_Calculation_Financial::FV',
791 + 'argumentCount' => '3-5'
792 + ),
793 + 'FVSCHEDULE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
794 + 'functionCall' => 'PHPExcel_Calculation_Financial::FVSCHEDULE',
795 + 'argumentCount' => '2'
796 + ),
797 + 'GAMMADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
798 + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMADIST',
799 + 'argumentCount' => '4'
800 + ),
801 + 'GAMMAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
802 + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMAINV',
803 + 'argumentCount' => '3'
804 + ),
805 + 'GAMMALN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
806 + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMALN',
807 + 'argumentCount' => '1'
808 + ),
809 + 'GCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
810 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::GCD',
811 + 'argumentCount' => '1+'
812 + ),
813 + 'GEOMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
814 + 'functionCall' => 'PHPExcel_Calculation_Statistical::GEOMEAN',
815 + 'argumentCount' => '1+'
816 + ),
817 + 'GESTEP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
818 + 'functionCall' => 'PHPExcel_Calculation_Engineering::GESTEP',
819 + 'argumentCount' => '1,2'
820 + ),
821 + 'GETPIVOTDATA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
822 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
823 + 'argumentCount' => '2+'
824 + ),
825 + 'GROWTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
826 + 'functionCall' => 'PHPExcel_Calculation_Statistical::GROWTH',
827 + 'argumentCount' => '1-4'
828 + ),
829 + 'HARMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
830 + 'functionCall' => 'PHPExcel_Calculation_Statistical::HARMEAN',
831 + 'argumentCount' => '1+'
832 + ),
833 + 'HEX2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
834 + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOBIN',
835 + 'argumentCount' => '1,2'
836 + ),
837 + 'HEX2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
838 + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTODEC',
839 + 'argumentCount' => '1'
840 + ),
841 + 'HEX2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
842 + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOOCT',
843 + 'argumentCount' => '1,2'
844 + ),
845 + 'HLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
846 + 'functionCall' => 'PHPExcel_Calculation_LookupRef::HLOOKUP',
847 + 'argumentCount' => '3,4'
848 + ),
849 + 'HOUR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
850 + 'functionCall' => 'PHPExcel_Calculation_DateTime::HOUROFDAY',
851 + 'argumentCount' => '1'
852 + ),
853 + 'HYPERLINK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
854 + 'functionCall' => 'PHPExcel_Calculation_LookupRef::HYPERLINK',
855 + 'argumentCount' => '1,2',
856 + 'passCellReference'=> TRUE
857 + ),
858 + 'HYPGEOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
859 + 'functionCall' => 'PHPExcel_Calculation_Statistical::HYPGEOMDIST',
860 + 'argumentCount' => '4'
861 + ),
862 + 'IF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL,
863 + 'functionCall' => 'PHPExcel_Calculation_Logical::STATEMENT_IF',
864 + 'argumentCount' => '1-3'
865 + ),
866 + 'IFERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL,
867 + 'functionCall' => 'PHPExcel_Calculation_Logical::IFERROR',
868 + 'argumentCount' => '2'
869 + ),
870 + 'IMABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
871 + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMABS',
872 + 'argumentCount' => '1'
873 + ),
874 + 'IMAGINARY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
875 + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMAGINARY',
876 + 'argumentCount' => '1'
877 + ),
878 + 'IMARGUMENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
879 + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMARGUMENT',
880 + 'argumentCount' => '1'
881 + ),
882 + 'IMCONJUGATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
883 + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCONJUGATE',
884 + 'argumentCount' => '1'
885 + ),
886 + 'IMCOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
887 + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCOS',
888 + 'argumentCount' => '1'
889 + ),
890 + 'IMDIV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
891 + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMDIV',
892 + 'argumentCount' => '2'
893 + ),
894 + 'IMEXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
895 + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMEXP',
896 + 'argumentCount' => '1'
897 + ),
898 + 'IMLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
899 + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLN',
900 + 'argumentCount' => '1'
901 + ),
902 + 'IMLOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
903 + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG10',
904 + 'argumentCount' => '1'
905 + ),
906 + 'IMLOG2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
907 + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG2',
908 + 'argumentCount' => '1'
909 + ),
910 + 'IMPOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
911 + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPOWER',
912 + 'argumentCount' => '2'
913 + ),
914 + 'IMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
915 + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPRODUCT',
916 + 'argumentCount' => '1+'
917 + ),
918 + 'IMREAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
919 + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMREAL',
920 + 'argumentCount' => '1'
921 + ),
922 + 'IMSIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
923 + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSIN',
924 + 'argumentCount' => '1'
925 + ),
926 + 'IMSQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
927 + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSQRT',
928 + 'argumentCount' => '1'
929 + ),
930 + 'IMSUB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
931 + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUB',
932 + 'argumentCount' => '2'
933 + ),
934 + 'IMSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
935 + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUM',
936 + 'argumentCount' => '1+'
937 + ),
938 + 'INDEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
939 + 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDEX',
940 + 'argumentCount' => '1-4'
941 + ),
942 + 'INDIRECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
943 + 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDIRECT',
944 + 'argumentCount' => '1,2',
945 + 'passCellReference'=> TRUE
946 + ),
947 + 'INFO' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
948 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
949 + 'argumentCount' => '1'
950 + ),
951 + 'INT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
952 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::INT',
953 + 'argumentCount' => '1'
954 + ),
955 + 'INTERCEPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
956 + 'functionCall' => 'PHPExcel_Calculation_Statistical::INTERCEPT',
957 + 'argumentCount' => '2'
958 + ),
959 + 'INTRATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
960 + 'functionCall' => 'PHPExcel_Calculation_Financial::INTRATE',
961 + 'argumentCount' => '4,5'
962 + ),
963 + 'IPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
964 + 'functionCall' => 'PHPExcel_Calculation_Financial::IPMT',
965 + 'argumentCount' => '4-6'
966 + ),
967 + 'IRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
968 + 'functionCall' => 'PHPExcel_Calculation_Financial::IRR',
969 + 'argumentCount' => '1,2'
970 + ),
971 + 'ISBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
972 + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_BLANK',
973 + 'argumentCount' => '1'
974 + ),
975 + 'ISERR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
976 + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERR',
977 + 'argumentCount' => '1'
978 + ),
979 + 'ISERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
980 + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERROR',
981 + 'argumentCount' => '1'
982 + ),
983 + 'ISEVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
984 + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_EVEN',
985 + 'argumentCount' => '1'
986 + ),
987 + 'ISLOGICAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
988 + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_LOGICAL',
989 + 'argumentCount' => '1'
990 + ),
991 + 'ISNA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
992 + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NA',
993 + 'argumentCount' => '1'
994 + ),
995 + 'ISNONTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
996 + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NONTEXT',
997 + 'argumentCount' => '1'
998 + ),
999 + 'ISNUMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1000 + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NUMBER',
1001 + 'argumentCount' => '1'
1002 + ),
1003 + 'ISODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1004 + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ODD',
1005 + 'argumentCount' => '1'
1006 + ),
1007 + 'ISPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1008 + 'functionCall' => 'PHPExcel_Calculation_Financial::ISPMT',
1009 + 'argumentCount' => '4'
1010 + ),
1011 + 'ISREF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1012 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1013 + 'argumentCount' => '1'
1014 + ),
1015 + 'ISTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1016 + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_TEXT',
1017 + 'argumentCount' => '1'
1018 + ),
1019 + 'JIS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1020 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1021 + 'argumentCount' => '1'
1022 + ),
1023 + 'KURT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1024 + 'functionCall' => 'PHPExcel_Calculation_Statistical::KURT',
1025 + 'argumentCount' => '1+'
1026 + ),
1027 + 'LARGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1028 + 'functionCall' => 'PHPExcel_Calculation_Statistical::LARGE',
1029 + 'argumentCount' => '2'
1030 + ),
1031 + 'LCM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1032 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::LCM',
1033 + 'argumentCount' => '1+'
1034 + ),
1035 + 'LEFT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1036 + 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT',
1037 + 'argumentCount' => '1,2'
1038 + ),
1039 + 'LEFTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1040 + 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT',
1041 + 'argumentCount' => '1,2'
1042 + ),
1043 + 'LEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1044 + 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH',
1045 + 'argumentCount' => '1'
1046 + ),
1047 + 'LENB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1048 + 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH',
1049 + 'argumentCount' => '1'
1050 + ),
1051 + 'LINEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1052 + 'functionCall' => 'PHPExcel_Calculation_Statistical::LINEST',
1053 + 'argumentCount' => '1-4'
1054 + ),
1055 + 'LN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1056 + 'functionCall' => 'log',
1057 + 'argumentCount' => '1'
1058 + ),
1059 + 'LOG' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1060 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::LOG_BASE',
1061 + 'argumentCount' => '1,2'
1062 + ),
1063 + 'LOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1064 + 'functionCall' => 'log10',
1065 + 'argumentCount' => '1'
1066 + ),
1067 + 'LOGEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1068 + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGEST',
1069 + 'argumentCount' => '1-4'
1070 + ),
1071 + 'LOGINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1072 + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGINV',
1073 + 'argumentCount' => '3'
1074 + ),
1075 + 'LOGNORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1076 + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGNORMDIST',
1077 + 'argumentCount' => '3'
1078 + ),
1079 + 'LOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
1080 + 'functionCall' => 'PHPExcel_Calculation_LookupRef::LOOKUP',
1081 + 'argumentCount' => '2,3'
1082 + ),
1083 + 'LOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1084 + 'functionCall' => 'PHPExcel_Calculation_TextData::LOWERCASE',
1085 + 'argumentCount' => '1'
1086 + ),
1087 + 'MATCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
1088 + 'functionCall' => 'PHPExcel_Calculation_LookupRef::MATCH',
1089 + 'argumentCount' => '2,3'
1090 + ),
1091 + 'MAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1092 + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAX',
1093 + 'argumentCount' => '1+'
1094 + ),
1095 + 'MAXA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1096 + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXA',
1097 + 'argumentCount' => '1+'
1098 + ),
1099 + 'MAXIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1100 + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXIF',
1101 + 'argumentCount' => '2+'
1102 + ),
1103 + 'MDETERM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1104 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MDETERM',
1105 + 'argumentCount' => '1'
1106 + ),
1107 + 'MDURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1108 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1109 + 'argumentCount' => '5,6'
1110 + ),
1111 + 'MEDIAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1112 + 'functionCall' => 'PHPExcel_Calculation_Statistical::MEDIAN',
1113 + 'argumentCount' => '1+'
1114 + ),
1115 + 'MEDIANIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1116 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1117 + 'argumentCount' => '2+'
1118 + ),
1119 + 'MID' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1120 + 'functionCall' => 'PHPExcel_Calculation_TextData::MID',
1121 + 'argumentCount' => '3'
1122 + ),
1123 + 'MIDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1124 + 'functionCall' => 'PHPExcel_Calculation_TextData::MID',
1125 + 'argumentCount' => '3'
1126 + ),
1127 + 'MIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1128 + 'functionCall' => 'PHPExcel_Calculation_Statistical::MIN',
1129 + 'argumentCount' => '1+'
1130 + ),
1131 + 'MINA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1132 + 'functionCall' => 'PHPExcel_Calculation_Statistical::MINA',
1133 + 'argumentCount' => '1+'
1134 + ),
1135 + 'MINIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1136 + 'functionCall' => 'PHPExcel_Calculation_Statistical::MINIF',
1137 + 'argumentCount' => '2+'
1138 + ),
1139 + 'MINUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1140 + 'functionCall' => 'PHPExcel_Calculation_DateTime::MINUTEOFHOUR',
1141 + 'argumentCount' => '1'
1142 + ),
1143 + 'MINVERSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1144 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MINVERSE',
1145 + 'argumentCount' => '1'
1146 + ),
1147 + 'MIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1148 + 'functionCall' => 'PHPExcel_Calculation_Financial::MIRR',
1149 + 'argumentCount' => '3'
1150 + ),
1151 + 'MMULT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1152 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MMULT',
1153 + 'argumentCount' => '2'
1154 + ),
1155 + 'MOD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1156 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MOD',
1157 + 'argumentCount' => '2'
1158 + ),
1159 + 'MODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1160 + 'functionCall' => 'PHPExcel_Calculation_Statistical::MODE',
1161 + 'argumentCount' => '1+'
1162 + ),
1163 + 'MONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1164 + 'functionCall' => 'PHPExcel_Calculation_DateTime::MONTHOFYEAR',
1165 + 'argumentCount' => '1'
1166 + ),
1167 + 'MROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1168 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MROUND',
1169 + 'argumentCount' => '2'
1170 + ),
1171 + 'MULTINOMIAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1172 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MULTINOMIAL',
1173 + 'argumentCount' => '1+'
1174 + ),
1175 + 'N' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1176 + 'functionCall' => 'PHPExcel_Calculation_Functions::N',
1177 + 'argumentCount' => '1'
1178 + ),
1179 + 'NA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1180 + 'functionCall' => 'PHPExcel_Calculation_Functions::NA',
1181 + 'argumentCount' => '0'
1182 + ),
1183 + 'NEGBINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1184 + 'functionCall' => 'PHPExcel_Calculation_Statistical::NEGBINOMDIST',
1185 + 'argumentCount' => '3'
1186 + ),
1187 + 'NETWORKDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1188 + 'functionCall' => 'PHPExcel_Calculation_DateTime::NETWORKDAYS',
1189 + 'argumentCount' => '2+'
1190 + ),
1191 + 'NOMINAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1192 + 'functionCall' => 'PHPExcel_Calculation_Financial::NOMINAL',
1193 + 'argumentCount' => '2'
1194 + ),
1195 + 'NORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1196 + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMDIST',
1197 + 'argumentCount' => '4'
1198 + ),
1199 + 'NORMINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1200 + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMINV',
1201 + 'argumentCount' => '3'
1202 + ),
1203 + 'NORMSDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1204 + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSDIST',
1205 + 'argumentCount' => '1'
1206 + ),
1207 + 'NORMSINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1208 + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSINV',
1209 + 'argumentCount' => '1'
1210 + ),
1211 + 'NOT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL,
1212 + 'functionCall' => 'PHPExcel_Calculation_Logical::NOT',
1213 + 'argumentCount' => '1'
1214 + ),
1215 + 'NOW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1216 + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATETIMENOW',
1217 + 'argumentCount' => '0'
1218 + ),
1219 + 'NPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1220 + 'functionCall' => 'PHPExcel_Calculation_Financial::NPER',
1221 + 'argumentCount' => '3-5'
1222 + ),
1223 + 'NPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1224 + 'functionCall' => 'PHPExcel_Calculation_Financial::NPV',
1225 + 'argumentCount' => '2+'
1226 + ),
1227 + 'OCT2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1228 + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOBIN',
1229 + 'argumentCount' => '1,2'
1230 + ),
1231 + 'OCT2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1232 + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTODEC',
1233 + 'argumentCount' => '1'
1234 + ),
1235 + 'OCT2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING,
1236 + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOHEX',
1237 + 'argumentCount' => '1,2'
1238 + ),
1239 + 'ODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1240 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ODD',
1241 + 'argumentCount' => '1'
1242 + ),
1243 + 'ODDFPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1244 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1245 + 'argumentCount' => '8,9'
1246 + ),
1247 + 'ODDFYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1248 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1249 + 'argumentCount' => '8,9'
1250 + ),
1251 + 'ODDLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1252 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1253 + 'argumentCount' => '7,8'
1254 + ),
1255 + 'ODDLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1256 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1257 + 'argumentCount' => '7,8'
1258 + ),
1259 + 'OFFSET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
1260 + 'functionCall' => 'PHPExcel_Calculation_LookupRef::OFFSET',
1261 + 'argumentCount' => '3,5',
1262 + 'passCellReference'=> TRUE,
1263 + 'passByReference' => array(TRUE)
1264 + ),
1265 + 'OR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL,
1266 + 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_OR',
1267 + 'argumentCount' => '1+'
1268 + ),
1269 + 'PEARSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1270 + 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL',
1271 + 'argumentCount' => '2'
1272 + ),
1273 + 'PERCENTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1274 + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTILE',
1275 + 'argumentCount' => '2'
1276 + ),
1277 + 'PERCENTRANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1278 + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTRANK',
1279 + 'argumentCount' => '2,3'
1280 + ),
1281 + 'PERMUT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1282 + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERMUT',
1283 + 'argumentCount' => '2'
1284 + ),
1285 + 'PHONETIC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1286 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1287 + 'argumentCount' => '1'
1288 + ),
1289 + 'PI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1290 + 'functionCall' => 'pi',
1291 + 'argumentCount' => '0'
1292 + ),
1293 + 'PMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1294 + 'functionCall' => 'PHPExcel_Calculation_Financial::PMT',
1295 + 'argumentCount' => '3-5'
1296 + ),
1297 + 'POISSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1298 + 'functionCall' => 'PHPExcel_Calculation_Statistical::POISSON',
1299 + 'argumentCount' => '3'
1300 + ),
1301 + 'POWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1302 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::POWER',
1303 + 'argumentCount' => '2'
1304 + ),
1305 + 'PPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1306 + 'functionCall' => 'PHPExcel_Calculation_Financial::PPMT',
1307 + 'argumentCount' => '4-6'
1308 + ),
1309 + 'PRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1310 + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICE',
1311 + 'argumentCount' => '6,7'
1312 + ),
1313 + 'PRICEDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1314 + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEDISC',
1315 + 'argumentCount' => '4,5'
1316 + ),
1317 + 'PRICEMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1318 + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEMAT',
1319 + 'argumentCount' => '5,6'
1320 + ),
1321 + 'PROB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1322 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1323 + 'argumentCount' => '3,4'
1324 + ),
1325 + 'PRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1326 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::PRODUCT',
1327 + 'argumentCount' => '1+'
1328 + ),
1329 + 'PROPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1330 + 'functionCall' => 'PHPExcel_Calculation_TextData::PROPERCASE',
1331 + 'argumentCount' => '1'
1332 + ),
1333 + 'PV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1334 + 'functionCall' => 'PHPExcel_Calculation_Financial::PV',
1335 + 'argumentCount' => '3-5'
1336 + ),
1337 + 'QUARTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1338 + 'functionCall' => 'PHPExcel_Calculation_Statistical::QUARTILE',
1339 + 'argumentCount' => '2'
1340 + ),
1341 + 'QUOTIENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1342 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::QUOTIENT',
1343 + 'argumentCount' => '2'
1344 + ),
1345 + 'RADIANS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1346 + 'functionCall' => 'deg2rad',
1347 + 'argumentCount' => '1'
1348 + ),
1349 + 'RAND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1350 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND',
1351 + 'argumentCount' => '0'
1352 + ),
1353 + 'RANDBETWEEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1354 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND',
1355 + 'argumentCount' => '2'
1356 + ),
1357 + 'RANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1358 + 'functionCall' => 'PHPExcel_Calculation_Statistical::RANK',
1359 + 'argumentCount' => '2,3'
1360 + ),
1361 + 'RATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1362 + 'functionCall' => 'PHPExcel_Calculation_Financial::RATE',
1363 + 'argumentCount' => '3-6'
1364 + ),
1365 + 'RECEIVED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1366 + 'functionCall' => 'PHPExcel_Calculation_Financial::RECEIVED',
1367 + 'argumentCount' => '4-5'
1368 + ),
1369 + 'REPLACE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1370 + 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE',
1371 + 'argumentCount' => '4'
1372 + ),
1373 + 'REPLACEB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1374 + 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE',
1375 + 'argumentCount' => '4'
1376 + ),
1377 + 'REPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1378 + 'functionCall' => 'str_repeat',
1379 + 'argumentCount' => '2'
1380 + ),
1381 + 'RIGHT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1382 + 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT',
1383 + 'argumentCount' => '1,2'
1384 + ),
1385 + 'RIGHTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1386 + 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT',
1387 + 'argumentCount' => '1,2'
1388 + ),
1389 + 'ROMAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1390 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROMAN',
1391 + 'argumentCount' => '1,2'
1392 + ),
1393 + 'ROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1394 + 'functionCall' => 'round',
1395 + 'argumentCount' => '2'
1396 + ),
1397 + 'ROUNDDOWN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1398 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDDOWN',
1399 + 'argumentCount' => '2'
1400 + ),
1401 + 'ROUNDUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1402 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDUP',
1403 + 'argumentCount' => '2'
1404 + ),
1405 + 'ROW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
1406 + 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROW',
1407 + 'argumentCount' => '-1',
1408 + 'passByReference' => array(TRUE)
1409 + ),
1410 + 'ROWS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
1411 + 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROWS',
1412 + 'argumentCount' => '1'
1413 + ),
1414 + 'RSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1415 + 'functionCall' => 'PHPExcel_Calculation_Statistical::RSQ',
1416 + 'argumentCount' => '2'
1417 + ),
1418 + 'RTD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
1419 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1420 + 'argumentCount' => '1+'
1421 + ),
1422 + 'SEARCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1423 + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE',
1424 + 'argumentCount' => '2,3'
1425 + ),
1426 + 'SEARCHB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1427 + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE',
1428 + 'argumentCount' => '2,3'
1429 + ),
1430 + 'SECOND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1431 + 'functionCall' => 'PHPExcel_Calculation_DateTime::SECONDOFMINUTE',
1432 + 'argumentCount' => '1'
1433 + ),
1434 + 'SERIESSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1435 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SERIESSUM',
1436 + 'argumentCount' => '4'
1437 + ),
1438 + 'SIGN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1439 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SIGN',
1440 + 'argumentCount' => '1'
1441 + ),
1442 + 'SIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1443 + 'functionCall' => 'sin',
1444 + 'argumentCount' => '1'
1445 + ),
1446 + 'SINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1447 + 'functionCall' => 'sinh',
1448 + 'argumentCount' => '1'
1449 + ),
1450 + 'SKEW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1451 + 'functionCall' => 'PHPExcel_Calculation_Statistical::SKEW',
1452 + 'argumentCount' => '1+'
1453 + ),
1454 + 'SLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1455 + 'functionCall' => 'PHPExcel_Calculation_Financial::SLN',
1456 + 'argumentCount' => '3'
1457 + ),
1458 + 'SLOPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1459 + 'functionCall' => 'PHPExcel_Calculation_Statistical::SLOPE',
1460 + 'argumentCount' => '2'
1461 + ),
1462 + 'SMALL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1463 + 'functionCall' => 'PHPExcel_Calculation_Statistical::SMALL',
1464 + 'argumentCount' => '2'
1465 + ),
1466 + 'SQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1467 + 'functionCall' => 'sqrt',
1468 + 'argumentCount' => '1'
1469 + ),
1470 + 'SQRTPI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1471 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SQRTPI',
1472 + 'argumentCount' => '1'
1473 + ),
1474 + 'STANDARDIZE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1475 + 'functionCall' => 'PHPExcel_Calculation_Statistical::STANDARDIZE',
1476 + 'argumentCount' => '3'
1477 + ),
1478 + 'STDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1479 + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEV',
1480 + 'argumentCount' => '1+'
1481 + ),
1482 + 'STDEVA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1483 + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVA',
1484 + 'argumentCount' => '1+'
1485 + ),
1486 + 'STDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1487 + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVP',
1488 + 'argumentCount' => '1+'
1489 + ),
1490 + 'STDEVPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1491 + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVPA',
1492 + 'argumentCount' => '1+'
1493 + ),
1494 + 'STEYX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1495 + 'functionCall' => 'PHPExcel_Calculation_Statistical::STEYX',
1496 + 'argumentCount' => '2'
1497 + ),
1498 + 'SUBSTITUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1499 + 'functionCall' => 'PHPExcel_Calculation_TextData::SUBSTITUTE',
1500 + 'argumentCount' => '3,4'
1501 + ),
1502 + 'SUBTOTAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1503 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUBTOTAL',
1504 + 'argumentCount' => '2+'
1505 + ),
1506 + 'SUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1507 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUM',
1508 + 'argumentCount' => '1+'
1509 + ),
1510 + 'SUMIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1511 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMIF',
1512 + 'argumentCount' => '2,3'
1513 + ),
1514 + 'SUMIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1515 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1516 + 'argumentCount' => '?'
1517 + ),
1518 + 'SUMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1519 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMPRODUCT',
1520 + 'argumentCount' => '1+'
1521 + ),
1522 + 'SUMSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1523 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMSQ',
1524 + 'argumentCount' => '1+'
1525 + ),
1526 + 'SUMX2MY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1527 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2MY2',
1528 + 'argumentCount' => '2'
1529 + ),
1530 + 'SUMX2PY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1531 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2PY2',
1532 + 'argumentCount' => '2'
1533 + ),
1534 + 'SUMXMY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1535 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMXMY2',
1536 + 'argumentCount' => '2'
1537 + ),
1538 + 'SYD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1539 + 'functionCall' => 'PHPExcel_Calculation_Financial::SYD',
1540 + 'argumentCount' => '4'
1541 + ),
1542 + 'T' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1543 + 'functionCall' => 'PHPExcel_Calculation_TextData::RETURNSTRING',
1544 + 'argumentCount' => '1'
1545 + ),
1546 + 'TAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1547 + 'functionCall' => 'tan',
1548 + 'argumentCount' => '1'
1549 + ),
1550 + 'TANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1551 + 'functionCall' => 'tanh',
1552 + 'argumentCount' => '1'
1553 + ),
1554 + 'TBILLEQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1555 + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLEQ',
1556 + 'argumentCount' => '3'
1557 + ),
1558 + 'TBILLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1559 + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLPRICE',
1560 + 'argumentCount' => '3'
1561 + ),
1562 + 'TBILLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1563 + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLYIELD',
1564 + 'argumentCount' => '3'
1565 + ),
1566 + 'TDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1567 + 'functionCall' => 'PHPExcel_Calculation_Statistical::TDIST',
1568 + 'argumentCount' => '3'
1569 + ),
1570 + 'TEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1571 + 'functionCall' => 'PHPExcel_Calculation_TextData::TEXTFORMAT',
1572 + 'argumentCount' => '2'
1573 + ),
1574 + 'TIME' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1575 + 'functionCall' => 'PHPExcel_Calculation_DateTime::TIME',
1576 + 'argumentCount' => '3'
1577 + ),
1578 + 'TIMEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1579 + 'functionCall' => 'PHPExcel_Calculation_DateTime::TIMEVALUE',
1580 + 'argumentCount' => '1'
1581 + ),
1582 + 'TINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1583 + 'functionCall' => 'PHPExcel_Calculation_Statistical::TINV',
1584 + 'argumentCount' => '2'
1585 + ),
1586 + 'TODAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1587 + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATENOW',
1588 + 'argumentCount' => '0'
1589 + ),
1590 + 'TRANSPOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
1591 + 'functionCall' => 'PHPExcel_Calculation_LookupRef::TRANSPOSE',
1592 + 'argumentCount' => '1'
1593 + ),
1594 + 'TREND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1595 + 'functionCall' => 'PHPExcel_Calculation_Statistical::TREND',
1596 + 'argumentCount' => '1-4'
1597 + ),
1598 + 'TRIM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1599 + 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMSPACES',
1600 + 'argumentCount' => '1'
1601 + ),
1602 + 'TRIMMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1603 + 'functionCall' => 'PHPExcel_Calculation_Statistical::TRIMMEAN',
1604 + 'argumentCount' => '2'
1605 + ),
1606 + 'TRUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL,
1607 + 'functionCall' => 'PHPExcel_Calculation_Logical::TRUE',
1608 + 'argumentCount' => '0'
1609 + ),
1610 + 'TRUNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,
1611 + 'functionCall' => 'PHPExcel_Calculation_MathTrig::TRUNC',
1612 + 'argumentCount' => '1,2'
1613 + ),
1614 + 'TTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1615 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1616 + 'argumentCount' => '4'
1617 + ),
1618 + 'TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1619 + 'functionCall' => 'PHPExcel_Calculation_Functions::TYPE',
1620 + 'argumentCount' => '1'
1621 + ),
1622 + 'UPPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1623 + 'functionCall' => 'PHPExcel_Calculation_TextData::UPPERCASE',
1624 + 'argumentCount' => '1'
1625 + ),
1626 + 'USDOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1627 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1628 + 'argumentCount' => '2'
1629 + ),
1630 + 'VALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,
1631 + 'functionCall' => 'PHPExcel_Calculation_TextData::VALUE',
1632 + 'argumentCount' => '1'
1633 + ),
1634 + 'VAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1635 + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARFunc',
1636 + 'argumentCount' => '1+'
1637 + ),
1638 + 'VARA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1639 + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARA',
1640 + 'argumentCount' => '1+'
1641 + ),
1642 + 'VARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1643 + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARP',
1644 + 'argumentCount' => '1+'
1645 + ),
1646 + 'VARPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1647 + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARPA',
1648 + 'argumentCount' => '1+'
1649 + ),
1650 + 'VDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1651 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1652 + 'argumentCount' => '5-7'
1653 + ),
1654 + 'VERSION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
1655 + 'functionCall' => 'PHPExcel_Calculation_Functions::VERSION',
1656 + 'argumentCount' => '0'
1657 + ),
1658 + 'VLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
1659 + 'functionCall' => 'PHPExcel_Calculation_LookupRef::VLOOKUP',
1660 + 'argumentCount' => '3,4'
1661 + ),
1662 + 'WEEKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1663 + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFWEEK',
1664 + 'argumentCount' => '1,2'
1665 + ),
1666 + 'WEEKNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1667 + 'functionCall' => 'PHPExcel_Calculation_DateTime::WEEKOFYEAR',
1668 + 'argumentCount' => '1,2'
1669 + ),
1670 + 'WEIBULL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1671 + 'functionCall' => 'PHPExcel_Calculation_Statistical::WEIBULL',
1672 + 'argumentCount' => '4'
1673 + ),
1674 + 'WORKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1675 + 'functionCall' => 'PHPExcel_Calculation_DateTime::WORKDAY',
1676 + 'argumentCount' => '2+'
1677 + ),
1678 + 'XIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1679 + 'functionCall' => 'PHPExcel_Calculation_Financial::XIRR',
1680 + 'argumentCount' => '2,3'
1681 + ),
1682 + 'XNPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1683 + 'functionCall' => 'PHPExcel_Calculation_Financial::XNPV',
1684 + 'argumentCount' => '3'
1685 + ),
1686 + 'YEAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1687 + 'functionCall' => 'PHPExcel_Calculation_DateTime::YEAR',
1688 + 'argumentCount' => '1'
1689 + ),
1690 + 'YEARFRAC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,
1691 + 'functionCall' => 'PHPExcel_Calculation_DateTime::YEARFRAC',
1692 + 'argumentCount' => '2,3'
1693 + ),
1694 + 'YIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1695 + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY',
1696 + 'argumentCount' => '6,7'
1697 + ),
1698 + 'YIELDDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1699 + 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDDISC',
1700 + 'argumentCount' => '4,5'
1701 + ),
1702 + 'YIELDMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL,
1703 + 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDMAT',
1704 + 'argumentCount' => '5,6'
1705 + ),
1706 + 'ZTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
1707 + 'functionCall' => 'PHPExcel_Calculation_Statistical::ZTEST',
1708 + 'argumentCount' => '2-3'
1709 + )
1710 + );
1711 +
1712 +
1713 + // Internal functions used for special control purposes
1714 + private static $_controlFunctions = array(
1715 + 'MKMATRIX' => array('argumentCount' => '*',
1716 + 'functionCall' => 'self::_mkMatrix'
1717 + )
1718 + );
1719 +
1720 +
1721 +
1722 +
1723 + private function __construct(PHPExcel $workbook = NULL) {
1724 + $setPrecision = (PHP_INT_SIZE == 4) ? 14 : 16;
1725 + $this->_savedPrecision = ini_get('precision');
1726 + if ($this->_savedPrecision < $setPrecision) {
1727 + ini_set('precision',$setPrecision);
1728 + }
1729 + $this->delta = 1 * pow(10, -$setPrecision);
1730 +
1731 + if ($workbook !== NULL) {
1732 + self::$_workbookSets[$workbook->getID()] = $this;
1733 + }
1734 +
1735 + $this->_workbook = $workbook;
1736 + $this->_cyclicReferenceStack = new PHPExcel_CalcEngine_CyclicReferenceStack();
1737 + $this->_debugLog = new PHPExcel_CalcEngine_Logger($this->_cyclicReferenceStack);
1738 + } // function __construct()
1739 +
1740 +
1741 + public function __destruct() {
1742 + if ($this->_savedPrecision != ini_get('precision')) {
1743 + ini_set('precision',$this->_savedPrecision);
1744 + }
1745 + }
1746 +
1747 + private static function _loadLocales() {
1748 + $localeFileDirectory = PHPEXCEL_ROOT.'PHPExcel/locale/';
1749 + foreach (glob($localeFileDirectory.'/*',GLOB_ONLYDIR) as $filename) {
1750 + $filename = substr($filename,strlen($localeFileDirectory)+1);
1751 + if ($filename != 'en') {
1752 + self::$_validLocaleLanguages[] = $filename;
1753 + }
1754 + }
1755 + }
1756 +
1757 + /**
1758 + * Get an instance of this class
1759 + *
1760 + * @access public
1761 + * @param PHPExcel $workbook Injected workbook for working with a PHPExcel object,
1762 + * or NULL to create a standalone claculation engine
1763 + * @return PHPExcel_Calculation
1764 + */
1765 + public static function getInstance(PHPExcel $workbook = NULL) {
1766 + if ($workbook !== NULL) {
1767 + if (isset(self::$_workbookSets[$workbook->getID()])) {
1768 + return self::$_workbookSets[$workbook->getID()];
1769 + }
1770 + return new PHPExcel_Calculation($workbook);
1771 + }
1772 +
1773 + if (!isset(self::$_instance) || (self::$_instance === NULL)) {
1774 + self::$_instance = new PHPExcel_Calculation();
1775 + }
1776 +
1777 + return self::$_instance;
1778 + } // function getInstance()
1779 +
1780 + /**
1781 + * Unset an instance of this class
1782 + *
1783 + * @access public
1784 + * @param PHPExcel $workbook Injected workbook identifying the instance to unset
1785 + */
1786 + public static function unsetInstance(PHPExcel $workbook = NULL) {
1787 + if ($workbook !== NULL) {
1788 + if (isset(self::$_workbookSets[$workbook->getID()])) {
1789 + unset(self::$_workbookSets[$workbook->getID()]);
1790 + }
1791 + }
2113 1792 }
2114 1793
2115 - /**
2116 - * Unset an instance of this class
2117 - *
2118 - * @access public
2119 - */
2120 - public function __destruct()
2121 - {
2122 - $this->workbook = null;
2123 - }
1794 + /**
1795 + * Flush the calculation cache for any existing instance of this class
1796 + * but only if a PHPExcel_Calculation instance exists
1797 + *
1798 + * @access public
1799 + * @return null
1800 + */
1801 + public function flushInstance() {
1802 + $this->clearCalculationCache();
1803 + } // function flushInstance()
2124 1804
2125 - /**
2126 - * Flush the calculation cache for any existing instance of this class
2127 - * but only if a PHPExcel_Calculation instance exists
2128 - *
2129 - * @access public
2130 - * @return null
2131 - */
2132 - public function flushInstance()
2133 - {
2134 - $this->clearCalculationCache();
2135 - }
2136 1805
1806 + /**
1807 + * Get the debuglog for this claculation engine instance
1808 + *
1809 + * @access public
1810 + * @return PHPExcel_CalcEngine_Logger
1811 + */
1812 + public function getDebugLog() {
1813 + return $this->_debugLog;
1814 + }
2137 1815
2138 - /**
2139 - * Get the debuglog for this claculation engine instance
2140 - *
2141 - * @access public
2142 - * @return PHPExcel_CalcEngine_Logger
2143 - */
2144 - public function getDebugLog()
2145 - {
2146 - return $this->_debugLog;
2147 - }
1816 + /**
1817 + * __clone implementation. Cloning should not be allowed in a Singleton!
1818 + *
1819 + * @access public
1820 + * @throws PHPExcel_Calculation_Exception
1821 + */
1822 + public final function __clone() {
1823 + throw new PHPExcel_Calculation_Exception ('Cloning the calculation engine is not allowed!');
1824 + } // function __clone()
2148 1825
2149 - /**
2150 - * __clone implementation. Cloning should not be allowed in a Singleton!
2151 - *
2152 - * @access public
2153 - * @throws PHPExcel_Calculation_Exception
2154 - */
2155 - final public function __clone()
2156 - {
2157 - throw new PHPExcel_Calculation_Exception('Cloning the calculation engine is not allowed!');
2158 - }
2159 1826
1827 + /**
1828 + * Return the locale-specific translation of TRUE
1829 + *
1830 + * @access public
1831 + * @return string locale-specific translation of TRUE
1832 + */
1833 + public static function getTRUE() {
1834 + return self::$_localeBoolean['TRUE'];
1835 + }
2160 1836
2161 - /**
2162 - * Return the locale-specific translation of TRUE
2163 - *
2164 - * @access public
2165 - * @return string locale-specific translation of TRUE
2166 - */
2167 - public static function getTRUE()
2168 - {
2169 - return self::$localeBoolean['TRUE'];
2170 - }
1837 + /**
1838 + * Return the locale-specific translation of FALSE
1839 + *
1840 + * @access public
1841 + * @return string locale-specific translation of FALSE
1842 + */
1843 + public static function getFALSE() {
1844 + return self::$_localeBoolean['FALSE'];
1845 + }
2171 1846
2172 - /**
2173 - * Return the locale-specific translation of FALSE
2174 - *
2175 - * @access public
2176 - * @return string locale-specific translation of FALSE
2177 - */
2178 - public static function getFALSE()
2179 - {
2180 - return self::$localeBoolean['FALSE'];
2181 - }
1847 + /**
1848 + * Set the Array Return Type (Array or Value of first element in the array)
1849 + *
1850 + * @access public
1851 + * @param string $returnType Array return type
1852 + * @return boolean Success or failure
1853 + */
1854 + public static function setArrayReturnType($returnType) {
1855 + if (($returnType == self::RETURN_ARRAY_AS_VALUE) ||
1856 + ($returnType == self::RETURN_ARRAY_AS_ERROR) ||
1857 + ($returnType == self::RETURN_ARRAY_AS_ARRAY)) {
1858 + self::$returnArrayAsType = $returnType;
1859 + return TRUE;
1860 + }
1861 + return FALSE;
1862 + } // function setArrayReturnType()
2182 1863
2183 - /**
2184 - * Set the Array Return Type (Array or Value of first element in the array)
2185 - *
2186 - * @access public
2187 - * @param string $returnType Array return type
2188 - * @return boolean Success or failure
2189 - */
2190 - public static function setArrayReturnType($returnType)
2191 - {
2192 - if (($returnType == self::RETURN_ARRAY_AS_VALUE) ||
2193 - ($returnType == self::RETURN_ARRAY_AS_ERROR) ||
2194 - ($returnType == self::RETURN_ARRAY_AS_ARRAY)) {
2195 - self::$returnArrayAsType = $returnType;
2196 - return true;
2197 - }
2198 - return false;
2199 - }
2200 1864
1865 + /**
1866 + * Return the Array Return Type (Array or Value of first element in the array)
1867 + *
1868 + * @access public
1869 + * @return string $returnType Array return type
1870 + */
1871 + public static function getArrayReturnType() {
1872 + return self::$returnArrayAsType;
1873 + } // function getArrayReturnType()
2201 1874
2202 - /**
2203 - * Return the Array Return Type (Array or Value of first element in the array)
2204 - *
2205 - * @access public
2206 - * @return string $returnType Array return type
2207 - */
2208 - public static function getArrayReturnType()
2209 - {
2210 - return self::$returnArrayAsType;
2211 - }
2212 1875
1876 + /**
1877 + * Is calculation caching enabled?
1878 + *
1879 + * @access public
1880 + * @return boolean
1881 + */
1882 + public function getCalculationCacheEnabled() {
1883 + return $this->_calculationCacheEnabled;
1884 + } // function getCalculationCacheEnabled()
2213 1885
2214 - /**
2215 - * Is calculation caching enabled?
2216 - *
2217 - * @access public
2218 - * @return boolean
2219 - */
2220 - public function getCalculationCacheEnabled()
2221 - {
2222 - return $this->calculationCacheEnabled;
2223 - }
1886 + /**
1887 + * Enable/disable calculation cache
1888 + *
1889 + * @access public
1890 + * @param boolean $pValue
1891 + */
1892 + public function setCalculationCacheEnabled($pValue = TRUE) {
1893 + $this->_calculationCacheEnabled = $pValue;
1894 + $this->clearCalculationCache();
1895 + } // function setCalculationCacheEnabled()
2224 1896
2225 - /**
2226 - * Enable/disable calculation cache
2227 - *
2228 - * @access public
2229 - * @param boolean $pValue
2230 - */
2231 - public function setCalculationCacheEnabled($pValue = true)
2232 - {
2233 - $this->calculationCacheEnabled = $pValue;
2234 - $this->clearCalculationCache();
2235 - }
2236 1897
1898 + /**
1899 + * Enable calculation cache
1900 + */
1901 + public function enableCalculationCache() {
1902 + $this->setCalculationCacheEnabled(TRUE);
1903 + } // function enableCalculationCache()
2237 1904
2238 - /**
2239 - * Enable calculation cache
2240 - */
2241 - public function enableCalculationCache()
2242 - {
2243 - $this->setCalculationCacheEnabled(true);
2244 - }
2245 1905
1906 + /**
1907 + * Disable calculation cache
1908 + */
1909 + public function disableCalculationCache() {
1910 + $this->setCalculationCacheEnabled(FALSE);
1911 + } // function disableCalculationCache()
2246 1912
2247 - /**
2248 - * Disable calculation cache
2249 - */
2250 - public function disableCalculationCache()
2251 - {
2252 - $this->setCalculationCacheEnabled(false);
2253 - }
2254 1913
1914 + /**
1915 + * Clear calculation cache
1916 + */
1917 + public function clearCalculationCache() {
1918 + $this->_calculationCache = array();
1919 + } // function clearCalculationCache()
2255 1920
2256 - /**
2257 - * Clear calculation cache
2258 - */
2259 - public function clearCalculationCache()
2260 - {
2261 - $this->calculationCache = array();
2262 - }
1921 + /**
1922 + * Clear calculation cache for a specified worksheet
1923 + *
1924 + * @param string $worksheetName
1925 + */
1926 + public function clearCalculationCacheForWorksheet($worksheetName) {
1927 + if (isset($this->_calculationCache[$worksheetName])) {
1928 + unset($this->_calculationCache[$worksheetName]);
1929 + }
1930 + } // function clearCalculationCacheForWorksheet()
2263 1931
2264 - /**
2265 - * Clear calculation cache for a specified worksheet
2266 - *
2267 - * @param string $worksheetName
2268 - */
2269 - public function clearCalculationCacheForWorksheet($worksheetName)
2270 - {
2271 - if (isset($this->calculationCache[$worksheetName])) {
2272 - unset($this->calculationCache[$worksheetName]);
2273 - }
2274 - }
1932 + /**
1933 + * Rename calculation cache for a specified worksheet
1934 + *
1935 + * @param string $fromWorksheetName
1936 + * @param string $toWorksheetName
1937 + */
1938 + public function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksheetName) {
1939 + if (isset($this->_calculationCache[$fromWorksheetName])) {
1940 + $this->_calculationCache[$toWorksheetName] = &$this->_calculationCache[$fromWorksheetName];
1941 + unset($this->_calculationCache[$fromWorksheetName]);
1942 + }
1943 + } // function renameCalculationCacheForWorksheet()
2275 1944
2276 - /**
2277 - * Rename calculation cache for a specified worksheet
2278 - *
2279 - * @param string $fromWorksheetName
2280 - * @param string $toWorksheetName
2281 - */
2282 - public function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksheetName)
2283 - {
2284 - if (isset($this->calculationCache[$fromWorksheetName])) {
2285 - $this->calculationCache[$toWorksheetName] = &$this->calculationCache[$fromWorksheetName];
2286 - unset($this->calculationCache[$fromWorksheetName]);
2287 - }
2288 - }
2289 1945
1946 + /**
1947 + * Get the currently defined locale code
1948 + *
1949 + * @return string
1950 + */
1951 + public function getLocale() {
1952 + return self::$_localeLanguage;
1953 + } // function getLocale()
2290 1954
2291 - /**
2292 - * Get the currently defined locale code
2293 - *
2294 - * @return string
2295 - */
2296 - public function getLocale()
2297 - {
2298 - return self::$localeLanguage;
2299 - }
2300 1955
1956 + /**
1957 + * Set the locale code
1958 + *
1959 + * @param string $locale The locale to use for formula translation
1960 + * @return boolean
1961 + */
1962 + public function setLocale($locale = 'en_us') {
1963 + // Identify our locale and language
1964 + $language = $locale = strtolower($locale);
1965 + if (strpos($locale,'_') !== FALSE) {
1966 + list($language) = explode('_',$locale);
1967 + }
2301 1968
2302 - /**
2303 - * Set the locale code
2304 - *
2305 - * @param string $locale The locale to use for formula translation
2306 - * @return boolean
2307 - */
2308 - public function setLocale($locale = 'en_us')
2309 - {
2310 - // Identify our locale and language
2311 - $language = $locale = strtolower($locale);
2312 - if (strpos($locale, '_') !== false) {
2313 - list($language) = explode('_', $locale);
2314 - }
1969 + if (count(self::$_validLocaleLanguages) == 1)
1970 + self::_loadLocales();
2315 1971
2316 - if (count(self::$validLocaleLanguages) == 1) {
2317 - self::loadLocales();
2318 - }
2319 - // Test whether we have any language data for this language (any locale)
2320 - if (in_array($language, self::$validLocaleLanguages)) {
2321 - // initialise language/locale settings
2322 - self::$localeFunctions = array();
2323 - self::$localeArgumentSeparator = ',';
2324 - self::$localeBoolean = array('TRUE' => 'TRUE', 'FALSE' => 'FALSE', 'NULL' => 'NULL');
2325 - // Default is English, if user isn't requesting english, then read the necessary data from the locale files
2326 - if ($locale != 'en_us') {
2327 - // Search for a file with a list of function names for locale
2328 - $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $locale).DIRECTORY_SEPARATOR.'functions';
2329 - if (!file_exists($functionNamesFile)) {
2330 - // If there isn't a locale specific function file, look for a language specific function file
2331 - $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'functions';
2332 - if (!file_exists($functionNamesFile)) {
2333 - return false;
2334 - }
2335 - }
2336 - // Retrieve the list of locale or language specific function names
2337 - $localeFunctions = file($functionNamesFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
2338 - foreach ($localeFunctions as $localeFunction) {
2339 - list($localeFunction) = explode('##', $localeFunction); // Strip out comments
2340 - if (strpos($localeFunction, '=') !== false) {
2341 - list($fName, $lfName) = explode('=', $localeFunction);
2342 - $fName = trim($fName);
2343 - $lfName = trim($lfName);
2344 - if ((isset(self::$PHPExcelFunctions[$fName])) && ($lfName != '') && ($fName != $lfName)) {
2345 - self::$localeFunctions[$fName] = $lfName;
2346 - }
2347 - }
2348 - }
2349 - // Default the TRUE and FALSE constants to the locale names of the TRUE() and FALSE() functions
2350 - if (isset(self::$localeFunctions['TRUE'])) {
2351 - self::$localeBoolean['TRUE'] = self::$localeFunctions['TRUE'];
2352 - }
2353 - if (isset(self::$localeFunctions['FALSE'])) {
2354 - self::$localeBoolean['FALSE'] = self::$localeFunctions['FALSE'];
2355 - }
1972 + // Test whether we have any language data for this language (any locale)
1973 + if (in_array($language,self::$_validLocaleLanguages)) {
1974 + // initialise language/locale settings
1975 + self::$_localeFunctions = array();
1976 + self::$_localeArgumentSeparator = ',';
1977 + self::$_localeBoolean = array('TRUE' => 'TRUE', 'FALSE' => 'FALSE', 'NULL' => 'NULL');
1978 + // Default is English, if user isn't requesting english, then read the necessary data from the locale files
1979 + if ($locale != 'en_us') {
1980 + // Search for a file with a list of function names for locale
1981 + $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'functions';
1982 + if (!file_exists($functionNamesFile)) {
1983 + // If there isn't a locale specific function file, look for a language specific function file
1984 + $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'functions';
1985 + if (!file_exists($functionNamesFile)) {
1986 + return FALSE;
1987 + }
1988 + }
1989 + // Retrieve the list of locale or language specific function names
1990 + $localeFunctions = file($functionNamesFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
1991 + foreach ($localeFunctions as $localeFunction) {
1992 + list($localeFunction) = explode('##',$localeFunction); // Strip out comments
1993 + if (strpos($localeFunction,'=') !== FALSE) {
1994 + list($fName,$lfName) = explode('=',$localeFunction);
1995 + $fName = trim($fName);
1996 + $lfName = trim($lfName);
1997 + if ((isset(self::$_PHPExcelFunctions[$fName])) && ($lfName != '') && ($fName != $lfName)) {
1998 + self::$_localeFunctions[$fName] = $lfName;
1999 + }
2000 + }
2001 + }
2002 + // Default the TRUE and FALSE constants to the locale names of the TRUE() and FALSE() functions
2003 + if (isset(self::$_localeFunctions['TRUE'])) { self::$_localeBoolean['TRUE'] = self::$_localeFunctions['TRUE']; }
2004 + if (isset(self::$_localeFunctions['FALSE'])) { self::$_localeBoolean['FALSE'] = self::$_localeFunctions['FALSE']; }
2356 2005
2357 - $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $locale).DIRECTORY_SEPARATOR.'config';
2358 - if (!file_exists($configFile)) {
2359 - $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'config';
2360 - }
2361 - if (file_exists($configFile)) {
2362 - $localeSettings = file($configFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
2363 - foreach ($localeSettings as $localeSetting) {
2364 - list($localeSetting) = explode('##', $localeSetting); // Strip out comments
2365 - if (strpos($localeSetting, '=') !== false) {
2366 - list($settingName, $settingValue) = explode('=', $localeSetting);
2367 - $settingName = strtoupper(trim($settingName));
2368 - switch ($settingName) {
2369 - case 'ARGUMENTSEPARATOR':
2370 - self::$localeArgumentSeparator = trim($settingValue);
2371 - break;
2372 - }
2373 - }
2374 - }
2375 - }
2376 - }
2006 + $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'config';
2007 + if (!file_exists($configFile)) {
2008 + $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'config';
2009 + }
2010 + if (file_exists($configFile)) {
2011 + $localeSettings = file($configFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
2012 + foreach ($localeSettings as $localeSetting) {
2013 + list($localeSetting) = explode('##',$localeSetting); // Strip out comments
2014 + if (strpos($localeSetting,'=') !== FALSE) {
2015 + list($settingName,$settingValue) = explode('=',$localeSetting);
2016 + $settingName = strtoupper(trim($settingName));
2017 + switch ($settingName) {
2018 + case 'ARGUMENTSEPARATOR' :
2019 + self::$_localeArgumentSeparator = trim($settingValue);
2020 + break;
2021 + }
2022 + }
2023 + }
2024 + }
2025 + }
2377 2026
2378 - self::$functionReplaceFromExcel = self::$functionReplaceToExcel =
2379 - self::$functionReplaceFromLocale = self::$functionReplaceToLocale = null;
2380 - self::$localeLanguage = $locale;
2381 - return true;
2382 - }
2383 - return false;
2384 - }
2027 + self::$functionReplaceFromExcel = self::$functionReplaceToExcel =
2028 + self::$functionReplaceFromLocale = self::$functionReplaceToLocale = NULL;
2029 + self::$_localeLanguage = $locale;
2030 + return TRUE;
2031 + }
2032 + return FALSE;
2033 + } // function setLocale()
2385 2034
2386 2035
2387 2036
2388 - public static function translateSeparator($fromSeparator, $toSeparator, $formula, &$inBraces)
2389 - {
2390 - $strlen = mb_strlen($formula);
2391 - for ($i = 0; $i < $strlen; ++$i) {
2392 - $chr = mb_substr($formula, $i, 1);
2393 - switch ($chr) {
2394 - case '{':
2395 - $inBraces = true;
2396 - break;
2397 - case '}':
2398 - $inBraces = false;
2399 - break;
2400 - case $fromSeparator:
2401 - if (!$inBraces) {
2402 - $formula = mb_substr($formula, 0, $i).$toSeparator.mb_substr($formula, $i+1);
2403 - }
2404 - }
2405 - }
2406 - return $formula;
2407 - }
2037 + public static function _translateSeparator($fromSeparator,$toSeparator,$formula,&$inBraces) {
2038 + $strlen = mb_strlen($formula);
2039 + for ($i = 0; $i < $strlen; ++$i) {
2040 + $chr = mb_substr($formula,$i,1);
2041 + switch ($chr) {
2042 + case '{' : $inBraces = TRUE;
2043 + break;
2044 + case '}' : $inBraces = FALSE;
2045 + break;
2046 + case $fromSeparator :
2047 + if (!$inBraces) {
2048 + $formula = mb_substr($formula,0,$i).$toSeparator.mb_substr($formula,$i+1);
2049 + }
2050 + }
2051 + }
2052 + return $formula;
2053 + }
2408 2054
2409 - private static function translateFormula($from, $to, $formula, $fromSeparator, $toSeparator)
2410 - {
2411 - // Convert any Excel function names to the required language
2412 - if (self::$localeLanguage !== 'en_us') {
2413 - $inBraces = false;
2414 - // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators
2415 - if (strpos($formula, '"') !== false) {
2416 - // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded
2417 - // the formula
2418 - $temp = explode('"', $formula);
2419 - $i = false;
2420 - foreach ($temp as &$value) {
2421 - // Only count/replace in alternating array entries
2422 - if ($i = !$i) {
2423 - $value = preg_replace($from, $to, $value);
2424 - $value = self::translateSeparator($fromSeparator, $toSeparator, $value, $inBraces);
2425 - }
2426 - }
2427 - unset($value);
2428 - // Then rebuild the formula string
2429 - $formula = implode('"', $temp);
2430 - } else {
2431 - // If there's no quoted strings, then we do a simple count/replace
2432 - $formula = preg_replace($from, $to, $formula);
2433 - $formula = self::translateSeparator($fromSeparator, $toSeparator, $formula, $inBraces);
2434 - }
2435 - }
2055 + private static function _translateFormula($from,$to,$formula,$fromSeparator,$toSeparator) {
2056 + // Convert any Excel function names to the required language
2057 + if (self::$_localeLanguage !== 'en_us') {
2058 + $inBraces = FALSE;
2059 + // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators
2060 + if (strpos($formula,'"') !== FALSE) {
2061 + // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded
2062 + // the formula
2063 + $temp = explode('"',$formula);
2064 + $i = FALSE;
2065 + foreach($temp as &$value) {
2066 + // Only count/replace in alternating array entries
2067 + if ($i = !$i) {
2068 + $value = preg_replace($from,$to,$value);
2069 + $value = self::_translateSeparator($fromSeparator,$toSeparator,$value,$inBraces);
2070 + }
2071 + }
2072 + unset($value);
2073 + // Then rebuild the formula string
2074 + $formula = implode('"',$temp);
2075 + } else {
2076 + // If there's no quoted strings, then we do a simple count/replace
2077 + $formula = preg_replace($from,$to,$formula);
2078 + $formula = self::_translateSeparator($fromSeparator,$toSeparator,$formula,$inBraces);
2079 + }
2080 + }
2436 2081
2437 - return $formula;
2438 - }
2082 + return $formula;
2083 + }
2439 2084
2440 - private static $functionReplaceFromExcel = null;
2441 - private static $functionReplaceToLocale = null;
2085 + private static $functionReplaceFromExcel = NULL;
2086 + private static $functionReplaceToLocale = NULL;
2442 2087
2443 - public function _translateFormulaToLocale($formula)
2444 - {
2445 - if (self::$functionReplaceFromExcel === null) {
2446 - self::$functionReplaceFromExcel = array();
2447 - foreach (array_keys(self::$localeFunctions) as $excelFunctionName) {
2448 - self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelFunctionName).'([\s]*\()/Ui';
2449 - }
2450 - foreach (array_keys(self::$localeBoolean) as $excelBoolean) {
2451 - self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui';
2452 - }
2088 + public function _translateFormulaToLocale($formula) {
2089 + if (self::$functionReplaceFromExcel === NULL) {
2090 + self::$functionReplaceFromExcel = array();
2091 + foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) {
2092 + self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelFunctionName).'([\s]*\()/Ui';
2093 + }
2094 + foreach(array_keys(self::$_localeBoolean) as $excelBoolean) {
2095 + self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui';
2096 + }
2453 2097
2454 - }
2098 + }
2455 2099
2456 - if (self::$functionReplaceToLocale === null) {
2457 - self::$functionReplaceToLocale = array();
2458 - foreach (array_values(self::$localeFunctions) as $localeFunctionName) {
2459 - self::$functionReplaceToLocale[] = '$1'.trim($localeFunctionName).'$2';
2460 - }
2461 - foreach (array_values(self::$localeBoolean) as $localeBoolean) {
2462 - self::$functionReplaceToLocale[] = '$1'.trim($localeBoolean).'$2';
2463 - }
2464 - }
2100 + if (self::$functionReplaceToLocale === NULL) {
2101 + self::$functionReplaceToLocale = array();
2102 + foreach(array_values(self::$_localeFunctions) as $localeFunctionName) {
2103 + self::$functionReplaceToLocale[] = '$1'.trim($localeFunctionName).'$2';
2104 + }
2105 + foreach(array_values(self::$_localeBoolean) as $localeBoolean) {
2106 + self::$functionReplaceToLocale[] = '$1'.trim($localeBoolean).'$2';
2107 + }
2108 + }
2465 2109
2466 - return self::translateFormula(self::$functionReplaceFromExcel, self::$functionReplaceToLocale, $formula, ',', self::$localeArgumentSeparator);
2467 - }
2110 + return self::_translateFormula(self::$functionReplaceFromExcel,self::$functionReplaceToLocale,$formula,',',self::$_localeArgumentSeparator);
2111 + } // function _translateFormulaToLocale()
2468 2112
2469 2113
2470 - private static $functionReplaceFromLocale = null;
2471 - private static $functionReplaceToExcel = null;
2114 + private static $functionReplaceFromLocale = NULL;
2115 + private static $functionReplaceToExcel = NULL;
2472 2116
2473 - public function _translateFormulaToEnglish($formula)
2474 - {
2475 - if (self::$functionReplaceFromLocale === null) {
2476 - self::$functionReplaceFromLocale = array();
2477 - foreach (array_values(self::$localeFunctions) as $localeFunctionName) {
2478 - self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($localeFunctionName).'([\s]*\()/Ui';
2479 - }
2480 - foreach (array_values(self::$localeBoolean) as $excelBoolean) {
2481 - self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui';
2482 - }
2483 - }
2117 + public function _translateFormulaToEnglish($formula) {
2118 + if (self::$functionReplaceFromLocale === NULL) {
2119 + self::$functionReplaceFromLocale = array();
2120 + foreach(array_values(self::$_localeFunctions) as $localeFunctionName) {
2121 + self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($localeFunctionName).'([\s]*\()/Ui';
2122 + }
2123 + foreach(array_values(self::$_localeBoolean) as $excelBoolean) {
2124 + self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui';
2125 + }
2126 + }
2484 2127
2485 - if (self::$functionReplaceToExcel === null) {
2486 - self::$functionReplaceToExcel = array();
2487 - foreach (array_keys(self::$localeFunctions) as $excelFunctionName) {
2488 - self::$functionReplaceToExcel[] = '$1'.trim($excelFunctionName).'$2';
2489 - }
2490 - foreach (array_keys(self::$localeBoolean) as $excelBoolean) {
2491 - self::$functionReplaceToExcel[] = '$1'.trim($excelBoolean).'$2';
2492 - }
2493 - }
2128 + if (self::$functionReplaceToExcel === NULL) {
2129 + self::$functionReplaceToExcel = array();
2130 + foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) {
2131 + self::$functionReplaceToExcel[] = '$1'.trim($excelFunctionName).'$2';
2132 + }
2133 + foreach(array_keys(self::$_localeBoolean) as $excelBoolean) {
2134 + self::$functionReplaceToExcel[] = '$1'.trim($excelBoolean).'$2';
2135 + }
2136 + }
2494 2137
2495 - return self::translateFormula(self::$functionReplaceFromLocale, self::$functionReplaceToExcel, $formula, self::$localeArgumentSeparator, ',');
2496 - }
2138 + return self::_translateFormula(self::$functionReplaceFromLocale,self::$functionReplaceToExcel,$formula,self::$_localeArgumentSeparator,',');
2139 + } // function _translateFormulaToEnglish()
2497 2140
2498 2141
2499 - public static function localeFunc($function)
2500 - {
2501 - if (self::$localeLanguage !== 'en_us') {
2502 - $functionName = trim($function, '(');
2503 - if (isset(self::$localeFunctions[$functionName])) {
2504 - $brace = ($functionName != $function);
2505 - $function = self::$localeFunctions[$functionName];
2506 - if ($brace) {
2507 - $function .= '(';
2508 - }
2509 - }
2510 - }
2511 - return $function;
2512 - }
2142 + public static function _localeFunc($function) {
2143 + if (self::$_localeLanguage !== 'en_us') {
2144 + $functionName = trim($function,'(');
2145 + if (isset(self::$_localeFunctions[$functionName])) {
2146 + $brace = ($functionName != $function);
2147 + $function = self::$_localeFunctions[$functionName];
2148 + if ($brace) { $function .= '('; }
2149 + }
2150 + }
2151 + return $function;
2152 + }
2513 2153
2514 2154
2515 2155
2516 2156
2517 - /**
2518 - * Wrap string values in quotes
2519 - *
2520 - * @param mixed $value
2521 - * @return mixed
2522 - */
2523 - public static function wrapResult($value)
2524 - {
2525 - if (is_string($value)) {
2526 - // Error values cannot be "wrapped"
2527 - if (preg_match('/^'.self::CALCULATION_REGEXP_ERROR.'$/i', $value, $match)) {
2528 - // Return Excel errors "as is"
2529 - return $value;
2530 - }
2531 - // Return strings wrapped in quotes
2532 - return '"'.$value.'"';
2533 - // Convert numeric errors to NaN error
2534 - } elseif ((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) {
2535 - return PHPExcel_Calculation_Functions::NaN();
2536 - }
2157 + /**
2158 + * Wrap string values in quotes
2159 + *
2160 + * @param mixed $value
2161 + * @return mixed
2162 + */
2163 + public static function _wrapResult($value) {
2164 + if (is_string($value)) {
2165 + // Error values cannot be "wrapped"
2166 + if (preg_match('/^'.self::CALCULATION_REGEXP_ERROR.'$/i', $value, $match)) {
2167 + // Return Excel errors "as is"
2168 + return $value;
2169 + }
2170 + // Return strings wrapped in quotes
2171 + return '"'.$value.'"';
2172 + // Convert numeric errors to NaN error
2173 + } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) {
2174 + return PHPExcel_Calculation_Functions::NaN();
2175 + }
2537 2176
2538 - return $value;
2539 - }
2177 + return $value;
2178 + } // function _wrapResult()
2540 2179
2541 2180
2542 - /**
2543 - * Remove quotes used as a wrapper to identify string values
2544 - *
2545 - * @param mixed $value
2546 - * @return mixed
2547 - */
2548 - public static function unwrapResult($value)
2549 - {
2550 - if (is_string($value)) {
2551 - if ((isset($value{0})) && ($value{0} == '"') && (substr($value, -1) == '"')) {
2552 - return substr($value, 1, -1);
2553 - }
2554 - // Convert numeric errors to NaN error
2555 - } elseif ((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) {
2556 - return PHPExcel_Calculation_Functions::NaN();
2557 - }
2558 - return $value;
2559 - }
2181 + /**
2182 + * Remove quotes used as a wrapper to identify string values
2183 + *
2184 + * @param mixed $value
2185 + * @return mixed
2186 + */
2187 + public static function _unwrapResult($value) {
2188 + if (is_string($value)) {
2189 + if ((isset($value{0})) && ($value{0} == '"') && (substr($value,-1) == '"')) {
2190 + return substr($value,1,-1);
2191 + }
2192 + // Convert numeric errors to NaN error
2193 + } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) {
2194 + return PHPExcel_Calculation_Functions::NaN();
2195 + }
2196 + return $value;
2197 + } // function _unwrapResult()
2560 2198
2561 2199
2562 2200
2563 2201
2564 - /**
2565 - * Calculate cell value (using formula from a cell ID)
2566 - * Retained for backward compatibility
2567 - *
2568 - * @access public
2569 - * @param PHPExcel_Cell $pCell Cell to calculate
2570 - * @return mixed
2571 - * @throws PHPExcel_Calculation_Exception
2572 - */
2573 - public function calculate(PHPExcel_Cell $pCell = null)
2574 - {
2575 - try {
2576 - return $this->calculateCellValue($pCell);
2577 - } catch (PHPExcel_Exception $e) {
2578 - throw new PHPExcel_Calculation_Exception($e->getMessage());
2579 - }
2580 - }
2202 + /**
2203 + * Calculate cell value (using formula from a cell ID)
2204 + * Retained for backward compatibility
2205 + *
2206 + * @access public
2207 + * @param PHPExcel_Cell $pCell Cell to calculate
2208 + * @return mixed
2209 + * @throws PHPExcel_Calculation_Exception
2210 + */
2211 + public function calculate(PHPExcel_Cell $pCell = NULL) {
2212 + try {
2213 + return $this->calculateCellValue($pCell);
2214 + } catch (PHPExcel_Exception $e) {
2215 + throw new PHPExcel_Calculation_Exception($e->getMessage());
2216 + }
2217 + } // function calculate()
2581 2218
2582 2219
2583 - /**
2584 - * Calculate the value of a cell formula
2585 - *
2586 - * @access public
2587 - * @param PHPExcel_Cell $pCell Cell to calculate
2588 - * @param Boolean $resetLog Flag indicating whether the debug log should be reset or not
2589 - * @return mixed
2590 - * @throws PHPExcel_Calculation_Exception
2591 - */
2592 - public function calculateCellValue(PHPExcel_Cell $pCell = null, $resetLog = true)
2593 - {
2594 - if ($pCell === null) {
2595 - return null;
2596 - }
2220 + /**
2221 + * Calculate the value of a cell formula
2222 + *
2223 + * @access public
2224 + * @param PHPExcel_Cell $pCell Cell to calculate
2225 + * @param Boolean $resetLog Flag indicating whether the debug log should be reset or not
2226 + * @return mixed
2227 + * @throws PHPExcel_Calculation_Exception
2228 + */
2229 + public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE) {
2230 + if ($pCell === NULL) {
2231 + return NULL;
2232 + }
2597 2233
2598 - $returnArrayAsType = self::$returnArrayAsType;
2599 - if ($resetLog) {
2600 - // Initialise the logging settings if requested
2601 - $this->formulaError = null;
2602 - $this->_debugLog->clearLog();
2603 - $this->cyclicReferenceStack->clear();
2604 - $this->cyclicFormulaCounter = 1;
2234 + $returnArrayAsType = self::$returnArrayAsType;
2235 + if ($resetLog) {
2236 + // Initialise the logging settings if requested
2237 + $this->formulaError = null;
2238 + $this->_debugLog->clearLog();
2239 + $this->_cyclicReferenceStack->clear();
2240 + $this->_cyclicFormulaCount = 1;
2605 2241
2606 - self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY;
2607 - }
2242 + self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY;
2243 + }
2608 2244
2609 - // Execute the calculation for the cell formula
2610 - $this->cellStack[] = array(
2245 + // Execute the calculation for the cell formula
2246 + $this->_cellStack[] = array(
2611 2247 'sheet' => $pCell->getWorksheet()->getTitle(),
2612 2248 'cell' => $pCell->getCoordinate(),
2613 2249 );
2614 - try {
2615 - $result = self::unwrapResult($this->_calculateFormulaValue($pCell->getValue(), $pCell->getCoordinate(), $pCell));
2616 - $cellAddress = array_pop($this->cellStack);
2617 - $this->workbook->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']);
2618 - } catch (PHPExcel_Exception $e) {
2619 - $cellAddress = array_pop($this->cellStack);
2620 - $this->workbook->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']);
2621 - throw new PHPExcel_Calculation_Exception($e->getMessage());
2622 - }
2250 + try {
2251 + $result = self::_unwrapResult($this->_calculateFormulaValue($pCell->getValue(), $pCell->getCoordinate(), $pCell));
2252 + $cellAddress = array_pop($this->_cellStack);
2253 + $this->_workbook->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']);
2254 + } catch (PHPExcel_Exception $e) {
2255 + $cellAddress = array_pop($this->_cellStack);
2256 + $this->_workbook->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']);
2257 + throw new PHPExcel_Calculation_Exception($e->getMessage());
2258 + }
2623 2259
2624 - if ((is_array($result)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) {
2625 - self::$returnArrayAsType = $returnArrayAsType;
2626 - $testResult = PHPExcel_Calculation_Functions::flattenArray($result);
2627 - if (self::$returnArrayAsType == self::RETURN_ARRAY_AS_ERROR) {
2628 - return PHPExcel_Calculation_Functions::VALUE();
2629 - }
2630 - // If there's only a single cell in the array, then we allow it
2631 - if (count($testResult) != 1) {
2632 - // If keys are numeric, then it's a matrix result rather than a cell range result, so we permit it
2633 - $r = array_keys($result);
2634 - $r = array_shift($r);
2635 - if (!is_numeric($r)) {
2636 - return PHPExcel_Calculation_Functions::VALUE();
2637 - }
2638 - if (is_array($result[$r])) {
2639 - $c = array_keys($result[$r]);
2640 - $c = array_shift($c);
2641 - if (!is_numeric($c)) {
2642 - return PHPExcel_Calculation_Functions::VALUE();
2643 - }
2644 - }
2645 - }
2646 - $result = array_shift($testResult);
2647 - }
2648 - self::$returnArrayAsType = $returnArrayAsType;
2260 + if ((is_array($result)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) {
2261 + self::$returnArrayAsType = $returnArrayAsType;
2262 + $testResult = PHPExcel_Calculation_Functions::flattenArray($result);
2263 + if (self::$returnArrayAsType == self::RETURN_ARRAY_AS_ERROR) {
2264 + return PHPExcel_Calculation_Functions::VALUE();
2265 + }
2266 + // If there's only a single cell in the array, then we allow it
2267 + if (count($testResult) != 1) {
2268 + // If keys are numeric, then it's a matrix result rather than a cell range result, so we permit it
2269 + $r = array_keys($result);
2270 + $r = array_shift($r);
2271 + if (!is_numeric($r)) { return PHPExcel_Calculation_Functions::VALUE(); }
2272 + if (is_array($result[$r])) {
2273 + $c = array_keys($result[$r]);
2274 + $c = array_shift($c);
2275 + if (!is_numeric($c)) {
2276 + return PHPExcel_Calculation_Functions::VALUE();
2277 + }
2278 + }
2279 + }
2280 + $result = array_shift($testResult);
2281 + }
2282 + self::$returnArrayAsType = $returnArrayAsType;
2649 2283
2650 2284
2651 - if ($result === null) {
2652 - return 0;
2653 - } elseif ((is_float($result)) && ((is_nan($result)) || (is_infinite($result)))) {
2654 - return PHPExcel_Calculation_Functions::NaN();
2655 - }
2656 - return $result;
2657 - }
2285 + if ($result === NULL) {
2286 + return 0;
2287 + } elseif((is_float($result)) && ((is_nan($result)) || (is_infinite($result)))) {
2288 + return PHPExcel_Calculation_Functions::NaN();
2289 + }
2290 + return $result;
2291 + } // function calculateCellValue(
2658 2292
2659 2293
2660 - /**
2661 - * Validate and parse a formula string
2662 - *
2663 - * @param string $formula Formula to parse
2664 - * @return array
2665 - * @throws PHPExcel_Calculation_Exception
2666 - */
2667 - public function parseFormula($formula)
2668 - {
2669 - // Basic validation that this is indeed a formula
2670 - // We return an empty array if not
2671 - $formula = trim($formula);
2672 - if ((!isset($formula{0})) || ($formula{0} != '=')) {
2673 - return array();
2674 - }
2675 - $formula = ltrim(substr($formula, 1));
2676 - if (!isset($formula{0})) {
2677 - return array();
2678 - }
2294 + /**
2295 + * Validate and parse a formula string
2296 + *
2297 + * @param string $formula Formula to parse
2298 + * @return array
2299 + * @throws PHPExcel_Calculation_Exception
2300 + */
2301 + public function parseFormula($formula) {
2302 + // Basic validation that this is indeed a formula
2303 + // We return an empty array if not
2304 + $formula = trim($formula);
2305 + if ((!isset($formula{0})) || ($formula{0} != '=')) return array();
2306 + $formula = ltrim(substr($formula,1));
2307 + if (!isset($formula{0})) return array();
2679 2308
2680 - // Parse the formula and return the token stack
2681 - return $this->_parseFormula($formula);
2682 - }
2309 + // Parse the formula and return the token stack
2310 + return $this->_parseFormula($formula);
2311 + } // function parseFormula()
2683 2312
2684 2313
2685 - /**
2686 - * Calculate the value of a formula
2687 - *
2688 - * @param string $formula Formula to parse
2689 - * @param string $cellID Address of the cell to calculate
2690 - * @param PHPExcel_Cell $pCell Cell to calculate
2691 - * @return mixed
2692 - * @throws PHPExcel_Calculation_Exception
2693 - */
2694 - public function calculateFormula($formula, $cellID = null, PHPExcel_Cell $pCell = null)
2695 - {
2696 - // Initialise the logging settings
2697 - $this->formulaError = null;
2698 - $this->_debugLog->clearLog();
2699 - $this->cyclicReferenceStack->clear();
2314 + /**
2315 + * Calculate the value of a formula
2316 + *
2317 + * @param string $formula Formula to parse
2318 + * @param string $cellID Address of the cell to calculate
2319 + * @param PHPExcel_Cell $pCell Cell to calculate
2320 + * @return mixed
2321 + * @throws PHPExcel_Calculation_Exception
2322 + */
2323 + public function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = NULL) {
2324 + // Initialise the logging settings
2325 + $this->formulaError = null;
2326 + $this->_debugLog->clearLog();
2327 + $this->_cyclicReferenceStack->clear();
2700 2328
2701 - if ($this->workbook !== null && $cellID === null && $pCell === null) {
2702 - $cellID = 'A1';
2703 - $pCell = $this->workbook->getActiveSheet()->getCell($cellID);
2704 - } else {
2705 - // Disable calculation cacheing because it only applies to cell calculations, not straight formulae
2706 - // But don't actually flush any cache
2707 - $resetCache = $this->getCalculationCacheEnabled();
2708 - $this->calculationCacheEnabled = false;
2709 - }
2329 + // Disable calculation cacheing because it only applies to cell calculations, not straight formulae
2330 + // But don't actually flush any cache
2331 + $resetCache = $this->getCalculationCacheEnabled();
2332 + $this->_calculationCacheEnabled = FALSE;
2333 + // Execute the calculation
2334 + try {
2335 + $result = self::_unwrapResult($this->_calculateFormulaValue($formula, $cellID, $pCell));
2336 + } catch (PHPExcel_Exception $e) {
2337 + throw new PHPExcel_Calculation_Exception($e->getMessage());
2338 + }
2710 2339
2711 - // Execute the calculation
2712 - try {
2713 - $result = self::unwrapResult($this->_calculateFormulaValue($formula, $cellID, $pCell));
2714 - } catch (PHPExcel_Exception $e) {
2715 - throw new PHPExcel_Calculation_Exception($e->getMessage());
2716 - }
2340 + // Reset calculation cacheing to its previous state
2341 + $this->_calculationCacheEnabled = $resetCache;
2717 2342
2718 - if ($this->workbook === null) {
2719 - // Reset calculation cacheing to its previous state
2720 - $this->calculationCacheEnabled = $resetCache;
2721 - }
2343 + return $result;
2344 + } // function calculateFormula()
2722 2345
2723 - return $result;
2724 - }
2725 2346
2726 -
2727 - public function getValueFromCache($cellReference, &$cellValue)
2728 - {
2729 - // Is calculation cacheing enabled?
2730 - // Is the value present in calculation cache?
2731 - $this->_debugLog->writeDebugLog('Testing cache value for cell ', $cellReference);
2732 - if (($this->calculationCacheEnabled) && (isset($this->calculationCache[$cellReference]))) {
2733 - $this->_debugLog->writeDebugLog('Retrieving value for cell ', $cellReference, ' from cache');
2734 - // Return the cached result
2735 - $cellValue = $this->calculationCache[$cellReference];
2736 - return true;
2737 - }
2738 - return false;
2347 + public function getValueFromCache($cellReference, &$cellValue) {
2348 + // Is calculation cacheing enabled?
2349 + // Is the value present in calculation cache?
2350 + $this->_debugLog->writeDebugLog('Testing cache value for cell ', $cellReference);
2351 + if (($this->_calculationCacheEnabled) && (isset($this->_calculationCache[$cellReference]))) {
2352 + $this->_debugLog->writeDebugLog('Retrieving value for cell ', $cellReference, ' from cache');
2353 + // Return the cached result
2354 + $cellValue = $this->_calculationCache[$cellReference];
2355 + return TRUE;
2356 + }
2357 + return FALSE;
2739 2358 }
2740 2359
2741 - public function saveValueToCache($cellReference, $cellValue)
2742 - {
2743 - if ($this->calculationCacheEnabled) {
2744 - $this->calculationCache[$cellReference] = $cellValue;
2745 - }
2746 - }
2360 + public function saveValueToCache($cellReference, $cellValue) {
2361 + if ($this->_calculationCacheEnabled) {
2362 + $this->_calculationCache[$cellReference] = $cellValue;
2363 + }
2364 + }
2747 2365
2748 - /**
2749 - * Parse a cell formula and calculate its value
2750 - *
2751 - * @param string $formula The formula to parse and calculate
2752 - * @param string $cellID The ID (e.g. A3) of the cell that we are calculating
2753 - * @param PHPExcel_Cell $pCell Cell to calculate
2754 - * @return mixed
2755 - * @throws PHPExcel_Calculation_Exception
2756 - */
2757 - public function _calculateFormulaValue($formula, $cellID = null, PHPExcel_Cell $pCell = null)
2758 - {
2759 - $cellValue = null;
2366 + /**
2367 + * Parse a cell formula and calculate its value
2368 + *
2369 + * @param string $formula The formula to parse and calculate
2370 + * @param string $cellID The ID (e.g. A3) of the cell that we are calculating
2371 + * @param PHPExcel_Cell $pCell Cell to calculate
2372 + * @return mixed
2373 + * @throws PHPExcel_Calculation_Exception
2374 + */
2375 + public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pCell = null) {
2376 + $cellValue = null;
2760 2377
2761 - // Basic validation that this is indeed a formula
2762 - // We simply return the cell value if not
2763 - $formula = trim($formula);
2764 - if ($formula{0} != '=') {
2765 - return self::wrapResult($formula);
2766 - }
2767 - $formula = ltrim(substr($formula, 1));
2768 - if (!isset($formula{0})) {
2769 - return self::wrapResult($formula);
2770 - }
2378 + // Basic validation that this is indeed a formula
2379 + // We simply return the cell value if not
2380 + $formula = trim($formula);
2381 + if ($formula{0} != '=') return self::_wrapResult($formula);
2382 + $formula = ltrim(substr($formula, 1));
2383 + if (!isset($formula{0})) return self::_wrapResult($formula);
2771 2384
2772 - $pCellParent = ($pCell !== null) ? $pCell->getWorksheet() : null;
2773 - $wsTitle = ($pCellParent !== null) ? $pCellParent->getTitle() : "\x00Wrk";
2385 + $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL;
2386 + $wsTitle = ($pCellParent !== NULL) ? $pCellParent->getTitle() : "\x00Wrk";
2774 2387 $wsCellReference = $wsTitle . '!' . $cellID;
2775 2388
2776 - if (($cellID !== null) && ($this->getValueFromCache($wsCellReference, $cellValue))) {
2777 - return $cellValue;
2778 - }
2389 + if (($cellID !== NULL) && ($this->getValueFromCache($wsCellReference, $cellValue))) {
2390 + return $cellValue;
2391 + }
2779 2392
2780 - if (($wsTitle{0} !== "\x00") && ($this->cyclicReferenceStack->onStack($wsCellReference))) {
2393 + if (($wsTitle{0} !== "\x00") && ($this->_cyclicReferenceStack->onStack($wsCellReference))) {
2781 2394 if ($this->cyclicFormulaCount <= 0) {
2782 - $this->cyclicFormulaCell = '';
2783 - return $this->raiseFormulaError('Cyclic Reference in Formula');
2784 - } elseif ($this->cyclicFormulaCell === $wsCellReference) {
2785 - ++$this->cyclicFormulaCounter;
2786 - if ($this->cyclicFormulaCounter >= $this->cyclicFormulaCount) {
2787 - $this->cyclicFormulaCell = '';
2788 - return $cellValue;
2789 - }
2790 - } elseif ($this->cyclicFormulaCell == '') {
2791 - if ($this->cyclicFormulaCounter >= $this->cyclicFormulaCount) {
2792 - return $cellValue;
2793 - }
2794 - $this->cyclicFormulaCell = $wsCellReference;
2795 - }
2796 - }
2395 + $this->_cyclicFormulaCell = '';
2396 + return $this->_raiseFormulaError('Cyclic Reference in Formula');
2397 + } elseif ($this->_cyclicFormulaCell === $wsCellReference) {
2398 + ++$this->_cyclicFormulaCount;
2399 + if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) {
2400 + $this->_cyclicFormulaCell = '';
2401 + return $cellValue;
2402 + }
2403 + } elseif ($this->_cyclicFormulaCell == '') {
2404 + if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) {
2405 + return $cellValue;
2406 + }
2407 + $this->_cyclicFormulaCell = $wsCellReference;
2408 + }
2409 + }
2797 2410
2798 - // Parse the formula onto the token stack and calculate the value
2799 - $this->cyclicReferenceStack->push($wsCellReference);
2800 - $cellValue = $this->processTokenStack($this->_parseFormula($formula, $pCell), $cellID, $pCell);
2801 - $this->cyclicReferenceStack->pop();
2411 + // Parse the formula onto the token stack and calculate the value
2412 + $this->_cyclicReferenceStack->push($wsCellReference);
2413 + $cellValue = $this->_processTokenStack($this->_parseFormula($formula, $pCell), $cellID, $pCell);
2414 + $this->_cyclicReferenceStack->pop();
2802 2415
2803 - // Save to calculation cache
2804 - if ($cellID !== null) {
2805 - $this->saveValueToCache($wsCellReference, $cellValue);
2806 - }
2416 + // Save to calculation cache
2417 + if ($cellID !== NULL) {
2418 + $this->saveValueToCache($wsCellReference, $cellValue);
2419 + }
2807 2420
2808 - // Return the calculated value
2809 - return $cellValue;
2810 - }
2421 + // Return the calculated value
2422 + return $cellValue;
2423 + } // function _calculateFormulaValue()
2811 2424
2812 2425
2813 - /**
2814 - * Ensure that paired matrix operands are both matrices and of the same size
2815 - *
2816 - * @param mixed &$operand1 First matrix operand
2817 - * @param mixed &$operand2 Second matrix operand
2818 - * @param integer $resize Flag indicating whether the matrices should be resized to match
2819 - * and (if so), whether the smaller dimension should grow or the
2820 - * larger should shrink.
2821 - * 0 = no resize
2822 - * 1 = shrink to fit
2823 - * 2 = extend to fit
2824 - */
2825 - private static function checkMatrixOperands(&$operand1, &$operand2, $resize = 1)
2826 - {
2827 - // Examine each of the two operands, and turn them into an array if they aren't one already
2828 - // Note that this function should only be called if one or both of the operand is already an array
2829 - if (!is_array($operand1)) {
2830 - list($matrixRows, $matrixColumns) = self::getMatrixDimensions($operand2);
2831 - $operand1 = array_fill(0, $matrixRows, array_fill(0, $matrixColumns, $operand1));
2832 - $resize = 0;
2833 - } elseif (!is_array($operand2)) {
2834 - list($matrixRows, $matrixColumns) = self::getMatrixDimensions($operand1);
2835 - $operand2 = array_fill(0, $matrixRows, array_fill(0, $matrixColumns, $operand2));
2836 - $resize = 0;
2837 - }
2426 + /**
2427 + * Ensure that paired matrix operands are both matrices and of the same size
2428 + *
2429 + * @param mixed &$operand1 First matrix operand
2430 + * @param mixed &$operand2 Second matrix operand
2431 + * @param integer $resize Flag indicating whether the matrices should be resized to match
2432 + * and (if so), whether the smaller dimension should grow or the
2433 + * larger should shrink.
2434 + * 0 = no resize
2435 + * 1 = shrink to fit
2436 + * 2 = extend to fit
2437 + */
2438 + private static function _checkMatrixOperands(&$operand1,&$operand2,$resize = 1) {
2439 + // Examine each of the two operands, and turn them into an array if they aren't one already
2440 + // Note that this function should only be called if one or both of the operand is already an array
2441 + if (!is_array($operand1)) {
2442 + list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand2);
2443 + $operand1 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand1));
2444 + $resize = 0;
2445 + } elseif (!is_array($operand2)) {
2446 + list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand1);
2447 + $operand2 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand2));
2448 + $resize = 0;
2449 + }
2838 2450
2839 - list($matrix1Rows, $matrix1Columns) = self::getMatrixDimensions($operand1);
2840 - list($matrix2Rows, $matrix2Columns) = self::getMatrixDimensions($operand2);
2841 - if (($matrix1Rows == $matrix2Columns) && ($matrix2Rows == $matrix1Columns)) {
2842 - $resize = 1;
2843 - }
2451 + list($matrix1Rows,$matrix1Columns) = self::_getMatrixDimensions($operand1);
2452 + list($matrix2Rows,$matrix2Columns) = self::_getMatrixDimensions($operand2);
2453 + if (($matrix1Rows == $matrix2Columns) && ($matrix2Rows == $matrix1Columns)) {
2454 + $resize = 1;
2455 + }
2844 2456
2845 - if ($resize == 2) {
2846 - // Given two matrices of (potentially) unequal size, convert the smaller in each dimension to match the larger
2847 - self::resizeMatricesExtend($operand1, $operand2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns);
2848 - } elseif ($resize == 1) {
2849 - // Given two matrices of (potentially) unequal size, convert the larger in each dimension to match the smaller
2850 - self::resizeMatricesShrink($operand1, $operand2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns);
2851 - }
2852 - return array( $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns);
2853 - }
2457 + if ($resize == 2) {
2458 + // Given two matrices of (potentially) unequal size, convert the smaller in each dimension to match the larger
2459 + self::_resizeMatricesExtend($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns);
2460 + } elseif ($resize == 1) {
2461 + // Given two matrices of (potentially) unequal size, convert the larger in each dimension to match the smaller
2462 + self::_resizeMatricesShrink($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns);
2463 + }
2464 + return array( $matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns);
2465 + } // function _checkMatrixOperands()
2854 2466
2855 2467
2856 - /**
2857 - * Read the dimensions of a matrix, and re-index it with straight numeric keys starting from row 0, column 0
2858 - *
2859 - * @param mixed &$matrix matrix operand
2860 - * @return array An array comprising the number of rows, and number of columns
2861 - */
2862 - private static function getMatrixDimensions(&$matrix)
2863 - {
2864 - $matrixRows = count($matrix);
2865 - $matrixColumns = 0;
2866 - foreach ($matrix as $rowKey => $rowValue) {
2867 - $matrixColumns = max(count($rowValue), $matrixColumns);
2868 - if (!is_array($rowValue)) {
2869 - $matrix[$rowKey] = array($rowValue);
2870 - } else {
2871 - $matrix[$rowKey] = array_values($rowValue);
2872 - }
2873 - }
2874 - $matrix = array_values($matrix);
2875 - return array($matrixRows, $matrixColumns);
2876 - }
2468 + /**
2469 + * Read the dimensions of a matrix, and re-index it with straight numeric keys starting from row 0, column 0
2470 + *
2471 + * @param mixed &$matrix matrix operand
2472 + * @return array An array comprising the number of rows, and number of columns
2473 + */
2474 + public static function _getMatrixDimensions(&$matrix) {
2475 + $matrixRows = count($matrix);
2476 + $matrixColumns = 0;
2477 + foreach($matrix as $rowKey => $rowValue) {
2478 + $matrixColumns = max(count($rowValue),$matrixColumns);
2479 + if (!is_array($rowValue)) {
2480 + $matrix[$rowKey] = array($rowValue);
2481 + } else {
2482 + $matrix[$rowKey] = array_values($rowValue);
2483 + }
2484 + }
2485 + $matrix = array_values($matrix);
2486 + return array($matrixRows,$matrixColumns);
2487 + } // function _getMatrixDimensions()
2877 2488
2878 2489
2879 - /**
2880 - * Ensure that paired matrix operands are both matrices of the same size
2881 - *
2882 - * @param mixed &$matrix1 First matrix operand
2883 - * @param mixed &$matrix2 Second matrix operand
2884 - * @param integer $matrix1Rows Row size of first matrix operand
2885 - * @param integer $matrix1Columns Column size of first matrix operand
2886 - * @param integer $matrix2Rows Row size of second matrix operand
2887 - * @param integer $matrix2Columns Column size of second matrix operand
2888 - */
2889 - private static function resizeMatricesShrink(&$matrix1, &$matrix2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns)
2890 - {
2891 - if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) {
2892 - if ($matrix2Rows < $matrix1Rows) {
2893 - for ($i = $matrix2Rows; $i < $matrix1Rows; ++$i) {
2894 - unset($matrix1[$i]);
2895 - }
2896 - }
2897 - if ($matrix2Columns < $matrix1Columns) {
2898 - for ($i = 0; $i < $matrix1Rows; ++$i) {
2899 - for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) {
2900 - unset($matrix1[$i][$j]);
2901 - }
2902 - }
2903 - }
2904 - }
2490 + /**
2491 + * Ensure that paired matrix operands are both matrices of the same size
2492 + *
2493 + * @param mixed &$matrix1 First matrix operand
2494 + * @param mixed &$matrix2 Second matrix operand
2495 + * @param integer $matrix1Rows Row size of first matrix operand
2496 + * @param integer $matrix1Columns Column size of first matrix operand
2497 + * @param integer $matrix2Rows Row size of second matrix operand
2498 + * @param integer $matrix2Columns Column size of second matrix operand
2499 + */
2500 + private static function _resizeMatricesShrink(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) {
2501 + if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) {
2502 + if ($matrix2Rows < $matrix1Rows) {
2503 + for ($i = $matrix2Rows; $i < $matrix1Rows; ++$i) {
2504 + unset($matrix1[$i]);
2505 + }
2506 + }
2507 + if ($matrix2Columns < $matrix1Columns) {
2508 + for ($i = 0; $i < $matrix1Rows; ++$i) {
2509 + for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) {
2510 + unset($matrix1[$i][$j]);
2511 + }
2512 + }
2513 + }
2514 + }
2905 2515
2906 - if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) {
2907 - if ($matrix1Rows < $matrix2Rows) {
2908 - for ($i = $matrix1Rows; $i < $matrix2Rows; ++$i) {
2909 - unset($matrix2[$i]);
2910 - }
2911 - }
2912 - if ($matrix1Columns < $matrix2Columns) {
2913 - for ($i = 0; $i < $matrix2Rows; ++$i) {
2914 - for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) {
2915 - unset($matrix2[$i][$j]);
2916 - }
2917 - }
2918 - }
2919 - }
2920 - }
2516 + if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) {
2517 + if ($matrix1Rows < $matrix2Rows) {
2518 + for ($i = $matrix1Rows; $i < $matrix2Rows; ++$i) {
2519 + unset($matrix2[$i]);
2520 + }
2521 + }
2522 + if ($matrix1Columns < $matrix2Columns) {
2523 + for ($i = 0; $i < $matrix2Rows; ++$i) {
2524 + for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) {
2525 + unset($matrix2[$i][$j]);
2526 + }
2527 + }
2528 + }
2529 + }
2530 + } // function _resizeMatricesShrink()
2921 2531
2922 2532
2923 - /**
2924 - * Ensure that paired matrix operands are both matrices of the same size
2925 - *
2926 - * @param mixed &$matrix1 First matrix operand
2927 - * @param mixed &$matrix2 Second matrix operand
2928 - * @param integer $matrix1Rows Row size of first matrix operand
2929 - * @param integer $matrix1Columns Column size of first matrix operand
2930 - * @param integer $matrix2Rows Row size of second matrix operand
2931 - * @param integer $matrix2Columns Column size of second matrix operand
2932 - */
2933 - private static function resizeMatricesExtend(&$matrix1, &$matrix2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns)
2934 - {
2935 - if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) {
2936 - if ($matrix2Columns < $matrix1Columns) {
2937 - for ($i = 0; $i < $matrix2Rows; ++$i) {
2938 - $x = $matrix2[$i][$matrix2Columns-1];
2939 - for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) {
2940 - $matrix2[$i][$j] = $x;
2941 - }
2942 - }
2943 - }
2944 - if ($matrix2Rows < $matrix1Rows) {
2945 - $x = $matrix2[$matrix2Rows-1];
2946 - for ($i = 0; $i < $matrix1Rows; ++$i) {
2947 - $matrix2[$i] = $x;
2948 - }
2949 - }
2950 - }
2533 + /**
2534 + * Ensure that paired matrix operands are both matrices of the same size
2535 + *
2536 + * @param mixed &$matrix1 First matrix operand
2537 + * @param mixed &$matrix2 Second matrix operand
2538 + * @param integer $matrix1Rows Row size of first matrix operand
2539 + * @param integer $matrix1Columns Column size of first matrix operand
2540 + * @param integer $matrix2Rows Row size of second matrix operand
2541 + * @param integer $matrix2Columns Column size of second matrix operand
2542 + */
2543 + private static function _resizeMatricesExtend(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) {
2544 + if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) {
2545 + if ($matrix2Columns < $matrix1Columns) {
2546 + for ($i = 0; $i < $matrix2Rows; ++$i) {
2547 + $x = $matrix2[$i][$matrix2Columns-1];
2548 + for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) {
2549 + $matrix2[$i][$j] = $x;
2550 + }
2551 + }
2552 + }
2553 + if ($matrix2Rows < $matrix1Rows) {
2554 + $x = $matrix2[$matrix2Rows-1];
2555 + for ($i = 0; $i < $matrix1Rows; ++$i) {
2556 + $matrix2[$i] = $x;
2557 + }
2558 + }
2559 + }
2951 2560
2952 - if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) {
2953 - if ($matrix1Columns < $matrix2Columns) {
2954 - for ($i = 0; $i < $matrix1Rows; ++$i) {
2955 - $x = $matrix1[$i][$matrix1Columns-1];
2956 - for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) {
2957 - $matrix1[$i][$j] = $x;
2958 - }
2959 - }
2960 - }
2961 - if ($matrix1Rows < $matrix2Rows) {
2962 - $x = $matrix1[$matrix1Rows-1];
2963 - for ($i = 0; $i < $matrix2Rows; ++$i) {
2964 - $matrix1[$i] = $x;
2965 - }
2966 - }
2967 - }
2968 - }
2561 + if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) {
2562 + if ($matrix1Columns < $matrix2Columns) {
2563 + for ($i = 0; $i < $matrix1Rows; ++$i) {
2564 + $x = $matrix1[$i][$matrix1Columns-1];
2565 + for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) {
2566 + $matrix1[$i][$j] = $x;
2567 + }
2568 + }
2569 + }
2570 + if ($matrix1Rows < $matrix2Rows) {
2571 + $x = $matrix1[$matrix1Rows-1];
2572 + for ($i = 0; $i < $matrix2Rows; ++$i) {
2573 + $matrix1[$i] = $x;
2574 + }
2575 + }
2576 + }
2577 + } // function _resizeMatricesExtend()
2969 2578
2970 2579
2971 - /**
2972 - * Format details of an operand for display in the log (based on operand type)
2973 - *
2974 - * @param mixed $value First matrix operand
2975 - * @return mixed
2976 - */
2977 - private function showValue($value)
2978 - {
2979 - if ($this->_debugLog->getWriteDebugLog()) {
2980 - $testArray = PHPExcel_Calculation_Functions::flattenArray($value);
2981 - if (count($testArray) == 1) {
2982 - $value = array_pop($testArray);
2983 - }
2580 + /**
2581 + * Format details of an operand for display in the log (based on operand type)
2582 + *
2583 + * @param mixed $value First matrix operand
2584 + * @return mixed
2585 + */
2586 + private function _showValue($value) {
2587 + if ($this->_debugLog->getWriteDebugLog()) {
2588 + $testArray = PHPExcel_Calculation_Functions::flattenArray($value);
2589 + if (count($testArray) == 1) {
2590 + $value = array_pop($testArray);
2591 + }
2984 2592
2985 - if (is_array($value)) {
2986 - $returnMatrix = array();
2987 - $pad = $rpad = ', ';
2988 - foreach ($value as $row) {
2989 - if (is_array($row)) {
2990 - $returnMatrix[] = implode($pad, array_map(array($this, 'showValue'), $row));
2991 - $rpad = '; ';
2992 - } else {
2993 - $returnMatrix[] = $this->showValue($row);
2994 - }
2995 - }
2996 - return '{ '.implode($rpad, $returnMatrix).' }';
2997 - } elseif (is_string($value) && (trim($value, '"') == $value)) {
2998 - return '"'.$value.'"';
2999 - } elseif (is_bool($value)) {
3000 - return ($value) ? self::$localeBoolean['TRUE'] : self::$localeBoolean['FALSE'];
3001 - }
3002 - }
3003 - return PHPExcel_Calculation_Functions::flattenSingleValue($value);
3004 - }
2593 + if (is_array($value)) {
2594 + $returnMatrix = array();
2595 + $pad = $rpad = ', ';
2596 + foreach($value as $row) {
2597 + if (is_array($row)) {
2598 + $returnMatrix[] = implode($pad,array_map(array($this,'_showValue'),$row));
2599 + $rpad = '; ';
2600 + } else {
2601 + $returnMatrix[] = $this->_showValue($row);
2602 + }
2603 + }
2604 + return '{ '.implode($rpad,$returnMatrix).' }';
2605 + } elseif(is_string($value) && (trim($value,'"') == $value)) {
2606 + return '"'.$value.'"';
2607 + } elseif(is_bool($value)) {
2608 + return ($value) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE'];
2609 + }
2610 + }
2611 + return PHPExcel_Calculation_Functions::flattenSingleValue($value);
2612 + } // function _showValue()
3005 2613
3006 2614
3007 - /**
3008 - * Format type and details of an operand for display in the log (based on operand type)
3009 - *
3010 - * @param mixed $value First matrix operand
3011 - * @return mixed
3012 - */
3013 - private function showTypeDetails($value)
3014 - {
3015 - if ($this->_debugLog->getWriteDebugLog()) {
3016 - $testArray = PHPExcel_Calculation_Functions::flattenArray($value);
3017 - if (count($testArray) == 1) {
3018 - $value = array_pop($testArray);
3019 - }
2615 + /**
2616 + * Format type and details of an operand for display in the log (based on operand type)
2617 + *
2618 + * @param mixed $value First matrix operand
2619 + * @return mixed
2620 + */
2621 + private function _showTypeDetails($value) {
2622 + if ($this->_debugLog->getWriteDebugLog()) {
2623 + $testArray = PHPExcel_Calculation_Functions::flattenArray($value);
2624 + if (count($testArray) == 1) {
2625 + $value = array_pop($testArray);
2626 + }
3020 2627
3021 - if ($value === null) {
3022 - return 'a NULL value';
3023 - } elseif (is_float($value)) {
3024 - $typeString = 'a floating point number';
3025 - } elseif (is_int($value)) {
3026 - $typeString = 'an integer number';
3027 - } elseif (is_bool($value)) {
3028 - $typeString = 'a boolean';
3029 - } elseif (is_array($value)) {
3030 - $typeString = 'a matrix';
3031 - } else {
3032 - if ($value == '') {
3033 - return 'an empty string';
3034 - } elseif ($value{0} == '#') {
3035 - return 'a '.$value.' error';
3036 - } else {
3037 - $typeString = 'a string';
3038 - }
3039 - }
3040 - return $typeString.' with a value of '.$this->showValue($value);
3041 - }
3042 - }
2628 + if ($value === NULL) {
2629 + return 'a NULL value';
2630 + } elseif (is_float($value)) {
2631 + $typeString = 'a floating point number';
2632 + } elseif(is_int($value)) {
2633 + $typeString = 'an integer number';
2634 + } elseif(is_bool($value)) {
2635 + $typeString = 'a boolean';
2636 + } elseif(is_array($value)) {
2637 + $typeString = 'a matrix';
2638 + } else {
2639 + if ($value == '') {
2640 + return 'an empty string';
2641 + } elseif ($value{0} == '#') {
2642 + return 'a '.$value.' error';
2643 + } else {
2644 + $typeString = 'a string';
2645 + }
2646 + }
2647 + return $typeString.' with a value of '.$this->_showValue($value);
2648 + }
2649 + } // function _showTypeDetails()
3043 2650
3044 2651
3045 - private function convertMatrixReferences($formula)
3046 - {
3047 - static $matrixReplaceFrom = array('{', ';', '}');
3048 - static $matrixReplaceTo = array('MKMATRIX(MKMATRIX(', '),MKMATRIX(', '))');
2652 + private function _convertMatrixReferences($formula) {
2653 + static $matrixReplaceFrom = array('{',';','}');
2654 + static $matrixReplaceTo = array('MKMATRIX(MKMATRIX(','),MKMATRIX(','))');
3049 2655
3050 - // Convert any Excel matrix references to the MKMATRIX() function
3051 - if (strpos($formula, '{') !== false) {
3052 - // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators
3053 - if (strpos($formula, '"') !== false) {
3054 - // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded
3055 - // the formula
3056 - $temp = explode('"', $formula);
3057 - // Open and Closed counts used for trapping mismatched braces in the formula
3058 - $openCount = $closeCount = 0;
3059 - $i = false;
3060 - foreach ($temp as &$value) {
3061 - // Only count/replace in alternating array entries
3062 - if ($i = !$i) {
3063 - $openCount += substr_count($value, '{');
3064 - $closeCount += substr_count($value, '}');
3065 - $value = str_replace($matrixReplaceFrom, $matrixReplaceTo, $value);
3066 - }
3067 - }
3068 - unset($value);
3069 - // Then rebuild the formula string
3070 - $formula = implode('"', $temp);
3071 - } else {
3072 - // If there's no quoted strings, then we do a simple count/replace
3073 - $openCount = substr_count($formula, '{');
3074 - $closeCount = substr_count($formula, '}');
3075 - $formula = str_replace($matrixReplaceFrom, $matrixReplaceTo, $formula);
3076 - }
3077 - // Trap for mismatched braces and trigger an appropriate error
3078 - if ($openCount < $closeCount) {
3079 - if ($openCount > 0) {
3080 - return $this->raiseFormulaError("Formula Error: Mismatched matrix braces '}'");
3081 - } else {
3082 - return $this->raiseFormulaError("Formula Error: Unexpected '}' encountered");
3083 - }
3084 - } elseif ($openCount > $closeCount) {
3085 - if ($closeCount > 0) {
3086 - return $this->raiseFormulaError("Formula Error: Mismatched matrix braces '{'");
3087 - } else {
3088 - return $this->raiseFormulaError("Formula Error: Unexpected '{' encountered");
3089 - }
3090 - }
3091 - }
2656 + // Convert any Excel matrix references to the MKMATRIX() function
2657 + if (strpos($formula,'{') !== FALSE) {
2658 + // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators
2659 + if (strpos($formula,'"') !== FALSE) {
2660 + // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded
2661 + // the formula
2662 + $temp = explode('"',$formula);
2663 + // Open and Closed counts used for trapping mismatched braces in the formula
2664 + $openCount = $closeCount = 0;
2665 + $i = FALSE;
2666 + foreach($temp as &$value) {
2667 + // Only count/replace in alternating array entries
2668 + if ($i = !$i) {
2669 + $openCount += substr_count($value,'{');
2670 + $closeCount += substr_count($value,'}');
2671 + $value = str_replace($matrixReplaceFrom,$matrixReplaceTo,$value);
2672 + }
2673 + }
2674 + unset($value);
2675 + // Then rebuild the formula string
2676 + $formula = implode('"',$temp);
2677 + } else {
2678 + // If there's no quoted strings, then we do a simple count/replace
2679 + $openCount = substr_count($formula,'{');
2680 + $closeCount = substr_count($formula,'}');
2681 + $formula = str_replace($matrixReplaceFrom,$matrixReplaceTo,$formula);
2682 + }
2683 + // Trap for mismatched braces and trigger an appropriate error
2684 + if ($openCount < $closeCount) {
2685 + if ($openCount > 0) {
2686 + return $this->_raiseFormulaError("Formula Error: Mismatched matrix braces '}'");
2687 + } else {
2688 + return $this->_raiseFormulaError("Formula Error: Unexpected '}' encountered");
2689 + }
2690 + } elseif ($openCount > $closeCount) {
2691 + if ($closeCount > 0) {
2692 + return $this->_raiseFormulaError("Formula Error: Mismatched matrix braces '{'");
2693 + } else {
2694 + return $this->_raiseFormulaError("Formula Error: Unexpected '{' encountered");
2695 + }
2696 + }
2697 + }
3092 2698
3093 - return $formula;
3094 - }
2699 + return $formula;
2700 + } // function _convertMatrixReferences()
3095 2701
3096 2702
3097 - private static function mkMatrix()
3098 - {
3099 - return func_get_args();
3100 - }
2703 + private static function _mkMatrix() {
2704 + return func_get_args();
2705 + } // function _mkMatrix()
3101 2706
3102 2707
3103 - // Binary Operators
3104 - // These operators always work on two values
3105 - // Array key is the operator, the value indicates whether this is a left or right associative operator
3106 - private static $operatorAssociativity = array(
3107 - '^' => 0, // Exponentiation
3108 - '*' => 0, '/' => 0, // Multiplication and Division
3109 - '+' => 0, '-' => 0, // Addition and Subtraction
3110 - '&' => 0, // Concatenation
3111 - '|' => 0, ':' => 0, // Intersect and Range
3112 - '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison
3113 - );
2708 + // Binary Operators
2709 + // These operators always work on two values
2710 + // Array key is the operator, the value indicates whether this is a left or right associative operator
2711 + private static $_operatorAssociativity = array(
2712 + '^' => 0, // Exponentiation
2713 + '*' => 0, '/' => 0, // Multiplication and Division
2714 + '+' => 0, '-' => 0, // Addition and Subtraction
2715 + '&' => 0, // Concatenation
2716 + '|' => 0, ':' => 0, // Intersect and Range
2717 + '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison
2718 + );
3114 2719
3115 - // Comparison (Boolean) Operators
3116 - // These operators work on two values, but always return a boolean result
3117 - private static $comparisonOperators = array('>' => true, '<' => true, '=' => true, '>=' => true, '<=' => true, '<>' => true);
2720 + // Comparison (Boolean) Operators
2721 + // These operators work on two values, but always return a boolean result
2722 + private static $_comparisonOperators = array('>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE);
3118 2723
3119 - // Operator Precedence
3120 - // This list includes all valid operators, whether binary (including boolean) or unary (such as %)
3121 - // Array key is the operator, the value is its precedence
3122 - private static $operatorPrecedence = array(
3123 - ':' => 8, // Range
3124 - '|' => 7, // Intersect
3125 - '~' => 6, // Negation
3126 - '%' => 5, // Percentage
3127 - '^' => 4, // Exponentiation
3128 - '*' => 3, '/' => 3, // Multiplication and Division
3129 - '+' => 2, '-' => 2, // Addition and Subtraction
3130 - '&' => 1, // Concatenation
3131 - '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison
3132 - );
2724 + // Operator Precedence
2725 + // This list includes all valid operators, whether binary (including boolean) or unary (such as %)
2726 + // Array key is the operator, the value is its precedence
2727 + private static $_operatorPrecedence = array(
2728 + ':' => 8, // Range
2729 + '|' => 7, // Intersect
2730 + '~' => 6, // Negation
2731 + '%' => 5, // Percentage
2732 + '^' => 4, // Exponentiation
2733 + '*' => 3, '/' => 3, // Multiplication and Division
2734 + '+' => 2, '-' => 2, // Addition and Subtraction
2735 + '&' => 1, // Concatenation
2736 + '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison
2737 + );
3133 2738
3134 - // Convert infix to postfix notation
3135 - private function _parseFormula($formula, PHPExcel_Cell $pCell = null)
3136 - {
3137 - if (($formula = $this->convertMatrixReferences(trim($formula))) === false) {
3138 - return false;
3139 - }
2739 + // Convert infix to postfix notation
2740 + private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) {
2741 + if (($formula = $this->_convertMatrixReferences(trim($formula))) === FALSE) {
2742 + return FALSE;
2743 + }
3140 2744
3141 - // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet),
3142 - // so we store the parent worksheet so that we can re-attach it when necessary
3143 - $pCellParent = ($pCell !== null) ? $pCell->getWorksheet() : null;
2745 + // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet),
2746 + // so we store the parent worksheet so that we can re-attach it when necessary
2747 + $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL;
3144 2748
3145 - $regexpMatchString = '/^('.self::CALCULATION_REGEXP_FUNCTION.
3146 - '|'.self::CALCULATION_REGEXP_CELLREF.
3147 - '|'.self::CALCULATION_REGEXP_NUMBER.
3148 - '|'.self::CALCULATION_REGEXP_STRING.
3149 - '|'.self::CALCULATION_REGEXP_OPENBRACE.
3150 - '|'.self::CALCULATION_REGEXP_NAMEDRANGE.
3151 - '|'.self::CALCULATION_REGEXP_ERROR.
3152 - ')/si';
2749 + $regexpMatchString = '/^('.self::CALCULATION_REGEXP_FUNCTION.
2750 + '|'.self::CALCULATION_REGEXP_CELLREF.
2751 + '|'.self::CALCULATION_REGEXP_NUMBER.
2752 + '|'.self::CALCULATION_REGEXP_STRING.
2753 + '|'.self::CALCULATION_REGEXP_OPENBRACE.
2754 + '|'.self::CALCULATION_REGEXP_NAMEDRANGE.
2755 + '|'.self::CALCULATION_REGEXP_ERROR.
2756 + ')/si';
3153 2757
3154 - // Start with initialisation
3155 - $index = 0;
3156 - $stack = new PHPExcel_Calculation_Token_Stack;
3157 - $output = array();
3158 - $expectingOperator = false; // We use this test in syntax-checking the expression to determine when a
3159 - // - is a negation or + is a positive operator rather than an operation
3160 - $expectingOperand = false; // We use this test in syntax-checking the expression to determine whether an operand
3161 - // should be null in a function call
3162 - // The guts of the lexical parser
3163 - // Loop through the formula extracting each operator and operand in turn
3164 - while (true) {
3165 -//echo 'Assessing Expression '.substr($formula, $index), PHP_EOL;
3166 - $opCharacter = $formula{$index}; // Get the first character of the value at the current index position
3167 -//echo 'Initial character of expression block is '.$opCharacter, PHP_EOL;
3168 - if ((isset(self::$comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset(self::$comparisonOperators[$formula{$index+1}]))) {
3169 - $opCharacter .= $formula{++$index};
2758 + // Start with initialisation
2759 + $index = 0;
2760 + $stack = new PHPExcel_Calculation_Token_Stack;
2761 + $output = array();
2762 + $expectingOperator = FALSE; // We use this test in syntax-checking the expression to determine when a
2763 + // - is a negation or + is a positive operator rather than an operation
2764 + $expectingOperand = FALSE; // We use this test in syntax-checking the expression to determine whether an operand
2765 + // should be null in a function call
2766 + // The guts of the lexical parser
2767 + // Loop through the formula extracting each operator and operand in turn
2768 + while(TRUE) {
2769 +//echo 'Assessing Expression '.substr($formula, $index),PHP_EOL;
2770 + $opCharacter = $formula{$index}; // Get the first character of the value at the current index position
2771 +//echo 'Initial character of expression block is '.$opCharacter,PHP_EOL;
2772 + if ((isset(self::$_comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset(self::$_comparisonOperators[$formula{$index+1}]))) {
2773 + $opCharacter .= $formula{++$index};
3170 2774 //echo 'Initial character of expression block is comparison operator '.$opCharacter.PHP_EOL;
3171 - }
2775 + }
3172 2776
3173 - // Find out if we're currently at the beginning of a number, variable, cell reference, function, parenthesis or operand
3174 - $isOperandOrFunction = preg_match($regexpMatchString, substr($formula, $index), $match);
2777 + // Find out if we're currently at the beginning of a number, variable, cell reference, function, parenthesis or operand
2778 + $isOperandOrFunction = preg_match($regexpMatchString, substr($formula, $index), $match);
3175 2779 //echo '$isOperandOrFunction is '.(($isOperandOrFunction) ? 'True' : 'False').PHP_EOL;
3176 2780 //var_dump($match);
3177 2781
3178 - if ($opCharacter == '-' && !$expectingOperator) { // Is it a negation instead of a minus?
3179 -//echo 'Element is a Negation operator', PHP_EOL;
3180 - $stack->push('Unary Operator', '~'); // Put a negation on the stack
3181 - ++$index; // and drop the negation symbol
3182 - } elseif ($opCharacter == '%' && $expectingOperator) {
3183 -//echo 'Element is a Percentage operator', PHP_EOL;
3184 - $stack->push('Unary Operator', '%'); // Put a percentage on the stack
3185 - ++$index;
3186 - } elseif ($opCharacter == '+' && !$expectingOperator) { // Positive (unary plus rather than binary operator plus) can be discarded?
3187 -//echo 'Element is a Positive number, not Plus operator', PHP_EOL;
3188 - ++$index; // Drop the redundant plus symbol
3189 - } elseif ((($opCharacter == '~') || ($opCharacter == '|')) && (!$isOperandOrFunction)) { // We have to explicitly deny a tilde or pipe, because they are legal
3190 - return $this->raiseFormulaError("Formula Error: Illegal character '~'"); // on the stack but not in the input expression
2782 + if ($opCharacter == '-' && !$expectingOperator) { // Is it a negation instead of a minus?
2783 +//echo 'Element is a Negation operator',PHP_EOL;
2784 + $stack->push('Unary Operator','~'); // Put a negation on the stack
2785 + ++$index; // and drop the negation symbol
2786 + } elseif ($opCharacter == '%' && $expectingOperator) {
2787 +//echo 'Element is a Percentage operator',PHP_EOL;
2788 + $stack->push('Unary Operator','%'); // Put a percentage on the stack
2789 + ++$index;
2790 + } elseif ($opCharacter == '+' && !$expectingOperator) { // Positive (unary plus rather than binary operator plus) can be discarded?
2791 +//echo 'Element is a Positive number, not Plus operator',PHP_EOL;
2792 + ++$index; // Drop the redundant plus symbol
2793 + } elseif ((($opCharacter == '~') || ($opCharacter == '|')) && (!$isOperandOrFunction)) { // We have to explicitly deny a tilde or pipe, because they are legal
2794 + return $this->_raiseFormulaError("Formula Error: Illegal character '~'"); // on the stack but not in the input expression
3191 2795
3192 - } elseif ((isset(self::$operators[$opCharacter]) or $isOperandOrFunction) && $expectingOperator) { // Are we putting an operator on the stack?
3193 -//echo 'Element with value '.$opCharacter.' is an Operator', PHP_EOL;
3194 - while ($stack->count() > 0 &&
3195 - ($o2 = $stack->last()) &&
3196 - isset(self::$operators[$o2['value']]) &&
3197 - @(self::$operatorAssociativity[$opCharacter] ? self::$operatorPrecedence[$opCharacter] < self::$operatorPrecedence[$o2['value']] : self::$operatorPrecedence[$opCharacter] <= self::$operatorPrecedence[$o2['value']])) {
3198 - $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output
3199 - }
3200 - $stack->push('Binary Operator', $opCharacter); // Finally put our current operator onto the stack
3201 - ++$index;
3202 - $expectingOperator = false;
2796 + } elseif ((isset(self::$_operators[$opCharacter]) or $isOperandOrFunction) && $expectingOperator) { // Are we putting an operator on the stack?
2797 +//echo 'Element with value '.$opCharacter.' is an Operator',PHP_EOL;
2798 + while($stack->count() > 0 &&
2799 + ($o2 = $stack->last()) &&
2800 + isset(self::$_operators[$o2['value']]) &&
2801 + @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) {
2802 + $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output
2803 + }
2804 + $stack->push('Binary Operator',$opCharacter); // Finally put our current operator onto the stack
2805 + ++$index;
2806 + $expectingOperator = FALSE;
3203 2807
3204 - } elseif ($opCharacter == ')' && $expectingOperator) { // Are we expecting to close a parenthesis?
3205 -//echo 'Element is a Closing bracket', PHP_EOL;
3206 - $expectingOperand = false;
3207 - while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last (
3208 - if ($o2 === null) {
3209 - return $this->raiseFormulaError('Formula Error: Unexpected closing brace ")"');
3210 - } else {
3211 - $output[] = $o2;
3212 - }
3213 - }
3214 - $d = $stack->last(2);
3215 - if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) { // Did this parenthesis just close a function?
3216 - $functionName = $matches[1]; // Get the function name
3217 -//echo 'Closed Function is '.$functionName, PHP_EOL;
3218 - $d = $stack->pop();
3219 - $argumentCount = $d['value']; // See how many arguments there were (argument count is the next value stored on the stack)
2808 + } elseif ($opCharacter == ')' && $expectingOperator) { // Are we expecting to close a parenthesis?
2809 +//echo 'Element is a Closing bracket',PHP_EOL;
2810 + $expectingOperand = FALSE;
2811 + while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last (
2812 + if ($o2 === NULL) return $this->_raiseFormulaError('Formula Error: Unexpected closing brace ")"');
2813 + else $output[] = $o2;
2814 + }
2815 + $d = $stack->last(2);
2816 + if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) { // Did this parenthesis just close a function?
2817 + $functionName = $matches[1]; // Get the function name
2818 +//echo 'Closed Function is '.$functionName,PHP_EOL;
2819 + $d = $stack->pop();
2820 + $argumentCount = $d['value']; // See how many arguments there were (argument count is the next value stored on the stack)
3220 2821 //if ($argumentCount == 0) {
3221 -// echo 'With no arguments', PHP_EOL;
2822 +// echo 'With no arguments',PHP_EOL;
3222 2823 //} elseif ($argumentCount == 1) {
3223 -// echo 'With 1 argument', PHP_EOL;
2824 +// echo 'With 1 argument',PHP_EOL;
3224 2825 //} else {
3225 -// echo 'With '.$argumentCount.' arguments', PHP_EOL;
2826 +// echo 'With '.$argumentCount.' arguments',PHP_EOL;
3226 2827 //}
3227 - $output[] = $d; // Dump the argument count on the output
3228 - $output[] = $stack->pop(); // Pop the function and push onto the output
3229 - if (isset(self::$controlFunctions[$functionName])) {
3230 -//echo 'Built-in function '.$functionName, PHP_EOL;
3231 - $expectedArgumentCount = self::$controlFunctions[$functionName]['argumentCount'];
3232 - $functionCall = self::$controlFunctions[$functionName]['functionCall'];
3233 - } elseif (isset(self::$PHPExcelFunctions[$functionName])) {
3234 -//echo 'PHPExcel function '.$functionName, PHP_EOL;
3235 - $expectedArgumentCount = self::$PHPExcelFunctions[$functionName]['argumentCount'];
3236 - $functionCall = self::$PHPExcelFunctions[$functionName]['functionCall'];
3237 - } else { // did we somehow push a non-function on the stack? this should never happen
3238 - return $this->raiseFormulaError("Formula Error: Internal error, non-function on stack");
3239 - }
3240 - // Check the argument count
3241 - $argumentCountError = false;
3242 - if (is_numeric($expectedArgumentCount)) {
3243 - if ($expectedArgumentCount < 0) {
3244 -//echo '$expectedArgumentCount is between 0 and '.abs($expectedArgumentCount), PHP_EOL;
3245 - if ($argumentCount > abs($expectedArgumentCount)) {
3246 - $argumentCountError = true;
3247 - $expectedArgumentCountString = 'no more than '.abs($expectedArgumentCount);
3248 - }
3249 - } else {
3250 -//echo '$expectedArgumentCount is numeric '.$expectedArgumentCount, PHP_EOL;
3251 - if ($argumentCount != $expectedArgumentCount) {
3252 - $argumentCountError = true;
3253 - $expectedArgumentCountString = $expectedArgumentCount;
3254 - }
3255 - }
3256 - } elseif ($expectedArgumentCount != '*') {
3257 - $isOperandOrFunction = preg_match('/(\d*)([-+,])(\d*)/', $expectedArgumentCount, $argMatch);
2828 + $output[] = $d; // Dump the argument count on the output
2829 + $output[] = $stack->pop(); // Pop the function and push onto the output
2830 + if (isset(self::$_controlFunctions[$functionName])) {
2831 +//echo 'Built-in function '.$functionName,PHP_EOL;
2832 + $expectedArgumentCount = self::$_controlFunctions[$functionName]['argumentCount'];
2833 + $functionCall = self::$_controlFunctions[$functionName]['functionCall'];
2834 + } elseif (isset(self::$_PHPExcelFunctions[$functionName])) {
2835 +//echo 'PHPExcel function '.$functionName,PHP_EOL;
2836 + $expectedArgumentCount = self::$_PHPExcelFunctions[$functionName]['argumentCount'];
2837 + $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall'];
2838 + } else { // did we somehow push a non-function on the stack? this should never happen
2839 + return $this->_raiseFormulaError("Formula Error: Internal error, non-function on stack");
2840 + }
2841 + // Check the argument count
2842 + $argumentCountError = FALSE;
2843 + if (is_numeric($expectedArgumentCount)) {
2844 + if ($expectedArgumentCount < 0) {
2845 +//echo '$expectedArgumentCount is between 0 and '.abs($expectedArgumentCount),PHP_EOL;
2846 + if ($argumentCount > abs($expectedArgumentCount)) {
2847 + $argumentCountError = TRUE;
2848 + $expectedArgumentCountString = 'no more than '.abs($expectedArgumentCount);
2849 + }
2850 + } else {
2851 +//echo '$expectedArgumentCount is numeric '.$expectedArgumentCount,PHP_EOL;
2852 + if ($argumentCount != $expectedArgumentCount) {
2853 + $argumentCountError = TRUE;
2854 + $expectedArgumentCountString = $expectedArgumentCount;
2855 + }
2856 + }
2857 + } elseif ($expectedArgumentCount != '*') {
2858 + $isOperandOrFunction = preg_match('/(\d*)([-+,])(\d*)/',$expectedArgumentCount,$argMatch);
3258 2859 //print_r($argMatch);
3259 2860 //echo PHP_EOL;
3260 - switch ($argMatch[2]) {
3261 - case '+':
3262 - if ($argumentCount < $argMatch[1]) {
3263 - $argumentCountError = true;
3264 - $expectedArgumentCountString = $argMatch[1].' or more ';
3265 - }
3266 - break;
3267 - case '-':
3268 - if (($argumentCount < $argMatch[1]) || ($argumentCount > $argMatch[3])) {
3269 - $argumentCountError = true;
3270 - $expectedArgumentCountString = 'between '.$argMatch[1].' and '.$argMatch[3];
3271 - }
3272 - break;
3273 - case ',':
3274 - if (($argumentCount != $argMatch[1]) && ($argumentCount != $argMatch[3])) {
3275 - $argumentCountError = true;
3276 - $expectedArgumentCountString = 'either '.$argMatch[1].' or '.$argMatch[3];
3277 - }
3278 - break;
3279 - }
3280 - }
3281 - if ($argumentCountError) {
3282 - return $this->raiseFormulaError("Formula Error: Wrong number of arguments for $functionName() function: $argumentCount given, ".$expectedArgumentCountString." expected");
3283 - }
3284 - }
3285 - ++$index;
2861 + switch ($argMatch[2]) {
2862 + case '+' :
2863 + if ($argumentCount < $argMatch[1]) {
2864 + $argumentCountError = TRUE;
2865 + $expectedArgumentCountString = $argMatch[1].' or more ';
2866 + }
2867 + break;
2868 + case '-' :
2869 + if (($argumentCount < $argMatch[1]) || ($argumentCount > $argMatch[3])) {
2870 + $argumentCountError = TRUE;
2871 + $expectedArgumentCountString = 'between '.$argMatch[1].' and '.$argMatch[3];
2872 + }
2873 + break;
2874 + case ',' :
2875 + if (($argumentCount != $argMatch[1]) && ($argumentCount != $argMatch[3])) {
2876 + $argumentCountError = TRUE;
2877 + $expectedArgumentCountString = 'either '.$argMatch[1].' or '.$argMatch[3];
2878 + }
2879 + break;
2880 + }
2881 + }
2882 + if ($argumentCountError) {
2883 + return $this->_raiseFormulaError("Formula Error: Wrong number of arguments for $functionName() function: $argumentCount given, ".$expectedArgumentCountString." expected");
2884 + }
2885 + }
2886 + ++$index;
3286 2887
3287 - } elseif ($opCharacter == ',') { // Is this the separator for function arguments?
3288 -//echo 'Element is a Function argument separator', PHP_EOL;
3289 - while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last (
3290 - if ($o2 === null) {
3291 - return $this->raiseFormulaError("Formula Error: Unexpected ,");
3292 - } else {
3293 - $output[] = $o2; // pop the argument expression stuff and push onto the output
3294 - }
3295 - }
3296 - // If we've a comma when we're expecting an operand, then what we actually have is a null operand;
3297 - // so push a null onto the stack
3298 - if (($expectingOperand) || (!$expectingOperator)) {
3299 - $output[] = array('type' => 'NULL Value', 'value' => self::$excelConstants['NULL'], 'reference' => null);
3300 - }
3301 - // make sure there was a function
3302 - $d = $stack->last(2);
3303 - if (!preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) {
3304 - return $this->raiseFormulaError("Formula Error: Unexpected ,");
3305 - }
3306 - $d = $stack->pop();
3307 - $stack->push($d['type'], ++$d['value'], $d['reference']); // increment the argument count
3308 - $stack->push('Brace', '('); // put the ( back on, we'll need to pop back to it again
3309 - $expectingOperator = false;
3310 - $expectingOperand = true;
3311 - ++$index;
2888 + } elseif ($opCharacter == ',') { // Is this the separator for function arguments?
2889 +//echo 'Element is a Function argument separator',PHP_EOL;
2890 + while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last (
2891 + if ($o2 === NULL) return $this->_raiseFormulaError("Formula Error: Unexpected ,");
2892 + else $output[] = $o2; // pop the argument expression stuff and push onto the output
2893 + }
2894 + // If we've a comma when we're expecting an operand, then what we actually have is a null operand;
2895 + // so push a null onto the stack
2896 + if (($expectingOperand) || (!$expectingOperator)) {
2897 + $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL);
2898 + }
2899 + // make sure there was a function
2900 + $d = $stack->last(2);
2901 + if (!preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches))
2902 + return $this->_raiseFormulaError("Formula Error: Unexpected ,");
2903 + $d = $stack->pop();
2904 + $stack->push($d['type'],++$d['value'],$d['reference']); // increment the argument count
2905 + $stack->push('Brace', '('); // put the ( back on, we'll need to pop back to it again
2906 + $expectingOperator = FALSE;
2907 + $expectingOperand = TRUE;
2908 + ++$index;
3312 2909
3313 - } elseif ($opCharacter == '(' && !$expectingOperator) {
3314 -// echo 'Element is an Opening Bracket<br />';
3315 - $stack->push('Brace', '(');
3316 - ++$index;
2910 + } elseif ($opCharacter == '(' && !$expectingOperator) {
2911 +// echo 'Element is an Opening Bracket<br />';
2912 + $stack->push('Brace', '(');
2913 + ++$index;
3317 2914
3318 - } elseif ($isOperandOrFunction && !$expectingOperator) { // do we now have a function/variable/number?
3319 - $expectingOperator = true;
3320 - $expectingOperand = false;
3321 - $val = $match[1];
3322 - $length = strlen($val);
3323 -// echo 'Element with value '.$val.' is an Operand, Variable, Constant, String, Number, Cell Reference or Function<br />';
2915 + } elseif ($isOperandOrFunction && !$expectingOperator) { // do we now have a function/variable/number?
2916 + $expectingOperator = TRUE;
2917 + $expectingOperand = FALSE;
2918 + $val = $match[1];
2919 + $length = strlen($val);
2920 +// echo 'Element with value '.$val.' is an Operand, Variable, Constant, String, Number, Cell Reference or Function<br />';
3324 2921
3325 - if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $val, $matches)) {
3326 - $val = preg_replace('/\s/u', '', $val);
3327 -// echo 'Element '.$val.' is a Function<br />';
3328 - if (isset(self::$PHPExcelFunctions[strtoupper($matches[1])]) || isset(self::$controlFunctions[strtoupper($matches[1])])) { // it's a function
3329 - $stack->push('Function', strtoupper($val));
3330 - $ax = preg_match('/^\s*(\s*\))/ui', substr($formula, $index+$length), $amatch);
3331 - if ($ax) {
3332 - $stack->push('Operand Count for Function '.strtoupper($val).')', 0);
3333 - $expectingOperator = true;
3334 - } else {
3335 - $stack->push('Operand Count for Function '.strtoupper($val).')', 1);
3336 - $expectingOperator = false;
3337 - }
3338 - $stack->push('Brace', '(');
3339 - } else { // it's a var w/ implicit multiplication
3340 - $output[] = array('type' => 'Value', 'value' => $matches[1], 'reference' => null);
3341 - }
3342 - } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $val, $matches)) {
3343 -// echo 'Element '.$val.' is a Cell reference<br />';
3344 - // Watch for this case-change when modifying to allow cell references in different worksheets...
3345 - // Should only be applied to the actual cell column, not the worksheet name
2922 + if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $val, $matches)) {
2923 + $val = preg_replace('/\s/u','',$val);
2924 +// echo 'Element '.$val.' is a Function<br />';
2925 + if (isset(self::$_PHPExcelFunctions[strtoupper($matches[1])]) || isset(self::$_controlFunctions[strtoupper($matches[1])])) { // it's a function
2926 + $stack->push('Function', strtoupper($val));
2927 + $ax = preg_match('/^\s*(\s*\))/ui', substr($formula, $index+$length), $amatch);
2928 + if ($ax) {
2929 + $stack->push('Operand Count for Function '.strtoupper($val).')', 0);
2930 + $expectingOperator = TRUE;
2931 + } else {
2932 + $stack->push('Operand Count for Function '.strtoupper($val).')', 1);
2933 + $expectingOperator = FALSE;
2934 + }
2935 + $stack->push('Brace', '(');
2936 + } else { // it's a var w/ implicit multiplication
2937 + $output[] = array('type' => 'Value', 'value' => $matches[1], 'reference' => NULL);
2938 + }
2939 + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $val, $matches)) {
2940 +// echo 'Element '.$val.' is a Cell reference<br />';
2941 + // Watch for this case-change when modifying to allow cell references in different worksheets...
2942 + // Should only be applied to the actual cell column, not the worksheet name
3346 2943
3347 - // If the last entry on the stack was a : operator, then we have a cell range reference
3348 - $testPrevOp = $stack->last(1);
3349 - if ($testPrevOp['value'] == ':') {
3350 - // If we have a worksheet reference, then we're playing with a 3D reference
3351 - if ($matches[2] == '') {
3352 - // Otherwise, we 'inherit' the worksheet reference from the start cell reference
3353 - // The start of the cell range reference should be the last entry in $output
3354 - $startCellRef = $output[count($output)-1]['value'];
3355 - preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $startCellRef, $startMatches);
3356 - if ($startMatches[2] > '') {
3357 - $val = $startMatches[2].'!'.$val;
3358 - }
3359 - } else {
3360 - return $this->raiseFormulaError("3D Range references are not yet supported");
3361 - }
3362 - }
2944 + // If the last entry on the stack was a : operator, then we have a cell range reference
2945 + $testPrevOp = $stack->last(1);
2946 + if ($testPrevOp['value'] == ':') {
2947 + // If we have a worksheet reference, then we're playing with a 3D reference
2948 + if ($matches[2] == '') {
2949 + // Otherwise, we 'inherit' the worksheet reference from the start cell reference
2950 + // The start of the cell range reference should be the last entry in $output
2951 + $startCellRef = $output[count($output)-1]['value'];
2952 + preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $startCellRef, $startMatches);
2953 + if ($startMatches[2] > '') {
2954 + $val = $startMatches[2].'!'.$val;
2955 + }
2956 + } else {
2957 + return $this->_raiseFormulaError("3D Range references are not yet supported");
2958 + }
2959 + }
3363 2960
3364 - $output[] = array('type' => 'Cell Reference', 'value' => $val, 'reference' => $val);
3365 -// $expectingOperator = FALSE;
3366 - } else { // it's a variable, constant, string, number or boolean
3367 -// echo 'Element is a Variable, Constant, String, Number or Boolean<br />';
3368 - // If the last entry on the stack was a : operator, then we may have a row or column range reference
3369 - $testPrevOp = $stack->last(1);
3370 - if ($testPrevOp['value'] == ':') {
3371 - $startRowColRef = $output[count($output)-1]['value'];
3372 - $rangeWS1 = '';
3373 - if (strpos('!', $startRowColRef) !== false) {
3374 - list($rangeWS1, $startRowColRef) = explode('!', $startRowColRef);
3375 - }
3376 - if ($rangeWS1 != '') {
3377 - $rangeWS1 .= '!';
3378 - }
3379 - $rangeWS2 = $rangeWS1;
3380 - if (strpos('!', $val) !== false) {
3381 - list($rangeWS2, $val) = explode('!', $val);
3382 - }
3383 - if ($rangeWS2 != '') {
3384 - $rangeWS2 .= '!';
3385 - }
3386 - if ((is_integer($startRowColRef)) && (ctype_digit($val)) &&
3387 - ($startRowColRef <= 1048576) && ($val <= 1048576)) {
3388 - // Row range
3389 - $endRowColRef = ($pCellParent !== null) ? $pCellParent->getHighestColumn() : 'XFD'; // Max 16,384 columns for Excel2007
3390 - $output[count($output)-1]['value'] = $rangeWS1.'A'.$startRowColRef;
3391 - $val = $rangeWS2.$endRowColRef.$val;
3392 - } elseif ((ctype_alpha($startRowColRef)) && (ctype_alpha($val)) &&
3393 - (strlen($startRowColRef) <= 3) && (strlen($val) <= 3)) {
3394 - // Column range
3395 - $endRowColRef = ($pCellParent !== null) ? $pCellParent->getHighestRow() : 1048576; // Max 1,048,576 rows for Excel2007
3396 - $output[count($output)-1]['value'] = $rangeWS1.strtoupper($startRowColRef).'1';
3397 - $val = $rangeWS2.$val.$endRowColRef;
3398 - }
3399 - }
2961 + $output[] = array('type' => 'Cell Reference', 'value' => $val, 'reference' => $val);
2962 +// $expectingOperator = FALSE;
2963 + } else { // it's a variable, constant, string, number or boolean
2964 +// echo 'Element is a Variable, Constant, String, Number or Boolean<br />';
2965 + // If the last entry on the stack was a : operator, then we may have a row or column range reference
2966 + $testPrevOp = $stack->last(1);
2967 + if ($testPrevOp['value'] == ':') {
2968 + $startRowColRef = $output[count($output)-1]['value'];
2969 + $rangeWS1 = '';
2970 + if (strpos('!',$startRowColRef) !== FALSE) {
2971 + list($rangeWS1,$startRowColRef) = explode('!',$startRowColRef);
2972 + }
2973 + if ($rangeWS1 != '') $rangeWS1 .= '!';
2974 + $rangeWS2 = $rangeWS1;
2975 + if (strpos('!',$val) !== FALSE) {
2976 + list($rangeWS2,$val) = explode('!',$val);
2977 + }
2978 + if ($rangeWS2 != '') $rangeWS2 .= '!';
2979 + if ((is_integer($startRowColRef)) && (ctype_digit($val)) &&
2980 + ($startRowColRef <= 1048576) && ($val <= 1048576)) {
2981 + // Row range
2982 + $endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestColumn() : 'XFD'; // Max 16,384 columns for Excel2007
2983 + $output[count($output)-1]['value'] = $rangeWS1.'A'.$startRowColRef;
2984 + $val = $rangeWS2.$endRowColRef.$val;
2985 + } elseif ((ctype_alpha($startRowColRef)) && (ctype_alpha($val)) &&
2986 + (strlen($startRowColRef) <= 3) && (strlen($val) <= 3)) {
2987 + // Column range
2988 + $endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestRow() : 1048576; // Max 1,048,576 rows for Excel2007
2989 + $output[count($output)-1]['value'] = $rangeWS1.strtoupper($startRowColRef).'1';
2990 + $val = $rangeWS2.$val.$endRowColRef;
2991 + }
2992 + }
3400 2993
3401 - $localeConstant = false;
3402 - if ($opCharacter == '"') {
3403 -// echo 'Element is a String<br />';
3404 - // UnEscape any quotes within the string
3405 - $val = self::wrapResult(str_replace('""', '"', self::unwrapResult($val)));
3406 - } elseif (is_numeric($val)) {
3407 -// echo 'Element is a Number<br />';
3408 - if ((strpos($val, '.') !== false) || (stripos($val, 'e') !== false) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) {
3409 -// echo 'Casting '.$val.' to float<br />';
3410 - $val = (float) $val;
3411 - } else {
3412 -// echo 'Casting '.$val.' to integer<br />';
3413 - $val = (integer) $val;
3414 - }
3415 - } elseif (isset(self::$excelConstants[trim(strtoupper($val))])) {
3416 - $excelConstant = trim(strtoupper($val));
3417 -// echo 'Element '.$excelConstant.' is an Excel Constant<br />';
3418 - $val = self::$excelConstants[$excelConstant];
3419 - } elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$localeBoolean)) !== false) {
3420 -// echo 'Element '.$localeConstant.' is an Excel Constant<br />';
3421 - $val = self::$excelConstants[$localeConstant];
3422 - }
3423 - $details = array('type' => 'Value', 'value' => $val, 'reference' => null);
3424 - if ($localeConstant) {
3425 - $details['localeValue'] = $localeConstant;
3426 - }
3427 - $output[] = $details;
3428 - }
3429 - $index += $length;
2994 + $localeConstant = FALSE;
2995 + if ($opCharacter == '"') {
2996 +// echo 'Element is a String<br />';
2997 + // UnEscape any quotes within the string
2998 + $val = self::_wrapResult(str_replace('""','"',self::_unwrapResult($val)));
2999 + } elseif (is_numeric($val)) {
3000 +// echo 'Element is a Number<br />';
3001 + if ((strpos($val,'.') !== FALSE) || (stripos($val,'e') !== FALSE) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) {
3002 +// echo 'Casting '.$val.' to float<br />';
3003 + $val = (float) $val;
3004 + } else {
3005 +// echo 'Casting '.$val.' to integer<br />';
3006 + $val = (integer) $val;
3007 + }
3008 + } elseif (isset(self::$_ExcelConstants[trim(strtoupper($val))])) {
3009 + $excelConstant = trim(strtoupper($val));
3010 +// echo 'Element '.$excelConstant.' is an Excel Constant<br />';
3011 + $val = self::$_ExcelConstants[$excelConstant];
3012 + } elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$_localeBoolean)) !== FALSE) {
3013 +// echo 'Element '.$localeConstant.' is an Excel Constant<br />';
3014 + $val = self::$_ExcelConstants[$localeConstant];
3015 + }
3016 + $details = array('type' => 'Value', 'value' => $val, 'reference' => NULL);
3017 + if ($localeConstant) { $details['localeValue'] = $localeConstant; }
3018 + $output[] = $details;
3019 + }
3020 + $index += $length;
3430 3021
3431 - } elseif ($opCharacter == '$') { // absolute row or column range
3432 - ++$index;
3433 - } elseif ($opCharacter == ')') { // miscellaneous error checking
3434 - if ($expectingOperand) {
3435 - $output[] = array('type' => 'NULL Value', 'value' => self::$excelConstants['NULL'], 'reference' => null);
3436 - $expectingOperand = false;
3437 - $expectingOperator = true;
3438 - } else {
3439 - return $this->raiseFormulaError("Formula Error: Unexpected ')'");
3440 - }
3441 - } elseif (isset(self::$operators[$opCharacter]) && !$expectingOperator) {
3442 - return $this->raiseFormulaError("Formula Error: Unexpected operator '$opCharacter'");
3443 - } else { // I don't even want to know what you did to get here
3444 - return $this->raiseFormulaError("Formula Error: An unexpected error occured");
3445 - }
3446 - // Test for end of formula string
3447 - if ($index == strlen($formula)) {
3448 - // Did we end with an operator?.
3449 - // Only valid for the % unary operator
3450 - if ((isset(self::$operators[$opCharacter])) && ($opCharacter != '%')) {
3451 - return $this->raiseFormulaError("Formula Error: Operator '$opCharacter' has no operands");
3452 - } else {
3453 - break;
3454 - }
3455 - }
3456 - // Ignore white space
3457 - while (($formula{$index} == "\n") || ($formula{$index} == "\r")) {
3458 - ++$index;
3459 - }
3460 - if ($formula{$index} == ' ') {
3461 - while ($formula{$index} == ' ') {
3462 - ++$index;
3463 - }
3464 - // If we're expecting an operator, but only have a space between the previous and next operands (and both are
3465 - // Cell References) then we have an INTERSECTION operator
3466 -// echo 'Possible Intersect Operator<br />';
3467 - if (($expectingOperator) && (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'.*/Ui', substr($formula, $index), $match)) &&
3468 - ($output[count($output)-1]['type'] == 'Cell Reference')) {
3469 -// echo 'Element is an Intersect Operator<br />';
3470 - while ($stack->count() > 0 &&
3471 - ($o2 = $stack->last()) &&
3472 - isset(self::$operators[$o2['value']]) &&
3473 - @(self::$operatorAssociativity[$opCharacter] ? self::$operatorPrecedence[$opCharacter] < self::$operatorPrecedence[$o2['value']] : self::$operatorPrecedence[$opCharacter] <= self::$operatorPrecedence[$o2['value']])) {
3474 - $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output
3475 - }
3476 - $stack->push('Binary Operator', '|'); // Put an Intersect Operator on the stack
3477 - $expectingOperator = false;
3478 - }
3479 - }
3480 - }
3022 + } elseif ($opCharacter == '$') { // absolute row or column range
3023 + ++$index;
3024 + } elseif ($opCharacter == ')') { // miscellaneous error checking
3025 + if ($expectingOperand) {
3026 + $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL);
3027 + $expectingOperand = FALSE;
3028 + $expectingOperator = TRUE;
3029 + } else {
3030 + return $this->_raiseFormulaError("Formula Error: Unexpected ')'");
3031 + }
3032 + } elseif (isset(self::$_operators[$opCharacter]) && !$expectingOperator) {
3033 + return $this->_raiseFormulaError("Formula Error: Unexpected operator '$opCharacter'");
3034 + } else { // I don't even want to know what you did to get here
3035 + return $this->_raiseFormulaError("Formula Error: An unexpected error occured");
3036 + }
3037 + // Test for end of formula string
3038 + if ($index == strlen($formula)) {
3039 + // Did we end with an operator?.
3040 + // Only valid for the % unary operator
3041 + if ((isset(self::$_operators[$opCharacter])) && ($opCharacter != '%')) {
3042 + return $this->_raiseFormulaError("Formula Error: Operator '$opCharacter' has no operands");
3043 + } else {
3044 + break;
3045 + }
3046 + }
3047 + // Ignore white space
3048 + while (($formula{$index} == "\n") || ($formula{$index} == "\r")) {
3049 + ++$index;
3050 + }
3051 + if ($formula{$index} == ' ') {
3052 + while ($formula{$index} == ' ') {
3053 + ++$index;
3054 + }
3055 + // If we're expecting an operator, but only have a space between the previous and next operands (and both are
3056 + // Cell References) then we have an INTERSECTION operator
3057 +// echo 'Possible Intersect Operator<br />';
3058 + if (($expectingOperator) && (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'.*/Ui', substr($formula, $index), $match)) &&
3059 + ($output[count($output)-1]['type'] == 'Cell Reference')) {
3060 +// echo 'Element is an Intersect Operator<br />';
3061 + while($stack->count() > 0 &&
3062 + ($o2 = $stack->last()) &&
3063 + isset(self::$_operators[$o2['value']]) &&
3064 + @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) {
3065 + $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output
3066 + }
3067 + $stack->push('Binary Operator','|'); // Put an Intersect Operator on the stack
3068 + $expectingOperator = FALSE;
3069 + }
3070 + }
3071 + }
3481 3072
3482 - while (($op = $stack->pop()) !== null) { // pop everything off the stack and push onto output
3483 - if ((is_array($op) && $op['value'] == '(') || ($op === '(')) {
3484 - return $this->raiseFormulaError("Formula Error: Expecting ')'"); // if there are any opening braces on the stack, then braces were unbalanced
3485 - }
3486 - $output[] = $op;
3487 - }
3488 - return $output;
3489 - }
3073 + while (($op = $stack->pop()) !== NULL) { // pop everything off the stack and push onto output
3074 + if ((is_array($op) && $op['value'] == '(') || ($op === '('))
3075 + return $this->_raiseFormulaError("Formula Error: Expecting ')'"); // if there are any opening braces on the stack, then braces were unbalanced
3076 + $output[] = $op;
3077 + }
3078 + return $output;
3079 + } // function _parseFormula()
3490 3080
3491 3081
3492 - private static function dataTestReference(&$operandData)
3493 - {
3494 - $operand = $operandData['value'];
3495 - if (($operandData['reference'] === null) && (is_array($operand))) {
3496 - $rKeys = array_keys($operand);
3497 - $rowKey = array_shift($rKeys);
3498 - $cKeys = array_keys(array_keys($operand[$rowKey]));
3499 - $colKey = array_shift($cKeys);
3500 - if (ctype_upper($colKey)) {
3501 - $operandData['reference'] = $colKey.$rowKey;
3502 - }
3503 - }
3504 - return $operand;
3505 - }
3082 + private static function _dataTestReference(&$operandData)
3083 + {
3084 + $operand = $operandData['value'];
3085 + if (($operandData['reference'] === NULL) && (is_array($operand))) {
3086 + $rKeys = array_keys($operand);
3087 + $rowKey = array_shift($rKeys);
3088 + $cKeys = array_keys(array_keys($operand[$rowKey]));
3089 + $colKey = array_shift($cKeys);
3090 + if (ctype_upper($colKey)) {
3091 + $operandData['reference'] = $colKey.$rowKey;
3092 + }
3093 + }
3094 + return $operand;
3095 + }
3506 3096
3507 - // evaluate postfix notation
3508 - private function processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCell = null)
3509 - {
3510 - if ($tokens == false) {
3511 - return false;
3512 - }
3097 + // evaluate postfix notation
3098 + private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCell = NULL) {
3099 + if ($tokens == FALSE) return FALSE;
3513 3100
3514 - // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent cell collection),
3515 - // so we store the parent cell collection so that we can re-attach it when necessary
3516 - $pCellWorksheet = ($pCell !== null) ? $pCell->getWorksheet() : null;
3517 - $pCellParent = ($pCell !== null) ? $pCell->getParent() : null;
3518 - $stack = new PHPExcel_Calculation_Token_Stack;
3101 + // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent cell collection),
3102 + // so we store the parent cell collection so that we can re-attach it when necessary
3103 + $pCellWorksheet = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL;
3104 + $pCellParent = ($pCell !== NULL) ? $pCell->getParent() : null;
3105 + $stack = new PHPExcel_Calculation_Token_Stack;
3519 3106
3520 - // Loop through each token in turn
3521 - foreach ($tokens as $tokenData) {
3522 -// print_r($tokenData);
3523 -// echo '<br />';
3524 - $token = $tokenData['value'];
3525 -// echo '<b>Token is '.$token.'</b><br />';
3526 - // if the token is a binary operator, pop the top two values off the stack, do the operation, and push the result back on the stack
3527 - if (isset(self::$binaryOperators[$token])) {
3528 -// echo 'Token is a binary operator<br />';
3529 - // We must have two operands, error if we don't
3530 - if (($operand2Data = $stack->pop()) === null) {
3531 - return $this->raiseFormulaError('Internal error - Operand value missing from stack');
3532 - }
3533 - if (($operand1Data = $stack->pop()) === null) {
3534 - return $this->raiseFormulaError('Internal error - Operand value missing from stack');
3535 - }
3107 + // Loop through each token in turn
3108 + foreach ($tokens as $tokenData) {
3109 +// print_r($tokenData);
3110 +// echo '<br />';
3111 + $token = $tokenData['value'];
3112 +// echo '<b>Token is '.$token.'</b><br />';
3113 + // if the token is a binary operator, pop the top two values off the stack, do the operation, and push the result back on the stack
3114 + if (isset(self::$_binaryOperators[$token])) {
3115 +// echo 'Token is a binary operator<br />';
3116 + // We must have two operands, error if we don't
3117 + if (($operand2Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack');
3118 + if (($operand1Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack');
3536 3119
3537 - $operand1 = self::dataTestReference($operand1Data);
3538 - $operand2 = self::dataTestReference($operand2Data);
3120 + $operand1 = self::_dataTestReference($operand1Data);
3121 + $operand2 = self::_dataTestReference($operand2Data);
3539 3122
3540 - // Log what we're doing
3541 - if ($token == ':') {
3542 - $this->_debugLog->writeDebugLog('Evaluating Range ', $this->showValue($operand1Data['reference']), ' ', $token, ' ', $this->showValue($operand2Data['reference']));
3543 - } else {
3544 - $this->_debugLog->writeDebugLog('Evaluating ', $this->showValue($operand1), ' ', $token, ' ', $this->showValue($operand2));
3545 - }
3123 + // Log what we're doing
3124 + if ($token == ':') {
3125 + $this->_debugLog->writeDebugLog('Evaluating Range ', $this->_showValue($operand1Data['reference']), ' ', $token, ' ', $this->_showValue($operand2Data['reference']));
3126 + } else {
3127 + $this->_debugLog->writeDebugLog('Evaluating ', $this->_showValue($operand1), ' ', $token, ' ', $this->_showValue($operand2));
3128 + }
3546 3129
3547 - // Process the operation in the appropriate manner
3548 - switch ($token) {
3549 - // Comparison (Boolean) Operators
3550 - case '>': // Greater than
3551 - case '<': // Less than
3552 - case '>=': // Greater than or Equal to
3553 - case '<=': // Less than or Equal to
3554 - case '=': // Equality
3555 - case '<>': // Inequality
3556 - $this->executeBinaryComparisonOperation($cellID, $operand1, $operand2, $token, $stack);
3557 - break;
3558 - // Binary Operators
3559 - case ':': // Range
3560 - $sheet1 = $sheet2 = '';
3561 - if (strpos($operand1Data['reference'], '!') !== false) {
3562 - list($sheet1, $operand1Data['reference']) = explode('!', $operand1Data['reference']);
3563 - } else {
3564 - $sheet1 = ($pCellParent !== null) ? $pCellWorksheet->getTitle() : '';
3565 - }
3566 - if (strpos($operand2Data['reference'], '!') !== false) {
3567 - list($sheet2, $operand2Data['reference']) = explode('!', $operand2Data['reference']);
3568 - } else {
3569 - $sheet2 = $sheet1;
3570 - }
3571 - if ($sheet1 == $sheet2) {
3572 - if ($operand1Data['reference'] === null) {
3573 - if ((trim($operand1Data['value']) != '') && (is_numeric($operand1Data['value']))) {
3574 - $operand1Data['reference'] = $pCell->getColumn().$operand1Data['value'];
3575 - } elseif (trim($operand1Data['reference']) == '') {
3576 - $operand1Data['reference'] = $pCell->getCoordinate();
3577 - } else {
3578 - $operand1Data['reference'] = $operand1Data['value'].$pCell->getRow();
3579 - }
3580 - }
3581 - if ($operand2Data['reference'] === null) {
3582 - if ((trim($operand2Data['value']) != '') && (is_numeric($operand2Data['value']))) {
3583 - $operand2Data['reference'] = $pCell->getColumn().$operand2Data['value'];
3584 - } elseif (trim($operand2Data['reference']) == '') {
3585 - $operand2Data['reference'] = $pCell->getCoordinate();
3586 - } else {
3587 - $operand2Data['reference'] = $operand2Data['value'].$pCell->getRow();
3588 - }
3589 - }
3130 + // Process the operation in the appropriate manner
3131 + switch ($token) {
3132 + // Comparison (Boolean) Operators
3133 + case '>' : // Greater than
3134 + case '<' : // Less than
3135 + case '>=' : // Greater than or Equal to
3136 + case '<=' : // Less than or Equal to
3137 + case '=' : // Equality
3138 + case '<>' : // Inequality
3139 + $this->_executeBinaryComparisonOperation($cellID,$operand1,$operand2,$token,$stack);
3140 + break;
3141 + // Binary Operators
3142 + case ':' : // Range
3143 + $sheet1 = $sheet2 = '';
3144 + if (strpos($operand1Data['reference'],'!') !== FALSE) {
3145 + list($sheet1,$operand1Data['reference']) = explode('!',$operand1Data['reference']);
3146 + } else {
3147 + $sheet1 = ($pCellParent !== NULL) ? $pCellWorksheet->getTitle() : '';
3148 + }
3149 + if (strpos($operand2Data['reference'],'!') !== FALSE) {
3150 + list($sheet2,$operand2Data['reference']) = explode('!',$operand2Data['reference']);
3151 + } else {
3152 + $sheet2 = $sheet1;
3153 + }
3154 + if ($sheet1 == $sheet2) {
3155 + if ($operand1Data['reference'] === NULL) {
3156 + if ((trim($operand1Data['value']) != '') && (is_numeric($operand1Data['value']))) {
3157 + $operand1Data['reference'] = $pCell->getColumn().$operand1Data['value'];
3158 + } elseif (trim($operand1Data['reference']) == '') {
3159 + $operand1Data['reference'] = $pCell->getCoordinate();
3160 + } else {
3161 + $operand1Data['reference'] = $operand1Data['value'].$pCell->getRow();
3162 + }
3163 + }
3164 + if ($operand2Data['reference'] === NULL) {
3165 + if ((trim($operand2Data['value']) != '') && (is_numeric($operand2Data['value']))) {
3166 + $operand2Data['reference'] = $pCell->getColumn().$operand2Data['value'];
3167 + } elseif (trim($operand2Data['reference']) == '') {
3168 + $operand2Data['reference'] = $pCell->getCoordinate();
3169 + } else {
3170 + $operand2Data['reference'] = $operand2Data['value'].$pCell->getRow();
3171 + }
3172 + }
3590 3173
3591 - $oData = array_merge(explode(':', $operand1Data['reference']), explode(':', $operand2Data['reference']));
3592 - $oCol = $oRow = array();
3593 - foreach ($oData as $oDatum) {
3594 - $oCR = PHPExcel_Cell::coordinateFromString($oDatum);
3595 - $oCol[] = PHPExcel_Cell::columnIndexFromString($oCR[0]) - 1;
3596 - $oRow[] = $oCR[1];
3597 - }
3598 - $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow);
3599 - if ($pCellParent !== null) {
3600 - $cellValue = $this->extractCellRange($cellRef, $this->workbook->getSheetByName($sheet1), false);
3601 - } else {
3602 - return $this->raiseFormulaError('Unable to access Cell Reference');
3603 - }
3604 - $stack->push('Cell Reference', $cellValue, $cellRef);
3605 - } else {
3606 - $stack->push('Error', PHPExcel_Calculation_Functions::REF(), null);
3607 - }
3608 - break;
3609 - case '+': // Addition
3610 - $this->executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'plusEquals', $stack);
3611 - break;
3612 - case '-': // Subtraction
3613 - $this->executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'minusEquals', $stack);
3614 - break;
3615 - case '*': // Multiplication
3616 - $this->executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'arrayTimesEquals', $stack);
3617 - break;
3618 - case '/': // Division
3619 - $this->executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'arrayRightDivide', $stack);
3620 - break;
3621 - case '^': // Exponential
3622 - $this->executeNumericBinaryOperation($cellID, $operand1, $operand2, $token, 'power', $stack);
3623 - break;
3624 - case '&': // Concatenation
3625 - // If either of the operands is a matrix, we need to treat them both as matrices
3626 - // (converting the other operand to a matrix if need be); then perform the required
3627 - // matrix operation
3628 - if (is_bool($operand1)) {
3629 - $operand1 = ($operand1) ? self::$localeBoolean['TRUE'] : self::$localeBoolean['FALSE'];
3630 - }
3631 - if (is_bool($operand2)) {
3632 - $operand2 = ($operand2) ? self::$localeBoolean['TRUE'] : self::$localeBoolean['FALSE'];
3633 - }
3634 - if ((is_array($operand1)) || (is_array($operand2))) {
3635 - // Ensure that both operands are arrays/matrices
3636 - self::checkMatrixOperands($operand1, $operand2, 2);
3637 - try {
3638 - // Convert operand 1 from a PHP array to a matrix
3639 - $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1);
3640 - // Perform the required operation against the operand 1 matrix, passing in operand 2
3641 - $matrixResult = $matrix->concat($operand2);
3642 - $result = $matrixResult->getArray();
3643 - } catch (PHPExcel_Exception $ex) {
3644 - $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage());
3645 - $result = '#VALUE!';
3646 - }
3647 - } else {
3648 - $result = '"'.str_replace('""', '"', self::unwrapResult($operand1, '"').self::unwrapResult($operand2, '"')).'"';
3649 - }
3650 - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->showTypeDetails($result));
3651 - $stack->push('Value', $result);
3652 - break;
3653 - case '|': // Intersect
3654 - $rowIntersect = array_intersect_key($operand1, $operand2);
3655 - $cellIntersect = $oCol = $oRow = array();
3656 - foreach (array_keys($rowIntersect) as $row) {
3657 - $oRow[] = $row;
3658 - foreach ($rowIntersect[$row] as $col => $data) {
3659 - $oCol[] = PHPExcel_Cell::columnIndexFromString($col) - 1;
3660 - $cellIntersect[$row] = array_intersect_key($operand1[$row], $operand2[$row]);
3661 - }
3662 - }
3663 - $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow);
3664 - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->showTypeDetails($cellIntersect));
3665 - $stack->push('Value', $cellIntersect, $cellRef);
3666 - break;
3667 - }
3174 + $oData = array_merge(explode(':',$operand1Data['reference']),explode(':',$operand2Data['reference']));
3175 + $oCol = $oRow = array();
3176 + foreach($oData as $oDatum) {
3177 + $oCR = PHPExcel_Cell::coordinateFromString($oDatum);
3178 + $oCol[] = PHPExcel_Cell::columnIndexFromString($oCR[0]) - 1;
3179 + $oRow[] = $oCR[1];
3180 + }
3181 + $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow);
3182 + if ($pCellParent !== NULL) {
3183 + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($sheet1), FALSE);
3184 + } else {
3185 + return $this->_raiseFormulaError('Unable to access Cell Reference');
3186 + }
3187 + $stack->push('Cell Reference',$cellValue,$cellRef);
3188 + } else {
3189 + $stack->push('Error',PHPExcel_Calculation_Functions::REF(),NULL);
3190 + }
3668 3191
3669 - // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on
3670 - } elseif (($token === '~') || ($token === '%')) {
3671 -// echo 'Token is a unary operator<br />';
3672 - if (($arg = $stack->pop()) === null) {
3673 - return $this->raiseFormulaError('Internal error - Operand value missing from stack');
3674 - }
3675 - $arg = $arg['value'];
3676 - if ($token === '~') {
3677 -// echo 'Token is a negation operator<br />';
3678 - $this->_debugLog->writeDebugLog('Evaluating Negation of ', $this->showValue($arg));
3679 - $multiplier = -1;
3680 - } else {
3681 -// echo 'Token is a percentile operator<br />';
3682 - $this->_debugLog->writeDebugLog('Evaluating Percentile of ', $this->showValue($arg));
3683 - $multiplier = 0.01;
3684 - }
3685 - if (is_array($arg)) {
3686 - self::checkMatrixOperands($arg, $multiplier, 2);
3687 - try {
3688 - $matrix1 = new PHPExcel_Shared_JAMA_Matrix($arg);
3689 - $matrixResult = $matrix1->arrayTimesEquals($multiplier);
3690 - $result = $matrixResult->getArray();
3691 - } catch (PHPExcel_Exception $ex) {
3692 - $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage());
3693 - $result = '#VALUE!';
3694 - }
3695 - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->showTypeDetails($result));
3696 - $stack->push('Value', $result);
3697 - } else {
3698 - $this->executeNumericBinaryOperation($cellID, $multiplier, $arg, '*', 'arrayTimesEquals', $stack);
3699 - }
3192 + break;
3193 + case '+' : // Addition
3194 + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'plusEquals',$stack);
3195 + break;
3196 + case '-' : // Subtraction
3197 + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'minusEquals',$stack);
3198 + break;
3199 + case '*' : // Multiplication
3200 + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayTimesEquals',$stack);
3201 + break;
3202 + case '/' : // Division
3203 + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayRightDivide',$stack);
3204 + break;
3205 + case '^' : // Exponential
3206 + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'power',$stack);
3207 + break;
3208 + case '&' : // Concatenation
3209 + // If either of the operands is a matrix, we need to treat them both as matrices
3210 + // (converting the other operand to a matrix if need be); then perform the required
3211 + // matrix operation
3212 + if (is_bool($operand1)) {
3213 + $operand1 = ($operand1) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE'];
3214 + }
3215 + if (is_bool($operand2)) {
3216 + $operand2 = ($operand2) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE'];
3217 + }
3218 + if ((is_array($operand1)) || (is_array($operand2))) {
3219 + // Ensure that both operands are arrays/matrices
3220 + self::_checkMatrixOperands($operand1,$operand2,2);
3221 + try {
3222 + // Convert operand 1 from a PHP array to a matrix
3223 + $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1);
3224 + // Perform the required operation against the operand 1 matrix, passing in operand 2
3225 + $matrixResult = $matrix->concat($operand2);
3226 + $result = $matrixResult->getArray();
3227 + } catch (PHPExcel_Exception $ex) {
3228 + $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage());
3229 + $result = '#VALUE!';
3230 + }
3231 + } else {
3232 + $result = '"'.str_replace('""','"',self::_unwrapResult($operand1,'"').self::_unwrapResult($operand2,'"')).'"';
3233 + }
3234 + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result));
3235 + $stack->push('Value',$result);
3236 + break;
3237 + case '|' : // Intersect
3238 + $rowIntersect = array_intersect_key($operand1,$operand2);
3239 + $cellIntersect = $oCol = $oRow = array();
3240 + foreach(array_keys($rowIntersect) as $row) {
3241 + $oRow[] = $row;
3242 + foreach($rowIntersect[$row] as $col => $data) {
3243 + $oCol[] = PHPExcel_Cell::columnIndexFromString($col) - 1;
3244 + $cellIntersect[$row] = array_intersect_key($operand1[$row],$operand2[$row]);
3245 + }
3246 + }
3247 + $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow);
3248 + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($cellIntersect));
3249 + $stack->push('Value',$cellIntersect,$cellRef);
3250 + break;
3251 + }
3700 3252
3701 - } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $token, $matches)) {
3702 - $cellRef = null;
3703 -// echo 'Element '.$token.' is a Cell reference<br />';
3704 - if (isset($matches[8])) {
3705 -// echo 'Reference is a Range of cells<br />';
3706 - if ($pCell === null) {
3707 -// We can't access the range, so return a REF error
3708 - $cellValue = PHPExcel_Calculation_Functions::REF();
3709 - } else {
3710 - $cellRef = $matches[6].$matches[7].':'.$matches[9].$matches[10];
3711 - if ($matches[2] > '') {
3712 - $matches[2] = trim($matches[2], "\"'");
3713 - if ((strpos($matches[2], '[') !== false) || (strpos($matches[2], ']') !== false)) {
3714 - // It's a Reference to an external workbook (not currently supported)
3715 - return $this->raiseFormulaError('Unable to access External Workbook');
3716 - }
3717 - $matches[2] = trim($matches[2], "\"'");
3718 -// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />';
3719 - $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]);
3720 - if ($pCellParent !== null) {
3721 - $cellValue = $this->extractCellRange($cellRef, $this->workbook->getSheetByName($matches[2]), false);
3722 - } else {
3723 - return $this->raiseFormulaError('Unable to access Cell Reference');
3724 - }
3725 - $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->showTypeDetails($cellValue));
3726 -// $cellRef = $matches[2].'!'.$cellRef;
3727 - } else {
3728 -// echo '$cellRef='.$cellRef.' in current worksheet<br />';
3729 - $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in current worksheet');
3730 - if ($pCellParent !== null) {
3731 - $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, false);
3732 - } else {
3733 - return $this->raiseFormulaError('Unable to access Cell Reference');
3734 - }
3735 - $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' is ', $this->showTypeDetails($cellValue));
3736 - }
3737 - }
3738 - } else {
3739 -// echo 'Reference is a single Cell<br />';
3740 - if ($pCell === null) {
3741 -// We can't access the cell, so return a REF error
3742 - $cellValue = PHPExcel_Calculation_Functions::REF();
3743 - } else {
3744 - $cellRef = $matches[6].$matches[7];
3745 - if ($matches[2] > '') {
3746 - $matches[2] = trim($matches[2], "\"'");
3747 - if ((strpos($matches[2], '[') !== false) || (strpos($matches[2], ']') !== false)) {
3748 - // It's a Reference to an external workbook (not currently supported)
3749 - return $this->raiseFormulaError('Unable to access External Workbook');
3750 - }
3751 -// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />';
3752 - $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]);
3753 - if ($pCellParent !== null) {
3754 - $cellSheet = $this->workbook->getSheetByName($matches[2]);
3755 - if ($cellSheet && $cellSheet->cellExists($cellRef)) {
3756 - $cellValue = $this->extractCellRange($cellRef, $this->workbook->getSheetByName($matches[2]), false);
3757 - $pCell->attach($pCellParent);
3758 - } else {
3759 - $cellValue = null;
3760 - }
3761 - } else {
3762 - return $this->raiseFormulaError('Unable to access Cell Reference');
3763 - }
3764 - $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->showTypeDetails($cellValue));
3765 -// $cellRef = $matches[2].'!'.$cellRef;
3766 - } else {
3767 -// echo '$cellRef='.$cellRef.' in current worksheet<br />';
3768 - $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in current worksheet');
3769 - if ($pCellParent->isDataSet($cellRef)) {
3770 - $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, false);
3771 - $pCell->attach($pCellParent);
3772 - } else {
3773 - $cellValue = null;
3774 - }
3775 - $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' is ', $this->showTypeDetails($cellValue));
3776 - }
3777 - }
3778 - }
3779 - $stack->push('Value', $cellValue, $cellRef);
3253 + // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on
3254 + } elseif (($token === '~') || ($token === '%')) {
3255 +// echo 'Token is a unary operator<br />';
3256 + if (($arg = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack');
3257 + $arg = $arg['value'];
3258 + if ($token === '~') {
3259 +// echo 'Token is a negation operator<br />';
3260 + $this->_debugLog->writeDebugLog('Evaluating Negation of ', $this->_showValue($arg));
3261 + $multiplier = -1;
3262 + } else {
3263 +// echo 'Token is a percentile operator<br />';
3264 + $this->_debugLog->writeDebugLog('Evaluating Percentile of ', $this->_showValue($arg));
3265 + $multiplier = 0.01;
3266 + }
3267 + if (is_array($arg)) {
3268 + self::_checkMatrixOperands($arg,$multiplier,2);
3269 + try {
3270 + $matrix1 = new PHPExcel_Shared_JAMA_Matrix($arg);
3271 + $matrixResult = $matrix1->arrayTimesEquals($multiplier);
3272 + $result = $matrixResult->getArray();
3273 + } catch (PHPExcel_Exception $ex) {
3274 + $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage());
3275 + $result = '#VALUE!';
3276 + }
3277 + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result));
3278 + $stack->push('Value',$result);
3279 + } else {
3280 + $this->_executeNumericBinaryOperation($cellID,$multiplier,$arg,'*','arrayTimesEquals',$stack);
3281 + }
3780 3282
3781 - // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on
3782 - } elseif (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $token, $matches)) {
3783 -// echo 'Token is a function<br />';
3784 - $functionName = $matches[1];
3785 - $argCount = $stack->pop();
3786 - $argCount = $argCount['value'];
3787 - if ($functionName != 'MKMATRIX') {
3788 - $this->_debugLog->writeDebugLog('Evaluating Function ', self::localeFunc($functionName), '() with ', (($argCount == 0) ? 'no' : $argCount), ' argument', (($argCount == 1) ? '' : 's'));
3789 - }
3790 - if ((isset(self::$PHPExcelFunctions[$functionName])) || (isset(self::$controlFunctions[$functionName]))) { // function
3791 - if (isset(self::$PHPExcelFunctions[$functionName])) {
3792 - $functionCall = self::$PHPExcelFunctions[$functionName]['functionCall'];
3793 - $passByReference = isset(self::$PHPExcelFunctions[$functionName]['passByReference']);
3794 - $passCellReference = isset(self::$PHPExcelFunctions[$functionName]['passCellReference']);
3795 - } elseif (isset(self::$controlFunctions[$functionName])) {
3796 - $functionCall = self::$controlFunctions[$functionName]['functionCall'];
3797 - $passByReference = isset(self::$controlFunctions[$functionName]['passByReference']);
3798 - $passCellReference = isset(self::$controlFunctions[$functionName]['passCellReference']);
3799 - }
3800 - // get the arguments for this function
3801 -// echo 'Function '.$functionName.' expects '.$argCount.' arguments<br />';
3802 - $args = $argArrayVals = array();
3803 - for ($i = 0; $i < $argCount; ++$i) {
3804 - $arg = $stack->pop();
3805 - $a = $argCount - $i - 1;
3806 - if (($passByReference) &&
3807 - (isset(self::$PHPExcelFunctions[$functionName]['passByReference'][$a])) &&
3808 - (self::$PHPExcelFunctions[$functionName]['passByReference'][$a])) {
3809 - if ($arg['reference'] === null) {
3810 - $args[] = $cellID;
3811 - if ($functionName != 'MKMATRIX') {
3812 - $argArrayVals[] = $this->showValue($cellID);
3813 - }
3814 - } else {
3815 - $args[] = $arg['reference'];
3816 - if ($functionName != 'MKMATRIX') {
3817 - $argArrayVals[] = $this->showValue($arg['reference']);
3818 - }
3819 - }
3820 - } else {
3821 - $args[] = self::unwrapResult($arg['value']);
3822 - if ($functionName != 'MKMATRIX') {
3823 - $argArrayVals[] = $this->showValue($arg['value']);
3824 - }
3825 - }
3826 - }
3827 - // Reverse the order of the arguments
3828 - krsort($args);
3829 - if (($passByReference) && ($argCount == 0)) {
3830 - $args[] = $cellID;
3831 - $argArrayVals[] = $this->showValue($cellID);
3832 - }
3833 -// echo 'Arguments are: ';
3834 -// print_r($args);
3835 -// echo '<br />';
3836 - if ($functionName != 'MKMATRIX') {
3837 - if ($this->_debugLog->getWriteDebugLog()) {
3838 - krsort($argArrayVals);
3839 - $this->_debugLog->writeDebugLog('Evaluating ', self::localeFunc($functionName), '( ', implode(self::$localeArgumentSeparator.' ', PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )');
3840 - }
3841 - }
3842 - // Process each argument in turn, building the return value as an array
3843 -// if (($argCount == 1) && (is_array($args[1])) && ($functionName != 'MKMATRIX')) {
3844 -// $operand1 = $args[1];
3845 -// $this->_debugLog->writeDebugLog('Argument is a matrix: ', $this->showValue($operand1));
3846 -// $result = array();
3847 -// $row = 0;
3848 -// foreach($operand1 as $args) {
3849 -// if (is_array($args)) {
3850 -// foreach($args as $arg) {
3851 -// $this->_debugLog->writeDebugLog('Evaluating ', self::localeFunc($functionName), '( ', $this->showValue($arg), ' )');
3852 -// $r = call_user_func_array($functionCall, $arg);
3853 -// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::localeFunc($functionName), '() function call is ', $this->showTypeDetails($r));
3854 -// $result[$row][] = $r;
3855 -// }
3856 -// ++$row;
3857 -// } else {
3858 -// $this->_debugLog->writeDebugLog('Evaluating ', self::localeFunc($functionName), '( ', $this->showValue($args), ' )');
3859 -// $r = call_user_func_array($functionCall, $args);
3860 -// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::localeFunc($functionName), '() function call is ', $this->showTypeDetails($r));
3861 -// $result[] = $r;
3862 -// }
3863 -// }
3864 -// } else {
3865 - // Process the argument with the appropriate function call
3866 - if ($passCellReference) {
3867 - $args[] = $pCell;
3868 - }
3869 - if (strpos($functionCall, '::') !== false) {
3870 - $result = call_user_func_array(explode('::', $functionCall), $args);
3871 - } else {
3872 - foreach ($args as &$arg) {
3873 - $arg = PHPExcel_Calculation_Functions::flattenSingleValue($arg);
3874 - }
3875 - unset($arg);
3876 - $result = call_user_func_array($functionCall, $args);
3877 - }
3878 - if ($functionName != 'MKMATRIX') {
3879 - $this->_debugLog->writeDebugLog('Evaluation Result for ', self::localeFunc($functionName), '() function call is ', $this->showTypeDetails($result));
3880 - }
3881 - $stack->push('Value', self::wrapResult($result));
3882 - }
3283 + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $token, $matches)) {
3284 + $cellRef = NULL;
3285 +// echo 'Element '.$token.' is a Cell reference<br />';
3286 + if (isset($matches[8])) {
3287 +// echo 'Reference is a Range of cells<br />';
3288 + if ($pCell === NULL) {
3289 +// We can't access the range, so return a REF error
3290 + $cellValue = PHPExcel_Calculation_Functions::REF();
3291 + } else {
3292 + $cellRef = $matches[6].$matches[7].':'.$matches[9].$matches[10];
3293 + if ($matches[2] > '') {
3294 + $matches[2] = trim($matches[2],"\"'");
3295 + if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) {
3296 + // It's a Reference to an external workbook (not currently supported)
3297 + return $this->_raiseFormulaError('Unable to access External Workbook');
3298 + }
3299 + $matches[2] = trim($matches[2],"\"'");
3300 +// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />';
3301 + $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]);
3302 + if ($pCellParent !== NULL) {
3303 + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE);
3304 + } else {
3305 + return $this->_raiseFormulaError('Unable to access Cell Reference');
3306 + }
3307 + $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue));
3308 +// $cellRef = $matches[2].'!'.$cellRef;
3309 + } else {
3310 +// echo '$cellRef='.$cellRef.' in current worksheet<br />';
3311 + $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in current worksheet');
3312 + if ($pCellParent !== NULL) {
3313 + $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE);
3314 + } else {
3315 + return $this->_raiseFormulaError('Unable to access Cell Reference');
3316 + }
3317 + $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' is ', $this->_showTypeDetails($cellValue));
3318 + }
3319 + }
3320 + } else {
3321 +// echo 'Reference is a single Cell<br />';
3322 + if ($pCell === NULL) {
3323 +// We can't access the cell, so return a REF error
3324 + $cellValue = PHPExcel_Calculation_Functions::REF();
3325 + } else {
3326 + $cellRef = $matches[6].$matches[7];
3327 + if ($matches[2] > '') {
3328 + $matches[2] = trim($matches[2],"\"'");
3329 + if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) {
3330 + // It's a Reference to an external workbook (not currently supported)
3331 + return $this->_raiseFormulaError('Unable to access External Workbook');
3332 + }
3333 +// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />';
3334 + $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]);
3335 + if ($pCellParent !== NULL) {
3336 + $cellSheet = $this->_workbook->getSheetByName($matches[2]);
3337 + if ($cellSheet && $cellSheet->cellExists($cellRef)) {
3338 + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE);
3339 + $pCell->attach($pCellParent);
3340 + } else {
3341 + $cellValue = NULL;
3342 + }
3343 + } else {
3344 + return $this->_raiseFormulaError('Unable to access Cell Reference');
3345 + }
3346 + $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue));
3347 +// $cellRef = $matches[2].'!'.$cellRef;
3348 + } else {
3349 +// echo '$cellRef='.$cellRef.' in current worksheet<br />';
3350 + $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in current worksheet');
3351 + if ($pCellParent->isDataSet($cellRef)) {
3352 + $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE);
3353 + $pCell->attach($pCellParent);
3354 + } else {
3355 + $cellValue = NULL;
3356 + }
3357 + $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' is ', $this->_showTypeDetails($cellValue));
3358 + }
3359 + }
3360 + }
3361 + $stack->push('Value',$cellValue,$cellRef);
3883 3362
3884 - } else {
3885 - // if the token is a number, boolean, string or an Excel error, push it onto the stack
3886 - if (isset(self::$excelConstants[strtoupper($token)])) {
3887 - $excelConstant = strtoupper($token);
3888 -// echo 'Token is a PHPExcel constant: '.$excelConstant.'<br />';
3889 - $stack->push('Constant Value', self::$excelConstants[$excelConstant]);
3890 - $this->_debugLog->writeDebugLog('Evaluating Constant ', $excelConstant, ' as ', $this->showTypeDetails(self::$excelConstants[$excelConstant]));
3891 - } elseif ((is_numeric($token)) || ($token === null) || (is_bool($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) {
3892 -// echo 'Token is a number, boolean, string, null or an Excel error<br />';
3893 - $stack->push('Value', $token);
3894 - // if the token is a named range, push the named range name onto the stack
3895 - } elseif (preg_match('/^'.self::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $token, $matches)) {
3896 -// echo 'Token is a named range<br />';
3897 - $namedRange = $matches[6];
3898 -// echo 'Named Range is '.$namedRange.'<br />';
3899 - $this->_debugLog->writeDebugLog('Evaluating Named Range ', $namedRange);
3900 - $cellValue = $this->extractNamedRange($namedRange, ((null !== $pCell) ? $pCellWorksheet : null), false);
3901 - $pCell->attach($pCellParent);
3902 - $this->_debugLog->writeDebugLog('Evaluation Result for named range ', $namedRange, ' is ', $this->showTypeDetails($cellValue));
3903 - $stack->push('Named Range', $cellValue, $namedRange);
3904 - } else {
3905 - return $this->raiseFormulaError("undefined variable '$token'");
3906 - }
3907 - }
3908 - }
3909 - // when we're out of tokens, the stack should have a single element, the final result
3910 - if ($stack->count() != 1) {
3911 - return $this->raiseFormulaError("internal error");
3912 - }
3913 - $output = $stack->pop();
3914 - $output = $output['value'];
3363 + // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on
3364 + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $token, $matches)) {
3365 +// echo 'Token is a function<br />';
3366 + $functionName = $matches[1];
3367 + $argCount = $stack->pop();
3368 + $argCount = $argCount['value'];
3369 + if ($functionName != 'MKMATRIX') {
3370 + $this->_debugLog->writeDebugLog('Evaluating Function ', self::_localeFunc($functionName), '() with ', (($argCount == 0) ? 'no' : $argCount), ' argument', (($argCount == 1) ? '' : 's'));
3371 + }
3372 + if ((isset(self::$_PHPExcelFunctions[$functionName])) || (isset(self::$_controlFunctions[$functionName]))) { // function
3373 + if (isset(self::$_PHPExcelFunctions[$functionName])) {
3374 + $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall'];
3375 + $passByReference = isset(self::$_PHPExcelFunctions[$functionName]['passByReference']);
3376 + $passCellReference = isset(self::$_PHPExcelFunctions[$functionName]['passCellReference']);
3377 + } elseif (isset(self::$_controlFunctions[$functionName])) {
3378 + $functionCall = self::$_controlFunctions[$functionName]['functionCall'];
3379 + $passByReference = isset(self::$_controlFunctions[$functionName]['passByReference']);
3380 + $passCellReference = isset(self::$_controlFunctions[$functionName]['passCellReference']);
3381 + }
3382 + // get the arguments for this function
3383 +// echo 'Function '.$functionName.' expects '.$argCount.' arguments<br />';
3384 + $args = $argArrayVals = array();
3385 + for ($i = 0; $i < $argCount; ++$i) {
3386 + $arg = $stack->pop();
3387 + $a = $argCount - $i - 1;
3388 + if (($passByReference) &&
3389 + (isset(self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) &&
3390 + (self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) {
3391 + if ($arg['reference'] === NULL) {
3392 + $args[] = $cellID;
3393 + if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($cellID); }
3394 + } else {
3395 + $args[] = $arg['reference'];
3396 + if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['reference']); }
3397 + }
3398 + } else {
3399 + $args[] = self::_unwrapResult($arg['value']);
3400 + if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['value']); }
3401 + }
3402 + }
3403 + // Reverse the order of the arguments
3404 + krsort($args);
3405 + if (($passByReference) && ($argCount == 0)) {
3406 + $args[] = $cellID;
3407 + $argArrayVals[] = $this->_showValue($cellID);
3408 + }
3409 +// echo 'Arguments are: ';
3410 +// print_r($args);
3411 +// echo '<br />';
3412 + if ($functionName != 'MKMATRIX') {
3413 + if ($this->_debugLog->getWriteDebugLog()) {
3414 + krsort($argArrayVals);
3415 + $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', implode(self::$_localeArgumentSeparator.' ',PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )');
3416 + }
3417 + }
3418 + // Process each argument in turn, building the return value as an array
3419 +// if (($argCount == 1) && (is_array($args[1])) && ($functionName != 'MKMATRIX')) {
3420 +// $operand1 = $args[1];
3421 +// $this->_debugLog->writeDebugLog('Argument is a matrix: ', $this->_showValue($operand1));
3422 +// $result = array();
3423 +// $row = 0;
3424 +// foreach($operand1 as $args) {
3425 +// if (is_array($args)) {
3426 +// foreach($args as $arg) {
3427 +// $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($arg), ' )');
3428 +// $r = call_user_func_array($functionCall,$arg);
3429 +// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r));
3430 +// $result[$row][] = $r;
3431 +// }
3432 +// ++$row;
3433 +// } else {
3434 +// $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($args), ' )');
3435 +// $r = call_user_func_array($functionCall,$args);
3436 +// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r));
3437 +// $result[] = $r;
3438 +// }
3439 +// }
3440 +// } else {
3441 + // Process the argument with the appropriate function call
3442 + if ($passCellReference) {
3443 + $args[] = $pCell;
3444 + }
3445 + if (strpos($functionCall,'::') !== FALSE) {
3446 + $result = call_user_func_array(explode('::',$functionCall),$args);
3447 + } else {
3448 + foreach($args as &$arg) {
3449 + $arg = PHPExcel_Calculation_Functions::flattenSingleValue($arg);
3450 + }
3451 + unset($arg);
3452 + $result = call_user_func_array($functionCall,$args);
3453 + }
3454 +// }
3455 + if ($functionName != 'MKMATRIX') {
3456 + $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($result));
3457 + }
3458 + $stack->push('Value',self::_wrapResult($result));
3459 + }
3915 3460
3916 -// if ((is_array($output)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) {
3917 -// return array_shift(PHPExcel_Calculation_Functions::flattenArray($output));
3918 -// }
3919 - return $output;
3920 - }
3461 + } else {
3462 + // if the token is a number, boolean, string or an Excel error, push it onto the stack
3463 + if (isset(self::$_ExcelConstants[strtoupper($token)])) {
3464 + $excelConstant = strtoupper($token);
3465 +// echo 'Token is a PHPExcel constant: '.$excelConstant.'<br />';
3466 + $stack->push('Constant Value',self::$_ExcelConstants[$excelConstant]);
3467 + $this->_debugLog->writeDebugLog('Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$_ExcelConstants[$excelConstant]));
3468 + } elseif ((is_numeric($token)) || ($token === NULL) || (is_bool($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) {
3469 +// echo 'Token is a number, boolean, string, null or an Excel error<br />';
3470 + $stack->push('Value',$token);
3471 + // if the token is a named range, push the named range name onto the stack
3472 + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $token, $matches)) {
3473 +// echo 'Token is a named range<br />';
3474 + $namedRange = $matches[6];
3475 +// echo 'Named Range is '.$namedRange.'<br />';
3476 + $this->_debugLog->writeDebugLog('Evaluating Named Range ', $namedRange);
3477 + $cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellWorksheet : NULL), FALSE);
3478 + $pCell->attach($pCellParent);
3479 + $this->_debugLog->writeDebugLog('Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue));
3480 + $stack->push('Named Range',$cellValue,$namedRange);
3481 + } else {
3482 + return $this->_raiseFormulaError("undefined variable '$token'");
3483 + }
3484 + }
3485 + }
3486 + // when we're out of tokens, the stack should have a single element, the final result
3487 + if ($stack->count() != 1) return $this->_raiseFormulaError("internal error");
3488 + $output = $stack->pop();
3489 + $output = $output['value'];
3921 3490
3491 +// if ((is_array($output)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) {
3492 +// return array_shift(PHPExcel_Calculation_Functions::flattenArray($output));
3493 +// }
3494 + return $output;
3495 + } // function _processTokenStack()
3922 3496
3923 - private function validateBinaryOperand($cellID, &$operand, &$stack)
3924 - {
3925 - if (is_array($operand)) {
3926 - if ((count($operand, COUNT_RECURSIVE) - count($operand)) == 1) {
3927 - do {
3928 - $operand = array_pop($operand);
3929 - } while (is_array($operand));
3930 - }
3931 - }
3932 - // Numbers, matrices and booleans can pass straight through, as they're already valid
3933 - if (is_string($operand)) {
3934 - // We only need special validations for the operand if it is a string
3935 - // Start by stripping off the quotation marks we use to identify true excel string values internally
3936 - if ($operand > '' && $operand{0} == '"') {
3937 - $operand = self::unwrapResult($operand);
3938 - }
3939 - // If the string is a numeric value, we treat it as a numeric, so no further testing
3940 - if (!is_numeric($operand)) {
3941 - // If not a numeric, test to see if the value is an Excel error, and so can't be used in normal binary operations
3942 - if ($operand > '' && $operand{0} == '#') {
3943 - $stack->push('Value', $operand);
3944 - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->showTypeDetails($operand));
3945 - return false;
3946 - } elseif (!PHPExcel_Shared_String::convertToNumberIfFraction($operand)) {
3947 - // If not a numeric or a fraction, then it's a text string, and so can't be used in mathematical binary operations
3948 - $stack->push('Value', '#VALUE!');
3949 - $this->_debugLog->writeDebugLog('Evaluation Result is a ', $this->showTypeDetails('#VALUE!'));
3950 - return false;
3951 - }
3952 - }
3953 - }
3954 3497
3955 - // return a true if the value of the operand is one that we can use in normal binary operations
3956 - return true;
3957 - }
3498 + private function _validateBinaryOperand($cellID, &$operand, &$stack) {
3499 + if (is_array($operand)) {
3500 + if ((count($operand, COUNT_RECURSIVE) - count($operand)) == 1) {
3501 + do {
3502 + $operand = array_pop($operand);
3503 + } while (is_array($operand));
3504 + }
3505 + }
3506 + // Numbers, matrices and booleans can pass straight through, as they're already valid
3507 + if (is_string($operand)) {
3508 + // We only need special validations for the operand if it is a string
3509 + // Start by stripping off the quotation marks we use to identify true excel string values internally
3510 + if ($operand > '' && $operand{0} == '"') { $operand = self::_unwrapResult($operand); }
3511 + // If the string is a numeric value, we treat it as a numeric, so no further testing
3512 + if (!is_numeric($operand)) {
3513 + // If not a numeric, test to see if the value is an Excel error, and so can't be used in normal binary operations
3514 + if ($operand > '' && $operand{0} == '#') {
3515 + $stack->push('Value', $operand);
3516 + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($operand));
3517 + return FALSE;
3518 + } elseif (!PHPExcel_Shared_String::convertToNumberIfFraction($operand)) {
3519 + // If not a numeric or a fraction, then it's a text string, and so can't be used in mathematical binary operations
3520 + $stack->push('Value', '#VALUE!');
3521 + $this->_debugLog->writeDebugLog('Evaluation Result is a ', $this->_showTypeDetails('#VALUE!'));
3522 + return FALSE;
3523 + }
3524 + }
3525 + }
3958 3526
3527 + // return a true if the value of the operand is one that we can use in normal binary operations
3528 + return TRUE;
3529 + } // function _validateBinaryOperand()
3959 3530
3960 - private function executeBinaryComparisonOperation($cellID, $operand1, $operand2, $operation, &$stack, $recursingArrays = false)
3961 - {
3962 - // If we're dealing with matrix operations, we want a matrix result
3963 - if ((is_array($operand1)) || (is_array($operand2))) {
3964 - $result = array();
3965 - if ((is_array($operand1)) && (!is_array($operand2))) {
3966 - foreach ($operand1 as $x => $operandData) {
3967 - $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->showValue($operandData), ' ', $operation, ' ', $this->showValue($operand2));
3968 - $this->executeBinaryComparisonOperation($cellID, $operandData, $operand2, $operation, $stack);
3969 - $r = $stack->pop();
3970 - $result[$x] = $r['value'];
3971 - }
3972 - } elseif ((!is_array($operand1)) && (is_array($operand2))) {
3973 - foreach ($operand2 as $x => $operandData) {
3974 - $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->showValue($operand1), ' ', $operation, ' ', $this->showValue($operandData));
3975 - $this->executeBinaryComparisonOperation($cellID, $operand1, $operandData, $operation, $stack);
3976 - $r = $stack->pop();
3977 - $result[$x] = $r['value'];
3978 - }
3979 - } else {
3980 - if (!$recursingArrays) {
3981 - self::checkMatrixOperands($operand1, $operand2, 2);
3982 - }
3983 - foreach ($operand1 as $x => $operandData) {
3984 - $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->showValue($operandData), ' ', $operation, ' ', $this->showValue($operand2[$x]));
3985 - $this->executeBinaryComparisonOperation($cellID, $operandData, $operand2[$x], $operation, $stack, true);
3986 - $r = $stack->pop();
3987 - $result[$x] = $r['value'];
3988 - }
3989 - }
3990 - // Log the result details
3991 - $this->_debugLog->writeDebugLog('Comparison Evaluation Result is ', $this->showTypeDetails($result));
3992 - // And push the result onto the stack
3993 - $stack->push('Array', $result);
3994 - return true;
3995 - }
3996 3531
3997 - // Simple validate the two operands if they are string values
3998 - if (is_string($operand1) && $operand1 > '' && $operand1{0} == '"') {
3999 - $operand1 = self::unwrapResult($operand1);
4000 - }
4001 - if (is_string($operand2) && $operand2 > '' && $operand2{0} == '"') {
4002 - $operand2 = self::unwrapResult($operand2);
4003 - }
3532 + private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2, $operation, &$stack, $recursingArrays=FALSE) {
3533 + // If we're dealing with matrix operations, we want a matrix result
3534 + if ((is_array($operand1)) || (is_array($operand2))) {
3535 + $result = array();
3536 + if ((is_array($operand1)) && (!is_array($operand2))) {
3537 + foreach($operand1 as $x => $operandData) {
3538 + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2));
3539 + $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2,$operation,$stack);
3540 + $r = $stack->pop();
3541 + $result[$x] = $r['value'];
3542 + }
3543 + } elseif ((!is_array($operand1)) && (is_array($operand2))) {
3544 + foreach($operand2 as $x => $operandData) {
3545 + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operand1), ' ', $operation, ' ', $this->_showValue($operandData));
3546 + $this->_executeBinaryComparisonOperation($cellID,$operand1,$operandData,$operation,$stack);
3547 + $r = $stack->pop();
3548 + $result[$x] = $r['value'];
3549 + }
3550 + } else {
3551 + if (!$recursingArrays) { self::_checkMatrixOperands($operand1,$operand2,2); }
3552 + foreach($operand1 as $x => $operandData) {
3553 + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x]));
3554 + $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2[$x],$operation,$stack,TRUE);
3555 + $r = $stack->pop();
3556 + $result[$x] = $r['value'];
3557 + }
3558 + }
3559 + // Log the result details
3560 + $this->_debugLog->writeDebugLog('Comparison Evaluation Result is ', $this->_showTypeDetails($result));
3561 + // And push the result onto the stack
3562 + $stack->push('Array',$result);
3563 + return TRUE;
3564 + }
4004 3565
4005 - // Use case insensitive comparaison if not OpenOffice mode
4006 - if (PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {
4007 - if (is_string($operand1)) {
4008 - $operand1 = strtoupper($operand1);
4009 - }
4010 - if (is_string($operand2)) {
4011 - $operand2 = strtoupper($operand2);
4012 - }
4013 - }
3566 + // Simple validate the two operands if they are string values
3567 + if (is_string($operand1) && $operand1 > '' && $operand1{0} == '"') { $operand1 = self::_unwrapResult($operand1); }
3568 + if (is_string($operand2) && $operand2 > '' && $operand2{0} == '"') { $operand2 = self::_unwrapResult($operand2); }
4014 3569
4015 - $useLowercaseFirstComparison = is_string($operand1) && is_string($operand2) && PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE;
3570 + // Use case insensitive comparaison if not OpenOffice mode
3571 + if (PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE)
3572 + {
3573 + if (is_string($operand1)) {
3574 + $operand1 = strtoupper($operand1);
3575 + }
4016 3576
4017 - // execute the necessary operation
4018 - switch ($operation) {
4019 - // Greater than
4020 - case '>':
4021 - if ($useLowercaseFirstComparison) {
4022 - $result = $this->strcmpLowercaseFirst($operand1, $operand2) > 0;
4023 - } else {
4024 - $result = ($operand1 > $operand2);
4025 - }
4026 - break;
4027 - // Less than
4028 - case '<':
4029 - if ($useLowercaseFirstComparison) {
4030 - $result = $this->strcmpLowercaseFirst($operand1, $operand2) < 0;
4031 - } else {
4032 - $result = ($operand1 < $operand2);
4033 - }
4034 - break;
4035 - // Equality
4036 - case '=':
3577 + if (is_string($operand2)) {
3578 + $operand2 = strtoupper($operand2);
3579 + }
3580 + }
3581 +
3582 + $useLowercaseFirstComparison = is_string($operand1) && is_string($operand2) && PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE;
3583 +
3584 + // execute the necessary operation
3585 + switch ($operation) {
3586 + // Greater than
3587 + case '>':
3588 + if ($useLowercaseFirstComparison) {
3589 + $result = $this->strcmpLowercaseFirst($operand1, $operand2) > 0;
3590 + } else {
3591 + $result = ($operand1 > $operand2);
3592 + }
3593 + break;
3594 + // Less than
3595 + case '<':
3596 + if ($useLowercaseFirstComparison) {
3597 + $result = $this->strcmpLowercaseFirst($operand1, $operand2) < 0;
3598 + } else {
3599 + $result = ($operand1 < $operand2);
3600 + }
3601 + break;
3602 + // Equality
3603 + case '=':
4037 3604 if (is_numeric($operand1) && is_numeric($operand2)) {
4038 3605 $result = (abs($operand1 - $operand2) < $this->delta);
4039 3606 } else {
4040 3607 $result = strcmp($operand1, $operand2) == 0;
4041 3608 }
4042 - break;
4043 - // Greater than or equal
4044 - case '>=':
3609 + break;
3610 + // Greater than or equal
3611 + case '>=':
4045 3612 if (is_numeric($operand1) && is_numeric($operand2)) {
4046 3613 $result = ((abs($operand1 - $operand2) < $this->delta) || ($operand1 > $operand2));
4047 - } elseif ($useLowercaseFirstComparison) {
4048 - $result = $this->strcmpLowercaseFirst($operand1, $operand2) >= 0;
4049 - } else {
4050 - $result = strcmp($operand1, $operand2) >= 0;
4051 - }
4052 - break;
4053 - // Less than or equal
4054 - case '<=':
3614 + } elseif ($useLowercaseFirstComparison) {
3615 + $result = $this->strcmpLowercaseFirst($operand1, $operand2) >= 0;
3616 + } else {
3617 + $result = strcmp($operand1, $operand2) >= 0;
3618 + }
3619 + break;
3620 + // Less than or equal
3621 + case '<=':
4055 3622 if (is_numeric($operand1) && is_numeric($operand2)) {
4056 3623 $result = ((abs($operand1 - $operand2) < $this->delta) || ($operand1 < $operand2));
4057 3624 } elseif ($useLowercaseFirstComparison) {
4058 - $result = $this->strcmpLowercaseFirst($operand1, $operand2) <= 0;
4059 - } else {
4060 - $result = strcmp($operand1, $operand2) <= 0;
4061 - }
4062 - break;
4063 - // Inequality
4064 - case '<>':
3625 + $result = $this->strcmpLowercaseFirst($operand1, $operand2) <= 0;
3626 + } else {
3627 + $result = strcmp($operand1, $operand2) <= 0;
3628 + }
3629 + break;
3630 + // Inequality
3631 + case '<>':
4065 3632 if (is_numeric($operand1) && is_numeric($operand2)) {
4066 3633 $result = (abs($operand1 - $operand2) > 1E-14);
4067 3634 } else {
4068 3635 $result = strcmp($operand1, $operand2) != 0;
4069 3636 }
4070 - break;
4071 - }
3637 + break;
3638 + }
4072 3639
4073 - // Log the result details
4074 - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->showTypeDetails($result));
4075 - // And push the result onto the stack
4076 - $stack->push('Value', $result);
4077 - return true;
4078 - }
3640 + // Log the result details
3641 + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result));
3642 + // And push the result onto the stack
3643 + $stack->push('Value',$result);
3644 + return true;
3645 + }
4079 3646
4080 - /**
4081 - * Compare two strings in the same way as strcmp() except that lowercase come before uppercase letters
4082 - * @param string $str1 First string value for the comparison
4083 - * @param string $str2 Second string value for the comparison
4084 - * @return integer
4085 - */
4086 - private function strcmpLowercaseFirst($str1, $str2)
4087 - {
3647 + /**
3648 + * Compare two strings in the same way as strcmp() except that lowercase come before uppercase letters
3649 + * @param string $str1 First string value for the comparison
3650 + * @param string $str2 Second string value for the comparison
3651 + * @return integer
3652 + */
3653 + private function strcmpLowercaseFirst($str1, $str2)
3654 + {
4088 3655 $inversedStr1 = PHPExcel_Shared_String::StrCaseReverse($str1);
4089 3656 $inversedStr2 = PHPExcel_Shared_String::StrCaseReverse($str2);
4090 3657
4091 - return strcmp($inversedStr1, $inversedStr2);
4092 - }
3658 + return strcmp($inversedStr1, $inversedStr2);
3659 + }
4093 3660
4094 - private function executeNumericBinaryOperation($cellID, $operand1, $operand2, $operation, $matrixFunction, &$stack)
4095 - {
4096 - // Validate the two operands
4097 - if (!$this->validateBinaryOperand($cellID, $operand1, $stack)) {
4098 - return false;
4099 - }
4100 - if (!$this->validateBinaryOperand($cellID, $operand2, $stack)) {
4101 - return false;
4102 - }
3661 + private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$operation,$matrixFunction,&$stack) {
3662 + // Validate the two operands
3663 + if (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return FALSE;
3664 + if (!$this->_validateBinaryOperand($cellID,$operand2,$stack)) return FALSE;
4103 3665
4104 - // If either of the operands is a matrix, we need to treat them both as matrices
4105 - // (converting the other operand to a matrix if need be); then perform the required
4106 - // matrix operation
4107 - if ((is_array($operand1)) || (is_array($operand2))) {
4108 - // Ensure that both operands are arrays/matrices of the same size
4109 - self::checkMatrixOperands($operand1, $operand2, 2);
3666 + // If either of the operands is a matrix, we need to treat them both as matrices
3667 + // (converting the other operand to a matrix if need be); then perform the required
3668 + // matrix operation
3669 + if ((is_array($operand1)) || (is_array($operand2))) {
3670 + // Ensure that both operands are arrays/matrices of the same size
3671 + self::_checkMatrixOperands($operand1, $operand2, 2);
4110 3672
4111 - try {
4112 - // Convert operand 1 from a PHP array to a matrix
4113 - $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1);
4114 - // Perform the required operation against the operand 1 matrix, passing in operand 2
4115 - $matrixResult = $matrix->$matrixFunction($operand2);
4116 - $result = $matrixResult->getArray();
4117 - } catch (PHPExcel_Exception $ex) {
4118 - $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage());
4119 - $result = '#VALUE!';
4120 - }
4121 - } else {
4122 - if ((PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) &&
4123 - ((is_string($operand1) && !is_numeric($operand1) && strlen($operand1)>0) ||
3673 + try {
3674 + // Convert operand 1 from a PHP array to a matrix
3675 + $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1);
3676 + // Perform the required operation against the operand 1 matrix, passing in operand 2
3677 + $matrixResult = $matrix->$matrixFunction($operand2);
3678 + $result = $matrixResult->getArray();
3679 + } catch (PHPExcel_Exception $ex) {
3680 + $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage());
3681 + $result = '#VALUE!';
3682 + }
3683 + } else {
3684 + if ((PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) &&
3685 + ((is_string($operand1) && !is_numeric($operand1) && strlen($operand1)>0) ||
4124 3686 (is_string($operand2) && !is_numeric($operand2) && strlen($operand2)>0))) {
4125 - $result = PHPExcel_Calculation_Functions::VALUE();
4126 - } else {
4127 - // If we're dealing with non-matrix operations, execute the necessary operation
4128 - switch ($operation) {
4129 - // Addition
4130 - case '+':
4131 - $result = $operand1 + $operand2;
4132 - break;
4133 - // Subtraction
4134 - case '-':
4135 - $result = $operand1 - $operand2;
4136 - break;
4137 - // Multiplication
4138 - case '*':
4139 - $result = $operand1 * $operand2;
4140 - break;
4141 - // Division
4142 - case '/':
4143 - if ($operand2 == 0) {
4144 - // Trap for Divide by Zero error
4145 - $stack->push('Value', '#DIV/0!');
4146 - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->showTypeDetails('#DIV/0!'));
4147 - return false;
4148 - } else {
4149 - $result = $operand1 / $operand2;
4150 - }
4151 - break;
4152 - // Power
4153 - case '^':
4154 - $result = pow($operand1, $operand2);
4155 - break;
4156 - }
4157 - }
4158 - }
3687 + $result = PHPExcel_Calculation_Functions::VALUE();
3688 + } else {
3689 + // If we're dealing with non-matrix operations, execute the necessary operation
3690 + switch ($operation) {
3691 + // Addition
3692 + case '+':
3693 + $result = $operand1 + $operand2;
3694 + break;
3695 + // Subtraction
3696 + case '-':
3697 + $result = $operand1 - $operand2;
3698 + break;
3699 + // Multiplication
3700 + case '*':
3701 + $result = $operand1 * $operand2;
3702 + break;
3703 + // Division
3704 + case '/':
3705 + if ($operand2 == 0) {
3706 + // Trap for Divide by Zero error
3707 + $stack->push('Value','#DIV/0!');
3708 + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails('#DIV/0!'));
3709 + return FALSE;
3710 + } else {
3711 + $result = $operand1 / $operand2;
3712 + }
3713 + break;
3714 + // Power
3715 + case '^':
3716 + $result = pow($operand1, $operand2);
3717 + break;
3718 + }
3719 + }
3720 + }
4159 3721
4160 - // Log the result details
4161 - $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->showTypeDetails($result));
4162 - // And push the result onto the stack
4163 - $stack->push('Value', $result);
4164 - return true;
4165 - }
3722 + // Log the result details
3723 + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result));
3724 + // And push the result onto the stack
3725 + $stack->push('Value',$result);
3726 + return TRUE;
3727 + } // function _executeNumericBinaryOperation()
4166 3728
4167 3729
4168 - // trigger an error, but nicely, if need be
4169 - protected function raiseFormulaError($errorMessage)
4170 - {
4171 - $this->formulaError = $errorMessage;
4172 - $this->cyclicReferenceStack->clear();
4173 - if (!$this->suppressFormulaErrors) {
4174 - throw new PHPExcel_Calculation_Exception($errorMessage);
4175 - }
4176 - trigger_error($errorMessage, E_USER_ERROR);
4177 - }
3730 + // trigger an error, but nicely, if need be
3731 + protected function _raiseFormulaError($errorMessage) {
3732 + $this->formulaError = $errorMessage;
3733 + $this->_cyclicReferenceStack->clear();
3734 + if (!$this->suppressFormulaErrors) throw new PHPExcel_Calculation_Exception($errorMessage);
3735 + trigger_error($errorMessage, E_USER_ERROR);
3736 + } // function _raiseFormulaError()
4178 3737
4179 3738
4180 - /**
4181 - * Extract range values
4182 - *
4183 - * @param string &$pRange String based range representation
4184 - * @param PHPExcel_Worksheet $pSheet Worksheet
4185 - * @param boolean $resetLog Flag indicating whether calculation log should be reset or not
4186 - * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned.
4187 - * @throws PHPExcel_Calculation_Exception
4188 - */
4189 - public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = null, $resetLog = true)
4190 - {
4191 - // Return value
4192 - $returnValue = array ();
3739 + /**
3740 + * Extract range values
3741 + *
3742 + * @param string &$pRange String based range representation
3743 + * @param PHPExcel_Worksheet $pSheet Worksheet
3744 + * @param boolean $resetLog Flag indicating whether calculation log should be reset or not
3745 + * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned.
3746 + * @throws PHPExcel_Calculation_Exception
3747 + */
3748 + public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) {
3749 + // Return value
3750 + $returnValue = array ();
4193 3751
4194 -// echo 'extractCellRange('.$pRange.')', PHP_EOL;
4195 - if ($pSheet !== null) {
4196 - $pSheetName = $pSheet->getTitle();
4197 -// echo 'Passed sheet name is '.$pSheetName.PHP_EOL;
4198 -// echo 'Range reference is '.$pRange.PHP_EOL;
4199 - if (strpos($pRange, '!') !== false) {
4200 -// echo '$pRange reference includes sheet reference', PHP_EOL;
4201 - list($pSheetName, $pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true);
4202 -// echo 'New sheet name is '.$pSheetName, PHP_EOL;
4203 -// echo 'Adjusted Range reference is '.$pRange, PHP_EOL;
4204 - $pSheet = $this->workbook->getSheetByName($pSheetName);
4205 - }
3752 +// echo 'extractCellRange('.$pRange.')',PHP_EOL;
3753 + if ($pSheet !== NULL) {
3754 + $pSheetName = $pSheet->getTitle();
3755 +// echo 'Passed sheet name is '.$pSheetName.PHP_EOL;
3756 +// echo 'Range reference is '.$pRange.PHP_EOL;
3757 + if (strpos ($pRange, '!') !== false) {
3758 +// echo '$pRange reference includes sheet reference',PHP_EOL;
3759 + list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true);
3760 +// echo 'New sheet name is '.$pSheetName,PHP_EOL;
3761 +// echo 'Adjusted Range reference is '.$pRange,PHP_EOL;
3762 + $pSheet = $this->_workbook->getSheetByName($pSheetName);
3763 + }
4206 3764
4207 - // Extract range
4208 - $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange);
4209 - $pRange = $pSheetName.'!'.$pRange;
4210 - if (!isset($aReferences[1])) {
4211 - // Single cell in range
4212 - sscanf($aReferences[0], '%[A-Z]%d', $currentCol, $currentRow);
4213 - $cellValue = null;
4214 - if ($pSheet->cellExists($aReferences[0])) {
4215 - $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog);
4216 - } else {
4217 - $returnValue[$currentRow][$currentCol] = null;
4218 - }
4219 - } else {
4220 - // Extract cell data for all cells in the range
4221 - foreach ($aReferences as $reference) {
4222 - // Extract range
4223 - sscanf($reference, '%[A-Z]%d', $currentCol, $currentRow);
4224 - $cellValue = null;
4225 - if ($pSheet->cellExists($reference)) {
4226 - $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog);
4227 - } else {
4228 - $returnValue[$currentRow][$currentCol] = null;
4229 - }
4230 - }
4231 - }
4232 - }
3765 + // Extract range
3766 + $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange);
3767 + $pRange = $pSheetName.'!'.$pRange;
3768 + if (!isset($aReferences[1])) {
3769 + // Single cell in range
3770 + sscanf($aReferences[0],'%[A-Z]%d', $currentCol, $currentRow);
3771 + $cellValue = NULL;
3772 + if ($pSheet->cellExists($aReferences[0])) {
3773 + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog);
3774 + } else {
3775 + $returnValue[$currentRow][$currentCol] = NULL;
3776 + }
3777 + } else {
3778 + // Extract cell data for all cells in the range
3779 + foreach ($aReferences as $reference) {
3780 + // Extract range
3781 + sscanf($reference,'%[A-Z]%d', $currentCol, $currentRow);
3782 + $cellValue = NULL;
3783 + if ($pSheet->cellExists($reference)) {
3784 + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog);
3785 + } else {
3786 + $returnValue[$currentRow][$currentCol] = NULL;
3787 + }
3788 + }
3789 + }
3790 + }
4233 3791
4234 - return $returnValue;
4235 - }
3792 + // Return
3793 + return $returnValue;
3794 + } // function extractCellRange()
4236 3795
4237 3796
4238 - /**
4239 - * Extract range values
4240 - *
4241 - * @param string &$pRange String based range representation
4242 - * @param PHPExcel_Worksheet $pSheet Worksheet
4243 - * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned.
4244 - * @param boolean $resetLog Flag indicating whether calculation log should be reset or not
4245 - * @throws PHPExcel_Calculation_Exception
4246 - */
4247 - public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = null, $resetLog = true)
4248 - {
4249 - // Return value
4250 - $returnValue = array ();
3797 + /**
3798 + * Extract range values
3799 + *
3800 + * @param string &$pRange String based range representation
3801 + * @param PHPExcel_Worksheet $pSheet Worksheet
3802 + * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned.
3803 + * @param boolean $resetLog Flag indicating whether calculation log should be reset or not
3804 + * @throws PHPExcel_Calculation_Exception
3805 + */
3806 + public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) {
3807 + // Return value
3808 + $returnValue = array ();
4251 3809
4252 -// echo 'extractNamedRange('.$pRange.')<br />';
4253 - if ($pSheet !== null) {
4254 - $pSheetName = $pSheet->getTitle();
4255 -// echo 'Current sheet name is '.$pSheetName.'<br />';
4256 -// echo 'Range reference is '.$pRange.'<br />';
4257 - if (strpos($pRange, '!') !== false) {
4258 -// echo '$pRange reference includes sheet reference', PHP_EOL;
4259 - list($pSheetName, $pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true);
4260 -// echo 'New sheet name is '.$pSheetName, PHP_EOL;
4261 -// echo 'Adjusted Range reference is '.$pRange, PHP_EOL;
4262 - $pSheet = $this->workbook->getSheetByName($pSheetName);
4263 - }
3810 +// echo 'extractNamedRange('.$pRange.')<br />';
3811 + if ($pSheet !== NULL) {
3812 + $pSheetName = $pSheet->getTitle();
3813 +// echo 'Current sheet name is '.$pSheetName.'<br />';
3814 +// echo 'Range reference is '.$pRange.'<br />';
3815 + if (strpos ($pRange, '!') !== false) {
3816 +// echo '$pRange reference includes sheet reference',PHP_EOL;
3817 + list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true);
3818 +// echo 'New sheet name is '.$pSheetName,PHP_EOL;
3819 +// echo 'Adjusted Range reference is '.$pRange,PHP_EOL;
3820 + $pSheet = $this->_workbook->getSheetByName($pSheetName);
3821 + }
4264 3822
4265 - // Named range?
4266 - $namedRange = PHPExcel_NamedRange::resolveRange($pRange, $pSheet);
4267 - if ($namedRange !== null) {
4268 - $pSheet = $namedRange->getWorksheet();
4269 -// echo 'Named Range '.$pRange.' (';
4270 - $pRange = $namedRange->getRange();
4271 - $splitRange = PHPExcel_Cell::splitRange($pRange);
4272 - // Convert row and column references
4273 - if (ctype_alpha($splitRange[0][0])) {
4274 - $pRange = $splitRange[0][0] . '1:' . $splitRange[0][1] . $namedRange->getWorksheet()->getHighestRow();
4275 - } elseif (ctype_digit($splitRange[0][0])) {
4276 - $pRange = 'A' . $splitRange[0][0] . ':' . $namedRange->getWorksheet()->getHighestColumn() . $splitRange[0][1];
4277 - }
4278 -// echo $pRange.') is in sheet '.$namedRange->getWorksheet()->getTitle().'<br />';
3823 + // Named range?
3824 + $namedRange = PHPExcel_NamedRange::resolveRange($pRange, $pSheet);
3825 + if ($namedRange !== NULL) {
3826 + $pSheet = $namedRange->getWorksheet();
3827 +// echo 'Named Range '.$pRange.' (';
3828 + $pRange = $namedRange->getRange();
3829 + $splitRange = PHPExcel_Cell::splitRange($pRange);
3830 + // Convert row and column references
3831 + if (ctype_alpha($splitRange[0][0])) {
3832 + $pRange = $splitRange[0][0] . '1:' . $splitRange[0][1] . $namedRange->getWorksheet()->getHighestRow();
3833 + } elseif(ctype_digit($splitRange[0][0])) {
3834 + $pRange = 'A' . $splitRange[0][0] . ':' . $namedRange->getWorksheet()->getHighestColumn() . $splitRange[0][1];
3835 + }
3836 +// echo $pRange.') is in sheet '.$namedRange->getWorksheet()->getTitle().'<br />';
4279 3837
4280 -// if ($pSheet->getTitle() != $namedRange->getWorksheet()->getTitle()) {
4281 -// if (!$namedRange->getLocalOnly()) {
4282 -// $pSheet = $namedRange->getWorksheet();
4283 -// } else {
4284 -// return $returnValue;
4285 -// }
4286 -// }
4287 - } else {
4288 - return PHPExcel_Calculation_Functions::REF();
4289 - }
3838 +// if ($pSheet->getTitle() != $namedRange->getWorksheet()->getTitle()) {
3839 +// if (!$namedRange->getLocalOnly()) {
3840 +// $pSheet = $namedRange->getWorksheet();
3841 +// } else {
3842 +// return $returnValue;
3843 +// }
3844 +// }
3845 + } else {
3846 + return PHPExcel_Calculation_Functions::REF();
3847 + }
4290 3848
4291 - // Extract range
4292 - $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange);
4293 -// var_dump($aReferences);
4294 - if (!isset($aReferences[1])) {
4295 - // Single cell (or single column or row) in range
4296 - list($currentCol, $currentRow) = PHPExcel_Cell::coordinateFromString($aReferences[0]);
4297 - $cellValue = null;
4298 - if ($pSheet->cellExists($aReferences[0])) {
4299 - $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog);
4300 - } else {
4301 - $returnValue[$currentRow][$currentCol] = null;
4302 - }
4303 - } else {
4304 - // Extract cell data for all cells in the range
4305 - foreach ($aReferences as $reference) {
4306 - // Extract range
4307 - list($currentCol, $currentRow) = PHPExcel_Cell::coordinateFromString($reference);
4308 -// echo 'NAMED RANGE: $currentCol='.$currentCol.' $currentRow='.$currentRow.'<br />';
4309 - $cellValue = null;
4310 - if ($pSheet->cellExists($reference)) {
4311 - $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog);
4312 - } else {
4313 - $returnValue[$currentRow][$currentCol] = null;
4314 - }
4315 - }
4316 - }
4317 -// print_r($returnValue);
4318 -// echo '<br />';
4319 - }
3849 + // Extract range
3850 + $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange);
3851 +// var_dump($aReferences);
3852 + if (!isset($aReferences[1])) {
3853 + // Single cell (or single column or row) in range
3854 + list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($aReferences[0]);
3855 + $cellValue = NULL;
3856 + if ($pSheet->cellExists($aReferences[0])) {
3857 + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog);
3858 + } else {
3859 + $returnValue[$currentRow][$currentCol] = NULL;
3860 + }
3861 + } else {
3862 + // Extract cell data for all cells in the range
3863 + foreach ($aReferences as $reference) {
3864 + // Extract range
3865 + list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($reference);
3866 +// echo 'NAMED RANGE: $currentCol='.$currentCol.' $currentRow='.$currentRow.'<br />';
3867 + $cellValue = NULL;
3868 + if ($pSheet->cellExists($reference)) {
3869 + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog);
3870 + } else {
3871 + $returnValue[$currentRow][$currentCol] = NULL;
3872 + }
3873 + }
3874 + }
3875 +// print_r($returnValue);
3876 +// echo '<br />';
3877 + }
4320 3878
4321 - return $returnValue;
4322 - }
3879 + // Return
3880 + return $returnValue;
3881 + } // function extractNamedRange()
4323 3882
4324 3883
4325 - /**
4326 - * Is a specific function implemented?
4327 - *
4328 - * @param string $pFunction Function Name
4329 - * @return boolean
4330 - */
4331 - public function isImplemented($pFunction = '')
4332 - {
4333 - $pFunction = strtoupper($pFunction);
4334 - if (isset(self::$PHPExcelFunctions[$pFunction])) {
4335 - return (self::$PHPExcelFunctions[$pFunction]['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY');
4336 - } else {
4337 - return false;
4338 - }
4339 - }
3884 + /**
3885 + * Is a specific function implemented?
3886 + *
3887 + * @param string $pFunction Function Name
3888 + * @return boolean
3889 + */
3890 + public function isImplemented($pFunction = '') {
3891 + $pFunction = strtoupper ($pFunction);
3892 + if (isset(self::$_PHPExcelFunctions[$pFunction])) {
3893 + return (self::$_PHPExcelFunctions[$pFunction]['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY');
3894 + } else {
3895 + return FALSE;
3896 + }
3897 + } // function isImplemented()
4340 3898
4341 3899
4342 - /**
4343 - * Get a list of all implemented functions as an array of function objects
4344 - *
4345 - * @return array of PHPExcel_Calculation_Function
4346 - */
4347 - public function listFunctions()
4348 - {
4349 - $returnValue = array();
3900 + /**
3901 + * Get a list of all implemented functions as an array of function objects
3902 + *
3903 + * @return array of PHPExcel_Calculation_Function
3904 + */
3905 + public function listFunctions() {
3906 + // Return value
3907 + $returnValue = array();
3908 + // Loop functions
3909 + foreach(self::$_PHPExcelFunctions as $functionName => $function) {
3910 + if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') {
3911 + $returnValue[$functionName] = new PHPExcel_Calculation_Function($function['category'],
3912 + $functionName,
3913 + $function['functionCall']
3914 + );
3915 + }
3916 + }
4350 3917
4351 - foreach (self::$PHPExcelFunctions as $functionName => $function) {
4352 - if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') {
4353 - $returnValue[$functionName] = new PHPExcel_Calculation_Function(
4354 - $function['category'],
4355 - $functionName,
4356 - $function['functionCall']
4357 - );
4358 - }
4359 - }
3918 + // Return
3919 + return $returnValue;
3920 + } // function listFunctions()
4360 3921
4361 - return $returnValue;
4362 - }
4363 3922
3923 + /**
3924 + * Get a list of all Excel function names
3925 + *
3926 + * @return array
3927 + */
3928 + public function listAllFunctionNames() {
3929 + return array_keys(self::$_PHPExcelFunctions);
3930 + } // function listAllFunctionNames()
4364 3931
4365 - /**
4366 - * Get a list of all Excel function names
4367 - *
4368 - * @return array
4369 - */
4370 - public function listAllFunctionNames()
4371 - {
4372 - return array_keys(self::$PHPExcelFunctions);
4373 - }
3932 + /**
3933 + * Get a list of implemented Excel function names
3934 + *
3935 + * @return array
3936 + */
3937 + public function listFunctionNames() {
3938 + // Return value
3939 + $returnValue = array();
3940 + // Loop functions
3941 + foreach(self::$_PHPExcelFunctions as $functionName => $function) {
3942 + if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') {
3943 + $returnValue[] = $functionName;
3944 + }
3945 + }
4374 3946
4375 - /**
4376 - * Get a list of implemented Excel function names
4377 - *
4378 - * @return array
4379 - */
4380 - public function listFunctionNames()
4381 - {
4382 - $returnValue = array();
4383 - foreach (self::$PHPExcelFunctions as $functionName => $function) {
4384 - if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') {
4385 - $returnValue[] = $functionName;
4386 - }
4387 - }
3947 + // Return
3948 + return $returnValue;
3949 + } // function listFunctionNames()
4388 3950
4389 - return $returnValue;
4390 - }
4391 -}
3951 +} // class PHPExcel_Calculation
3952 +