Bài viết: Tạm dừng VBA bằng cách sử dụng Wait, Sleep hoặc Vòng lặp

Liên hệ QC

kyo

Nguyễn Khắc Duy
Thành viên danh dự
Tham gia
4/6/06
Bài viết
901
Được thích
2,714
Tạm dừng VBA bằng cách sử dụng Wait, Sleep hoặc Vòng lặp

Sẽ có nhiều lúc bạn cần tạm dừng VBA với một khoảng thời gian ngắn để chờ đợi một công việc nào đó hoàn tất, hoặc chờ người dùng khác cập nhật dữ liệu, hay chờ một macro khác hoàn thành xong, khi đó bạn có thể lựa chọn dùng Wait, Sleep hoặc vòng lặp.

24664412344_811f861d7d_o.png


Application.Wait

Phương thức Wait là một phương thức có sẵn trong Excel, tương tự như hàm của VBA. Nó đối lập hẳn với Sleep. Bạn có thể dùng chúng trong 1 macro nào đó để ngưng chương trình trong một khoảng thời gian chỉ định. Ví dụ dưới đây sẽ khiến Excel tạm nghỉ trong 10 giây.

Mã:
Application.Wait (Now + TimeValue("0:00:10"))

Wait không chấp nhận khoảng thời gian nhỏ hơn 1 giây.

Sleep

Sleep là một hàm API, là một phần của Windows. Mặc dù nó không phải là hàm của VBA, bạn vẫn có thể gọi nó bằng cách khai báo trong VBA.

Câu khai báo dưới đây chỉ nhằm đáp ứng 2 yêu cầu. Đầu tiên, nó sẽ ra lệnh cho Excel tìm kiếm một hàm API và thứ hai, nó cho phép Office 32bit và 64bit đều có thể chạy như bình thường.

Mã:
#If VBA7 Then
     Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal Milliseconds As LongPtr)
 #Else
     Public Declare Sub Sleep Lib "kernel32" (ByVal Milliseconds As Long)
 #End If

Sleep cho phép bạn dừng macro theo đơn vị một phần ngàn giây (millisecond). Đây là lợi thế của Sleep so với Wait. Và ví dụ dưới đây sẽ cho bạn thấy cách để dừng macro trong vòng 5 giây.

Mã:
Sleep 5000

Vòng lặp

Điểm trừ lớn nhất của Wait và Sleep là Excel sẽ khóa mọi hoạt động của bạn cho đến khi hoàn tất câu lệnh. Bạn có thể dùng CTRL + BREAK để dừng macro, nhưng phím tắt này là vô hiệu với Wait và Sleep.

Để vượt qua trở ngại này, bạn có thể sử dụng vòng lặp của VBA và cũng có thể cho phép mọi thứ được thực hiện khi vòng lặp đang chạy. Bạn có thể thử với ví dụ dưới đây:

Mã:
#If VBA7 Then
     Public Declare PtrSafe Function GetTickCount Lib "kernel32" () As LongPtr
#Else
     Public Declare Function GetTickCount Lib "kernel32" () As Long

Sub WaitingTime(Finish As Long)
    Dim NowTick As Long
    Dim EndTick As Long

    EndTick = GetTickCount + (Finish * 1000)
    
    Do
        NowTick = GetTickCount
        DoEvents
    Loop Until NowTick >= EndTick
 
End Sub

Chúng ta sử dụng Sub này để thực hiện việc tạm ngưng Excel, tuy nhiên điểm cộng ở đây chính là DoEvents. DoEvents sẽ cho Excel biết cần phải thực hiện một điều gì đó khác được đưa vào từ bàn phím và chuột. Chẳng hạn như ví dụ trên, macro vẫn thực hiện nhưng bạn vẫn có thể nhập số liệu vào bảng tính.

Một số bài viết có liên quan:
1/ Hiểu biết thêm về phương thức Evaluate - Understanding Evaluate Method
2/ Tổng quan về Scripting.Dictionary
3/ Sử dụng Worksheet Function trong VBA
 
Lần chỉnh sửa cuối:
Upvote 1
Wait không chấp nhận khoảng thời gian nhỏ hơn 1 giây.
điều này sai
có thể sử dụng Wait để chờ ít hơn 1 giây
Mã:
Public Sub hello()
Application.Wait (Now + 0.4 / 24 / 60 / 60)
MsgBox "hello"
End Sub
có nghĩa là chờ 0.4 giây
 
Chỉnh sửa lần cuối bởi điều hành viên:
Chào các bạn, mình là người mới mong giúp đỡ,
Làm sao để chờ 1 khoản thời gian không cố định ạ
 
Admin ơi, 3 bài viết liên quan không còn xem được nữa. Mọi người up lại cho bọn em đọc với ạ.
 
Admin ơi, 3 bài viết liên quan không còn xem được nữa. Mọi người up lại cho bọn em đọc với ạ.
Link ở bài viết
Rich (BB code):
https://www.giaiphapexcel.com/diendan/threads/110048.T%e1%bb%95ng-quan-v%e1%bb%81-Scripting-Dictionary
Bạn sửa lại thành như thế này sẽ được
Rich (BB code):
https://www.giaiphapexcel.com/diendan/threads/T%e1%bb%95ng-quan-v%e1%bb%81-Scripting-Dictionary.110048
 
Các bạn ơi cho mình hỏi cách đặt biến vào hàm TimeValue
Application.Wait (Now) + TimeValue("00:00:07") dòng lệnh này dừng chạy 7 giây, vậy mình muốn chờ theo tham số nhập vào thì phải viết câu lệnh này như nào? Mình viết như này nó báo lỗi, mong mọi người sửa giúp! Chân thành cảm ơn !
Application.Wait (Now) + TimeValue("00:khoang_cach_thoi_gian:07")
 
PHP:
Sub BienTG()
 Dim Tmr As Double, J As Integer
 
 Tmr = Timer()
 For J = 1 To 5 Step 2
    Application.Wait (Now) + TimeValue("00:00:0" & J)
 Next J
 MsgBox Format(Timer() - Tmr, "###.##0")
End Sub
 
Còn 1 điểm khác biệt nữa là:
- Wait và GetTickCount : CPU chạy và tốn tài nguyên CPU
- Sleep: không tốn tài nguyên CPU

Do vậy khi lựa chọn giữa Wait và Sleep thì mình luôn chọn Sleep.
 
Web KT
Back
Top Bottom