I am working with the RTD functions in excel using pythoncom and a
some great sample code from Chris Nilsson.  In Excel 2003 and 2007, I
am able to create my python object via the IRTDServer com interface.
Excel then passes a callback interface, IRTDServerEvents to my
object.  I hold on to that interface and callback using UpdateNotify
to let Excel know that I have an update for it.  Everything works fine
in 2003, but the interface callback in 2007 fails with an obscure COM
error.(below)   Other than that it works fine 2007.   IMO, if the typelib
information were wrong, the IRTDServer interface would not work
either.

I have checked versions in the registry, typelibs, GUIDs, and security
setting.  All settings are correct.  Even turned off multi-threaded calcs in
2007.

Here are the code snippets that get the callback interface and hold on
to it.

I set up Excel and the COM Interfaces

EXCEL_TLB_GUID = '{00020813-0000-0000-C000-
000000000046}'
EXCEL_TLB_LCID = 0
EXCEL_TLB_MAJOR = 1
#EXCEL_TLB_MINOR = 4   #Excel 2003
EXCEL_TLB_MINOR = 6      #Excel 2007 via registry??? Is this correct?

# Import the excel typelib to make sure we've got early-binding going
on.

gencache.EnsureModule(EXCEL_TLB_GUID, EXCEL_TLB_LCID, \
                     EXCEL_TLB_MAJOR, EXCEL_TLB_MINOR)
logging.debug('Gencache')

# Again, we feed in the Excel typelib as the source of these
interfaces.
universal.RegisterInterfaces(EXCEL_TLB_GUID,
                            EXCEL_TLB_LCID, EXCEL_TLB_MAJOR,
EXCEL_TLB_MINOR,
                            ['IRtdServer','IRTDUpdateEvent'])
...

 _com_interfaces_ = ['IRtdServer']
 _public_methods_ = ['ConnectData','DisconnectData','Heartbeat',
                     'RefreshData','ServerStart','ServerTerminate']
 _reg_clsctx_ = pythoncom.CLSCTX_INPROC_SERVER

...

>>>>>>>>>>>>>>>>>>>>>>>>>>>
This gets called from excel to create the object

def ServerStart(self, CallbackObject):
   """Excel has just created us... We take its callback for later,
and set up shop."""
   self.IsAlive = self.ALIVE

   if CallbackObject is None:
     raise COMException(desc='Excel did not provide a callback')
   #Check the uuid of IRTDServerEvent Interface
   rv =  win32com.client.CLSIDToClass.HasClass('{A43788C1-
D91B-11D3-8F39-00C04F3651B8}')

   logging.debug('Interface is good so far... %s', rv)
   logging.debug ('Callback is %s' % CallbackObject)    #PyIDispatch
object

   # Need to "cast" the raw PyIDispatch object to the IRTDUpdateEvent
interface
   IRTDUpdateEventKlass = win32com.client.CLSIDToClass.GetClass
('{A43788C1-D91B-11D3-8F39-00C04F3651B8}')


   self.__callback = IRTDUpdateEventKlass(CallbackObject)
   self.__callbackRaw = CallbackObject


.....


def SignalExcel(self):
   """Use the callback we were given to tell excel new data is
available."""
   logging.debug('Signalling Excel')
    if self.__callback is None:
     raise COMException(desc="Callback excel provided is Null")
   try:
     self.__callback.UpdateNotify()    <-----------------------THIS
IS WHERE IT FAILS IN Excel 2007
   except Exception, why:
     logging.debug('Exception raised %s ' % Exception)
     raise COMException(desc=str(why))
   finally:
     logging.debug('SignalExcel::Completed!!!!')

******************************************* With this error trace
***********

Exception in thread Thread-471:
Traceback (most recent call last):
  File "C:\Python26\Lib\threading.py", line 527, in __bootstrap_inner
    self.run()
  File "C:\Python26\Lib\threading.py", line 731, in run
    self.function(*self.args, **self.kwargs)
  File "C:\dev\python\ExcelRTD.py", line 391, in Update
    self.SignalExcel()
  File "C:\dev\python\ExcelRTD.py", line 151, in SignalExcel
    raise COMException(desc=str(why))
COMException: (None, "(-2147352567, 'Exception occurred.', (0, None, None,
None, 0, 0), None)", None, -1)

Thanks for your help.

Jack
_______________________________________________
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32

Reply via email to