Package: pycel-fixed
PycelPycel is a small python library that can translate an Excel spreadsheet into
executable python code which can be run independently of Excel.The python code is based on a graph and uses caching & lazy evaluation to
ensure (relatively) fast execution.  The graph can be exported and analyzed
using tools likeGephi. See the contained example
for an illustration.Required python libraries:dateutil,networkx,numpy,openpyxl,ruamel.yaml, and optionally:matplotlib,pydotThe full motivation behind pycel including some examples & screenshots is
described in thisblog post.UsageDownload the library and run the example file.Quick start:You can use binder to see and explore the tool quickly and interactively in the
browser:The good:All the main mathematical functions (sin, cos, atan2, …) and operators
(+,/,^, …) are supported as are ranges (A5:D7), and functions like
MIN, MAX, INDEX, LOOKUP, and LINEST.The codebase is small, relatively fast and should be easy to understand
and extend.I have tested it extensively on spreadsheets with 10 sheets & more than
10000 formulae.  In that case calculation of the equations takes about 50ms
and agrees with Excel up to 5 decimal places.The bad:My development is driven by the particular spreadsheets I need to handle so
I have only added support for functions that I need.  However, it is should be
straightforward to add support for others.The code does currently not support cell references so a function like OFFSET
would take some more work to implement.  Not inherently difficult, its just
that I have had no need for references yet.  Also, for obvious reasons, any
VBA code is not compiled but needs to be re-implemented manually on the
python side.The Ugly:The resulting graph-based code is fast enough for my purposes but to make it
truly fast you would probably replace the graph with a dependency tracker
based on sparse matrices or something similar.Excel AddinIt’s possible to run pycel as an excel addin usingPyXLL. Simply place pyxll.xll and pyxll.py in the
lib directory and add the xll file to the Excel Addins list as explained in
the pyxll documentation.AcknowledgementsThis code was originally made possible thanks to the python port of
Eric Bachtal’sExcel formula parsing codeby Robin Macharg.The code currently uses a tokenizer of similar origin from theopenpyxl library.Change Log1.0b27 (Unreleased)Greetings from Customs.1.0b26 (Unreleased)Major ChangesUpdate to Python 3.9, drop support for Python 3.5ChangesAdd bitwise functions: bitand, bitor, bitxor, bitlshift and bitrshift (Thanks, bogdan-oprescu-nxp)Add PV function (Thanks, estandiaa-marain)FixesFix Openpyxl > 3.0.4 (Thanks, ckp95)Fix HLOOKUP row_index_num validation to use num rows (Thanks, nanaposo)Fix #86, tokenize.TokenError: (‘EOF in multi-line statement’,Fix #88, Handle calcPR in workbook (Thanks, andreif)Fix #89, NPV function fails when passed range of cashflows (Thanks, jpp-0)Fix #93, AssertionError during set_value(), by adding a better error messageFix #99, Pycel raises NotImplementedError on rectangular ranges (Thanks, rmorel)Fix #103, build_operator_operand_fixup() throws #VALUE error when concatenating AddressCell objects (Thanks, nboukraa)Fix #104, Insufficient coverage and testing after recent mergesFix #105, Incorrect RPN for expressions with consecutive negations (Thanks, victorjmarin)Fix #109, String concatenation fails for particular cases (Thanks, bogdan-oprescu-nxp)Fix issue in =IF() when comparing to numpy resultFix MID() and REPLACE() and LEN() in a CSE contextFix INDEX() error handling1.0b23-1.0b25Skipped1.0b22 (2019-10-17)FixesFix #80, incompatible w/ networkx 2.41.0b21 (2019-10-13)ChangesSpeed up compileImplement defined names in multicolon rangesTokenize ‘:’ when adjoining functions as infix operatorVarious changes in prep to improve references, includingAdd reference expansion to function helpersAdd sheet to indirect() and ref_param=0 to offset()Implement is_address() helperImplement intersection and union for AddressCellFixesFix #77, empty arg in IFERROR()Fix #78, None compare and cleanup error handling for various IFS() funcs1.0b20 (2019-09-22)ChangesImplement multi colon rangesAdd support for missing (empty) function parametersFixesFix threading issue in iterative evaluatorFix range intersection with null result for ROW and COLUMNFix #74 - Count not working for ranges1.0b19 (2019-09-12)ChangesImplement INDIRECT & OFFSETImplement SMALL, LARGE & ROUNDDOWN  (Thanks, nanaposo)Add error message for unhandled missing function parameterFixesFix threading issue w/ CSE evaluator1.0b18 (2019-09-07)ChangesImplement CEILING_MATH, CEILING_PRECISION, FLOOR_MATH & FLOOR_PRECISIONImplement FACT & FACTDOUBLEImplement AVERAGEIF, MAXIFS, MINIFSImplement ODD, EVEN, ISODD, ISEVEN, SIGNFixesFix #67 - Evaluation with unbounded rangeFix bugs w/ single cells for xIFS functions1.0b17 (2019-09-02)ChangesAdd Formula Support for Multi Area Ranges from defined namesAllow ExcelCompiler init from openpyxl workbookImplement LOWER(), REPLACE(), TRIM() & UPPER()Implement DATEVALUE(), IFS() and ISERR()  (Thanks, int128t)Reorganized time and time utils and text functionsAdd excelutil.AddressMultiAreaRange.Add abs_coordinate() property to AddressRange and AddressCellCleanup import statementsFixesResolved tox version issue on travisFix defined names with Multi Area Range1.0b16 (2019-07-07)ChangesAdd twelve date and time functionsSerialize workbook filename and use it instead of the serialization filename (Thanks, nanaposo)1.0b15 (2019-06-30)ChangesImplement AVERAGEIFS()Take Iterative Calc Parameter defaults from workbookBug Fixes#60, Binder Notebook Example not Working1.0b14 (2019-06-16)ChangesAdded method to evaluate the conditional format (formulas) for a cell or cellsAdded ExcelCompiler(…, cycles=True) to allow Excel iterative calculations1.0b13 (2019-05-10)ChangesImplement VALUE()Improve compile performance reversion from CSE workBug Fixes#54, In normalize_year(), month % 12 can be 0 -> IllegalMonthError1.0b12 (2019-04-22)ChangesAdd library plugin supportImprove evaluate of unbounded row/col (ie: A:B)Fix some regressions from 1.0b111.0b11 (2019-04-21)Major ChangesRefactored ExcelWrapper, ExcelFormula & ExcelCompiler to allow…Added considerable extensions to CSE Array Formula SupportRefactored function_helpers to add decorators for excelizing library functionsAdded a dozen new functionsImproved various messages and exceptions in validate_calcs() and trim_graph()ChangesImplement LEFT()Implement ISERROR()Implement FIND()Implement ISNUMBER()Implement SUMPRODUCT()Implement CEILING()Implement TRUNC() and FLOOR()Add support for LOG()Improve ABS(), INT() and ROUND()Add quoted_address() method to AddressRange and AddressCellAdd public interface to get list of formula_cells()Improve Some NotImplementedError() messagesAdd NotImplementedError for “linked” sheet namesFix function info for paired functions from same lineAdd reference URL to function infoOnly build compiler eval context onceAddress Range Union and Intersection need sheet_nameCSE Array ChangesAdd CSE Array handling to excelformula and excelcompilerChange Row, Column & Index to rectangular arrays onlyAdd in_array_formula_contextAdd cse_array_wrapper() to allow calling functions in array contextAdd error_string_wrapper() to check for excel errorsMove math_wrap() to function_helpers.Handle Direct CSE Array in cellReorganize CSE Array Formula handling in excelwrapperFor CSE Arrays that are smaller than target fill w/ NoneTrim oversize array results to fit target rangeImprove needed addresses parser from python codeImprove _coerce_to_number() and _numerics() for CSE arraysRemove formulas from excelwrapper._OpxRange()Bug FixesFix Range IntersectionFix Unary Minus on Empty cellFix ISNA()Fix AddressCell create from tuplePower(0,-1) now returns DIV0Cleanup index()1.0b8 (2019-03-20)ChangesImplement operators for Array FormulasImplement concatenate and concatImplement subtotalAdd support for expanding array formulasFix column and row for array formulasAdd support for table relative referencesAdd function information methodsImprove messages for validate_calcs and not implemented functions1.0b7 (2019-03-10)ChangesImplement Array (CSE) FormulasBug FixesFix #45 - Unbounded Range Addresses (ie: A:B or 1:2) broken1.0b6 (2019-03-03)Bug FixesFix #42 - ‘ReadOnlyWorksheet’ object has no attribute ‘iter_cols’Fix #43 - Fix error with leading/trailing whitespace1.0b5 (2019-02-24)ChangesImplement XOR(), NOT(), TRUE(), FALSE()Improve error handling for AND(), OR()Implement POWER() function1.0b4 (2019-02-17)ChangesMove to openpyxl 2.6+Remove support for Python 3.41.0b3 (2019-02-02)ChangesWork around openpyxl returning datetimesPin to openpyxl 2.5.12 to avoid bug in 2.5.14 (fixed in PR #315)1.0b2 (2019-01-05)ChangesMuch work to better match Excel error processingExtend validate_calcs() to allow testing entire workbookImprovements to match(), including wildcard supportFinished implementing match(), lookup(), vlookup() and hlookup()Implement COLUMN() and ROW()Implement % operatorImplement len()Implement binary base number Excel functions (hex2dec, etc.)Fix PI()1.0b0 (2018-12-25)Major changesConverted to Python 3.4+Removed Windows Excel COM driver (openpyxl is used for all xlsx reading)Add support for defined namesAdd support for structured referencesFix support for relative formulasset_value() and evaluate() support ranges and listsAdd several more library functionsAdd AddressRange and AddressCell classes to encapsulate address calcsAdd validate_calcs() to aid debugging excellib functionsAddbuildfeature which can limit recompile to only when excel file changesImproved handling for #DIV0! and #VALUE!CompatibilityTests run on Python 3.4, 3.5, 3.6, 3.7 (via tox)Python 2 no longer supportedOther ChangesHeavily refactored ExcelCompilerMoved all formula evaluation, parsing, etc, code to ExcelFormula classConvert to using openpyxl tokenizerConverted prints to logging callsConvert to using pytestAdd support for travis and codecov.io100% unit test coverage (mostly)Add debuggable formula evaluationCleanup generated Python code to make easier to readAdd a text format (yaml or json) serialization formatflake8 (pep8) checks addedpip now handles which Python versions can be usedRelease to PyPIDocs updatedBugfixesNumerous0.0.1 (unreleased)Original version available fromDirk Ggorissen’s Pycel Github Page.Supports Python 2