Warten auf das Ende einer Shell-Anweisung in Excel VBA
Schritt-für-Schritt-Anleitung
Um Excel VBA dazu zu bringen, auf das Ende einer Shell-Anweisung zu warten, kannst du die OpenProcess
- und WaitForSingleObject
-Funktionen aus der kernel32.dll
nutzen. Hier ist eine Schritt-für-Schritt-Anleitung:
-
Deklariere die benötigten Funktionen:
Füge die folgenden Deklarationen am Anfang Deines Moduls hinzu:
Private Declare Function OpenProcess Lib "kernel32.dll" ( _
ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32.dll" ( _
ByVal hHandle As Long, _
ByVal dwMilliseconds As Long) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" ( _
ByVal hObject As Long) As Long
Private Const PROCESS_QUERY_INFORMATION = &H400
Private Const SYNCHRONIZE = &H100000
Private Const INFINITE As Long = &HFFFFFFFF
-
Erstelle die Subroutine für das Warten:
Erstelle eine Subroutine, die die Shell-Anweisung ausführt und wartet, bis sie abgeschlossen ist:
Public Sub ShellAndWait()
Dim lngTaskID As Long
Dim lngProcID As Long
' Beispiel für einen Shell-Befehl
lngTaskID = Shell("C:\Windows\NOTEPAD.EXE D:\test.txt", vbNormalFocus)
lngProcID = OpenProcess(SYNCHRONIZE + PROCESS_QUERY_INFORMATION, 0, lngTaskID)
' Warten, bis der Prozess abgeschlossen ist
Call WaitForSingleObject(lngProcID, INFINITE)
Call CloseHandle(lngProcID)
MsgBox "Jetzt geht's weiter"
End Sub
-
Ersetze den Shell-Befehl:
Ersetze den Shell-Befehl durch Deinen eigenen, z.B. um 7-Zip zu nutzen.
Häufige Fehler und Lösungen
-
Fehler: "Zugriffsverletzung"
Stelle sicher, dass Du die richtigen Berechtigungen hast, um den Prozess zu öffnen. Überprüfe die dwDesiredAccess
-Parameter in der OpenProcess
-Funktion.
-
Fehler: "Shell gibt -1 zurück"
Dies deutet darauf hin, dass die Shell-Anweisung nicht korrekt ist. Überprüfe den Pfad und die Argumente.
Alternative Methoden
Wenn Du die OpenProcess
- und WaitForSingleObject
-Funktionen nicht verwenden möchtest, kannst Du auch die Application.Wait
-Methode in Kombination mit einer Schleife nutzen. Beachte jedoch, dass dies weniger effizient ist:
Dim start As Double
start = Timer
Do While Timer < start + 5 ' Warten für 5 Sekunden
DoEvents ' Erlaubt es Excel, andere Tasks zu verarbeiten
Loop
Praktische Beispiele
Hier ist ein Beispiel, wie Du 7-Zip verwenden kannst, um eine Datei zu entpacken und auf das Ende des Prozesses zu warten:
Public Sub UnzipAndWait()
Dim fso As Object
Dim lngTaskID As Long
Dim lngProcID As Long
Dim str7zipProgramm As String
Dim str7zipArchiv As String
Dim str7zipOrdner As String
str7zipProgramm = "C:\Program Files\7-Zip\7z.exe" ' Pfad zur 7zip .exe
str7zipArchiv = "D:\TEMP\deinArchiv.zip" ' Pfad zur zu entpackenden Datei
str7zipOrdner = "D:\TEMP" ' Zielordner
Set fso = CreateObject("Scripting.FileSystemObject")
lngTaskID = Shell(str7zipProgramm & " x " & str7zipArchiv & " -o" & str7zipOrdner, vbNormalFocus)
lngProcID = OpenProcess(SYNCHRONIZE + PROCESS_QUERY_INFORMATION, 0, lngTaskID)
Call WaitForSingleObject(lngProcID, INFINITE)
Call CloseHandle(lngProcID)
MsgBox "Entpacken abgeschlossen!"
End Sub
Tipps für Profis
- Verwende
vbMinimizedNoFocus
, um die Shell-Anwendung im Hintergrund zu minimieren, ohne den Fokus zu verlieren.
- Teste Deine Shell-Befehle zuerst in der Eingabeaufforderung, um sicherzustellen, dass sie korrekt sind.
- Wenn Du regelmäßig mit externen Programmen arbeitest, erstelle eine Utility-Funktion, um die Wiederverwendbarkeit zu erhöhen.
FAQ: Häufige Fragen
1. Wie kann ich mehrere Prozesse gleichzeitig warten lassen?
Du kannst eine Schleife verwenden, die alle Prozess-IDs speichert und für jede WaitForSingleObject
aufruft.
2. Funktioniert dies auch in Excel 365?
Ja, die beschriebenen Methoden funktionieren in allen modernen Excel-Versionen, die VBA unterstützen.