如何强制python(使用win32com)创建新的excel实例?

如何强制python(使用win32com)创建新的excel实例?,python,excel,com,Python,Excel,Com,我正在自动化一些与excel相关的任务,这需要很长时间 我正在使用以下方法创建excel实例: excel = win32.gencache.EnsureDispatch('Excel.Application') wb = excel.Workbooks.Add() 但是,在脚本开始运行后,如果选择打开的excel工作簿(而不是python正在处理的工作簿),python脚本将崩溃。但是,如果我打开一个新的excel工作簿并在其中键入内容,python脚本不会受到影响 是否有一种特殊的方法可以

我正在自动化一些与excel相关的任务,这需要很长时间

我正在使用以下方法创建excel实例:

excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Add()
但是,在脚本开始运行后,如果选择打开的excel工作簿(而不是python正在处理的工作簿),python脚本将崩溃。但是,如果我打开一个新的excel工作簿并在其中键入内容,python脚本不会受到影响

是否有一种特殊的方法可以调用excel来防止这种情况发生?还是其他解决方案

编辑:这似乎有效

excel = win32.DispatchEx('Excel.Application')

你为什么不这样做呢

from win32com import client
excel=client.Dispatch("Excel.Application")

这里有一种创建新实例并使用静态缓存的方法(速度更快,并且可以使用kwargs):


Upd:改进版会在出现错误时重置缓存

如果您同时提及您正在使用的版本以备不时之需,这不会有什么坏处。那么问题的情况是什么?你找到答案了吗?请让我们知道。是的,我确实找到了解决方案,请参阅编辑。@jck您应该将此作为答案发布,而不是在问题中编辑它。如果您不运行make.py生成“静态com代理”,则需要
EnsureDispatch
才能访问
win32com.constants
。查看此链接:此外,
Dispatch
并不能解决他的问题,解决方案是
DispatchEx()
如果一个Excel进程已经作为同一个用户运行,则不会启动新的Excel进程。看见
import sys
import shutil
import pythoncom
from win32com.client import gencache

def EnsureDispatchEx(clsid, new_instance=True):
    """Create a new COM instance and ensure cache is built,
       unset read-only gencache flag"""
    if new_instance:
        clsid = pythoncom.CoCreateInstanceEx(clsid, None, pythoncom.CLSCTX_SERVER,
                                             None, (pythoncom.IID_IDispatch,))[0]
    if gencache.is_readonly:
        #fix for "freezed" app: py2exe.org/index.cgi/UsingEnsureDispatch
        gencache.is_readonly = False
        gencache.Rebuild()
    try:
        return gencache.EnsureDispatch(clsid)
    except (KeyError, AttributeError):  # no attribute 'CLSIDToClassMap'
        # something went wrong, reset cache
        shutil.rmtree(gencache.GetGeneratePath())
        for i in [i for i in sys.modules if i.startswith("win32com.gen_py.")]:
            del sys.modules[i]
        return gencache.EnsureDispatch(clsid)

wdApp = EnsureDispatchEx("Word.Application")