The code
import win32com.client as win32
Excel = win32.gencache.EnsureDispatch('Excel.Application')
used to work, but now it produces the error:
AttributeError: 'module' object has no attribute 'CLSIDToPackageMap'
what's going on?
The code
import win32com.client as win32
Excel = win32.gencache.EnsureDispatch('Excel.Application')
used to work, but now it produces the error:
AttributeError: 'module' object has no attribute 'CLSIDToPackageMap'
what's going on?
After deleting C:\Temp\gen_py, the code above works again. Hope it can save trouble!
The main reason for this attribute error is because your COM-server has shifted from late-binding (dynamic) to early binding (static).
There are two ways to fix this issue:
Use the dynamic module to force your code to work in a late-bound oriented way. Example use:
"win32com.client.Dispatch()" instead of "win32.gencache.EnsureDispatch('Excel.Application')"
Use camelcase sensitive keywords for the early bound oriented way. Example use:
"excel.Visible()" instead of "excel.VISIBLE()" or "excel.visible()"
I guess, the code works for the first run after deleting gen_py folder but from the second run throws an error as win32.gencache.EnsureDispatch being an early binding Dispatch, gen_py folder will be created again.
I found a more elegant solution on a Github discussion and incorporated it into a function. Worked for me.
def dispatch(app_name:str):
try:
from win32com import client
app = client.gencache.EnsureDispatch(app_name)
except AttributeError:
# Corner case dependencies.
import os
import re
import sys
import shutil
# Remove cache and try again.
MODULE_LIST = [m.__name__ for m in sys.modules.values()]
for module in MODULE_LIST:
if re.match(r'win32com\.gen_py\..+', module):
del sys.modules[module]
shutil.rmtree(os.path.join(os.environ.get('LOCALAPPDATA'), 'Temp', 'gen_py'))
from win32com import client
app = client.gencache.EnsureDispatch(app_name)
return app
Thanks - worked like a charm after adding your function and making this change:
#excel = win32.gencache.EnsureDispatch('Excel.Application')
excel = dispatch('Excel.Application')
Sincerely,
js