OVH Cloud OVH Cloud

Fermeture liaison VB - Excel

9 réponses
Avatar
Yann
Bonjour,

Je développe un programme en VB qui, pour effectuer des
calculs, utilise régulièrement un fichier Excel (dans
lequel j'entre des valeurs et dans lequel je récupère mes
résultats).

J'utilise pour ouvrir et fermer Excel 2 fonctions (cf ci
après), mais j'ai un problème de fermeture d'Excel qui ne
se ferme pas toujours (le processus reste dans le
gestionnaire des tâches).
Je ne comprends vraiment pas pourquoi Excel se ferme mal,
si c'est parce que je l'ouvre et le ferme plusieurs fois
de suite, si c'est à cause d'une liaison dans ce
classeur,
si c'est mon code qui est faux (faut-il faire à chaque
fois « exl2.Close SaveChanges:=False » , «
appex2.Quit" , « Set exl2 = Nothing » et « Set appex2 =
Nothing » ? )

Sub ouvreexcel2()

fermeexcel2 'ferme excel
Set appex2 = CreateObject("excel.Application")
nomfich2 = App.Path & "\Excelfiles\ParamCF.xls"
Set exl2 = appex2.Workbooks.Open(nomfich2, 0,
True, , , , , , , , False)

End Sub

Sub fermeexcel2()

On Error GoTo ges1

exl2.Close SaveChanges:=False
appex2.Quit
Set exl2 = Nothing
Set appex2 = Nothing
ges1:
Err.Clear
Resume Next

End Sub


Je me suis également dit qu'il pouvait y avoir plusieurs
instances de mon fichier Excel ouvertes, alors j'ai
essayé
ceci mais ça ne marche pas non plus.

For Each w In appex2.Workbooks
Debug.Print w.Name
appex2.Workbooks(w.Name).Close SaveChanges:=False
Next w

Merci d'avance pour votre aide.
Yann

9 réponses

Avatar
michdenis
Bonjour Yann,


Je ne sais pas exactement comment tu as défini tes variables "objet" dans ton code ... le code que tu as soumis ne l'indique
pas !!!

Si tu as besoin à plusieurs reprises une instance d'excel dans un formulaire pour manipuler Excel dans un programme VB,
Pourquoi ne pas déclarer dans le haut de ton formulaire une variable objet comme Public.

Public MonXl as Objet

Dans ton code dès que tu créeras l'instance excel par une ligne de code suivant :

Set MonXl = createobject("excel.application")

l'instance "Application" sera mise en mémoire. La même variable peut servir à ouvrir plusieurs classeurs différents dans
plusieurs procédures différentes. Il n'est pas nécessaire de fermer l'instance "Application" à chacune des fois.

Au niveau de chaque procédure, si tu dois ouvrir un fichier :

Tu détermines une variable locale :

Dim FichierXs as object

Set FichierXl = monXl.Workbooks.open "C:cheminMonFichier.xls")

à la fin de la procédure, tu fermes ton classeur

with FichierXl
.Close SaveChanges:úlse
End with

Set fichierXl = Nothing


Et si tu sais que tu vas devoir utiliser à nouveau une instance excel, ne ferme pas l'application .... au plus tu peux la
rendre "invisible" si désiré .

MonXl.Visible = False

Pour récupérer ton instance d'excel, ce sera beaucoup plus rapide.

Lorsque tu fermeras ton formulaire, tu fermeras seulement à ce moment l'instance d'excel :

MonXl.Quit
set MonXl = Nothing



Salutations!





"Yann" a écrit dans le message de news:
Bonjour,

Je développe un programme en VB qui, pour effectuer des
calculs, utilise régulièrement un fichier Excel (dans
lequel j'entre des valeurs et dans lequel je récupère mes
résultats).

J'utilise pour ouvrir et fermer Excel 2 fonctions (cf ci
après), mais j'ai un problème de fermeture d'Excel qui ne
se ferme pas toujours (le processus reste dans le
gestionnaire des tâches).
Je ne comprends vraiment pas pourquoi Excel se ferme mal,
si c'est parce que je l'ouvre et le ferme plusieurs fois
de suite, si c'est à cause d'une liaison dans ce
classeur,
si c'est mon code qui est faux (faut-il faire à chaque
fois « exl2.Close SaveChanges:úlse » , «
appex2.Quit" , « Set exl2 = Nothing » et « Set appex2 Nothing » ? )

Sub ouvreexcel2()

fermeexcel2 'ferme excel
Set appex2 = CreateObject("excel.Application")
nomfich2 = App.Path & "ExcelfilesParamCF.xls"
Set exl2 = appex2.Workbooks.Open(nomfich2, 0,
True, , , , , , , , False)

End Sub

Sub fermeexcel2()

On Error GoTo ges1

exl2.Close SaveChanges:úlse
appex2.Quit
Set exl2 = Nothing
Set appex2 = Nothing
ges1:
Err.Clear
Resume Next

End Sub


Je me suis également dit qu'il pouvait y avoir plusieurs
instances de mon fichier Excel ouvertes, alors j'ai
essayé
ceci mais ça ne marche pas non plus.

For Each w In appex2.Workbooks
Debug.Print w.Name
appex2.Workbooks(w.Name).Close SaveChanges:úlse
Next w

Merci d'avance pour votre aide.
Yann
Avatar
Yann
Bonjour,

Merci pour votre aide.
J'ai essayé ce que vous suggérez, je vais suivre votre conseil pour fermer
"MonXl" uniquement à la fin d'utilisation de mon programme.

En revanche je ne peux pas déclarer en local :
Dim FichierXs as object

je suis obligé de déclarer en global:
Public FichierXs as object

et de l'utiliser à chaque fois, car j'ai une procédure d'ouverture, le code
de ma form puis la procédure de fermeture.
Pensez-vous que mon problème vienne de là ? je ne comprends pas pourquoi
pour certaines form les procédures fonctionnent correctement et pour d'autres
non, je me suis dit que ça pouvait venir du fait que j'avais ouvert plusieurs
fois le même fichier donc j'ai essayé :

Dim w As Object
For Each w In MonXl.Workbooks
Debug.Print w.Name
MonXl.Workbooks(w.Name).Close SaveChanges:úlse
Next w
Set FichierXs = Nothing

dans ma procédure de fermeture mais ça ne marche pas non plus.

Si vous avez une idée...

Cordialement.
Yann

"michdenis" wrote:

Bonjour Yann,


Je ne sais pas exactement comment tu as défini tes variables "objet" dans ton code ... le code que tu as soumis ne l'indique
pas !!!

Si tu as besoin à plusieurs reprises une instance d'excel dans un formulaire pour manipuler Excel dans un programme VB,
Pourquoi ne pas déclarer dans le haut de ton formulaire une variable objet comme Public.

Public MonXl as Objet

Dans ton code dès que tu créeras l'instance excel par une ligne de code suivant :

Set MonXl = createobject("excel.application")

l'instance "Application" sera mise en mémoire. La même variable peut servir à ouvrir plusieurs classeurs différents dans
plusieurs procédures différentes. Il n'est pas nécessaire de fermer l'instance "Application" à chacune des fois.

Au niveau de chaque procédure, si tu dois ouvrir un fichier :

Tu détermines une variable locale :

Dim FichierXs as object

Set FichierXl = monXl.Workbooks.open "C:cheminMonFichier.xls")

à la fin de la procédure, tu fermes ton classeur

with FichierXl
.Close SaveChanges:úlse
End with

Set fichierXl = Nothing


Et si tu sais que tu vas devoir utiliser à nouveau une instance excel, ne ferme pas l'application .... au plus tu peux la
rendre "invisible" si désiré .

MonXl.Visible = False

Pour récupérer ton instance d'excel, ce sera beaucoup plus rapide.

Lorsque tu fermeras ton formulaire, tu fermeras seulement à ce moment l'instance d'excel :

MonXl.Quit
set MonXl = Nothing



Salutations!





"Yann" a écrit dans le message de news:
Bonjour,

Je développe un programme en VB qui, pour effectuer des
calculs, utilise régulièrement un fichier Excel (dans
lequel j'entre des valeurs et dans lequel je récupère mes
résultats).

J'utilise pour ouvrir et fermer Excel 2 fonctions (cf ci
après), mais j'ai un problème de fermeture d'Excel qui ne
se ferme pas toujours (le processus reste dans le
gestionnaire des tâches).
Je ne comprends vraiment pas pourquoi Excel se ferme mal,
si c'est parce que je l'ouvre et le ferme plusieurs fois
de suite, si c'est à cause d'une liaison dans ce
classeur,
si c'est mon code qui est faux (faut-il faire à chaque
fois « exl2.Close SaveChanges:úlse » , «
appex2.Quit" , « Set exl2 = Nothing » et « Set appex2 > Nothing » ? )

Sub ouvreexcel2()

fermeexcel2 'ferme excel
Set appex2 = CreateObject("excel.Application")
nomfich2 = App.Path & "ExcelfilesParamCF.xls"
Set exl2 = appex2.Workbooks.Open(nomfich2, 0,
True, , , , , , , , False)

End Sub

Sub fermeexcel2()

On Error GoTo ges1

exl2.Close SaveChanges:úlse
appex2.Quit
Set exl2 = Nothing
Set appex2 = Nothing
ges1:
Err.Clear
Resume Next

End Sub


Je me suis également dit qu'il pouvait y avoir plusieurs
instances de mon fichier Excel ouvertes, alors j'ai
essayé
ceci mais ça ne marche pas non plus.

For Each w In appex2.Workbooks
Debug.Print w.Name
appex2.Workbooks(w.Name).Close SaveChanges:úlse
Next w

Merci d'avance pour votre aide.
Yann





Avatar
michdenis
Bonjour Yann,

Lorsque tu déclares une variable dans le haut du module "Public" , il NE FAUT PAS déclarer la même variable au niveau local
d'une procédure ....sinon c'est la variable locale qui aura préséance sur la variable PUBLIC et tu te retrouveras avec le
même problème !

Lorsque tu fermes ta form, je ne vous pas pourquoi, ces lignes de code ne fermeraient pas l'application Excel

MonXl.Quit
set MonXl = Nothing

Ton problème semble une question "OÙ" déclarer la variable ...


Salutations!



"Yann" a écrit dans le message de news:
Bonjour,

Merci pour votre aide.
J'ai essayé ce que vous suggérez, je vais suivre votre conseil pour fermer
"MonXl" uniquement à la fin d'utilisation de mon programme.

En revanche je ne peux pas déclarer en local :
Dim FichierXs as object

je suis obligé de déclarer en global:
Public FichierXs as object

et de l'utiliser à chaque fois, car j'ai une procédure d'ouverture, le code
de ma form puis la procédure de fermeture.
Pensez-vous que mon problème vienne de là ? je ne comprends pas pourquoi
pour certaines form les procédures fonctionnent correctement et pour d'autres
non, je me suis dit que ça pouvait venir du fait que j'avais ouvert plusieurs
fois le même fichier donc j'ai essayé :

Dim w As Object
For Each w In MonXl.Workbooks
Debug.Print w.Name
MonXl.Workbooks(w.Name).Close SaveChanges:úlse
Next w
Set FichierXs = Nothing

dans ma procédure de fermeture mais ça ne marche pas non plus.

Si vous avez une idée...

Cordialement.
Yann

"michdenis" wrote:

Bonjour Yann,


Je ne sais pas exactement comment tu as défini tes variables "objet" dans ton code ... le code que tu as soumis ne
l'indique

pas !!!

Si tu as besoin à plusieurs reprises une instance d'excel dans un formulaire pour manipuler Excel dans un programme VB,
Pourquoi ne pas déclarer dans le haut de ton formulaire une variable objet comme Public.

Public MonXl as Objet

Dans ton code dès que tu créeras l'instance excel par une ligne de code suivant :

Set MonXl = createobject("excel.application")

l'instance "Application" sera mise en mémoire. La même variable peut servir à ouvrir plusieurs classeurs différents dans
plusieurs procédures différentes. Il n'est pas nécessaire de fermer l'instance "Application" à chacune des fois.

Au niveau de chaque procédure, si tu dois ouvrir un fichier :

Tu détermines une variable locale :

Dim FichierXs as object

Set FichierXl = monXl.Workbooks.open "C:cheminMonFichier.xls")

à la fin de la procédure, tu fermes ton classeur

with FichierXl
.Close SaveChanges:úlse
End with

Set fichierXl = Nothing


Et si tu sais que tu vas devoir utiliser à nouveau une instance excel, ne ferme pas l'application .... au plus tu peux la
rendre "invisible" si désiré .

MonXl.Visible = False

Pour récupérer ton instance d'excel, ce sera beaucoup plus rapide.

Lorsque tu fermeras ton formulaire, tu fermeras seulement à ce moment l'instance d'excel :

MonXl.Quit
set MonXl = Nothing



Salutations!





"Yann" a écrit dans le message de
news:

Bonjour,

Je développe un programme en VB qui, pour effectuer des
calculs, utilise régulièrement un fichier Excel (dans
lequel j'entre des valeurs et dans lequel je récupère mes
résultats).

J'utilise pour ouvrir et fermer Excel 2 fonctions (cf ci
après), mais j'ai un problème de fermeture d'Excel qui ne
se ferme pas toujours (le processus reste dans le
gestionnaire des tâches).
Je ne comprends vraiment pas pourquoi Excel se ferme mal,
si c'est parce que je l'ouvre et le ferme plusieurs fois
de suite, si c'est à cause d'une liaison dans ce
classeur,
si c'est mon code qui est faux (faut-il faire à chaque
fois « exl2.Close SaveChanges:úlse » , «
appex2.Quit" , « Set exl2 = Nothing » et « Set appex2 > Nothing » ? )

Sub ouvreexcel2()

fermeexcel2 'ferme excel
Set appex2 = CreateObject("excel.Application")
nomfich2 = App.Path & "ExcelfilesParamCF.xls"
Set exl2 = appex2.Workbooks.Open(nomfich2, 0,
True, , , , , , , , False)

End Sub

Sub fermeexcel2()

On Error GoTo ges1

exl2.Close SaveChanges:úlse
appex2.Quit
Set exl2 = Nothing
Set appex2 = Nothing
ges1:
Err.Clear
Resume Next

End Sub


Je me suis également dit qu'il pouvait y avoir plusieurs
instances de mon fichier Excel ouvertes, alors j'ai
essayé
ceci mais ça ne marche pas non plus.

For Each w In appex2.Workbooks
Debug.Print w.Name
appex2.Workbooks(w.Name).Close SaveChanges:úlse
Next w

Merci d'avance pour votre aide.
Yann





Avatar
Yann
Rebonjour,

Je ne déclare qu'une fois ma variable (en global), en revanche je fais
plusieurs fois "Set FichierXs = MonXL.Workbooks.Open(nomfich2, 0, True, , , ,
, , , , False)"

Je sais que ça devrait marcher, je dois avoir un autre problème qui parasite
mais je ne vois pas ce que ça peut être.

Merci néanmoins pour votre aide.

Cordialement.
Yann

"michdenis" wrote:

Bonjour Yann,

Lorsque tu déclares une variable dans le haut du module "Public" , il NE FAUT PAS déclarer la même variable au niveau local
d'une procédure ....sinon c'est la variable locale qui aura préséance sur la variable PUBLIC et tu te retrouveras avec le
même problème !

Lorsque tu fermes ta form, je ne vous pas pourquoi, ces lignes de code ne fermeraient pas l'application Excel

MonXl.Quit
set MonXl = Nothing

Ton problème semble une question "OÙ" déclarer la variable ...


Salutations!



Avatar
Clément Marcotte
Bonjour,

Je ne comprends vraiment pas pourquoi Excel se ferme mal,
si c'est parce que je l'ouvre et le ferme plusieurs fois
de suite, si c'est à cause d'une liaison dans ce
classeur,


C'est pareil chez moi. On dirait qu'il est impossible de fermer
convenablement Excel par automation. Pour cela j'ai récupéré quelque
chose pour le tuer par l'API.


1) Dans l'entête d'un module standard en dehors de toute procédure

Public Const MAX_PATH& = 260
Public Declare Function CreateToolhelpSnapshot Lib "kernel32" Alias
"CreateToolhelp32Snapshot" (ByVal lFlags As Long, lProcessID As Long)
As Long
Public Declare Function ProcessFirst Lib "kernel32" Alias
"Process32First" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32)
As Long
Public Declare Function OpenProcess Lib "kernel32" (ByVal
dwDesiredAccess As Long, ByVal blnheritHandle As Long, ByVal
dwAppProcessId As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As
Long) As Long
Public Declare Function ProcessNext Lib "kernel32" Alias
"Process32Next" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32)
As Long
Public Declare Function TerminateProcess Lib "kernel32" (ByVal
hProcess As Long, ByVal uExitCode As Long) As Long

Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szexeFile As String * MAX_PATH
End Type


2) Dans un module standard:

Public Function KillApp(myName As String) As Boolean
'Cette procédure vient du programme DFreeze.bas
'écrit par David Midkiff
'Sauf que j'ai vu des choses très ressemblantes
'Sur le site de Microsoft et le site de Allapi.com
'Donc, ce n'est pas vraiment possible de dire qui est
'le véritable auteur de la procédure.
'Chose certaine, ce n'est pas moi.
Dim z As String
Dim uProcess As PROCESSENTRY32
Dim rProcessFound As Long
Dim hSnapshot As Long
Dim szExename As String
Dim exitCode As Long
Dim myProcess As Long
Dim AppKill As Boolean
Dim appCount As Integer
Dim i As Integer

Const PROCESS_ALL_ACCESS = 0
Const TH32CS_SNAPPROCESS As Long = 2&

appCount = 0

uProcess.dwSize = Len(uProcess)
hSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
rProcessFound = ProcessFirst(hSnapshot, uProcess)
Do While rProcessFound
i = InStr(1, uProcess.szexeFile, Chr(0))
szExename = LCase$(Left$(uProcess.szexeFile, i - 1))
z = Environ("Windir") + ""
z = LCase$(z)
If Right$(szExename, Len(myName)) = LCase$(myName) Then
KillApp = True
appCount = appCount + 1
myProcess = OpenProcess(PROCESS_ALL_ACCESS, False,
uProcess.th32ProcessID)
AppKill = TerminateProcess(myProcess, exitCode)
Call CloseHandle(myProcess)
End If
rProcessFound = ProcessNext(hSnapshot, uProcess)
Loop
Call CloseHandle(hSnapshot)
Exit Function
End Function

Avatar
michdenis
Bonjour Yann, Clément,

Voici un petit exemple que j'ai testé dans visual basic ... et cela fonctionne très bien ... à la fermeture de la "Form"
il ne reste aucune instance d'excel (processus) en mémoire vive !

Voici le contenu de la Form

'Haut du module, déclaration des variables
Public Xl As Object 'Application
Public Wk As Object 'pour les classeurs (workbook)

'-------------------
Private Sub Form_Load()

Set Xl = CreateObject("Excel.Application")

End Sub
'-------------------
Private Sub Command1_Click()
'Ouverture d'un classeur
Set Wk = Xl.workbooks.open("c:excelClasseur1.xls")
Xl.Visible = True

End Sub
'-------------------
Private Sub Command2_Click()
'Fermeture du classeur
Wk.Close False
Set Wk = Nothing
Xl.Visible = False

End Sub
'-------------------
Private Sub Form_Unload(Cancel As Integer)
'Fermeture de l'instance d'excel
Xl.quit
Set Xl = Nothing
End Sub
'-------------------


Salutations!






"Yann" a écrit dans le message de
news:
Bonjour,

Je développe un programme en VB qui, pour effectuer des
calculs, utilise régulièrement un fichier Excel (dans
lequel j'entre des valeurs et dans lequel je récupère mes
résultats).

J'utilise pour ouvrir et fermer Excel 2 fonctions (cf ci
après), mais j'ai un problème de fermeture d'Excel qui ne
se ferme pas toujours (le processus reste dans le
gestionnaire des tâches).
Je ne comprends vraiment pas pourquoi Excel se ferme mal,
si c'est parce que je l'ouvre et le ferme plusieurs fois
de suite, si c'est à cause d'une liaison dans ce
classeur,
si c'est mon code qui est faux (faut-il faire à chaque
fois « exl2.Close SaveChanges:úlse » , «
appex2.Quit" , « Set exl2 = Nothing » et « Set appex2 Nothing » ? )

Sub ouvreexcel2()

fermeexcel2 'ferme excel
Set appex2 = CreateObject("excel.Application")
nomfich2 = App.Path & "ExcelfilesParamCF.xls"
Set exl2 = appex2.Workbooks.Open(nomfich2, 0,
True, , , , , , , , False)

End Sub

Sub fermeexcel2()

On Error GoTo ges1

exl2.Close SaveChanges:úlse
appex2.Quit
Set exl2 = Nothing
Set appex2 = Nothing
ges1:
Err.Clear
Resume Next

End Sub


Je me suis également dit qu'il pouvait y avoir plusieurs
instances de mon fichier Excel ouvertes, alors j'ai
essayé
ceci mais ça ne marche pas non plus.

For Each w In appex2.Workbooks
Debug.Print w.Name
appex2.Workbooks(w.Name).Close SaveChanges:úlse
Next w

Merci d'avance pour votre aide.
Yann
Avatar
Yann
Bonjour,

Merci beaucoup pour la réponse.
Comment utilise-t-on la fonction KillApp ? J'ai essayé de la mettre dans mon
form_unload mais je n'ai pas dû utiliser la bonne syntaxe.

Merci d'avance.
Cordialement.
Yann


Bonjour,

Je ne comprends vraiment pas pourquoi Excel se ferme mal,
si c'est parce que je l'ouvre et le ferme plusieurs fois
de suite, si c'est à cause d'une liaison dans ce
classeur,


C'est pareil chez moi. On dirait qu'il est impossible de fermer
convenablement Excel par automation. Pour cela j'ai récupéré quelque
chose pour le tuer par l'API.


1) Dans l'entête d'un module standard en dehors de toute procédure

Public Const MAX_PATH& = 260
Public Declare Function CreateToolhelpSnapshot Lib "kernel32" Alias
"CreateToolhelp32Snapshot" (ByVal lFlags As Long, lProcessID As Long)
As Long
Public Declare Function ProcessFirst Lib "kernel32" Alias
"Process32First" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32)
As Long
Public Declare Function OpenProcess Lib "kernel32" (ByVal
dwDesiredAccess As Long, ByVal blnheritHandle As Long, ByVal
dwAppProcessId As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As
Long) As Long
Public Declare Function ProcessNext Lib "kernel32" Alias
"Process32Next" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32)
As Long
Public Declare Function TerminateProcess Lib "kernel32" (ByVal
hProcess As Long, ByVal uExitCode As Long) As Long

Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szexeFile As String * MAX_PATH
End Type


2) Dans un module standard:

Public Function KillApp(myName As String) As Boolean
'Cette procédure vient du programme DFreeze.bas
'écrit par David Midkiff
'Sauf que j'ai vu des choses très ressemblantes
'Sur le site de Microsoft et le site de Allapi.com
'Donc, ce n'est pas vraiment possible de dire qui est
'le véritable auteur de la procédure.
'Chose certaine, ce n'est pas moi.
Dim z As String
Dim uProcess As PROCESSENTRY32
Dim rProcessFound As Long
Dim hSnapshot As Long
Dim szExename As String
Dim exitCode As Long
Dim myProcess As Long
Dim AppKill As Boolean
Dim appCount As Integer
Dim i As Integer

Const PROCESS_ALL_ACCESS = 0
Const TH32CS_SNAPPROCESS As Long = 2&

appCount = 0

uProcess.dwSize = Len(uProcess)
hSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
rProcessFound = ProcessFirst(hSnapshot, uProcess)
Do While rProcessFound
i = InStr(1, uProcess.szexeFile, Chr(0))
szExename = LCase$(Left$(uProcess.szexeFile, i - 1))
z = Environ("Windir") + ""
z = LCase$(z)
If Right$(szExename, Len(myName)) = LCase$(myName) Then
KillApp = True
appCount = appCount + 1
myProcess = OpenProcess(PROCESS_ALL_ACCESS, False,
uProcess.th32ProcessID)
AppKill = TerminateProcess(myProcess, exitCode)
Call CloseHandle(myProcess)
End If
rProcessFound = ProcessNext(hSnapshot, uProcess)
Loop
Call CloseHandle(hSnapshot)
Exit Function
End Function







Avatar
Clément Marcotte
Bonjour,

De mémoire:

Killapp("excel")

"Yann" a écrit dans le message de
news:
Bonjour,

Merci beaucoup pour la réponse.
Comment utilise-t-on la fonction KillApp ? J'ai essayé de la mettre
dans mon

form_unload mais je n'ai pas dû utiliser la bonne syntaxe.

Merci d'avance.
Cordialement.
Yann


Bonjour,

Je ne comprends vraiment pas pourquoi Excel se ferme mal,
si c'est parce que je l'ouvre et le ferme plusieurs fois
de suite, si c'est à cause d'une liaison dans ce
classeur,


C'est pareil chez moi. On dirait qu'il est impossible de fermer
convenablement Excel par automation. Pour cela j'ai récupéré
quelque


chose pour le tuer par l'API.


1) Dans l'entête d'un module standard en dehors de toute procédure

Public Const MAX_PATH& = 260
Public Declare Function CreateToolhelpSnapshot Lib "kernel32"
Alias


"CreateToolhelp32Snapshot" (ByVal lFlags As Long, lProcessID As
Long)


As Long
Public Declare Function ProcessFirst Lib "kernel32" Alias
"Process32First" (ByVal hSnapshot As Long, uProcess As
PROCESSENTRY32)


As Long
Public Declare Function OpenProcess Lib "kernel32" (ByVal
dwDesiredAccess As Long, ByVal blnheritHandle As Long, ByVal
dwAppProcessId As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject
As


Long) As Long
Public Declare Function ProcessNext Lib "kernel32" Alias
"Process32Next" (ByVal hSnapshot As Long, uProcess As
PROCESSENTRY32)


As Long
Public Declare Function TerminateProcess Lib "kernel32" (ByVal
hProcess As Long, ByVal uExitCode As Long) As Long

Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szexeFile As String * MAX_PATH
End Type


2) Dans un module standard:

Public Function KillApp(myName As String) As Boolean
'Cette procédure vient du programme DFreeze.bas
'écrit par David Midkiff
'Sauf que j'ai vu des choses très ressemblantes
'Sur le site de Microsoft et le site de Allapi.com
'Donc, ce n'est pas vraiment possible de dire qui est
'le véritable auteur de la procédure.
'Chose certaine, ce n'est pas moi.
Dim z As String
Dim uProcess As PROCESSENTRY32
Dim rProcessFound As Long
Dim hSnapshot As Long
Dim szExename As String
Dim exitCode As Long
Dim myProcess As Long
Dim AppKill As Boolean
Dim appCount As Integer
Dim i As Integer

Const PROCESS_ALL_ACCESS = 0
Const TH32CS_SNAPPROCESS As Long = 2&

appCount = 0

uProcess.dwSize = Len(uProcess)
hSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
rProcessFound = ProcessFirst(hSnapshot, uProcess)
Do While rProcessFound
i = InStr(1, uProcess.szexeFile, Chr(0))
szExename = LCase$(Left$(uProcess.szexeFile, i - 1))
z = Environ("Windir") + ""
z = LCase$(z)
If Right$(szExename, Len(myName)) = LCase$(myName) Then
KillApp = True
appCount = appCount + 1
myProcess = OpenProcess(PROCESS_ALL_ACCESS, False,
uProcess.th32ProcessID)
AppKill = TerminateProcess(myProcess, exitCode)
Call CloseHandle(myProcess)
End If
rProcessFound = ProcessNext(hSnapshot, uProcess)
Loop
Call CloseHandle(hSnapshot)
Exit Function
End Function









Avatar
Yann
Bonjour,

Merci beaucoup pour votre aide, grâce à votre idée j'ai fait des recherches
sur d'autres sites et j'ai trouvé une fonction killApp qui fonctionne avec
mon application.

Encore merci.
Yann

"Clément Marcotte" wrote:

Bonjour,

De mémoire:

Killapp("excel")

"Yann" a écrit dans le message de
news:
Bonjour,

Merci beaucoup pour la réponse.
Comment utilise-t-on la fonction KillApp ? J'ai essayé de la mettre
dans mon

form_unload mais je n'ai pas dû utiliser la bonne syntaxe.

Merci d'avance.
Cordialement.
Yann


Bonjour,

Je ne comprends vraiment pas pourquoi Excel se ferme mal,
si c'est parce que je l'ouvre et le ferme plusieurs fois
de suite, si c'est à cause d'une liaison dans ce
classeur,


C'est pareil chez moi. On dirait qu'il est impossible de fermer
convenablement Excel par automation. Pour cela j'ai récupéré
quelque


chose pour le tuer par l'API.


1) Dans l'entête d'un module standard en dehors de toute procédure

Public Const MAX_PATH& = 260
Public Declare Function CreateToolhelpSnapshot Lib "kernel32"
Alias


"CreateToolhelp32Snapshot" (ByVal lFlags As Long, lProcessID As
Long)


As Long
Public Declare Function ProcessFirst Lib "kernel32" Alias
"Process32First" (ByVal hSnapshot As Long, uProcess As
PROCESSENTRY32)


As Long
Public Declare Function OpenProcess Lib "kernel32" (ByVal
dwDesiredAccess As Long, ByVal blnheritHandle As Long, ByVal
dwAppProcessId As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject
As


Long) As Long
Public Declare Function ProcessNext Lib "kernel32" Alias
"Process32Next" (ByVal hSnapshot As Long, uProcess As
PROCESSENTRY32)


As Long
Public Declare Function TerminateProcess Lib "kernel32" (ByVal
hProcess As Long, ByVal uExitCode As Long) As Long

Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szexeFile As String * MAX_PATH
End Type


2) Dans un module standard:

Public Function KillApp(myName As String) As Boolean
'Cette procédure vient du programme DFreeze.bas
'écrit par David Midkiff
'Sauf que j'ai vu des choses très ressemblantes
'Sur le site de Microsoft et le site de Allapi.com
'Donc, ce n'est pas vraiment possible de dire qui est
'le véritable auteur de la procédure.
'Chose certaine, ce n'est pas moi.
Dim z As String
Dim uProcess As PROCESSENTRY32
Dim rProcessFound As Long
Dim hSnapshot As Long
Dim szExename As String
Dim exitCode As Long
Dim myProcess As Long
Dim AppKill As Boolean
Dim appCount As Integer
Dim i As Integer

Const PROCESS_ALL_ACCESS = 0
Const TH32CS_SNAPPROCESS As Long = 2&

appCount = 0

uProcess.dwSize = Len(uProcess)
hSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
rProcessFound = ProcessFirst(hSnapshot, uProcess)
Do While rProcessFound
i = InStr(1, uProcess.szexeFile, Chr(0))
szExename = LCase$(Left$(uProcess.szexeFile, i - 1))
z = Environ("Windir") + ""
z = LCase$(z)
If Right$(szExename, Len(myName)) = LCase$(myName) Then
KillApp = True
appCount = appCount + 1
myProcess = OpenProcess(PROCESS_ALL_ACCESS, False,
uProcess.th32ProcessID)
AppKill = TerminateProcess(myProcess, exitCode)
Call CloseHandle(myProcess)
End If
rProcessFound = ProcessNext(hSnapshot, uProcess)
Loop
Call CloseHandle(hSnapshot)
Exit Function
End Function