【问题标题】:python win32com close Excel processpython win32com关闭Excel进程
【发布时间】:2014-04-10 08:11:08
【问题描述】:

试图通过 python 更改 Excel_sheet 并且在进程恢复中完全困惑。

import win32com.client
class XlsClass:
    def __init__(self ,filename=None ,*,Visible=False ,Alerts=False):
        self.xlApp = win32com.client.Dispatch('Excel.Application')
        self.xlApp.Visible = Visible
        self.xlApp.DisplayAlerts = Alerts
        if filename:
            self.filename = filename
            self.xlBook = self.xlApp.Workbooks.Open(filename)
        else:
            self.xlBook = self.xlApp.Workbooks.Add()
            self.filename = ''

    def __del__(self):
        self.xlBook.Close()
        self.xlApp.Quit()

有时代码运行良好,但有时 python 会报错 就像'self.xlApp.Visible 不能设置?'。 这总是在循环中发生,就像:

for fname in filelist:
    xlbook = XlsClass(fname)
    #do something

然后我检查了我的“windowstasksmanager”并注意到

xlbook = Dispatch('Excel.Application') 

将创建一个名为“EXCEL.EXE*32”的进程。 当我输入'xlbook.Quit()' 时,进程仍然存在!? 那么可能是因为这个剩余过程而出现的“无法设置”错误? 调用 func 'Dispatch' 后,如何才能完全关闭它?

del xlbook

无法终止进程,它是如何工作的?

英语不好,等待帮助....谢谢。

================================================ =

2014 年 3 月 10 日: 我再次捕获错误并捕获回溯...

Traceback (most recent call last):
  File "C:\work_daily\work_RecPy\__RecLib\XlsClass.py", line 9, in __init__
    self.xlApp.Visible = Visible
  File "C:\Program Files\python33\lib\site-packages\win32com\client\dynamic.py", 
  line 576, in __setattr__
  raise AttributeError("Property '%s.%s' can not be set." % (self._username_,attr))
AttributeError: Property 'Excel.Application.Visible' can not be set.

我试过了 del self.xlApp 要么 xlbook = None 在创建新的 XlsClass() 但似乎不起作用之前...

【问题讨论】:

  • 抱歉,回溯信息模棱两可,如果再次出现错误,我会更新它。

标签: python excel win32com


【解决方案1】:

这很可能是由于 python 的垃圾收集:每次通过循环你都会创建一个 XlsClass;当一次迭代结束时,不再引用 XlsClass 的实例,因此它可用于垃圾回收,但这可能不会立即发生。因此,下次通过循环时,您将发送一个新的 Excel,但前一个可能尚未完全关闭。尝试在下一次迭代之前强制进行垃圾回收:

for fname in filelist:
    xlbook = XlsClass(fname)
    #do something
    xlbook = None
    gc.collect()

更新:

如果这不起作用,您可以尝试附加到正在运行的实例,即一旦分派,不要关闭应用程序,只需关闭工作簿。在这种情况下,您可能想要做这样的事情:

class XlsClass:
    def __init__(self, xlApp, filename=None ,*,Visible=False ,Alerts=False):
        self.xlApp = xlApp
        self.xlApp.Visible = Visible
        ...

    def otherMethod(self):
        # ....

    def close(self):
        self.xlBook.Close()
        self.xlBook = None
        self.xlApp = None
        # don't do anything with self.xlApp or self

xlApp = win32com.client.Dispatch('Excel.Application')
for fname in filelist:
    xlbook = XlsClass(xlApp, fname)
    # do something with xlbook
    xlbook.close()

请注意,最好显式关闭这本书,而不是等待垃圾收集器执行__del__

另外,您可以使用win32com.client.GetObject (filename),如果存在则获取现有实例,如果不存在则自动创建;您可以将GetObject 放入__init__。在这种情况下,您必须在退出脚本之前关闭 Excel,如果它已打开,方法是执行最终的 GetActiveObject(请参阅 Python/win32com - Check if Program is Open),然后执行 Close。在我的 win32com 脚本中,我检查脚本启动时 Excel 是否已经在运行,如果是,我会打印一个错误,要求用户关闭,以防用户打开 Excel 书籍更容易让它们清理并退出,以便从已知状态开始。

【讨论】:

  • 我已经尝试过了,但错误仍然发生,“del self.xlApp”也不起作用
猜你喜欢
  • 2017-10-19
  • 1970-01-01
  • 1970-01-01
  • 2011-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多