【问题标题】:python-win32com excel com model started generating errorspython-win32com excel com模型开始产生错误
【发布时间】:2021-11-01 17:35:43
【问题描述】:

在过去的几天里,我一直致力于为一些报告自动生成一些数据透视表。

归结为最低限度,以下代码可以正常工作:

import win32com.client    
objExcelApp = win32com.client.gencache.EnsureDispatch('Excel.Application')
objExcelApp.Visible = 1

这会弹出一个 excel 实例,我可以继续在 Python 中工作。但是突然之间,今天我的脚本失败了:

>>>import win32com.client
>>> objExcelApp = win32com.client.gencache.EnsureDispatch('Excel.Application')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\win32com\client\gencache.py", line 534, in EnsureDispatch
    mod = EnsureModule(tla[0], tla[1], tla[3], tla[4], bForDemand=bForDemand)
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\win32com\client\gencache.py", line 391, in EnsureModule
    module = GetModuleForTypelib(typelibCLSID, lcid, major, minor)
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\win32com\client\gencache.py", line 266, in GetModuleForTypelib
    AddModuleToCache(typelibCLSID, lcid, major, minor)
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\win32com\client\gencache.py", line 552, in AddModuleToCache
    dict = mod.CLSIDToClassMap
AttributeError: module 'win32com.gen_py.00020813-0000-0000-C000-000000000046x0x1x9' has no attribute 'CLSIDToClassMap'

代码从昨天到今天没有变化。我不知道发生了什么!!!。

另一个有趣的踢球者。如果我再次在同一个会话中执行相同的代码,我会得到一个不同的错误:

>>> objExcelApp = win32com.client.gencache.EnsureDispatch('Excel.Application')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\win32com\client\gencache.py", line 534, in EnsureDispatch
    mod = EnsureModule(tla[0], tla[1], tla[3], tla[4], bForDemand=bForDemand)
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\win32com\client\gencache.py", line 447, in EnsureModule
    if module.MinorVersion != tlbAttributes[4] or genpy.makepy_version != module.makepy_version:
AttributeError: module 'win32com.gen_py.00020813-0000-0000-C000-000000000046x0x1x9' has no attribute 'MinorVersion'
>>>

所以我跳到一台安装了全新 windows 的 windows 机器上,安装 python37 和 pip install pypiwin32。运行相同的行并打开 excel,就像昨天在我的原始机器上一样。

我尝试卸载并重新安装,但没有成功。知道这里发生了什么吗?

注意: 动态调度仍然有效:

import win32com.client
objExcelApp = win32com.client.Dispatch("Excel.Application")
objExcelApp.Visible = 1

但我特别需要静态分派,因为数据透视表不适用于动态分派的对象(在我的代码中很晚):

objExcelPivotCache = objExcelWorkbook.PivotCaches().Create(SourceType=win32c.xlDatabase, SourceData=objExcelPivotSourceRange)

【问题讨论】:

    标签: python excel win32com


    【解决方案1】:

    我遇到了同样的问题,我按照这里的说明解决了这个问题:https://mail.python.org/pipermail/python-win32/2007-August/006147.html

    删除 gen_py 输出目录并重新运行 makepy 成功 随后测试应用程序再次运行正常。

    所以症状得到了解决,但是任何关于这可能是如何产生的线索 发生了。这是一个运行时间很长的应用程序(想想 24x7 年),我担心导致这种情况再次发生的任何原因。

    要查找输出目录,请在您的 python 控制台/python 会话中运行:

    import win32com
    print(win32com.__gen_path__)
    

    根据您帖子中的异常消息,您需要删除的目录将标题为“00020813-0000-0000-C000-000000000046x0x1x9”。所以删除这个目录并重新运行代码。如果您担心删除它(就像我一样),只需剪切目录并将其粘贴到其他位置即可。

    我不知道为什么会发生这种情况,也不知道如何防止它再次发生,但我提供的链接中的说明似乎对我有用。

    【讨论】:

    • fwiw,我的路径是“C:\Users\\AppData\Local\Temp\gen_py”
    • @RafaelZayas,是的,所以导航到“C:\Users\\AppData\Local\Temp\gen_py”,然后在该目录中的某个位置,您会发现一个与显示的名称相同的文件夹在 AttributeError 消息中(并且根据原始帖子,操作应删除标题为“00020813-0000-0000-C000-000000000046x0x1x9”的文件夹)。所以找到那个奇怪的目录,删除它,然后重新运行你的代码。
    • 对于那些想知道如何在删除 gen_py 目录后运行 makepy 的用户,请导航到 C:\\Lib\site-packages\win32com\client,然后运行 ​​makepy.py。
    【解决方案2】:

    在相关问题Issue in using win32com to access Excel file 中发布了更直接的解决方案。

    基本上,您只需删除文件夹C:\Users\&lt;your username&gt;\AppData\Local\Temp\gen_py 并重新运行您的代码。

    【讨论】:

    • 它对我有用!我收到了module 'win32com.gen_py.00020813-0000-0000-C000-000000000046x0x1x9' has no attribute 'CLSIDToClassMap' 错误。删除gen_py文件夹后,问题解决了。
    • 我的 gen_py 中没有文件夹,请按照您的建议删除。谢谢!
    【解决方案3】:

    在 powershell 或 cmd 中执行此命令行(不在管理员模式下 => 对我不起作用)

       python -m win32com.client.makepy "Excel.Application"
    

    它修复了所有错误,您无需更改 Python 代码。 并继续使用

    win32com.client.gencache.EnsureDispatch("Excel.Application")
    

    使用 gencache.EnsureDispatch,您可以访问由 makepy 动态加载的应用程序的常量,该应用程序必须具有已注册的应用程序(在我们的示例中为 Excel.Application)。 如果您在使用 Outlook 时遇到同样的问题,请使用上面的“Outlook.Application”。

    如果仍然无法正常工作,请重新安装 python 发行版的 pywin32

    <path to python root or venv>\pip.exe uninstall pywin32
    <path to python root or venv>\pip.exe install pywin32
    

    【讨论】:

    • 就是这样。对于有效的python 3.7。谢谢
    【解决方案4】:

    对我有用的是:

    excel = win32.gencache.EnsureDispatch('Excel.Application')
    #change to =>
    excel = win32.Dispatch('Excel.Application')
    

    【讨论】:

    • 你的意思是 win32com.client.Dispatch。仅当您不使用 win32com.client.constants 时才有效,这是 Chris 描述的问题...
    • 我来谷歌搜索了一个类似的问题,但就我而言,我不关心可选参数 - pywin32 不接受它们。当然,我以前可以知道这种更简单的形式,但总是需要学习。 (我也猜想,在 tile 示例中,Dipatch 也可以用于 PivotTables,只需将可选参数的使用更改为默认顺序)。
    • 这对你有用,但对每个人都没有:请看here。特别是在Forcing Early or Late Binding 段。 tl;博士:尼基塔提出的不是确定性的。你让 Python 自动选择绑定(错误的来源),谁知道它是否选择正确:)
    【解决方案5】:

    对我来说,问题似乎在于我有多个进程通过win32com 与 Windows 应用程序交互。

    由于win32com 创建了"gen_py" directory in win32api.GetTempPath(),这可能会导致冲突和缓存损坏。

    我的解决方案是为每个进程设置“gen_py”的自定义位置。一个简单的例子:

    from pathlib import Path
    import win32com
    
    gen_py_path = '/some/custom/location/gen_py'
    
    Path(gen_py_path).mkdir(parents=True, exist_ok=True)
    win32com.__gen_path__ = gen_py_path
    
    # Any other imports/code that uses win32com
    

    这样您就不必删除默认的“gen_py”文件夹并想知道可能会出现什么问题。但是,如果您仍然发现需要删除,您可以删除自定义文件夹并知道您正在删除该进程的缓存。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-15
      • 2023-03-24
      • 2019-01-27
      • 2016-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-28
      相关资源
      最近更新 更多