Đồng hồ đếm ngược trên form (1 người xem)

  • Thread starter Thread starter anktdn
  • Ngày gửi Ngày gửi
Liên hệ QC

Người dùng đang xem chủ đề này

anktdn

Thành viên chính thức
Tham gia
18/6/06
Bài viết
72
Được thích
77
Nghề nghiệp
acc
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.
 
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ề đồ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
 

File đính kèm

Upvote 0
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

Có thêm đồng hồ đếm ngược chạy trên form thì hay quá .
 
Upvote 0
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ư flash 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.
 
Lần chỉnh sửa cuối:
Upvote 0
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.

Đúng như ý bạn nói, mình muốn hiển thị thời gian chạy trên form ví dụ trên form sẽ hiển thị 10:15, khi chạy hết đúng 10phút 15 giây form sẽ đóng lại. Ai có ý tưởng hay xin chì giúp. thanks
 
Upvote 0
Here is some code that works in Excel 97.

On the userform., two buttons to start and stop the timer and a label, lblCountdown, and this code


VBA:

PHP:
Private Sub cmdStart_Click() 
nTime = nCount 
Call RunTimer 
End Sub
PHP:
Private Sub cmsdStop_Click() 
nTime = 0 
End Sub

VBA tags courtesy of www.thecodenet.com

In a general module, this code


VBA:

PHP:
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

VBA tags courte
Tìm trên trang vba của tác giả XLD viết code cho bộ đồng hồ đếm ngược, mình đã thiết kế được đồng hồ trên form ,gửi file lên đẩ các bạn tham khảo, code đơn giản nhưng ứng dụng rất hay.
 

File đính kèm

Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Có vấn đề khi dùng lệnh OnTime là người dùng nếu điều chỉnh lại đồng hồ của máy tính (win) thì tẻo, excel có nhược điểm là phụ thuộc vào giờ hệ thống (win) bởi vậy khi làm các file có các macro điều khiển bằng time thì bị người dùng sửa giờ hệ thống để lách. Đang đau đầu vì không biết làm thế nào để xây dựng được 1 cái đồng hồ độc lập (không phụ thuộc vào giờ hệ thống) để khi đến những mốc thời gian hạn định file tự chạy các macro theo mình mong muốn mà những người dùng khác không lách được.
 
Upvote 0
thấy đồng hồ đếm ngược không biết chèn âm thanh vào như thế nào đây!
 
Upvote 0
Upvote 0
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 ạ!
 
Lần chỉnh sửa cuối:
Upvote 0
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...
 
Upvote 0
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Ể
 
Lần chỉnh sửa cuối:
Upvote 0
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Ể

Thầy nói cao siêu quá, em chẳng hiểu "tẹo" nào hết đó! Cám ơn Thầy!
 
Upvote 0
Thầy nói cao siêu quá, em chẳng hiểu "tẹo" nào hết đó! Cám ơn Thầy!
Ôi... tôi không nghĩ là nó quá khó hiểu
- Đếm ngược như các bài trước người ta delay 1 giây 1 lần và mỗi lần như thế người ta trừ giá trị giây của Label 1 đơn vị, đúng không
- Vậy để làm thêm 2 số như bạn nói thì trong khoảng thời gian 1 giây này, ta Delay thêm 100 lần nữa, mỗi lần là 10 đơn vị (của hàm Sleep), tương đương 1/100 giây
Thuật toán chỉ vậy thôi, còn việc tính toán thế nào để đưa giá trị vào 2 số sau của Label là việc của... mọi người
 
Upvote 0
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 ạ!
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

untitled.JPG

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!
 

File đính kèm

Upvote 0
Để 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!
 
Upvote 0
Để 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!
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à Cmd1Cmd2, có Caption là StartClose 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
PHP:
Private Sub Cmd2_Click()
  StopTimer
  Unload UserForm1
End Sub
2> Trong Module
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
PHP:
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
3> Trong UserForm
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
PHP:
Private Sub UserForm_Terminate()
  StopTimer
  ms = 0: iT = 0: Tmp = 0
  Sheet1.Cmd1.Caption = "Start"
End Sub
Xem file đính kèm! ---> Form cứ chạy và ta vẫn làm việc bình thường!
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
 

File đính kèm

Upvote 0
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à.
 
Upvote 0
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à.

Tôi nghĩ không quá phức tạp đâu ông bạn ơi, mở VBA ra, chọn thuộc tính trên form là ShowModal chọn là False thì ông bạn có thể vừa thao tác trên form vừa thao tác trên excel được. Tôi nói vậy không biết có đúng ý ông anh không?
 
Upvote 0
Bạn ndu kính mến! (nhưng có lẽ mình nhiều tuổi hơn Bạn, hì)
Nếu thế thì em gọi bằng ANH vậy!
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à.
Để 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)

untitled.JPG


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)
 
Lần chỉnh sửa cuối:
Upvote 0
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)

Quá tuyệt!
May nhờ ndu giảng mình mới nhận ra (vì không chịu kiểm tra kỹ), đồng hồ chạy mà như không chạy, thậm chí vừa viết code, vừa chạy cũng OK, nó chỉ khựng lại trong tích tắc khi nhấn chuột phải.
 
Upvote 0
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?
 
Upvote 0
Upvote 0
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!

Để làm đồng hồ kiểu này mà thời gian tăng thì sửa như thế nào à!
Xin cảm ơn!
 
Upvote 0
Gửi các anh,
Nếu bây giờ muốn vừa mở sheet ra sẽ hiện ra đồng hồ đếm ngược luôn thì phải làm sao ạ hic hic
 
Upvote 0
Anh Ndu có thể giúp em mod lại một số file này giúp em được không nhé:

- Không sử dụng Button Show/Stop trong sheet nữa.
- Khi mở file excel lên sẽ hiện ra 1 hộp thoại với msg box "bạn đã sẵn sàng chưa" => OK => vào sheet làm việc đồng thời đồng hồ bắt đầu đếm ngược luôn.

Cám ơn anh nhiều
 
Lần chỉnh sửa cuối:
Upvote 0
em gửi file gốc, giúp em tạo msg box
 
Lần chỉnh sửa cuối:
Upvote 0
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à Cmd1Cmd2, có Caption là StartClose 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
PHP:
Private Sub Cmd2_Click()
  StopTimer
  Unload UserForm1
End Sub
2> Trong Module
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
PHP:
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
3> Trong UserForm
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
PHP:
Private Sub UserForm_Terminate()
  StopTimer
  ms = 0: iT = 0: Tmp = 0
  Sheet1.Cmd1.Caption = "Start"
End Sub
Xem file đính kèm! ---> Form cứ chạy và ta vẫn làm việc bình thường!
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

Chào thầy Ndu!
Em xin phép lục lại bài viết cũ ạ.
Em thử sử dụng file thầy làm như code ở trên để đồng hồ đếm ngược không bị dừng khi ta làm việc. Nhưng báo lỗi ở đoạn code sau: Lỗi Type Mismatch kèm bôi đen ở dòng: AddressOf TimeProc

PHP:
Sub StartTimer()
StopTimer
SetTimer Application.hwnd, 1, 10, AddressOf TimeProc
End Sub

Em có tải được file mẫu của các thầy trên GPE và Youtube. Nhưng khi click đúp vào 1 cell thì đồng hồ dừng.
E up file lên đây, thầy có thể sửa giúp em để đồng hồ vẫn chạy khi ta làm việc được không ạ!
Em cảm ơn rất nhiều ạ.
(Bản chất e chưa học VBA, em chỉ biết 1 chút để có thể sử dụng được Marco và các đoạn code có sẵn các thầy cô bạn bè share thôi, nên có gì mong thầy bỏ qua ạ!)
 

File đính kèm

Upvote 0

Bài viết mới nhất

Back
Top Bottom