Python 打开和调度的excel进程之间的交互,win32com

Python 打开和调度的excel进程之间的交互,win32com,python,excel,win32com,Python,Excel,Win32com,我正在使用win32com(LiClipse中的python2.7(Anaconda))启动单独的excel实例 class ExcelDocument(object): """Excel class """ def __init__(self, xlDocIn, make_visible=False): """Open spreadsheet""" self.excelApp = DispatchEx('Excel.Application

我正在使用win32com(LiClipse中的python2.7(Anaconda))启动单独的excel实例

class ExcelDocument(object):
    """Excel class
    """
    def __init__(self, xlDocIn, make_visible=False):
        """Open spreadsheet"""
        self.excelApp = DispatchEx('Excel.Application')
然后我对excel文档执行bits和BOB操作(使用MS Office 2013),包括使用DispatchEx打开另一个文档

objExcel1 = ExcelDocument(PATH_TABLE,False)
objExcel1.update_sheets()
...
objExcel2 = ExcelDocument(PATH_BACKG, False)
尝试分配第二个ExceLDocument类将使脚本崩溃

如果我将init更改为

def __init__(self, xlDocIn, make_visible=False):
        """Open spreadsheet"""
        try:
            self.excelApp = GetActiveObject('Excel.Application')
        except:
            self.excelApp = DispatchEx('Excel.Application')
脚本运行良好

如果在运行脚本时打开了excel文件 A.编辑打开的文件时,脚本将崩溃。 B当执行这些代码行时,打开的excel文件将关闭

def close(self):
        """Close spreadsheet resources"""
        self.excelApp.DisplayAlerts = True
        self.workbook.Saved = 0
        self.workbook.Close(SaveChanges=0)
        self.excelApp.Visible = 0

有什么原因我不能第二次调用DispatchEx,因为我的脚本应该在后台运行,并且不会中断任何打开的excel文件?

您应该设计脚本,假设只有一个excel实例在运行,尽管它可以包含多个工作簿。如果使用
GetObject
(而不是
GetActiveObject
),则win32com将返回现有应用程序的句柄(如果存在),或者启动不存在的应用程序。因此,您不需要if/else

这在设计方面也意味着,您应该有一种跟踪打开哪些工作簿的方法,并且只关闭那些工作簿,以便Excel应用程序的最终状态与启动脚本时相同。因此,每个工作簿都有一个ExcelDocument实例,每个实例都使用
GetObject
,每个实例都关闭它所代表的工作簿。在创建第一个Excel文档之前,请保存
GetActiveObject
,以便脚本知道是否应该在退出时关闭应用程序

基本上:

activeXlApp = win32com.client.GetActiveObject('Excel.Application') 

objExcel1 = ExcelDocument(PATH_TABLE,False) # uses GetObject()
objExcel1.update_sheets()
...
objExcel2 = ExcelDocument(PATH_BACKG, False)

if activeXlApp is not None: 
    activeXlApp.Close()

谢谢,我最终将DispatchEx移出了课堂,这样我就可以用同一个过程打开多个Excel文件,并在不中断任何打开的Excel文件的情况下关闭此过程。@user3457621如果您能接受我的回答,将不胜感激(因为这与我的答案相同,只是您使用了
DispatchEx
而不是
GetActiveObject
),否则请解释为什么我的答案没有解决问题。谢谢,欢迎使用!