Attendre que la commande shell soit terminée [dupliquer]
cette question a déjà une réponse ici:
- attendre que Shell termine, puis formater des cellules-exécuter une commande synchrone 5 réponses
j'exécute une commande shell simple dans Excel VBA qui exécute un fichier batch dans un répertoire spécifié comme ci-dessous:
Dim strBatchName As String
strBatchName = "C:folderrunbat.bat"
Shell strBatchName
parfois, le fichier de lot peut prendre plus de temps sur un ordinateur à exécuter, et il ya procédure code VBA qui dépend du fichier de lot pour terminer l'exécution. Je sais que vous pouvez régler un minuteur d'attente comme ci-dessous:
Application.Wait Now + TimeSerial(0, 0, 5)
mais cela pourrait ne pas fonctionner sur un ordinateur qui sont trop lents. Y a-t-il un moyen de dire systématiquement à Excel de continuer avec le reste du code VBA jusqu'à après le shell a fini de fonctionner?
8 réponses
utilisez le WScript.Shell à la place, parce qu'il a une option waitOnReturn
:
Dim wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")
Dim waitOnReturn As Boolean: waitOnReturn = True
Dim windowStyle As Integer: windowStyle = 1
wsh.Run "C:\folder\runbat.bat", windowStyle, waitOnReturn
(idée copiée de attendre que Shell termine, puis formater des cellules - exécuter de manière synchrone une commande )
ajouter le sous-paragraphe suivant:
Sub SyncShell(ByVal Cmd As String, ByVal WindowStyle As VbAppWinStyle)
VBA.CreateObject("WScript.Shell").Run Cmd, WindowStyle, True
End Sub
Si vous ajoutez une référence à C:\Windows\system32\wshom.ocx
vous pouvez également utiliser:
Sub SyncShell(ByVal Cmd As String, ByVal WindowStyle As VbAppWinStyle)
Static wsh As New WshShell
wsh.Run Cmd, WindowStyle, True
End Sub
Cette version devrait être plus efficace.
Enregistrer le fichier bat sur "C:\WINDOWS\system32" et l'utilisation de code ci-dessous, il est de travail
Dim wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")
Dim waitOnReturn As Boolean: waitOnReturn = True
Dim windowStyle As Integer: windowStyle = 1
Dim errorCode As Integer
errorCode = wsh.Run("runbat.bat", windowStyle, waitOnReturn)
If errorCode = 0 Then
'Insert your code here
Else
MsgBox "Program exited with error code " & errorCode & "."
End If
ce que vous avez proposé avec un changement à la parenthèse à la commande Run a fonctionné très bien avec VBA pour moi
Dim wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")
Dim waitOnReturn As Boolean: waitOnReturn = True
Dim windowStyle As Integer: windowStyle = 1
Dim errorCode As Integer
wsh.Run "C:\folder\runbat.bat", windowStyle, waitOnReturn
pourriez-vous demander au lot de créer un fichier quand il est terminé et VBA attendre jusqu'à ce que ce fichier est créé? Ou est-ce que batch supprime un fichier flag une fois terminé et VBA attend jusqu'à ce que le flagfile soit parti?
soit lier l'interpréteur de commandes à un objet, est-ce que la tâche discontinue termine l'objet shell (exit) et est-ce que le code VBA continue une fois que l'objet shell = rien?
Ou jetez un oeil à cette: Capture de la valeur de sortie d'une commande shell en VBA?
c'est ce que j'utilise pour avoir VB
attendre que le processus soit terminé avant de continuer.
Je n'ai pas écrit cela et ne pas prendre de crédit.
il a été offert dans un autre forum ouvert et fonctionne très bien pour moi:
les déclarations suivantes sont nécessaires pour le sous-programme RunShell
:"
Option Explicit
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Const PROCESS_QUERY_INFORMATION = &H400
Private Const STATUS_PENDING = &H103&
'then in your subroutine where you need to shell:
RunShell (path and filename or command, as quoted text)
Dim wsh as new wshell
chdir "Répertoire du Fichier de commandes"
wsh.lancer "chemin complet du fichier Batch", vbnormalfocus, true
Fait Fils