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