使用 python 和 win32com 取消 Excel 的关闭事件
Cancel Excel's close event using python and win32com
目前我尝试使用 Python 和 win32com 取消 Excel 的关闭事件。一个月前,我已经设法用 IronPython 解决了这个问题。但是为了我公司部门的进一步目的,这也应该能够 Python。接下来你会看到两个片段。第一个将包含工作 IronPython Code
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 片段和 link
的示例
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 异常。此外,您还可以看到,事件处理程序所需的 "cancel" 变量的类型有两种不同的类型。在 IronPython 版本中它是 "StrongBox[bool]"。另一方面,Python 版本的类型是常见的 "class 'bool'" 类型(这解释了异常)。那就是我试着输入
cancel = True #prevent excel from closing
但是使用这种方式,excel 无论如何都会关闭。
我也做了一些研究,但无法找到解决此问题的方法。我的假设是需要某种包装器?
您可以通过返回所需的取消值实现与 IronPython 版本相同的行为,例如
return True
如果您想中止关闭事件。
此致
目前我尝试使用 Python 和 win32com 取消 Excel 的关闭事件。一个月前,我已经设法用 IronPython 解决了这个问题。但是为了我公司部门的进一步目的,这也应该能够 Python。接下来你会看到两个片段。第一个将包含工作 IronPython Code
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 片段和 link
的示例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 异常。此外,您还可以看到,事件处理程序所需的 "cancel" 变量的类型有两种不同的类型。在 IronPython 版本中它是 "StrongBox[bool]"。另一方面,Python 版本的类型是常见的 "class 'bool'" 类型(这解释了异常)。那就是我试着输入
cancel = True #prevent excel from closing
但是使用这种方式,excel 无论如何都会关闭。 我也做了一些研究,但无法找到解决此问题的方法。我的假设是需要某种包装器?
您可以通过返回所需的取消值实现与 IronPython 版本相同的行为,例如
return True
如果您想中止关闭事件。
此致