首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >python win32com close Excel进程

python win32com close Excel进程
EN

Stack Overflow用户
提问于 2014-03-07 17:04:49
回答 1查看 13.2K关注 0票数 5

尝试通过python更改Excel_sheet,在进程恢复中完全混乱。

代码语言:javascript
运行
复制
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不能被设置?”。这总是在循环中发生,就像这样:

代码语言:javascript
运行
复制
for fname in filelist:
    xlbook = XlsClass(fname)
    #do something

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

代码语言:javascript
运行
复制
xlbook = Dispatch('Excel.Application') 

wil创建一个名为'EXCEL.EXE*32‘的进程。当我输入'xlbook.Quit()'时,进程还在那里!?那么,“不能被设置”的错误是不是因为这个残差过程?在我调用func 'Dispatch‘之后,我怎样才能完全关闭它?

代码语言:javascript
运行
复制
del xlbook

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

英语不好,等着help....thank你。

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

2014/3/10:我再次捕获错误并捕获回溯...

代码语言:javascript
运行
复制
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.

在创建新的XlsClass()之前,我尝试了del self.xlAppxlbook = None,但似乎不起作用……

EN

Stack Overflow用户

回答已采纳

发布于 2014-03-07 21:07:57

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

代码语言:javascript
运行
复制
for fname in filelist:
    xlbook = XlsClass(fname)
    #do something
    xlbook = None
    gc.collect()

更新:

如果这不起作用,你可以尝试附加到一个正在运行的实例,即一旦调度,不要关闭应用程序,只关闭工作簿。在这种情况下,您可能希望执行以下操作:

代码语言:javascript
运行
复制
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__中。在这种情况下,您必须在退出脚本之前,通过执行最后一个GetActiveObject (请参见Python/win32com - Check if Program is Open),然后执行一个Close来关闭Excel。在我的win32com脚本中,当脚本启动时,我检查Excel是否已经在运行,如果是,我会打印一个错误,要求用户关闭,以防用户打开Excel书籍时更容易让它们清理和退出,这样您就可以从已知状态开始。

票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22245698

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档