Python与Excel - 检查文件是否已打开
大家好,我需要一些关于在Python中使用win32com的帮助:
我有一个程序,它会打开一个工作簿,创建一个工作表,并在上面放一些数据。
如果一切顺利,工作簿会被保存并关闭;如果出现问题,Python会话就会结束,但工作簿会保持打开状态。这样一来,程序就失去了对这个工作簿的引用。
当我重新运行代码时,Excel会弹出一个提示:“工作簿仍然打开,您想要重新打开吗?”
我想要的是不让这个提示出现。我找到了一种解决方案,适用于在写入工作表之前Python就结束的情况:
open_copys = self.xlApp.Workbooks.Count
if open_copys > 0:
""" Check if any copy is the desired one"""
for i in range(0, open_copys):
if(self.xlApp.Workbooks[i].FullName == self.file_path):
self.xlBook = self.xlApp.Workbooks[i]
else:
self.xlBook = self.xlApp.Workbooks.Open(self.file_path)
但是如果在Excel工作表上做了任何更改,这种方法就不管用了。
有没有人知道如何在新的Python会话中重新获取对一个已经打开并且被修改过的工作表的引用?
谢谢!
3 个回答
你这样做是不对的。你不应该让Python程序结束后,留下孤儿Excel进程。这一点特别重要,尤其是当你打算在其他机器上安装和运行这段代码时。相反,你应该找到错误并处理它们,这样就不会有孤儿进程需要你去处理了。
说到这里,有几件事情你可以考虑。你可以选择每次都新建一个Excel进程(使用Dispatch),或者使用一个已经存在的进程(使用DispatchEx)。这样你就可以查看哪些工作簿是打开的,还可以关闭它们,或者确保你的进程不会干扰到其他进程。此外,正如Scott所说,Excel应用程序有一些有趣的特性,比如在无人值守的情况下抑制错误,这些都是值得了解的。
我对Python不太熟悉,但在其他语言中写过一些Excel和Word的COM代码。
Excel的 Application.DisplayAlerts
属性可能会对你有帮助。把它设置为 False
可以屏蔽大部分Excel通常会显示的消息,并自动选择一个默认的响应,不过我觉得还是有一些例外情况。
看你现有的代码,我猜你应该在打开工作簿之前插入这一行:
self.xlApp.DisplayAlerts = False
你有没有试过在结束Python程序之前,先把所有对你的COM对象的引用都去掉?这样可以强制它们被垃圾回收(用gc.collect()),确保它们真的被清理掉。这样的话,工作簿就不会在内存中保持打开状态,你也就不会看到错误信息了。
试着在你的类里添加一个“close()”方法,像下面这样,然后在你的脚本结束之前调用它。
import gc
...
def close(self):
del self.xlApp
if hasattr(self, 'xlBook'):
del self.xlBook
gc.collect()