python win32com关闭Excel进程

Tpo*_*poy 5 python excel win32com

试图通过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()
Run Code Online (Sandbox Code Playgroud)

有时代码运行良好,但有时python会引发错误,就像'self.xlApp.Visible无法设置?'.这总是发生在循环中,如:

for fname in filelist:
    xlbook = XlsClass(fname)
    #do something
Run Code Online (Sandbox Code Playgroud)

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

xlbook = Dispatch('Excel.Application') 
Run Code Online (Sandbox Code Playgroud)

将创建一个名为'EXCEL.EXE*32'的进程.当我输入'xlbook.Quit()'的过程还在那里!?因此,这个剩余过程可能是'不能设置'错误?在我调用函数'Dispatch'后,我怎么能完全关闭它?

del xlbook
Run Code Online (Sandbox Code Playgroud)

不能杀死这个过程,它是如何工作的?

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

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

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.
Run Code Online (Sandbox Code Playgroud)

我尝试 del self.xlAppxlbook = None 在创建新的XlsClass()之前,但似乎没有工作......

Oli*_*ver 1

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

for fname in filelist:
    xlbook = XlsClass(fname)
    #do something
    xlbook = None
    gc.collect()
Run Code Online (Sandbox Code Playgroud)

更新:

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

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()
Run Code Online (Sandbox Code Playgroud)

__del__请注意,显式关闭该书比等待垃圾收集器执行要好。

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