Tặng tiện ích CALENDAR phiên bản cuối cùng (Excel 2007 trở về sau).

Liên hệ QC

Hoàng Trọng Nghĩa

Chuyên gia GPE
Thành viên BQT
Moderator
Tham gia
17/8/08
Bài viết
8,635
Được thích
16,696
Giới tính
Nam
Qua nhiều lần cải tiến và tôi nghĩ tới đây là nên chấm dứt chuyện Lịch này. Cho nên tôi đã lường hầu hết các trường hợp có thể xảy ra trên các đối tượng, các Range, các UserForm để đối tượng đó nhận ngày tháng sao cho Calendar show ra tại vị trí nơi nhận ngày tháng (có sự trợ giúp to lớn trong việc xác định vị trí của bạn doveandrose, xin cảm ơn bạn).

Nếu các bạn có xài Excel 2007 trở về sau thì nên tải về, giờ đây tôi cũng sẽ lưu file từ 2007 trở về sau mà không phải convert sang 2003 nữa.

Với phiên bản lần này, các bạn được tham khảo lập trình, cách thức add controls và cách tạo sự kiện cho các ActiveX Controls trên Sheet như TextBox, Frame, MultiPage (nguồn trong File Hướng Dẫn).

PHP:
Option Explicit
Private WithEvents frmTextBox1 As MSForms.TextBox
Private WithEvents frmTextBox2 As MSForms.TextBox
Private WithEvents frmTextBox3 As MSForms.TextBox
Private WithEvents mtpTextBox1 As MSForms.TextBox
Private WithEvents mtpTextBox2 As MSForms.TextBox
Private WithEvents mtpTextBox3 As MSForms.TextBox
''******************************************************************************************************
''SHEET EVENT:
''******************************************************************************************************
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Column = 2 And Target.Row > 10 And Target.Row < 21 Then
        Run "CALENDAR.xlam!CalendarExit"
        Run "CALENDAR.xlam!Calendar", Target
    End If
End Sub


Private Sub Worksheet_Deactivate()
    EraseFrameControlEvent
End Sub
''******************************************************************************************************
''CONTROL BELONG TO SHEET EVENT:
''******************************************************************************************************
Private Sub CommandButton1_Click()
    Frame.Show
End Sub

Private Sub TextBox1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    Run "CALENDAR.xlam!Calendar", TextBox1
End Sub

Private Sub Frame1_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    CreateFrameControlEvent
End Sub

Private Sub MultiPage1_MouseMove(ByVal Index As Long, ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    CreateFrameControlEvent
End Sub
''******************************************************************************************************
''CREATE EVENT FOR SOME TEXTBOXES INTO FRAME ON SHEET EVENT:
''******************************************************************************************************
Sub CreateFrameControlEvent()
    If frmTextBox1 Is Nothing Then
        Set frmTextBox1 = Sheet2.Frame1.Controls("TextBox1")
        Set frmTextBox2 = Sheet2.Frame1.Controls("TextBox2")
        Set frmTextBox3 = Sheet2.Frame1.Controls("TextBox3")
        Set mtpTextBox1 = Sheet2.MultiPage1.Pages(1).Controls("TextBox1")
        Set mtpTextBox2 = Sheet2.MultiPage1.Pages(0).Controls("TextBox2")
        Set mtpTextBox3 = Sheet2.MultiPage1.Pages(1).Controls("TextBox3")
    End If
End Sub

Sub EraseFrameControlEvent()
    Set frmTextBox1 = Nothing
    Set frmTextBox2 = Nothing
    Set frmTextBox3 = Nothing
    Set mtpTextBox1 = Nothing
    Set mtpTextBox2 = Nothing
    Set mtpTextBox3 = Nothing
End Sub
''******************************************************************************************************
''CONTROL BELONG TO FRAME ON SHEET EVENT:
''******************************************************************************************************
Private Sub frmTextBox1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    Run "CALENDAR.xlam!Calendar", frmTextBox1
End Sub

Private Sub frmTextBox2_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    Run "CALENDAR.xlam!Calendar", frmTextBox2
End Sub

Private Sub frmTextBox3_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    Run "CALENDAR.xlam!Calendar", frmTextBox3
End Sub
''******************************************************************************************************
''CONTROL BELONG TO MULTIPAGE ON SHEET EVENT:
''******************************************************************************************************
Private Sub mtpTextBox1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    Run "CALENDAR.xlam!Calendar", mtpTextBox1
End Sub

Private Sub mtpTextBox2_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    Run "CALENDAR.xlam!Calendar", mtpTextBox2
End Sub

Private Sub mtpTextBox3_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    Run "CALENDAR.xlam!Calendar", mtpTextBox3
End Sub
''******************************************************************************************************

Một cải tiến nữa là trên Tab Home của dải Ribbon, tôi có thêm 1 Icon mặt cười (Happy Face) để tiện cho việc show lịch.

ThucHanh.jpg

Với người lập trình khi sử dụng Calendar này lại thuận tiện hơn với cấu trúc giản tiện:

Run "CALENDAR.xlam!Calendar", Range("C5")

Run "CALENDAR.xlam!Calendar", TextBox1


Quá đơn giản để nhúng lịch vào chương trình của mình phải không!
 

File đính kèm

  • CALENDAR.xlam
    122.1 KB · Đọc: 298
  • HuongDan.xlsm
    50.3 KB · Đọc: 298
Lần chỉnh sửa cuối:

File đính kèm

  • VR2015-DUY-HTN.xlsm
    144.5 KB · Đọc: 45
Upvote 0
Bạn chép về không đầy đủ trong các module nên Calendar không hoạt động chứ sao!

Xem file nhé!

P/s: File chưa tới nửa Mb thì upload trực tiếp lên đây luôn đi, sao phải qua trang web khác làm gì không biết nữa, bộ hết quota up file rồi hả?
Cám ơn anh nhiều, hổm nay lu bu qua chưa có test file.
Do em đã hết Quota rồi, nên không up lên GPE được
Trân trọng!
 
Upvote 0
Qua nhiều lần cải tiến và tôi nghĩ tới đây là nên chấm dứt chuyện Lịch này. Cho nên tôi đã lường hầu hết các trường hợp có thể xảy ra trên các đối tượng, các Range, các UserForm để đối tượng đó nhận ngày tháng sao cho Calendar show ra tại vị trí nơi nhận ngày tháng (có sự trợ giúp to lớn trong việc xác định vị trí của bạn doveandrose, xin cảm ơn bạn).
....................................................
Quá đơn giản để nhúng lịch vào chương trình của mình phải không!

Anh cho em hỏi trường hợp addin của anh, em xuất ra và đưa vào file của em. Khi em click chọn textbox trên Form sau đó chọn Ngày tháng (VD: chọn ngày 01/12/2016 (dd/mm/yyyy), khi chọn xong thì textbox lại hiển thị lại thành 12/01/2016 (mm/dd/yyyy).
Máy em đã định dạng trong Control Panel dạng dd/mm/yyyy
Vậy làm cách nào để mình khắc phục tình trạng trên vậy anh
 
Upvote 0
Nói chung nên theo hệ Mẽo (MM/d/yyyy), nhưng định dạng theo hệ Fáp cho dễ nhìn!

-0-/.
 
Upvote 0
Tất nhiên là còn, nhưng thêm 1 cách ta cần trả giá 1 số hiểu biết!

Theo mình thì bạn rất chi là chăm học hành trên GPE.COM

Chỉ khuyên bạn 1 điều rằng, cần chọn lọc cho vừa tầm ở thời điểm hiện tại của bạn!
 
Upvote 0
Anh cho em hỏi trường hợp addin của anh, em xuất ra và đưa vào file của em. Khi em click chọn textbox trên Form sau đó chọn Ngày tháng (VD: chọn ngày 01/12/2016 (dd/mm/yyyy), khi chọn xong thì textbox lại hiển thị lại thành 12/01/2016 (mm/dd/yyyy).Máy em đã định dạng trong Control Panel dạng dd/mm/yyyyVậy làm cách nào để mình khắc phục tình trạng trên vậy anh
Bạn chụp hình lại cái hộp thoại mà bạn định dạng kiểu ngày tại Control Panel xem sao. Chứ riêng cái Calendar nó đều chạy theo kiểu của hệ thống.
 
Upvote 0
Bạn chụp hình lại cái hộp thoại mà bạn định dạng kiểu ngày tại Control Panel xem sao. Chứ riêng cái Calendar nó đều chạy theo kiểu của hệ thống.

Anh xem giùm em đinh dang trong Control ...
Với lại khi cập nhật từ Form xuống sheet cũng bị lỗi đinh dạng dd/mm/yyyy thành mm/dd/yyyy

[IMG]http://i.imgur.com/vye63KJ.png[/IMG]
 

File đính kèm

  • Capture.jpg
    Capture.jpg
    21.6 KB · Đọc: 50
Lần chỉnh sửa cuối:
Upvote 0
Qua nhiều lần cải tiến và tôi nghĩ tới đây là nên chấm dứt chuyện Lịch này. Cho nên tôi đã lường hầu hết các trường hợp có thể xảy ra trên các đối tượng, các Range, các UserForm để đối tượng đó nhận ngày tháng sao cho Calendar show ra tại vị trí nơi nhận ngày tháng (có sự trợ giúp to lớn trong việc xác định vị trí của bạn doveandrose, xin cảm ơn bạn).

Nếu các bạn có xài Excel 2007 trở về sau thì nên tải về, giờ đây tôi cũng sẽ lưu file từ 2007 trở về sau mà không phải convert sang 2003 nữa.

Với phiên bản lần này, các bạn được tham khảo lập trình, cách thức add controls và cách tạo sự kiện cho các ActiveX Controls trên Sheet như TextBox, Frame, MultiPage (nguồn trong File Hướng Dẫn).


Quá đơn giản để nhúng lịch vào chương trình của mình phải không!
sau khi add vào add in thì bị lỗi nhứ thế này .
chie còn cách bấm end mà thôi. bạn xem bị lỗi gì nhá
 

File đính kèm

  • calendar error1.jpg
    calendar error1.jpg
    55.3 KB · Đọc: 49
Upvote 0

Anh xem giùm em đinh dang trong Control ...
Với lại khi cập nhật từ Form xuống sheet cũng bị lỗi đinh dạng dd/mm/yyyy thành mm/dd/yyyy

Bạn thử chạy đoạn code dưới đây xem nó hiển thị trên máy của bạn như thế nào nhé:

Mã:
Sub Test()
    MsgBox Date
End Sub

Chụp hình lại cái MsgBox này nha bạn.
 
Upvote 0
Bạn thử chạy đoạn code dưới đây xem nó hiển thị trên máy của bạn như thế nào nhé:

Mã:
Sub Test()
    MsgBox Date
End Sub

Chụp hình lại cái MsgBox này nha bạn.


Capture.PNG


Trường hợp em muốn so sánh (textbox1, textbox2, CommandButton1). Với texbox1 và texbox2 là dạng ngày tháng.
Nhưng đoạn code dưới đây không thực hiện được, nhờ anh xem giúp em
[GPECODE=vba]Private Sub TextBox1_Change()
If TextBox2 > TextBox1 Then
CommandButton1.Enabled = True
Else
CommandButton1.Enabled = False
End If
End Sub


Private Sub TextBox2_Change()
If TextBox2 > TextBox1 Then
CommandButton1.Enabled = True
Else
CommandButton1.Enabled = False
End If
End Sub


Private Sub UserForm_Initialize()
CommandButton1.Enabled = False
End Sub
[/GPECODE]
 
Upvote 0
Trường hợp em muốn so sánh (textbox1, textbox2, CommandButton1). Với texbox1 và texbox2 là dạng ngày tháng.
Nhưng đoạn code dưới đây không thực hiện được, nhờ anh xem giúp em
[GPECODE=vba]Private Sub TextBox1_Change()
If TextBox2 > TextBox1 Then
CommandButton1.Enabled = True
Else
CommandButton1.Enabled = False
End If
End Sub


Private Sub TextBox2_Change()
If TextBox2 > TextBox1 Then
CommandButton1.Enabled = True
Else
CommandButton1.Enabled = False
End If
End Sub


Private Sub UserForm_Initialize()
CommandButton1.Enabled = False
End Sub
[/GPECODE]

Bạn nên làm như sau:

Mã:
Private Sub TextBox1_Change()
    On Error Resume Next
    If CDate(TextBox2) > CDate(TextBox1) Then
        CommandButton1.Enabled = True
    Else
        CommandButton1.Enabled = False
    End If
End Sub
 
 
Private Sub TextBox2_Change()
    On Error Resume Next
     If CDate(TextBox2) > CDate(TextBox1) Then
        CommandButton1.Enabled = True
    Else
        CommandButton1.Enabled = False
    End If
End Sub
P/s: Nhưng rốt cục thì máy bạn hiển thị ngày tháng trong các TextBox có đúng hay chưa?
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn nên làm như sau:

Mã:
Private Sub TextBox1_Change()
    On Error Resume Next
    If CDate(TextBox2) > CDate(TextBox1) Then
        CommandButton1.Enabled = True
    Else
        CommandButton1.Enabled = False
    End If
End Sub
 
 
Private Sub TextBox2_Change()
    On Error Resume Next
     If CDate(TextBox2) > CDate(TextBox1) Then
        CommandButton1.Enabled = True
    Else
        CommandButton1.Enabled = False
    End If
End Sub
P/s: Nhưng rốt cục thì máy bạn hiển thị ngày tháng trong các TextBox có đúng hay chưa?


Em sử dụng dạng này thì mới được, với textbox1 là chọn ngày cần nhập

[GPECODE=vba]Private Sub CmdLuu_Click()
If Me.TextBox1 <> "" Or (Me!txt_SoTien = "" Or Not IsNumeric(Me!txt_SoTien)) Then
If TextBox1 = "" Then
MsgBox "Chon ngay!", , "Thong Bao"
Me.TextBox1 = "": Exit Sub
ElseIf txt_SoTien = "" Or Not IsNumeric(Me!txt_SoTien) Then
MsgBox "Ban Càn Nhap Só Tièn!", , "Thong Bao"
Me!txt_SoTien = "": Exit Sub
End If
End If
With [A2].End(xlDown).Offset(1)
.Value = Day(TextBox1.Value) & "/" & Month(TextBox1.Value) & "/" & Year(TextBox1.Value)
.Value = StringToDate(Format(TextBox1.Value, "dd/mm/yyyy"))
.Offset(, 1).Value = cbb_DonVi.Text
.Offset(, 2).Value = cbb_DGiai.Text
.Offset(, 3).Value = txt_SoTien.Value
.Offset(, 4).Value = MaDD(TextBox1.Value, cbb_DonVi.Text, cbb_DGiai.Text)
End With
Me!txt_SoTien = ""
End Sub
[/GPECODE]
 
Lần chỉnh sửa cuối:
Upvote 0
Em sử dụng dạng này thì mới được, với textbox1 là chọn ngày cần nhập

[GPECODE=vba]Private Sub CmdLuu_Click()
If Me.TextBox1 <> "" Or (Me!txt_SoTien = "" Or Not IsNumeric(Me!txt_SoTien)) Then
If TextBox1 = "" Then
MsgBox "Chon ngay!", , "Thong Bao"
Me.TextBox1 = "": Exit Sub
ElseIf txt_SoTien = "" Or Not IsNumeric(Me!txt_SoTien) Then
MsgBox "Ban Càn Nhap Só Tièn!", , "Thong Bao"
Me!txt_SoTien = "": Exit Sub
End If
End If
With [A2].End(xlDown).Offset(1)
.Value = Day(TextBox1.Value) & "/" & Month(TextBox1.Value) & "/" & Year(TextBox1.Value)
.Value = StringToDate(Format(TextBox1.Value, "dd/mm/yyyy"))
.Offset(, 1).Value = cbb_DonVi.Text
.Offset(, 2).Value = cbb_DGiai.Text
.Offset(, 3).Value = txt_SoTien.Value
.Offset(, 4).Value = MaDD(TextBox1.Value, cbb_DonVi.Text, cbb_DGiai.Text)
End With
Me!txt_SoTien = ""
End Sub
[/GPECODE]

Chi vậy trời? Thay vì:

Mã:
[COLOR=#ff0000].Value = Day(TextBox1.Value) & "/" & Month(TextBox1.Value) & "/" & Year(TextBox1.Value)
.Value = StringToDate(Format(TextBox1.Value, "dd/mm/yyyy"))[/COLOR]

Thì chỉ cần 1 dòng ngắn ngủi vầy thôi:

Mã:
[COLOR=#0000ff].Value = CDate(TextBox1)[/COLOR]
 
Upvote 0
Web KT
Back
Top Bottom