Overview

Packages

  • JAMA
  • None
  • PHP
  • PHPExcel
    • CachedObjectStorage
    • Calculation
    • Cell
    • Chart
      • Renderer
    • Reader
      • Excel2007
      • Excel5
    • RichText
    • Settings
    • Shared
      • Escher
      • OLE
      • Trend
      • ZipArchive
    • Style
    • Worksheet
      • Drawing
    • Writer
      • 2007
      • CSV
      • Excel2007
      • Excel5
      • HTML
      • PDF

Classes

  • CholeskyDecomposition
  • Dao
  • DateTime
  • DateTimeZone
  • DOMNode
  • EigenvalueDecomposition
  • Elemento
  • Historial
  • Irradiacion
  • Latitud
  • MotorPhp
  • Panel
  • PclZip
  • Periodo
  • PHPExcel
  • PHPExcel_Autoloader
  • PHPExcel_Best_Fit
  • PHPExcel_CachedObjectStorage_APC
  • PHPExcel_CachedObjectStorage_CacheBase
  • PHPExcel_CachedObjectStorage_DiscISAM
  • PHPExcel_CachedObjectStorage_Igbinary
  • PHPExcel_CachedObjectStorage_Memcache
  • PHPExcel_CachedObjectStorage_Memory
  • PHPExcel_CachedObjectStorage_MemoryGZip
  • PHPExcel_CachedObjectStorage_MemorySerialized
  • PHPExcel_CachedObjectStorage_PHPTemp
  • PHPExcel_CachedObjectStorage_SQLite
  • PHPExcel_CachedObjectStorage_SQLite3
  • PHPExcel_CachedObjectStorage_Wincache
  • PHPExcel_CachedObjectStorageFactory
  • PHPExcel_CalcEngine_CyclicReferenceStack
  • PHPExcel_CalcEngine_Logger
  • PHPExcel_Calculation
  • PHPExcel_Calculation_Database
  • PHPExcel_Calculation_DateTime
  • PHPExcel_Calculation_Engineering
  • PHPExcel_Calculation_ExceptionHandler
  • PHPExcel_Calculation_Financial
  • PHPExcel_Calculation_FormulaParser
  • PHPExcel_Calculation_FormulaToken
  • PHPExcel_Calculation_Function
  • PHPExcel_Calculation_Functions
  • PHPExcel_Calculation_Logical
  • PHPExcel_Calculation_LookupRef
  • PHPExcel_Calculation_MathTrig
  • PHPExcel_Calculation_Statistical
  • PHPExcel_Calculation_TextData
  • PHPExcel_Calculation_Token_Stack
  • PHPExcel_Cell
  • PHPExcel_Cell_AdvancedValueBinder
  • PHPExcel_Cell_DataType
  • PHPExcel_Cell_DataValidation
  • PHPExcel_Cell_DefaultValueBinder
  • PHPExcel_Cell_Hyperlink
  • PHPExcel_Chart
  • PHPExcel_Chart_DataSeries
  • PHPExcel_Chart_DataSeriesValues
  • PHPExcel_Chart_Layout
  • PHPExcel_Chart_Legend
  • PHPExcel_Chart_PlotArea
  • PHPExcel_Chart_Renderer_jpgraph
  • PHPExcel_Chart_Title
  • PHPExcel_Comment
  • PHPExcel_DocumentProperties
  • PHPExcel_DocumentSecurity
  • PHPExcel_Exponential_Best_Fit
  • PHPExcel_HashTable
  • PHPExcel_IOFactory
  • PHPExcel_Linear_Best_Fit
  • PHPExcel_Logarithmic_Best_Fit
  • PHPExcel_NamedRange
  • PHPExcel_Polynomial_Best_Fit
  • PHPExcel_Power_Best_Fit
  • PHPExcel_Reader_Abstract
  • PHPExcel_Reader_CSV
  • PHPExcel_Reader_DefaultReadFilter
  • PHPExcel_Reader_Excel2003XML
  • PHPExcel_Reader_Excel2007
  • PHPExcel_Reader_Excel2007_Chart
  • PHPExcel_Reader_Excel2007_Theme
  • PHPExcel_Reader_Excel5
  • PHPExcel_Reader_Excel5_Escher
  • PHPExcel_Reader_Excel5_MD5
  • PHPExcel_Reader_Excel5_RC4
  • PHPExcel_Reader_Gnumeric
  • PHPExcel_Reader_HTML
  • PHPExcel_Reader_OOCalc
  • PHPExcel_Reader_SYLK
  • PHPExcel_ReferenceHelper
  • PHPExcel_RichText
  • PHPExcel_RichText_Run
  • PHPExcel_RichText_TextElement
  • PHPExcel_Settings
  • PHPExcel_Shared_CodePage
  • PHPExcel_Shared_Date
  • PHPExcel_Shared_Drawing
  • PHPExcel_Shared_Escher
  • PHPExcel_Shared_Escher_DgContainer
  • PHPExcel_Shared_Escher_DgContainer_SpgrContainer
  • PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer
  • PHPExcel_Shared_Escher_DggContainer
  • PHPExcel_Shared_Escher_DggContainer_BstoreContainer
  • PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE
  • PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip
  • PHPExcel_Shared_Excel5
  • PHPExcel_Shared_File
  • PHPExcel_Shared_Font
  • PHPExcel_Shared_JAMA_LUDecomposition
  • PHPExcel_Shared_JAMA_Matrix
  • PHPExcel_Shared_JAMA_QRDecomposition
  • PHPExcel_Shared_OLE
  • PHPExcel_Shared_OLE_ChainedBlockStream
  • PHPExcel_Shared_OLE_PPS
  • PHPExcel_Shared_OLE_PPS_File
  • PHPExcel_Shared_OLE_PPS_Root
  • PHPExcel_Shared_OLERead
  • PHPExcel_Shared_PasswordHasher
  • PHPExcel_Shared_String
  • PHPExcel_Shared_TimeZone
  • PHPExcel_Shared_XMLWriter
  • PHPExcel_Shared_ZipArchive
  • PHPExcel_Shared_ZipStreamWrapper
  • PHPExcel_Style
  • PHPExcel_Style_Alignment
  • PHPExcel_Style_Border
  • PHPExcel_Style_Borders
  • PHPExcel_Style_Color
  • PHPExcel_Style_Conditional
  • PHPExcel_Style_Fill
  • PHPExcel_Style_Font
  • PHPExcel_Style_NumberFormat
  • PHPExcel_Style_Protection
  • PHPExcel_Style_Supervisor
  • PHPExcel_Worksheet
  • PHPExcel_Worksheet_AutoFilter
  • PHPExcel_Worksheet_AutoFilter_Column
  • PHPExcel_Worksheet_AutoFilter_Column_Rule
  • PHPExcel_Worksheet_BaseDrawing
  • PHPExcel_Worksheet_CellIterator
  • PHPExcel_Worksheet_ColumnDimension
  • PHPExcel_Worksheet_Drawing
  • PHPExcel_Worksheet_Drawing_Shadow
  • PHPExcel_Worksheet_HeaderFooter
  • PHPExcel_Worksheet_HeaderFooterDrawing
  • PHPExcel_Worksheet_MemoryDrawing
  • PHPExcel_Worksheet_PageMargins
  • PHPExcel_Worksheet_PageSetup
  • PHPExcel_Worksheet_Protection
  • PHPExcel_Worksheet_Row
  • PHPExcel_Worksheet_RowDimension
  • PHPExcel_Worksheet_RowIterator
  • PHPExcel_Worksheet_SheetView
  • PHPExcel_WorksheetIterator
  • PHPExcel_Writer_Abstract
  • PHPExcel_Writer_CSV
  • PHPExcel_Writer_Excel2007
  • PHPExcel_Writer_Excel2007_Chart
  • PHPExcel_Writer_Excel2007_Comments
  • PHPExcel_Writer_Excel2007_ContentTypes
  • PHPExcel_Writer_Excel2007_DocProps
  • PHPExcel_Writer_Excel2007_Drawing
  • PHPExcel_Writer_Excel2007_Rels
  • PHPExcel_Writer_Excel2007_RelsRibbon
  • PHPExcel_Writer_Excel2007_RelsVBA
  • PHPExcel_Writer_Excel2007_StringTable
  • PHPExcel_Writer_Excel2007_Style
  • PHPExcel_Writer_Excel2007_Theme
  • PHPExcel_Writer_Excel2007_Workbook
  • PHPExcel_Writer_Excel2007_Worksheet
  • PHPExcel_Writer_Excel2007_WriterPart
  • PHPExcel_Writer_Excel5
  • PHPExcel_Writer_Excel5_BIFFwriter
  • PHPExcel_Writer_Excel5_Escher
  • PHPExcel_Writer_Excel5_Font
  • PHPExcel_Writer_Excel5_Parser
  • PHPExcel_Writer_Excel5_Workbook
  • PHPExcel_Writer_Excel5_Worksheet
  • PHPExcel_Writer_Excel5_Xf
  • PHPExcel_Writer_HTML
  • PHPExcel_Writer_PDF
  • PHPExcel_Writer_PDF_Core
  • PHPExcel_Writer_PDF_DomPDF
  • PHPExcel_Writer_PDF_mPDF
  • PHPExcel_Writer_PDF_tcPDF
  • Provincia
  • Radiacion
  • SingularValueDecomposition
  • Sistema
  • trendClass
  • xajax
  • xajaxArgumentManager
  • xajaxCallableObject
  • xajaxCallableObjectPlugin
  • xajaxControl
  • xajaxControlContainer
  • xajaxCustomRequest
  • xajaxCustomResponse
  • xajaxEvent
  • xajaxEventPlugin
  • xajaxFunctionPlugin
  • xajaxIncludeClientScriptPlugin
  • xajaxLanguageManager
  • xajaxPlugin
  • xajaxPluginManager
  • xajaxRequest
  • xajaxRequestPlugin
  • xajaxResponse
  • xajaxResponseManager
  • xajaxResponsePlugin
  • xajaxScriptPlugin
  • xajaxUserFunction
  • XMLWriter

Interfaces

  • DateTimeInterface
  • Iterator
  • PHPExcel_CachedObjectStorage_ICache
  • PHPExcel_Cell_IValueBinder
  • PHPExcel_IComparable
  • PHPExcel_Reader_IReader
  • PHPExcel_Reader_IReadFilter
  • PHPExcel_RichText_ITextElement
  • PHPExcel_Writer_IWriter
  • Throwable
  • Traversable

Exceptions

  • Exception
  • PHPExcel_Calculation_Exception
  • PHPExcel_Chart_Exception
  • PHPExcel_Exception
  • PHPExcel_Reader_Exception
  • PHPExcel_Writer_Exception

Functions

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