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?

24
demandé sur Jean-François Corbett 2013-04-11 18:46:05

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 )

53
répondu Nate Hekman 2017-05-23 12:10:34

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.

5
répondu Anonymous 2015-09-13 14:59:52

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   
2
répondu Asam 2014-10-09 07:26:51

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
1
répondu dadj 2014-07-18 12:20:22

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?

0
répondu Magoo 2013-04-11 14:51:20

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?

0
répondu K_B 2017-05-23 12:18:10

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)
0
répondu geek0 2014-03-05 21:51:38

Dim wsh as new wshell

chdir "Répertoire du Fichier de commandes"

wsh.lancer "chemin complet du fichier Batch", vbnormalfocus, true

Fait Fils

-2
répondu Borkman 2014-05-08 16:05:34