2014-03-07 159 views
4

试图通过python改变Excel_sheet,并完全混淆进程恢复。python win32com关闭Excel进程

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.xlAppxlbook = None 创建一个新的XlsClass(前),但似乎没有工作...

+0

对不起,我会更新它,如果错误再次提高。 – Tpoy

回答

1

这可能是由于蟒蛇的垃圾收集:每次通过循环创建一个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书籍更容易清理并退出,以便从已知状态开始。

+0

我已经尝试过,但错误仍然发生,“del self.xlApp”也不起作用 – Tpoy

+0

我会试试这个谢谢 – Tpoy

+0

@Tpoy尝试不关闭应用程序,看到更新的答案。 – Schollii