Author Topic: Configuration  (Read 565 times)

dhirschfeld

  • Newbie
  • *
  • Posts: 3
  • Karma: +0/-0
    • View Profile
Configuration
« on: July 23, 2015, 04:08:44 AM »
I'd like to be able to change the configuration by adding/removing modules when I install/remove a new pyxll app. I'd like to do this without changing the default configuration in `pyxll.cfg`. I envisage each new app having its own config `mynewapp.cfg` in config folder. So as to avoid having to change `pyxll.cfg` for every app added or removed would be possible to allow for glob patterns - e.g.

`external_config = ./config/*.cfg`


dhirschfeld

  • Newbie
  • *
  • Posts: 3
  • Karma: +0/-0
    • View Profile
Re: Configuration
« Reply #1 on: July 23, 2015, 04:24:04 AM »
Or possibly better, instead of polluting every spreadsheet with all the different pyxll functions for each app, if a spreadsheet named `myspreadsheet.xlsx` was loaded pyxll would load the default config then look for a `myspreadsheet.pyxll.cfg` file in the same dir and load it if present.

Tony

  • Administrator
  • Hero Member
  • *****
  • Posts: 544
  • Karma: +12/-1
    • View Profile
Re: Configuration
« Reply #2 on: July 23, 2015, 07:13:16 PM »
Hi,

using a wildcard in the external config should be a fairly minimal change. I'll take a look at adding that to a future release - thanks for the feedback!

In the meantime, it is possible to load modules programatically. You could have a single module in your config that when imported (or using the pyxll.xl_on_open decorator) looks for modules and imported them as needed. Once the modules were imported you then have to 'rebind' the newly imported python functions to Excel, which can be done using the pyxll_rebind macro. Note that is an Excel macro, not a python function and so has to be called as follows:

Code: [Select]
import win32com.client
xl_window = pyxll.get_active_object()
xl = win32com.client.Dispatch(xl_window).Application
xl.Run("pyxll_reload")

The snag with this, however, is that the Excel window doesn't exist at the time the PyXLL addin is loaded, and so you will have to wait before you can call the rebind macro. Something like this would do it...

Code: [Select]
def rebind()
        """rebind the Excel functions/macros/menus"""
        def on_timer(timer_id, unused):
            # try getting the window (this will fail until the window is created)
            try:
                xl_window = get_active_object()
            except RuntimeError:
                # retry later
                return

            # got the window so no need to retry again
            timer.kill_timer(timer_id)

            # call the pyxll_rebind macro
            xl = win32com.client.Dispatch(xl_window).Application
            xl.Run("pyxll_rebind")

      # start a timer to try to call pxl_rebind
      timer.set_timer(100, on_timer)

With regard to doing it per-spreadsheet, Excel add-ins are loaded for the Excel session and not for each individual spreadsheet. You could create an event handler that got called when a spreadsheet was loaded and then load more python modules and rebind as above. The object_cache example has an event handler that gets called whenever a workbook is opened which might be useful to look at if you wanted to try that (see ObjectCacheApplicationEventHandler.OnWorkbookOpen in that example).

Best regards,
Tony

dhirschfeld

  • Newbie
  • *
  • Posts: 3
  • Karma: +0/-0
    • View Profile
Re: Configuration
« Reply #3 on: July 27, 2015, 01:34:09 AM »
Thanks for the quick response! The dynamic loading could be pretty useful though it would still be great if the wildcard config could make it into a future release.

Cheers,
Dave

Tony

  • Administrator
  • Hero Member
  • *****
  • Posts: 544
  • Karma: +12/-1
    • View Profile
Re: Configuration
« Reply #4 on: August 11, 2015, 09:20:45 AM »
Hi Dave,

in the next release you will be able to use wildcards in the external_config setting (e.g. "external_config = ./config/*.cfg").

You can get a preview of this release from the beta site: https://beta.pyxll.com/download.html.

Best regards,
Tony