Behaviour
Work In Progress
This pags is currently a work in progress. Please read at your own risk
Introduction
xlpro aims to be as similar to plain Python development as possible, such that the user isn't bound by a proprietary codebase. However, the quirks of integrating function calling and visualisation within Excel require some compromises which have to strike a balance of convenience, readability, performance and syntax.
As a result, there are some behaviours worth noting to the user, which we hope only require minor adjustments.
Overview of Behaviours
-
String values stored in the Excel cells embed information.
"PyObj<...>"
is a reference to an arbitrary Python object."Promise<...>"
indicates that a cell is awaiting a return value from the server."...Exception(...)"
or"...Error(...)"
or any string representation of a Python exception indicates the Python function call raised an Exception, and you should debug the file.
-
xlpro can handle showing simple, array or image types.
- Basic types,
str
,float
,int
,bool
. - Numpy types,
np.float64
,np.int32
and others. - Datetime types
np.DateTime
, these are cast from and to Excel serial representation if formatted toDate
in Excel. numpy.ndarray
andpandas.Dataframe
structures including the above dtypes can be shown in Excel.- Images and
matplotlib
figures are supported with theshow_image()
method.
- Basic types,
-
All input arrays or values are checked for the string
"pyNone"
(Excel name=pyNone
), which is replaced by PythonNone
. This will cast numpy arrays todtype=object
. -
Types are cast using PEP 484 type hinting. E.g. a 2D Excel array is cast to a
xlpro.ndarray1d
,xlpro.ndarray1d[np.float64]
, orlist1d
to maintain behaviour between row or column vector inputs. -
Python functions with optional arguments are supported. Providing no input, or explcitly using the
=pyEmpty
Excel Name will use the default arguments. -
For convenience and to minimise disruption, A simple undo/redo mechanism is built into xlpro to mitigate xlpro wiping Excel's undo stack. The undo-tracker is queried periodically to ensure it is active in order to avoid mishaps (should the VBA context crash or reset).
-
For convenience, lists or tuples of objects are returned as column vector spill arrays natively. Use
xlpro.condense()
around the return type if you wish to enforce the result does not expand.
Special Notes
Type Pre-Processing and Casting
xlpro wraps each function call coming from Excel with a type caster which is based on the type hints provided by the author in the function signature.
In its simplest form, this is necessary to cast the 2D array structure from Excel into predictable Python structures, not to mention the convenience of not needing to handle this in your function.
Note
If you want a function to be agnostic of a column or row vector in Excel, use a 1D data type hint, If you want to maintain the structure, use a 2D type hint.
The following built in types are provided as simple wrappers of the numpy.ndarray
and list
types.
EXPERIMENTAL - Complex casting
Numpy types will attempt to cast to xlpro.ndarray1d[np.float64]
if provided as a type hint in the Python function signature, but this is experimental. If this doesn't give the desired behaviour, you could just use the xlpro.ndarray1d
and cast using .astype(np.float64)
at the beginning of your function.
Empty Cell Handling
The communication pipeline between Excel and Python is expensive. Some tricks are used to prevent this from being flooded unnecessarily.
xlpro generally completes an isReady
check on all function inputs to prevent wasted calls.
On inputs up to 32
cells in size, if any of the input values are strictly empty Excel cells, the function call assumes it is waiting for the cell to be populated from a spill array, for example. Strictly empty cells would pass an ISBLANK()
check, but may be a null string =""
.
The scenarios where isReady = False
are as follows:
- The argument is a
Promise
(indicating the cell is waiting for the result). - The argument looks like a Python
Exception
. - The argument is an Excel error value.
- The argument is an empty cell.
Passing None
from Excel to Python
Want to deliberately pass None
to Python? - use the =pyNone
formula in the cells in question. This string is converted to Python None
in the backend.
A note on casting when using None
The use of None
has implications on xlpro's type casting argument pre-processor.
The use of None
in your formulas will not affect casts to xlpro.list1d
or xlpro.list2d
, but casts to xlpro.ndarray1d
or xlpro.ndarray2d
will cause the numpy array to convert to dtype=object
. If this is undesired, handle the conversion back in the first line of your function body. See XXX
For arrays larger than 32 cells, Numpy's behaviour is natural and empty cells will cast to NaN
for numeric arrays.
Why do this?
Excel issues ghost function calls on any intermediate calculation, e.g. a subfunction of a larger formula. These flood the calculation queue and hog resources. Removing these while still in VBA-land is cheap, and significantly improves the performance of xlpro's calculation cycle.
The Excel Undo Stack
xlpro is fundamentally a macro, and like any Excel macro which modifies the Workbook, any remote calls from the server which modify a cell immediately wipe the undo history of the workbook. This could mean that touching any input cell could immediately prevent you undoing your last command.
This behaviour is frankly always going to be dealbreaker for the user no matter how good the tool is otherwise. To mitigate the worst offending cases of this, xlpro includes a custom undo/redo mechanism which can handle basic cell formula changes, copy/pasting, and cut/pasting. This is intended to catch the case where you mistype over a cell which issues an xlpro-recalculation cycle and would otherwise be lost permanently.
If you plan on bulk changes, consider disabling automatic calculation.
Not all is lost
The native Excel undo stack is maintained where possible. Only by triggering a new/unique function call will the stack be wiped
VBA and Undo, a Very Common Problem
Managing the undo stack when dealing with VBA macros is a widely recognised limitation of Excel. xlpro's implementation is not perfect, but is effective if the sequence of selecting, typing, copying and pasting is kept simple. The hope is that this catches any small errors.