2010-10-20 67 views
13

Giả sử tôi có một nút được nhúng vào bảng tính của tôi sẽ khởi chạy một số chức năng VBA.Làm thế nào để dừng mã VBA đang chạy?

Private Sub CommandButton1_Click() 
    SomeVBASub 
End Sub 

Private Sub SomeVBASub 
    DoStuff 
    DoAnotherStuff 
    AndFinallyDothis 
End Sub 

Tôi muốn có cơ hội để có một số loại nút "hủy" rằng sẽ ngừng SomeVBASub thực hiện tại một thời điểm tùy ý, và tôi không thành liên quan đến Ctrl+Break đây, vì tôi muốn thích làm âm thầm.

Tôi đoán đây là vấn đề khá phổ biến, có ý tưởng gì không?

Cảm ơn.

Trả lời

18

Thêm nút khác có tên "CancelButton" để đặt cờ, sau đó kiểm tra cờ đó.

Nếu bạn có vòng lặp dài trong "nội dung", hãy kiểm tra ở đó và thoát ra nếu được đặt. Sử dụng DoEvents bên trong vòng lặp dài để đảm bảo rằng giao diện người dùng hoạt động.

Bool Cancel 
Private Sub CancelButton_OnClick() 
    Cancel=True 
End Sub 
... 
Private Sub SomeVBASub 
    Cancel=False 
    DoStuff 
    If Cancel Then Exit Sub 
    DoAnotherStuff 
    If Cancel Then Exit Sub 
    AndFinallyDothis 
End Sub 
+2

tôi có một ý tưởng để thực hiện loại này logic nhưng nó khá embarasses tôi để đặt 'DoEvents-Kiểm tra chuỗi flag' trong mọi điểm thoát của thủ tục có thể (theo nghĩa đen, sau gần như mỗi chuỗi). –

+2

Phương pháp @Faheemitian mô tả dưới đây tránh điều đó, nhưng hoạt động khá giống với Ctrl + Break. Tùy thuộc vào mức độ kiểm soát bạn muốn trên giao diện người dùng (ví dụ:một nút) và nơi bạn có thể cho phép mã của bạn thoát. Nếu giao diện người dùng không quan trọng và việc thoát khỏi mã có thể tùy ý (ví dụ: không có vấn đề với phụ thuộc, khôi phục, v.v ... thì điều đó sẽ dễ nhất. Thông thường, việc thêm bẫy cho cờ hủy không quá nặng nề vì hầu hết thời gian thực hiện sẽ được sử dụng trong các vòng lặp, nhưng có lẽ đó không phải là trường hợp trong tình huống của bạn. –

+2

Hãy để tôi cũng thêm rằng nếu bạn lo ngại về thủ tục không dừng ngay lập tức khi họ nhấp vào "hủy" (do đó bạn cần phải thêm quá nhiều lần kiểm tra), điều tôi thường làm là tắt nút Hủy và thay đổi văn bản thành "Đợi ..." hoặc một cái gì đó trong quy trình Nhấp, vì vậy người dùng biết rằng ứng dụng đang thực sự xem xét yêu cầu của họ. –

0

gì jamietre nói, nhưng

Private Sub SomeVBASub 
    Cancel=False 
    DoStuff 
    If not Cancel Then DoAnotherStuff 
    If not Cancel Then AndFinallyDothis 
End Sub 
9

Làm thế nào về Application.EnableCancelKey - Sử dụng nút Esc

On Error GoTo handleCancel 
Application.EnableCancelKey = xlErrorHandler 
MsgBox "This may take a long time: press ESC to cancel" 
For x = 1 To 1000000 ' Do something 1,000,000 times (long!) 
    ' do something here 
Next x 

handleCancel: 
If Err = 18 Then 
    MsgBox "You cancelled" 
End If 

Snippet từ http://msdn.microsoft.com/en-us/library/aa214566(office.11).aspx

2

Hoặc, nếu bạn muốn tránh việc sử dụng biến toàn cầu bạn có thể sử dụng ít được sử dụng .Tag tài sản của userform:

Private Sub CommandButton1_Click() 
    Me.CommandButton1.Enabled = False 'Disabling button so user cannot push it 
             'multiple times 
    Me.CommandButton1.caption = "Wait..." 'Jamie's suggestion 
    Me.Tag = "Cancel" 
End Sub 

Private Sub SomeVBASub 
    If LCase(UserForm1.Tag) = "cancel" Then 
     GoTo StopProcess 
    Else 
     'DoStuff 
    End If 

Exit Sub 
StopProcess: 
    'Here you can do some steps to be able to cancel process adequately 
    'i.e. setting collections to "Nothing" deleting some files... 
End Sub 
0

Tôi làm điều này rất nhiều. Rất nhiều. :-)

Tôi đã quen với việc sử dụng "DoEvents" thường xuyên hơn, nhưng vẫn có xu hướng thiết lập mọi thứ đang chạy mà không thực sự kiểm tra kỹ phương pháp dừng chắc chắn.

Sau đó, hôm nay, đã thực hiện lại nó, tôi nghĩ, "Chà, chỉ cần đợi đến cuối trong 3 giờ", và bắt đầu chèo quanh trong dải băng. Trước đó, tôi đã nhận thấy trong phần "Xem" của ruy-băng, một "Macro" kéo xuống, và nghĩ rằng tôi có một cái nhìn để xem liệu tôi có thể nhìn thấy Macro chạy nhanh ...

Bây giờ tôi nhận ra bạn có thể cũng nhận được điều này bằng cách sử dụng Alt-F8.

Sau đó, tôi nghĩ, nếu tôi "bước vào" một Macro khác, điều đó có thể cứu tôi không? Nó đã làm :-) Nó cũng hoạt động nếu bạn bước vào Macro đang chạy (nhưng bạn vẫn mất nơi bạn đang tối đa), trừ khi bạn là một lập trình viên rất lười biếng như tôi và khai báo rất nhiều biến "Toàn cầu", trong trường hợp đó dữ liệu toàn cầu được giữ lại :-)

K

0

~ Đối với những người sử dụng hộp đầu vào tùy chỉnh

Private Sub CommandButton1_Click() 

DoCmd.Close acForm, Me.Name 
End 

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