python - 使用python和win32com取消Excel的关闭事件

标签 python excel ironpython pywin32 win32com

目前我尝试使用 Python 和 win32com 取消 Excel 的关闭事件。几个月前我已经设法用 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 版本的类型是常见的“class 'bool'”类型(这解释了异常)。那就是我试着输入

cancel = True #prevent excel from closing

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

最佳答案

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

return True

如果您想中止 Close 事件。

问候

关于python - 使用python和win32com取消Excel的关闭事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44065226/

相关文章:

python - 在 Pandas 数据框中为给定日期创建标志矩阵

JavaScript xlsx 文件上传

list - 使用 VBA 对 Excel 列表进行排序不起作用

python - Scipy LeastSq 误差线

python - 如何在Jupyter Notebook的 'markdown'单元格中获取标签空间

excel - 我可以只为包含计算数据的单元格构建数组,而忽略没有数据且仅包含基础公式的单元格吗?

Python .net 框架引用参数 Double[]&

c++ - 如何将 IronPython 嵌入到非 .NET 应用程序中?

python - CPython 还是 IronPython?

Python for 循环覆盖