J'exécute une commande Shell simple dans Excel VBA qui exécute un fichier de commandes dans un répertoire spécifié, comme ci-dessous:
Dim strBatchName As String
strBatchName = "C:\folder\runbat.bat"
Shell strBatchName
Parfois, l’exécution du fichier de commandes peut prendre plus de temps sur un ordinateur et le code VBA en cours dépend de l’exécution du fichier de commandes. Je sais que vous pouvez définir un délai d'attente comme ci-dessous:
Application.Wait Now + TimeSerial(0, 0, 5)
Mais cela pourrait ne pas fonctionner sur certains ordinateurs trop lents. Existe-t-il un moyen d'indiquer systématiquement à Excel de continuer à utiliser le reste du code VBA jusqu'à ce que après le shell ait été exécuté?
Utilisez plutôt WScript.Shell, car 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 à partir de Attendez que Shell se termine, puis formatez les cellules - exécutez une commande de manière synchrone )
Ajouter le sous 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.
Enregistrez le fichier bat sur "C:\WINDOWS\system32" et utilisez le code ci-dessous, il fonctionne
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 de parenthèse dans la commande Exécuter a bien fonctionné 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 à BATCH de créer un fichier à la fin et de laisser VBA attendre la création de ce fichier? Ou avez-vous supprimé par lots un fichier de drapeau une fois que c'est terminé et que VBA attend que le fichier de drapeau disparaisse?
Vous pouvez soit relier le shell à un objet, demander au travail par lots de mettre fin à l'objet shell (quitter) et laisser le code VBA continuer une fois que l'objet shell = rien?
Ou jetez un œil à ceci: Capturer la valeur de sortie d’une commande Shell dans VBA?
C’est ce que j’avais l'habitude d'avoir VB
d'attendre que le processus soit terminé avant de poursuivre… Je ne l'ai pas écrit et je ne m'en félicite pas.
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)