Fermer excel correctement et simplement

Soyez le premier à donner votre avis sur cette source.

Snippet vu 16 447 fois - Téléchargée 19 fois

Contenu du snippet

Voici un petit morceau de code qui vous permettra de fermer correctement et simplement un processus Excel, sans pour autant écrire une classe dédiée. 3 fonctions suffisent.

Source / Exemple :


Public Class Form1

'Ajouter la référence au projet : Microsoft Excel Object Library 
'Déclaration de notre objet Excel. 

Dim xlApp As Excel.Application

Private Function ListID() As Int16()
        ' Get the ID's processes list in a array and sort it
        ' It is the only way to close Excel:
        ' To close Excel, we need to list the Excel ID's processes  before user starts excel
        ' then we list them one more time just after opening Excel.
        ' We compare both of the lists we have to extract the new Excel ID of the brand new Excel 
        ' session.  So we can kill this process with the ID we got, without killing other Excel user
        ' session.
        ' L'explication ci-dessus résume l'explication générale de la méthode, cf présentation du code
        ' Get ID's processes list
        Dim Processes As Process() = Nothing
        Processes = Process.GetProcessesByName("EXCEL")
        ' Load ID Processes in Array
        Dim intProcesses(Processes.GetUpperBound(0)) As Int16
        Dim i As Int16
        For i = 0 To Processes.GetUpperBound(0)
            intProcesses(i) = CInt(Processes(i).Id.ToString)
        Next
        Return intProcesses
End Function

Private Function ExtractID(ByVal intFirstIDs As Int16(), ByVal intLastIDs As Int16()) As Int16
    Dim intID As Int16 = Nothing
    Dim intID_FirsList As Int16 = Nothing
    Dim intID_LastList As Int16 = Nothing
    Dim i As Int16 = Nothing
    For i = 0 To intLastIDs.GetUpperBound(0)
        intID_LastList = intLastIDs(i)
        If Array.IndexOf(intFirstIDs, intID_LastList) = -1 Then
            intID = intID_LastList
            Exit For
        End If
    Next
Return intID
End Function

Private Sub closeExcelFile(ByVal intIDExcel As int16)

        If intIDExcel <> 0 Then
            If Process.GetProcessById(intIDExcel).HasExited = False Then
                Try
                    Process.GetProcessById(intIDExcel).Kill()
                    intIDExcel = 0
                Catch ex As Exception
                    MessageBox.Show(ex.Message & ex.StackTrace, "Error while closing Excel integration.", _
                        MessageBoxButtons.OK, MessageBoxIcon.Error)
                End Try
            End If
        End If
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    dim myIDExcel As int16

    'L'idée ici est de récupérer la liste d'ID des process qui tournent sur le PC. On recupère la 
    'liste avant de faire un New et on recupère la liste après avoir fait le New. Ainci il ne reste
    'plus qu'à faire la différence des 2 listes grâce à la fonction ExtractID(,) pour retrouver le
    'bon ID de notre process Excel. Il ne reste plus qu'à la killer une fois notre application
    'terminée.

    'Première liste
    Dim intFirstExcelIDs() As Int16 = ListID()

    'Création de notre objet et attribution de l'ID
    xlApp = CType(CreateObject("Excel.Application"), Excel.Application)

    'Seconde liste
    Dim intLastExcelIDs() As Int16 = ListID()

    'Différence des 2 listes et récupération de notre ID
    myIDExcel = ExtractID(intFirstExcelIDs, intLastExcelIDs)

    'Ici vous faites ce que vous voulez avec votre application Excel
    '
    '
    '
    'Une fois terminée, vous pouvez fermer votre processus

    closeExcelFile(myIDExcel)      

End Sub

End Class

Conclusion :


Vous pouvez modifier la fonction closeExcelFiles() pour pouvoir lui passer en paramètre l'id du process de manière à pouvoir fermer autant de processus Excel que vous voulez. personnellement je l'ai adapté et j'utilise un tableau d'ID Excel.

Si vous avez des questions, ou si j'ai oublié des morceaux de code qui rend la source ci-dessus illogique, faites m'en part.

Je tiens à remercier gregory_forel de sa contribution. En effet mon code est adapté de son propre code que l'on peut trouver à l'adresse suivante : http://www.vbfrance.com/codes/FERMER-CORRECTEMENT-EXCEL-KILL-EXCEL_43802.aspx

J'ai retravaillé sa source car j'utilise pas mal de propriétés des book/sheets d'excel.

Pour tous commentaire n'hésitez pas

A voir également

Ajouter un commentaire

Commentaires

Messages postés
1
Date d'inscription
mardi 7 avril 2009
Statut
Membre
Dernière intervention
29 avril 2009

Bonjour à tous, la solution pour fermer un processus excel activé n'est elle pas de faire un app.save avant de fermer et libérer la mémoire (code moins lourd que de chercher et détruire l'ID du processus lancé) ?
Messages postés
38
Date d'inscription
dimanche 24 décembre 2000
Statut
Membre
Dernière intervention
4 mars 2009

nikel chrome méga chrome!!
c'est le top!!!
comment je suis content de trouver ce que je cherche!!!
MMeeeerrrkkiiiii!!!
Messages postés
39
Date d'inscription
vendredi 29 février 2008
Statut
Membre
Dernière intervention
19 juin 2009

salut tt le monde j'ai un vrai souci, je n'arrive pas à faire pareil sous VB6
c'est à dire dénicher l'ID du processus Excel delaissé dans la mémoire après fermeture d'EXCEL et le tuer sans toucher aux autres sessions Excel ouvertes.

Je vous remercie par avance
Messages postés
46
Date d'inscription
dimanche 10 octobre 2004
Statut
Membre
Dernière intervention
13 juin 2008

hello,

j'ai pas tout lu en détail, mais la façon la plus propre de fermer excel me semble la suivante. Elle ne tue AUCUN processus et elle est courte. Il faut mettre à jour le Garbage Collector après avoir quitter l'application et effacer l'objet.

objExcel.ActiveWorkbook.Close() 'Fermeture d'Excel
objExcel.DisplayAlerts = True 'remet l'alerte oui=True non=False
'objExcel.Application.Visible=True 'remet la visibilité
objExcel.Quit()

objClasseur = Nothing
objExcel = Nothing

GC.Collect()

A+
Messages postés
3
Date d'inscription
samedi 17 février 2007
Statut
Membre
Dernière intervention
30 octobre 2007

Très bien ton code et Vraiment merci car je lutte vraiment contre ce phenomène.
Dieu merci.
Ton code est vraiment impécable voici comment je l'ai adapter à mon projet

Module Module1
'Public oExcelApp As New MSExcelApp
Public sEnft As Byte
Public appExcel As Excel.Application
' Déclarations pour classeur Excel
Public Classeur As Excel.Workbook
Public Feuil1 As Excel.Worksheet, Feuil2 As Excel.Worksheet, Feuil3 As Excel.Worksheet
Public Feuil4 As Excel.Worksheet, Feuil5 As Excel.Worksheet, Feuil6 As Excel.Worksheet
Public Feuil7 As Excel.Worksheet
'Public NomClasseur As String = "C:\GeStocks\BD.xls"
Public myIDExcel As Int16
Public Sub OuvrirClasseur()

'L'idée ici est de récupérer la liste d'ID des process qui tournent sur le PC. On recupère la
'liste avant de faire un New et on recupère la liste après avoir fait le New. Ainci il ne reste
'plus qu'à faire la différence des 2 listes grâce à la fonction ExtractID(,) pour retrouver le
'bon ID de notre process Excel. Il ne reste plus qu'à la killer une fois notre application
'terminée.
'Première liste
Dim intFirstExcelIDs() As Int16 = ListID()
'Création de notre objet et attribution de l'ID
'Seconde liste

Try
appExcel = CType(CreateObject("Excel.Application"), Excel.Application)
'Ouverture d'un fichier Excel

Classeur = appExcel.Workbooks.Open(Filename:="C:\GeStocks\BD.xls", UpdateLinks:=0, ReadOnly:=False, Format:=5, Password:="diamp789")
Feuil1 = CType(Classeur.Worksheets("EntreStocks"), Excel.Worksheet)
Feuil2 = CType(Classeur.Worksheets("SortiStocks"), Excel.Worksheet)
Feuil3 = CType(Classeur.Worksheets("BonEntre"), Excel.Worksheet)
Feuil4 = CType(Classeur.Worksheets("BonSortie"), Excel.Worksheet)
Feuil5 = CType(Classeur.Worksheets("EntreImmob"), Excel.Worksheet)
Feuil6 = CType(Classeur.Worksheets("SortImmob"), Excel.Worksheet)
Feuil7 = CType(Classeur.Worksheets("QteRestant"), Excel.Worksheet)

'xlApp.Workbooks.Open(NomClasseur)
Catch ex As Exception
MsgBox("***** IMPOSSIBLE D'OUVRIR LE FICHIER EXCEL *****")
End Try
Dim intLastExcelIDs() As Int16 = ListID()
'Différence des 2 listes et récupération de notre ID
myIDExcel = ExtractID(intFirstExcelIDs, intLastExcelIDs)

End Sub

'Public Sub FermerClasseur()
' Fermeture du classeur
' Try
' Classeur.Save()
' Classeur.Save()
' Classeur.Close() 'Fermeture du classeur Excel
' appExcel.Quit() 'Fermeture de l'application Excel
'Désallocation(mémoire)
' Feuil1 = Nothing
' Feuil2 = Nothing
' Feuil3 = Nothing
' Feuil4 = Nothing
' Feuil5 = Nothing
' Feuil6 = Nothing
' Feuil7 = Nothing
' Classeur = Nothing
' appExcel = Nothing
'Catch ex As Exception
' End Try
' End Sub
Public Function ListID() As Int16()
Dim Processes As Process() = Nothing
Processes = Process.GetProcessesByName("EXCEL")
' Load ID Processes in Array
Dim intProcesses(Processes.GetUpperBound(0)) As Int16
Dim i As Int16
For i = 0 To Processes.GetUpperBound(0)
intProcesses(i) = CInt(Processes(i).Id.ToString)
Next
Return intProcesses
End Function
Public Function ExtractID(ByVal intFirstIDs As Int16(), ByVal intLastIDs As Int16()) As Int16
Dim intID As Int16 = Nothing
Dim intID_FirsList As Int16 = Nothing
Dim intID_LastList As Int16 = Nothing
Dim i As Int16 = Nothing
For i = 0 To intLastIDs.GetUpperBound(0)
intID_LastList = intLastIDs(i)
If Array.IndexOf(intFirstIDs, intID_LastList) = -1 Then
intID = intID_LastList
Exit For
End If
Next
Return intID
End Function
Public Sub FermerClasseur(ByVal intIDExcel As Int16)
If intIDExcel <> 0 Then
If Process.GetProcessById(intIDExcel).HasExited = False Then
Try
Process.GetProcessById(intIDExcel).Kill()
intIDExcel = 0
Catch ex As Exception
MessageBox.Show(ex.Message & ex.StackTrace, "Error while closing Excel integration.", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End If
End If
End Sub

End Module
Afficher les 16 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.