begin process at 2008 09 06 20:31:19
1 237 936 membres
318 nouveaux aujourd'hui
14 314 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

FERMER EXCEL CORRECTEMENT ET SIMPLEMENT


Information sur la source

Catégorie :Trucs & Astuces Source .NET ( DotNet ) Classé sous : Excel, Fermer, Fermeture, Kill, ID Niveau : Débutant Date de création : 05/10/2007 Date de mise à jour : 05/10/2007 16:25:45 Vu : 7 180

Note :
Aucune note

Commentaire sur cette source (13)
Ajouter un commentaire et/ou une note

Description

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

  • 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
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

05 octobre 2007 16:16:46 :
Ajout de quelques commentaires d'explication
05 octobre 2007 16:18:33 :
Correction quelques fautes grossières.
05 octobre 2007 16:25:45 :
Mise en page.
  • signaler à un administrateur
    Commentaire de Willi le 05/10/2007 22:51:48 administrateur CS

    Correctement peut-être mais ce n'est pas très propre de tuer le processus...(Comme les 3/4 des sources sur le sujet).
    Peux mieux faire.

  • signaler à un administrateur
    Commentaire de Kornebrume le 08/10/2007 10:25:43

    C'est la seule solution de fermer excel. Si tu fais un xlApp.Close() cela ferme la fenêtre mais le processus est toujours actif dans ton gestionnaire des tâches.

    Si tu as une solution plus adaptée et moins contraignante, n'hésite pas çà m'intéresse.

    Cordialement,

    Kornebrume

  • signaler à un administrateur
    Commentaire de Willi le 08/10/2007 11:57:41 administrateur CS

    Oui, bien fermer et détruire tes objets excel.

  • signaler à un administrateur
    Commentaire de Kornebrume le 08/10/2007 14:13:15

    xlBook.close()?

    xlApp=NOTHING?

    Je t'assure qu'en faisant les deux çà ne fonctionne pas, ton processus est toujours actif.
    Si tu y arrives autrement, propose-nous ton code.

    Merci à toi.

    Cordialement.

  • signaler à un administrateur
    Commentaire de Renfield le 08/10/2007 14:15:40 administrateur CS

    pas confondre

    xlApp = Nothing

    et xlApp.quit()

  • signaler à un administrateur
    Commentaire de Kornebrume le 08/10/2007 15:16:03

    Donc d'après vous en faisant :

    xlBook.close()
    xlApp.Quit()
    xlApp=nothing

    on libère toute la ressource utilisée par notre appli Excel?

  • signaler à un administrateur
    Commentaire de Adn56 le 24/10/2007 18:05:12

    salut , question de noob ^^ sur une de mes aplis je fais (suivant un code de ce fofo ;) ) :
    où :
        Dim oXL As Object ' objet excel
        Dim oBook As Object ' classeur
        Dim oSheet As Object ' feuille

    Apres mes taches il fait :

    oXL.Workbooks.Close()
            oXL.Quit()
            oXL = Nothing

    où aussi :

            oXL.Quit()
            oSheet = Nothing
            oBook = Nothing
            oXL = Nothing

    les deux façons ne laisse visiblement aucune trace dans le gestionnaire de processus (à condition que tout le code se déroule correctement biensur lol). Quelqu'un peux t'il commenter ces deux méthodes ?

  • signaler à un administrateur
    Commentaire de Adn56 le 24/10/2007 18:06:21

    donc pour Kornebrume j'ai envie de dire YEP ! ca roule ^^
    enfin attendons les réactions des sachants ;)
    ++

  • signaler à un administrateur
    Commentaire de Kornebrume le 26/10/2007 17:40:07

    Du moment que l'objet de l'appli est détruit, elle doit théoriquement disparaître des processus actifs dans le gestionnaire.

    A l'époque où j'ai testé ce genre de méthode, l'appli disparaissait du gestionnaire des tâches mais le processus était toujours actif (stocké en ram), il me fallait donc tuer le processus même si l'application était toujours fermée d'où la méthode pour récupérer l'ID du processus.

    Attention : application != processus. Excel peut très bien être fermé et le processus toujours actif et donc gourmand en ressource.

    Cdt.

  • signaler à un administrateur
    Commentaire de Adn56 le 26/10/2007 19:47:36

    à mince !
    et du coup tu conseils quoi ?

  • signaler à un administrateur
    Commentaire de Kornebrume le 29/10/2007 14:18:27

    Et bien tu utilises la méthode que j'ai utilisé.

    Tu établis la liste des des processus actifs grâce à la fonction ListID().
    Ensuite tu crées ton appli Excel : xlApp = CType(CreateObject("Excel.Application"), Excel.Application)
    Tu établis une seconde liste des processus actifs avec la fonction ListID()

    La fonction retourne un tableau d'ID. Tu compares donc les 2 tableaux grâce à la fonction : ExtractID()

    Il ne te reste plus qu'à faire ce que tu veux avec ton Excel.

    Une fois terminé, tu peux fermer ton application Excel en tuant le processus grâce à la fonction : closeExcelFile()

    Copier/coller des fonctions ci-dessus, çà fonctionne tout seul. Même si ce n'est pas hyper-propre, c'est le seul moyen de terminer le processus.

  • signaler à un administrateur
    Commentaire de diampa le 30/10/2007 15:40:33

    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

  • signaler à un administrateur
    Commentaire de mitsh666 le 09/01/2008 15:45:31

    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+

Ajouter un commentaire

Pub



Appels d'offres

CalendriCode

Septembre 2008
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
2930     

Téléchargements

Logiciels à télécharger sur le même thème :

Boutique

Boutique de goodies CodeS-SourceS