使用python和win32com取消Excel的close事件

时间:2017-05-19 08:37:43

标签: python excel ironpython pywin32 win32com

目前我尝试使用Python和win32com取消Excel的close事件。我已经设法在一个月前用IronPython处理这个问题了。但是对于我的公司部门的进一步目的,这也应该能够与Python一起使用。接下来你会看到两个片段。第一个将包含工作的IronPython代码

import clr
clr.AddReference("Microsoft.Office.Interop.Excel")
clr.AddReference("System.Windows.Forms")
from Microsoft.Office.Interop import Excel
from System.Windows.Forms import Form, Application, MessageBox, MessageBoxButtons, MessageBoxIcon, DialogResult

class CloseEventTry(Form):
    def __init__(self):
        excel = Excel.ApplicationClass()
        excel.Visible = True 
        excel.DisplayAlerts = False
        self.workbooks = excel.Workbooks.Add()
        self.Text = "Dummy GUI Window"      
        #link "BeforeCloseEvent" to the "beforeClose" method
        self.workbooks.BeforeClose +=Excel.WorkbookEvents_BeforeCloseEventHandler(self.beforeClose)

    def beforeClose(self, cancel):
        print type(cancel)  #Type: 'StrongBox[bool]
        choice = MessageBox.Show("Close Excel", "Close", MessageBoxButtons.YesNo, MessageBoxIcon.Information)
        if choice == DialogResult.Yes:
            cancel.Value = False    #do't cancel the close action
            self.Close()
        elif choice == DialogResult.No:
            cancel.Value = True     #prevent excel from closing 

Application.Run(CloseEventTry())

第二个将包含Python和win32com的版本。这个是基于我的IronPython片段和该链接的样本

https://win32com.goermezer.de/microsoft/office/events-in-microsoft-word-and-excel.html

import clr
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import Form, Application, MessageBox, MessageBoxButtons, MessageBoxIcon, DialogResult
import win32com.client as win32

#workbook event handler class. Needed according to this example https://win32com.goermezer.de/microsoft/office/events-in-microsoft-word-and-excel.html
class WorkBookEvents(object):
    def OnBeforeClose(self, cancel):
        print(type(cancel))  #Type: class 'bool'
        choice = MessageBox.Show("Close Excel", "Close", MessageBoxButtons.YesNo, MessageBoxIcon.Information)
        if choice == DialogResult.Yes:
            #do't cancel the close action => raises AttributeError: 'bool' object has no attribute 'Value' Exception
            cancel.Value = False    
            self.Close()
        elif choice == DialogResult.No:
            #prevent excel from closing => raises AttributeError: 'bool' object has no attribute 'Value' Exception
            cancel.Value = True     

class CloseEventTry(Form):
    def __init__(self):
        excel = win32.DispatchEx('Excel.Application')
        excel.Visible = True # makes the Excel application visible to the user
        excel.DisplayAlerts = False
        self.Text = "Dummy GUI Window"  
        self.workbooks = excel.Workbooks.Add()
        #define event handler according to this example https://win32com.goermezer.de/microsoft/office/events-in-microsoft-word-and-excel.html
        self.workbooks = win32.DispatchWithEvents(self.workbooks, WorkBookEvents)

Application.Run(CloseEventTry())

正如您将看到我可以连接到" OnBeforeClose"事件,但无法取消关闭事件,因为我已经使用IronPython版本完成了它。正如最后一段代码片段中所提到的,Python版本引发了一个AttributeError异常。此外,您还可以看到所需的类型"取消"事件处理程序的变量有两种不同的类型。在IronPython版本中,它是一个" StrongBox [bool]"。另一方面,Python版本的类型是常见的"类' bool'" type(解释异常)。多数民众赞成我尝试输入

的方式
cancel = True #prevent excel from closing

但是使用这种方式,excel仍会关闭。 我也做了一些研究,但无法找到解决这个问题的方法。我的假设是需要某种包装?

1 个答案:

答案 0 :(得分:1)

您可以通过返回所需的取消值来实现与IronPython版本相同的行为,例如

return True

如果您想要中止Close事件。

问候