打开和调度的Excel进程之间的交互,win32com
我正在使用win32com(Python 2.7(Anaconda)在LiClipse中)来启动多个Excel实例...
class ExcelDocument(object):
"""Excel class
"""
def __init__(self, xlDocIn, make_visible=False):
"""Open spreadsheet"""
self.excelApp = DispatchEx('Excel.Application')
然后我对Excel文档进行一些操作(使用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文件。
1 个回答
2
你在写脚本的时候,应该假设电脑上只能同时打开一个Excel程序,虽然这个程序可以有多个工作簿(就是你打开的文件)。如果你使用 GetObject
(而不是 GetActiveObject
),那么win32com会帮你找到已经打开的Excel程序,如果没有的话,它会自动启动一个新的。所以你就不需要用if/else来判断了。
这也意味着,在设计上,你需要有办法记录哪些工作簿被打开了,并且只关闭这些工作簿,这样最后Excel的状态就和你开始脚本时是一样的。也就是说,每个工作簿都应该有一个对应的ExcelDocument实例,每个实例都使用 GetObject
,并且负责关闭它所代表的工作簿。在你创建第一个ExcelDocument之前,先保存 GetActiveObject
,这样你的脚本就知道在退出时是否需要关闭Excel程序。
简单来说:
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()