It’s possible to register functions for PyXLL to call at certain points. These examples show how to use each of the callback decorators.
See also PyXLL callbacks.
"""
PyXLL Examples: Callbacks
The PyXLL Excel Addin is configured to load one or more
python modules when it's loaded.
Moldules can register callbacks with PyXLL that will be
called at various times to inform the user code of
certain events.
"""
from pyxll import xl_on_open, \
xl_on_reload, \
xl_on_close, \
xl_license_notifier, \
xlcCalculateNow
import logging
_log = logging.getLogger(__name__)
try:
import win32api
import win32con
except ImportError:
_log.warning( "*** win32api could not be imported ***")
_log.warning( "*** the callback examples will not work correctly ***")
_log.warning( "*** to fix this, install the pywin32 extensions ***")
win32api = None
@xl_on_open
def on_open(import_info):
"""
on_open is registered to be called by PyXLL when the addin
is opened via the xl_on_open decorator.
This happens each time Excel starts with PyXLL installed.
"""
# check to see which modules didn't import correctly
errors = []
for modulename, module, exc_info in import_info:
if module is None:
exc_type, exc_value, exc_traceback = exc_info
errors.append("Error loading '%s' : %s" % (modulename, exc_value))
if errors:
# report any errors to the user
if win32api:
win32api.MessageBox(0,
"\n".join(errors) + "\n\n(See callbacks.py example)",
"PyXLL Callbacks Example",
win32con.MB_ICONWARNING)
else:
_log.info("callbacks.on_open: " + "\n".join(errors))
@xl_on_reload
def on_reload(import_info):
"""
on_reload is registered to be called by PyXLL whenever a
reload occurs via the xl_on_reload decorator.
"""
# check to see which modules didn't import correctly
errors = []
for modulename, module, exc_info in import_info:
if module is None:
exc_type, exc_value, exc_traceback = exc_info
errors.append("Error loading '%s' : %s" % (modulename, exc_value))
if errors:
# report any errors to the user
if win32api:
win32api.MessageBox(0,
"\n".join(errors) + "\n\n(See callbacks.py example)",
"PyXLL Callbacks Example",
win32con.MB_ICONWARNING)
else:
_log.info("callbacks.on_reload: " + "\n".join(errors))
else:
# report everything reloaded OK
if win32api:
win32api.MessageBox(0,
"PyXLL Reloaded OK\n(See callbacks.py example)",
"PyXLL Callbacks Example",
win32con.MB_ICONINFORMATION)
else:
_log.info("callbacks.on_reload: PyXLL Reloaded OK")
# recalcuate all open workbooks
xlcCalculateNow()
@xl_on_close
def on_close():
"""
on_close will get called as Excel is about to close.
This is a good time to clean up any globals and stop
any background threads so that the python interpretter
can be closed down cleanly.
The user may cancel Excel closing after this has been
called, so your code should make sure that anything
that's been cleaned up here will get recreated again
if it's needed.
"""
_log.info("callbacks.on_close: PyXLL is closing")
@xl_license_notifier
def license_notifier(name, expdate, days_left, is_perpetual):
"""
license_notifier will be called when PyXLL is starting up, after
it has read the config and verified the license.
If there is no license name will be None and days_left will be less than 0.
"""
if days_left >= 0 or is_perpetual:
_log.info("callbacks.license_notifier: "
"This copy of PyXLL is licensed to %s" % name)
if not is_perpetual:
_log.info("callbacks.license_notifier: "
"%d days left before the license expires (%s)" % (days_left, expdate))
else:
_log.info("callbacks.license_notifier: "
"This copy of PyXLL is for evaluation or non-commercial use only")