2013-04-11 43 views
17

Tôi đang chạy một lệnh shell đơn giản trong Excel VBA chạy một tập tin thực thi trong một thư mục chỉ định như dưới đây:Chờ lệnh shell để hoàn

Dim strBatchName As String 
strBatchName = "C:\folder\runbat.bat" 
Shell strBatchName 

Đôi khi các tập tin thực thi có thể mất nhiều thời gian trên một số máy tính để chạy, và có tiến hành mã VBA phụ thuộc vào tập tin thực thi để kết thúc chạy. Tôi biết bạn có thể đặt hẹn giờ chờ như sau:

Application.Wait Now + TimeSerial(0, 0, 5) 

Nhưng điều đó có thể không hoạt động trên một số máy tính quá chậm. Có cách nào để hệ thống thông báo cho Excel tiếp tục với phần còn lại của mã VBA cho đến khi sau khi trình bao chạy xong không?

+0

xem http://stackoverflow.com/a/1439241/1176601 (WaitForSingleObject) – Aprillion

Trả lời

39

Sử dụng WScript.Shell thay vào đó, bởi vì nó có một lựa chọn 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 

(Idea sao chép từ Wait for Shell to finish, then format cells - synchronously execute a command)

+1

in .net, nhưng không phải trong VBA ... –

+1

Ok, được sửa đổi để sử dụng WScript.Shell. –

+0

Kể từ khi nâng cấp từ 2010 đến 2013 (và di chuyển tệp .xlam sang C: \ Program Files \ Microsoft Office 15 \ root \ office15 \ Library \) Tôi không thể khởi chạy tệp .exe bằng phương pháp này nữa. Tôi giả định một số quyền hạn của các tập tin - nhưng tôi đã thêm bản thân mình là toàn quyền kiểm soát (tôi cũng là thành viên của Quản trị viên), nhưng dường như tôi có đầy đủ quyền nhưng tôi vẫn gặp lỗi: Ứng dụng không thể bắt đầu chính xác (0xc000007b). Bấm OK để đóng ứng dụng. Bất kỳ ý tưởng/đề xuất? – Terry

0

Bạn có thể BATCH tạo tệp khi tệp được hoàn tất và VBA đợi cho đến khi tệp đó được tạo không? Hoặc có hàng loạt xóa một tập tin cờ khi nó kết thúc và VBA chờ đợi cho đến khi flagfile đã biến mất?

0

Hoặc liên kết vỏ đến một đối tượng, đã được công việc hàng loạt chấm dứt vỏ đối tượng (thoát) và có mã VBA tiếp tục khi đối tượng shell = Không có gì?

Hoặc có một cái nhìn lúc này: Capture output value from a shell command in VBA?

0

Đây là những gì tôi sử dụng để có VB chờ đợi cho quá trình hoàn thành trước khi tiếp tục. Tôi không viết thư này và không nhận tín dụng.

Nó được cung cấp tại một số diễn đàn đang mở khác và hoạt động rất tốt đối với tôi:

Các tờ khai sau là cần thiết cho RunShell chương trình con:

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) 
+1

Mã này không hoạt động trong VBA vì không có RunShell được xác định – CrazyHorse

-2

Dim wsh như wshshell mới

chdir "Danh mục tệp Batch"

wsh.chạy "Full Path of Batch File", vbnormalfocus, đúng

Xong Sơn

+0

Không hiểu câu trả lời của bạn .... –

1

những gì bạn đề nghị với một sự thay đổi tại ngoặc vào lệnh Run làm việc tốt với VBA cho tôi

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 
2

Save the file bat vào "C: \ WINDOWS \ system32" và sử dụng mã dưới đây nó đang làm việc

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 
4

Thêm Sub sau:

Sub SyncShell(ByVal Cmd As String, ByVal WindowStyle As VbAppWinStyle) 
VBA.CreateObject("WScript.Shell").Run Cmd, WindowStyle, True 
End Sub 

Nếu bạn thêm một tham chiếu đến C:\Windows\system32\wshom.ocx bạn cũng có thể sử dụng:

Sub SyncShell(ByVal Cmd As String, ByVal WindowStyle As VbAppWinStyle) 
Static wsh As New WshShell 
wsh.Run Cmd, WindowStyle, True 
End Sub 

Phiên bản này nên hiệu quả hơn.

Các vấn đề liên quan