https://mail.python.org/pipermail/python-win32/2004-October/002582.html summarizes my problem perfectly (with slight edits to update it for my case):
I would like to have a Word Document instance with all methods and properties visible during interactive session. This is my currnet apporach:
>>> from win32com.client import gencache, Dispatch >>> gencache.EnsureModule('{00020905-0000-0000-C000-000000000046}', 0, 8, 1, bForDemand=True) <module 'win32com.gen_py.00020905-0000-0000-C000-000000000046x0x8x1' from 'C:\DOCUME~1\osuchw\LOCALS~1\Temp\gen_py\2.3\00020905-0000-0000-C000-000000000046x0x8x1\__init__.py'> >>> word = Dispatch('Word.Application') >>> word <win32com.gen_py.Microsoft Word 12.0 Object Library._Application instance at 0x18074720> >>> doc = word.Documents.Add() >>> doc <win32com.gen_py.None.Document>
As you can see I am getting a dynamic object not knowing its methods/properties. What I would like to get is something like:
>>> doc = Dispatch('Word.Document') >>> doc <win32com.gen_py.Microsoft Word 12.0 Object Library._Document instance at 0x37038040>
I guess I need to also generate a wrapper from another type library (e.g. there is "Office 12.0 Object Library") but there's no hint on which it is. Likewise, there's no TypeLib
subkey at HKEY_CLASSES_ROOT\CLSID\{00020906-0000-0000-C000-000000000046}
which is what doc.CLSID
produces.
The only answer in that thread directs to RTFM a general book on Word programming w/o any hints whatsoever (I seriously doubt it even mentions typelibs).
I ended up generating wrappers for all the type libraries at the machine with the following code:
import win32com.client.selecttlb
ii=win32com.client.selecttlb.EnumTlbs()
ii=[i.desc for i in ii]
# one typelib - "Visual Basic runtime objects and procedures [6.0]" - produced an error
for i in ii: subprocess.call(['python','-m','win32com.client.makepy',i])
but even in this case, it's still win32com.gen_py.None.Document
.
The strangest thing is that the object's class is recognized and present in the cache:
>>> ad=win32com.client.gencache.EnsureDispatch("Word.Document")
>>> d = w.ActiveDocument
>>> d.__class__
<class win32com.gen_py.00020905-0000-0000-C000-000000000046x0x8x4.Document at 0x02A101B8>
>>> ad.__class__
<class win32com.gen_py.00020905-0000-0000-C000-000000000046x0x8x4._Document at 0x02A07B20>
>>> len(dir(ad.__class__))
141
>>> len(dir(d.__class__))
11
At the same time, VBA editor and VBSEdit list w.ActiveDocument
's members just fine. How do they do that and why can't pythoncom
do the same?