PHPExcel_Calculation
[ class tree: PHPExcel_Calculation ] [ index: PHPExcel_Calculation ] [ all elements ]

Source for file Calculation.php

Documentation is available at Calculation.php

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

Documentation generated on Sun, 27 Feb 2011 16:28:53 -0800 by phpDocumentor 1.4.3