Actuellement, j'essaie d'annuler l'événement de fermeture d'Excel en utilisant Python et win32com. J'ai déjà réussi à gérer ce problème avec IronPython il y a un mois. Mais pour d'autres objectifs de mon département des entreprises cela devrait aussi être possible avec Python. Suivi, vous verrez deux extraits. Le premier contiendra le code IronPython travailAnnuler l'événement de fermeture d'Excel en utilisant python et win32com
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())
Le second contiendra la version avec Python et win32com. Celui-ci est basé sur mon extrait IronPython et l'échantillon de ce lien
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())
Comme vous le verrez, je pouvais connecter à l'événement « OnBeforeClose », mais ne peut pas annuler l'événement à proximité comme je l'ai fait avec la version IronPython. Comme mentionné dans le commentaire du dernier extrait de code, la version Python déclenche une exception AttributeError. En outre, vous pouvez également voir que les types de la variable "cancel" nécessaire des gestionnaires d'événements ont deux types différents. Dans la version IronPython c'est un "StrongBox [bool]". D'un autre côté, le type de la version Python est un type commun "class 'bool'" (ce qui explique l'exception). C'est de cette façon que j'ai essayé de simplement taper
cancel = True #prevent excel from closing
Mais de cette façon, Excel se ferme de toute façon. J'ai aussi fait des recherches mais je n'ai pas trouvé de solution à ce problème. Mon hypothèse est qu'il y a une sorte d'emballage nécessaire?
Avez-vous essayé pythonnet? – denfromufa
Tout d'abord, merci pour votre réponse. Vous voulez dire en ajoutant une référence à 'Microsoft.Office.Interop.Excel' et utiliser le code égal à celui de IronPython? Ce fut la première chose que j'ai essayé de faire, mais il a lancé l'exception suivante System.IO.FileNotFoundException: Impossible de trouver l'assembly 'Microsoft.Office.Interop.Excel'. at Python.Runtime.CLRModule.AddReference (nom de la chaîne) –
Vous devez trouver l'emplacement de cet assembly 'Microsoft.Office.Interop.Excel'. Sinon, vous pouvez le télécharger depuis Nuget. Ajoutez ensuite une référence en ajoutant son emplacement à sys.path. Pour pythonnet il y a des instructions spéciales pour accéder aux objets com dynamiques: https://github.com/pythonnet/pythonnet/issues/260 – denfromufa