Em cần đồng hồ đếm ngược trên form, khi chạy hết thời gian thì tự động khóa sheet lại, mong các Pác giúp.
Private Sub UserForm_Activate()
Application.OnTime Now + TimeValue("00:00:05"), "dongform"
End Sub
Sub dongform()
UserForm1.Hide
End Sub
Về đồng hồ đếm ngược thì bạn tìm hiểu thêm trên diễn đàn. Mình chỉ nói đến thuật toán xác định thời gian đóng form
Ta tạo 1 Userform. Sử dụng sự kiện Active để xác định thời gian mở form
PHP:Private Sub UserForm_Activate() Application.OnTime Now + TimeValue("00:00:05"), "dongform" End Sub
Sau khi mở form 5 giây, thủ tục trên sẽ gọi thủ tục đóng form.
Bạn Insert module và nhập thủ tục này vào.
PHP:Sub dongform() UserForm1.Hide End Sub
Không phải vậy đâu Hoang Danh à, ý bạn ấy là cần bổ xung điều khiển Timer trong VB ấy. Như vậy trong thời gian cho phép thì người dùng muốn làm gì thì làm nhưng hết giờ buộc phải thoát. Còn như bạn thì nó giống như flast form thôi. Không hiếu sao máy của mình có điều khiển Timer nhưng không ad được nên đành chịu.
Private Sub cmdStart_Click()
nTime = nCount
Call RunTimer
End Sub
Private Sub cmsdStop_Click()
nTime = 0
End Sub
Public Const nCount As Long = 30 ' secs
Public nTime As Double
Public Sub RunTimer()
If nTime > 1 Then
nTime = nTime - 1
UserForm1.lblCountDown.Caption = Format(TimeSerial(0, 0, nTime), "hh:mm:ss")
Application.OnTime Now + TimeSerial(0, 0, 1), "RunTimer"
Else
Unload UserForm1
End If
End Sub
Xem file này thử nhéEm cần đồng hồ đếm ngược trên form, khi chạy hết thời gian thì tự động khóa sheet lại, mong các Pác giúp.
Vấn đề này nói nhiều trên diển đàn rồi mà:thấy đồng hồ đếm ngược không biết chèn âm thanh vào như thế nào đây!
Có thể tạo đồng hồ đếm ngược trên Form, nhưng đếm tới phần trăm của giây được không ạ?
Thay vì "00:00:00" thì thành "00:00:00:00"
Cám ơn rất nhiều ạ!
Có lẽ không được vì Excel chỉ có cấu trúc này:
TimeSerial(0, 0, 0) hoặc TimeValue("00:00:00", đâu có cái nào nói % đâu nhỉ? Ẹc ẹc...
Chưa chắc đâu! Hàm Sleep (API) cho phép Delay 1/1000 giây
Vậy:
- Mỗi lần ta Delay 10 đơn vị, tương đương 1/100 giây
- Mỗi lần Delay như thế, ta ghép giá trị tính toán vào 1 biến... Biến này sẽ dùng phép ghép chuổi để cho vào 2 số sau cùng của Label
- Sau khi Delay đúng 1 giây, thì sẽ trừ giá trị giây 1 đơn vị
vân.. vân...
Tôi chưa làm nhưng tôi nghĩ là.. CÓ THỂ
Ôi... tôi không nghĩ là nó quá khó hiểuThầy nói cao siêu quá, em chẳng hiểu "tẹo" nào hết đó! Cám ơn Thầy!
Làm luôn cho bạn đây:Có thể tạo đồng hồ đếm ngược trên Form, nhưng đếm tới phần trăm của giây được không ạ?
Thay vì "00:00:00" thì thành "00:00:00:00"
Cám ơn rất nhiều ạ!
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public Check As Boolean
Private Sub Cmd1_Click()
Dim LB As Control, TG As Double, ms As Long
On Error Resume Next
Set LB = UserForm1.Label1
Check = (Cmd1.Caption = "Start")
If UserForm1.Visible = False Then UserForm1.Show
TG = IIf(LB.Caption = "00:00:00:00", TimeSerial(0, 0, 15), TimeValue(Left(LB.Caption, 8)))
Cmd1.Caption = IIf(Check, "Stop", "Start")
Do While Check
DoEvents
TG = TG - TimeSerial(0, 0, 1)
ms = 100
Do
ms = ms - 1
LB.Caption = Format(TG, "hh:mm:ss") & ":" & Format(ms, "00")
Sleep 10
DoEvents
If LB.Caption = "00:00:00:00" Then
Check = False
Cmd1.Caption = "Start"
End If
Loop Until ms = 0 Or Check = False
Loop
End Sub
Private Sub Cmd2_Click()
If UserForm1.Visible Then
Check = False
Unload UserForm1
Cmd1.Caption = "Start"
End If
End Sub
Làm được như bạn nói thật chẳng dễ ăn đâu! Nếu không dùng hàm API thì... đừng có mơĐể Form vừa chạy (macro hoạt động) mà ta vẫn làm việc trên Excel được (như đồng hồ trên) thì nhờ các câu lệnh nào?. Mong các cao thủ chỉ giáo, xin cảm ơn!
Private Sub Cmd1_Click()
With Sheet1.Cmd1
.Caption = IIf(.Caption = "Start", "Stop", "Start")
Run IIf(.Caption = "Stop", "StartTimer", "StopTimer")
End With
With UserForm1
If .Visible = False Then .Show
If .Visible Then
If .Label1.Caption = "00:00:00:00" Then Tmp = TimeValue("00:00:15")
End If
End With
End Sub
Private Sub Cmd2_Click()
StopTimer
Unload UserForm1
End Sub
Declare Function SetTimer Lib "User32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Declare Function KillTimer Lib "User32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
Public iT As Double, ms As Double, Tmp As Double
Sub StartTimer()
StopTimer
SetTimer Application.hwnd, 1, 10, AddressOf TimeProc
End Sub
Sub StopTimer()
KillTimer Application.hwnd, 1
End Sub
Function TimeProc()
On Error Resume Next
With UserForm1
If .Label1.Caption = "00:00:00:01" Then
StopTimer
Sheet1.Cmd1.Caption = "Start"
End If
iT = iT + 1
ms = (100 - (iT Mod 100)) Mod 100
If ms = 99 Then Tmp = Tmp - TimeValue("00:00:01")
.Label1.Caption = Format(Tmp, "hh:mm:ss") & ":" & Format(ms, "00")
End With
End Function
Private Declare Function FindWindow Lib "User32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SetWindowLong Lib "User32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Sub UserForm_Initialize()
Dim hwnd As Long, HT As Double
HT = Me.Height - Me.InsideHeight
hwnd = FindWindow("ThunderDFrame", Me.Caption)
SetWindowLong hwnd, -16, &H84080080
Me.Height = Me.Height - HT
Tmp = TimeValue("00:00:15")
End Sub
Private Sub UserForm_Terminate()
StopTimer
ms = 0: iT = 0: Tmp = 0
Sheet1.Cmd1.Caption = "Start"
End Sub
Bạn ndu kính mến! (nhưng có lẽ mình nhiều tuổi hơn Bạn, hì)Làm được như bạn nói thật chẳng dễ ăn đâu! Nếu không dùng hàm API thì... đừng có mơ
Bạn ndu kính mến! (nhưng có lẽ mình nhiều tuổi hơn Bạn, hì)
Thật tình mình đâu dám làm phiền bạn nhiều vậy?
Mình chỉ hỏi một vài câu lệnh mà Bạn làm cho cả bài, Bạn rất giỏi và nhiệt tình!
Mình hỏi thêm là cái đồng hồ này khác với đồng hồ cũ (file CountDown_on_Form_3.xls) như thế nào? Vì đồng hồ cũ khi vừa chạy mình cũng đã vừa làm việc trên file được rồi mà.
Nếu thế thì em gọi bằng ANH vậy!Bạn ndu kính mến! (nhưng có lẽ mình nhiều tuổi hơn Bạn, hì)
Để Form hoạt động mà ta vẫn thao tác được trên sheet thì trong phần Properties của UserForm, set mục ShowModal = False (như hình)Mình hỏi thêm là cái đồng hồ này khác với đồng hồ cũ (file CountDown_on_Form_3.xls) như thế nào? Vì đồng hồ cũ khi vừa chạy mình cũng đã vừa làm việc trên file được rồi mà.
Tuy nhiên, để có thể THAO TÁC TRÊN SHEET 1 CÁCH BÌNH THƯỜNG thì không đơn giản thế ---> Anh mở file CountDown_in_Form_3.xls, cho Form chạy xem có Format Cells, tô chữ đậm, nghiêng, chọn size chữ... được hay không? (thậm chí Undo còn không được nữa là...)
Gọi là THAO TÁC BÌNH THƯỜNG có nghĩa là Form chạy cứ chạy mà không ảnh hưởng tí gì đến các thao tác của ta ---> Và làm được điều đó chỉ có thể là hàm SetTimer (API)
Tham khảo bài viết sau nhéCho em hỏi nếu thay chạy trên Form bằng hiển thị trực tiếp vào Cell thì làm thế nào?
Làm luôn cho bạn đây:
PHP:Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Public Check As Boolean
PHP:Private Sub Cmd1_Click() Dim LB As Control, TG As Double, ms As Long On Error Resume Next Set LB = UserForm1.Label1 Check = (Cmd1.Caption = "Start") If UserForm1.Visible = False Then UserForm1.Show TG = IIf(LB.Caption = "00:00:00:00", TimeSerial(0, 0, 15), TimeValue(Left(LB.Caption, 8))) Cmd1.Caption = IIf(Check, "Stop", "Start") Do While Check DoEvents TG = TG - TimeSerial(0, 0, 1) ms = 100 Do ms = ms - 1 LB.Caption = Format(TG, "hh:mm:ss") & ":" & Format(ms, "00") Sleep 10 DoEvents If LB.Caption = "00:00:00:00" Then Check = False Cmd1.Caption = "Start" End If Loop Until ms = 0 Or Check = False Loop End Sub
PHP:Private Sub Cmd2_Click() If UserForm1.Visible Then Check = False Unload UserForm1 Cmd1.Caption = "Start" End If End Sub
View attachment 48173
Mới tạm xong! Chắc còn có thể rút gọn thêm nữa ---> Bạn "cày" thử xem!
Xem file này thử nhé
Làm được như bạn nói thật chẳng dễ ăn đâu! Nếu không dùng hàm API thì... đừng có mơ
Cách làm như sau:
1> Trên Sheet
- Vẽ 2 CommandButton, đặt tên là Cmd1 và Cmd2, có Caption là Start và Close Form
- Code cho 2 Command Button này:
PHP:Private Sub Cmd1_Click() With Sheet1.Cmd1 .Caption = IIf(.Caption = "Start", "Stop", "Start") Run IIf(.Caption = "Stop", "StartTimer", "StopTimer") End With With UserForm1 If .Visible = False Then .Show If .Visible Then If .Label1.Caption = "00:00:00:00" Then Tmp = TimeValue("00:00:15") End If End With End Sub
2> Trong ModulePHP:Private Sub Cmd2_Click() StopTimer Unload UserForm1 End Sub
PHP:Declare Function SetTimer Lib "User32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long Declare Function KillTimer Lib "User32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long Public iT As Double, ms As Double, Tmp As Double
PHP:Sub StartTimer() StopTimer SetTimer Application.hwnd, 1, 10, AddressOf TimeProc End Sub
PHP:Sub StopTimer() KillTimer Application.hwnd, 1 End Sub
3> Trong UserFormPHP:Function TimeProc() On Error Resume Next With UserForm1 If .Label1.Caption = "00:00:00:01" Then StopTimer Sheet1.Cmd1.Caption = "Start" End If iT = iT + 1 ms = (100 - (iT Mod 100)) Mod 100 If ms = 99 Then Tmp = Tmp - TimeValue("00:00:01") .Label1.Caption = Format(Tmp, "hh:mm:ss") & ":" & Format(ms, "00") End With End Function
PHP:Private Declare Function FindWindow Lib "User32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Private Declare Function SetWindowLong Lib "User32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
PHP:Private Sub UserForm_Initialize() Dim hwnd As Long, HT As Double HT = Me.Height - Me.InsideHeight hwnd = FindWindow("ThunderDFrame", Me.Caption) SetWindowLong hwnd, -16, &H84080080 Me.Height = Me.Height - HT Tmp = TimeValue("00:00:15") End Sub
Xem file đính kèm! ---> Form cứ chạy và ta vẫn làm việc bình thường!PHP:Private Sub UserForm_Terminate() StopTimer ms = 0: iT = 0: Tmp = 0 Sheet1.Cmd1.Caption = "Start" End Sub
Vì dùng hàm SetTimer khá nguy hiểm nên các bạn hãy test thử xem có trục trặc gì không nha