Tặng tiện ích CALENDAR tuyệt đẹp!

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,611
Được thích
16,671
Giới tính
Nam
***************************************************************************************************************
***************************************************************************************************************

Đã có phiên bản mới tại đây:

Tặng tiện ích CALENDAR (Excel 2007 trở về sau)


***************************************************************************************************************
***************************************************************************************************************




Nhân dịp khoác trên vai “4 sao vàng”, tôi xin tặng các bạn một UserForm Calendar tuyệt đẹp, nó không những thay thế được với Control Calendar của Excel mà nó còn hiển thị ngày Âm lịch.

(Giới thiệu trước, gửi file ở bài sau)
3.jpg

Mặc dù mã nguồn tôi đã sưu tầm từ nhiều nơi (thật sự tôi không nhớ nguồn gốc của các mã này của ai sáng tác), nhưng tôi đã cải tiến cũng như thiết kế lại giao diện, kết hợp mã nguồn của dương lịch và mã nguồn chuyển Âm lịch, có đầy đủ “thiên can địa chi” cho năm.

Cũng như tại bài viết này tôi đã giới thiệu (http://www.giaiphapexcel.com/forum/showthread.php?36542-Đặt-caption-cho-nhiều-Label&p=242247#post242247) thì cải tiến lần này hoàn chỉnh nhất, Calendar này sẽ nhớ ngày hiện hành (hôm nay) bằng cách tô màu hồng đậm. Dùng phím mũi tên (lên, xuống, trái, phải) để di chuyển giữa các ô ngày; mỗi ô ngày được chọn sẽ có nền trắng, viền ngoài để phân biệt với ngày hiện hành và các ngày trong tháng.

Các bạn để ý sẽ thấy, khi ô ngày nào được chọn, thì Label ở dưới cùng thể hiện ngày Dương lịch được chọn bên trái và ngày Âm lịch được chọn bên phải, chúng có màu nền, cũng như màu font chữ của ô ngày hiện hành.

Cũng tại Label này, khi bạn đang chọn ngày khác với ngày hiện hành, thì bạn click vào đó nó sẽ chọn về ngày hôm nay.

2.jpg

Nếu bạn rê chuột ngang qua nó, nó sẽ show cho bạn một ToolTip để báo bạn biết chức năng của nó.

Đặc biệt, lần cải tiến này tôi đã thay đổi 2 Label tháng và năm thành 2 ComboBox THÁNG & NĂM để chúng ta có thể di chuyển ngay tới tháng hoặc năm cần xem.

1.jpg

– Chọn tháng –

4.jpg

– Chọn năm –

5.jpg

Các thao tác trên lịch:

  • Di chuyển giữa các ô ngày bằng các phím mũi tên để di chuyển qua lại, lên xuống.
  • Dùng phím Tab để di chuyển ngày kế tiếp, shift + tab để di chuyển ngược lại.
  • PgUp, PgDn để chọn tháng trước, tháng sau (tương đương với bấm vào 2 CommandButton mũi tên qua, lại sát ComboBox Tháng, cũng tương đương Shift + các phím mũi tên).
  • Shift+ PgUp/ PgDn để chọn năm trước, năm sau (tương đương với bấm vào 2 CommandButton mũi tên qua, lại sát ComboBox Năm).
  • Phím Home để trở về ngày hiện hành (ngày hôm nay).

Các bạn cứ bấm thử với Shift hoặc Ctrl kết hợp với các phím trên sẽ nắm rõ nguyên lý hoạt động của lịch.

Với phím Enter, Esc hoặc click vào ô ngày nào đó sẽ thoát lịch.

Nếu lịch được khởi động trên một UserForm và muốn nhận giá trị ngày từ Calendar vào một TextBox trên form này, thì sau khi thoát Lịch, giá trị lịch tại ô ngày nào được chọn sẽ nhập vào TextBox của UserForm đó.

Năm nào có tháng nhuần thì nó thể hiện chữ (N) trên Calendar.

6.jpg
Khi gọi Calendar từ một UserForm, nếu TextBox cần nhập Date có sẳn ngày tháng, lịch sẽ lấy ngày đó làm ngày hiển thị, ngược lại, lịch sẽ hiển thị ngày hiện hành.

7.jpg
 
Lần chỉnh sửa cuối:

File đính kèm

  • Calendar_New.rar
    60.6 KB · Đọc: 618
  • Calendar_New2_Update.rar
    79.3 KB · Đọc: 624
Lần chỉnh sửa cuối:
Upvote 0
Quả là rất hay và đẹp!
Nhưng nếu có thêm phần ghi chú,ghi nhớ (những sự kiện) theo ngày tháng năm rất Mỹ mãn Thầy ạ!
 
Upvote 0
Quả là rất hay và đẹp!
Nhưng nếu có thêm phần ghi chú,ghi nhớ (những sự kiện) theo ngày tháng năm rất Mỹ mãn Thầy ạ!

Vấn đề này tôi nghĩ cũng không khó, nhưng vấn đề chủ yếu của Calendar này các bạn chép nó (import) qua file của các bạn để nhập ngày tháng nhanh chóng là chủ yếu.

Còn việc nó trở thành hoặc như một phần mềm lịch có đầy đủ chức năng ghi chú, báo nhắc nhở, thậm chí tử vi thì khá rắc rối và mất quá nhiều thời gian, mặc dù nó rất linh tinh. Nhưng có thể một lúc nào đó tôi rãnh rỗi thì sẽ nghiên cứu và cải tiến thêm cho nó về các vấn đề này.
 
Upvote 0
Trong Calendar này tôi có để thủ tục khi load form như sau:

Mã:
'*********************************************************************************************
Private Sub UserForm_Initialize()
      Dim hForm As Long, TitleHeigh As Double
      TitleHeigh = Me.Height - Me.InsideHeight
      hForm = FindWindow("ThunderDFrame", Me.Caption)
      SetWindowLong hForm, GWL_STYLE, GetWindowLong(hForm, GWL_STYLE) And Not (WS_BORDER Or WS_CAPTION Or WS_THICKFRAME Or WS_DLGFRAME)
      SetWindowLong hForm, GWL_EXSTYLE, GetWindowLong(hForm, GWL_EXSTYLE) And Not WS_EX_DLGMODALFRAME
      Me.Height = Me.Height - TitleHeigh
      
      LbSolar.ControlTipText = "B" & ChrW$(7845) & "m vào " & ChrW$(273) & "ây " & ChrW$(273) & ChrW$(7875) & " ch" & ChrW$(7885) & "n ngày hôm nay."
      LbLunar.ControlTipText = LbSolar.ControlTipText
      
      CmdPreviousMonth.ControlTipText = "Xem tháng tr" & ChrW$(432) & ChrW$(7899) & "c"
      CmdNextMonth.ControlTipText = "Xem tháng k" & ChrW$(7871) & " ti" & ChrW$(7871) & "p"
      CmdPreviousYear.ControlTipText = "Xem n" & ChrW$(259) & "m tr" & ChrW$(432) & ChrW$(7899) & "c"
      CmdNextYear.ControlTipText = "Xem n" & ChrW$(259) & "m k" & ChrW$(7871) & " ti" & ChrW$(7871) & "p"

      Dim m As Long, y As Long
      For m = 1 To 12
            Month.AddItem "THÁNG " & Format(m, "00")
      Next
      
      For y = 1900 To 2199
            Year.AddItem "N" & ChrW$(258) & "M " & y
      Next
      
     [COLOR=#008000][B] 'If you want to close calendar after click a day, choose isClose = True, otherwise isClose = False.[/B][/COLOR][COLOR=#ff0000][B]
      isClose = True 'False[/B][/COLOR]
End Sub

Có nghĩa là, nếu các bạn không muốn click vào ngày đó nó tự thoát form, thì chọn cho isClose là False, chỉ thoát khi nhấn phím Enter hoặc Esc.
 
Upvote 0
Quả là rất hay. Đúng như Anh đã nói cái này chỉ để cài đặt nhập liệu và xem trong file của mình thôi chứ như một phần mềm để ghi chú thì hơi phúc tạp đó
 
Upvote 0
Trong Calendar này tôi có để thủ tục khi load form như sau:

Mã:
'*********************************************************************************************
Private Sub UserForm_Initialize()
      Dim hForm As Long, TitleHeigh As Double
      TitleHeigh = Me.Height - Me.InsideHeight
      hForm = FindWindow("ThunderDFrame", Me.Caption)
      SetWindowLong hForm, GWL_STYLE, GetWindowLong(hForm, GWL_STYLE) And Not (WS_BORDER Or WS_CAPTION Or WS_THICKFRAME Or WS_DLGFRAME)
      SetWindowLong hForm, GWL_EXSTYLE, GetWindowLong(hForm, GWL_EXSTYLE) And Not WS_EX_DLGMODALFRAME
      Me.Height = Me.Height - TitleHeigh
      
      LbSolar.ControlTipText = "B" & ChrW$(7845) & "m vào " & ChrW$(273) & "ây " & ChrW$(273) & ChrW$(7875) & " ch" & ChrW$(7885) & "n ngày hôm nay."
      LbLunar.ControlTipText = LbSolar.ControlTipText
      
      CmdPreviousMonth.ControlTipText = "Xem tháng tr" & ChrW$(432) & ChrW$(7899) & "c"
      CmdNextMonth.ControlTipText = "Xem tháng k" & ChrW$(7871) & " ti" & ChrW$(7871) & "p"
      CmdPreviousYear.ControlTipText = "Xem n" & ChrW$(259) & "m tr" & ChrW$(432) & ChrW$(7899) & "c"
      CmdNextYear.ControlTipText = "Xem n" & ChrW$(259) & "m k" & ChrW$(7871) & " ti" & ChrW$(7871) & "p"

      Dim m As Long, y As Long
      For m = 1 To 12
            Month.AddItem "THÁNG " & Format(m, "00")
      Next
      
      For y = 1900 To 2199
            Year.AddItem "N" & ChrW$(258) & "M " & y
      Next
      
     [COLOR=#008000][B]'If you want to close calendar after click a day, choose isClose = True, otherwise isClose = False.[/B][/COLOR][COLOR=#ff0000][B]
      isClose = True 'False[/B][/COLOR]
End Sub

Có nghĩa là, nếu các bạn không muốn click vào ngày đó nó tự thoát form, thì chọn cho isClose là False, chỉ thoát khi nhấn phím Enter hoặc Esc.

Mình xin có ý kiến, bạn thử tạo thành một add-ins để chạy cùng Excel để cần thì mở Ex lên là có ngay, khỏi mất công đi tìm.
Nếu muốn hiện trên tray thì bạn ghép với file này:
Thử xem
 

File đính kèm

  • System-Tray.rar
    30 KB · Đọc: 164
Lần chỉnh sửa cuối:
Upvote 0
Cải tiến: Kéo thả để di chuyển lịch, thêm Thứ trong tuần.

Tôi thấy cái lịch vì nó không có Caption trên Form nên không biết di dời nó ra chỗ khác bằng cách nào, hôm nay, cải tiến thêm một bước đó là rê con chuột đến 1 Label THỨ bất kỳ rồi nắm giữ chuột, sau đó kéo thả đến chỗ nào đó trên màn hình! Thủ tục như sau:

PHP:
''*********************************************************************************************
Private Sub lblDay1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
      PosX = X: PosY = Y
End Sub

Private Sub lblDay1_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
      Me.Left = Me.Left - (Button > 0) * (X - PosX)
      Me.Top = Me.Top - (Button > 0) * (Y - PosY)
End Sub

''*********************************************************************************************

Bạn nắm chuột vào các Label này:

attachment.php


''**********************************************************
Đồng thời, tôi cũng thêm một hàm Thứ trong tuần để hiển thị trên Label Dương Lịch:

PHP:
Function fThu(ByVal WeekNum) As String
      Dim DayWeek As Variant
      DayWeek = Array("", "Nh" & ChrW$(7853) & "t", "Hai", _
                          "Ba", "T" & ChrW$(432), _
                          "N" & ChrW$(259) & "m", "Sáu", _
                          "B" & ChrW$(7843) & "y")
      Select Case WeekNum
            Case 1
                  fThu = "Ch" & ChrW$(7911) & " " & DayWeek(WeekNum) & " "
            Case 2 To 7
                  fThu = "Th" & ChrW$(7913) & " " & DayWeek(WeekNum) & " "
            Case Else
                  GoTo ExitFunction
            End Select
      Exit Function
ExitFunction:
      fThu = ""
End Function

Giờ đây khi show lịch thì nó sẽ như thế này:

Picture1.jpg
- Có thêm "Thứ Ba" trên Calendar -

Các bạn tải file mới nhất tại bài 2 của topic này (đã update):

http://www.giaiphapexcel.com/forum/...n-ích-CALENDAR-tuyệt-đẹp!&p=451406#post451406
 

File đính kèm

  • Picture2.jpg
    Picture2.jpg
    3.2 KB · Đọc: 828
Lần chỉnh sửa cuối:
Upvote 0
Đồng thời, tôi cũng thêm một hàm Thứ trong tuần để hiển thị trên Label Dương Lịch:

PHP:
Function fThu(ByVal WeekNum) As String
      Dim DayWeek As Variant
      DayWeek = Array("", "Nh" & ChrW$(7853) & "t", "Hai", _
                          "Ba", "T" & ChrW$(432), _
                          "N" & ChrW$(259) & "m", "Sáu", _
                          "B" & ChrW$(7843) & "y")
      Select Case WeekNum
            Case 1
                  fThu = "Ch" & ChrW$(7911) & " " & DayWeek(WeekNum) & " "
            Case 2 To 7
                  fThu = "Th" & ChrW$(7913) & " " & DayWeek(WeekNum) & " "
            Case Else
                  GoTo ExitFunction
            End Select
      Exit Function
ExitFunction:
      fThu = ""
End Function
Trong UserForm có đoạn:
Mã:
.Caption = [COLOR=#ff0000]fThu[/COLOR](intCol) & DateSerial(iYear, iMonth, Day)
Với fThu chính là Function mà Nghĩa vừa viết
Nếu tôi sửa thế này thì sao:
Mã:
.Caption = Evaluate("Text(" & intCol & ", ""[$-42A]dddd "")") & DateSerial(iYear, iMonth, Day)
Tức là không cần đến Function vừa viết?
 
Upvote 0
Trong UserForm có đoạn:
Mã:
.Caption = [COLOR=#ff0000]fThu[/COLOR](intCol) & DateSerial(iYear, iMonth, Day)
Với fThu chính là Function mà Nghĩa vừa viết
Nếu tôi sửa thế này thì sao:
Mã:
.Caption = Evaluate("Text(" & intCol & ", ""[$-42A]dddd "")") & DateSerial(iYear, iMonth, Day)
Tức là không cần đến Function vừa viết?

Dạ, rất hay, vậy là ta có thể dùng hàm Evaluate để chuyển hàm Text trong Excel thay vì phải dùng đến WorksheetFunction. Có một điều em vẫn không thích kiểu định dạng này là vì đối với Excel 2003 trở về trước, thay vì là Chủ Nhật nó viết toàn bộ bằng chữ thường chủ nhật (phải thêm hàm PROPER vào nữa). Điều thứ hai em vẫn muốn nó xài rộng hơn cả Excel nên em không muốn lệ thuộc vào hàm của Excel.

Thay vì em dùng hàm cũ:

Mã:
Function fThu(ByVal WeekNum) As String
      Dim DayWeek As Variant
      DayWeek = Array("", "Nh" & ChrW$(7853) & "t", "Hai", _
                          "Ba", "T" & ChrW$(432), _
                          "N" & ChrW$(259) & "m", "Sáu", _
                          "B" & ChrW$(7843) & "y")
      Select Case WeekNum
            Case 1
                  fThu = "Ch" & ChrW$(7911) & " " & DayWeek(WeekNum) & " "
            Case 2 To 7
                  fThu = "Th" & ChrW$(7913) & " " & DayWeek(WeekNum) & " "
            Case Else
                  GoTo ExitFunction
            End Select
      Exit Function
ExitFunction:
      fThu = ""
End Function

Bây giờ em viết lại hàm đó như sau:

Mã:
Function DayInWeek(ByVal TheDate As Date) As String
      Dim DayWeek As Variant, str As String
      str = "Th" & ChrW$(7913)
      DayWeek = Array("", "Ch" & ChrW$(7911) & " Nh" & ChrW$(7853) & "t", _
                          str & " Hai", _
                          str & " Ba", _
                          str & " T" & ChrW$(432), _
                          str & " N" & ChrW$(259) & "m", _
                          str & " Sáu", _
                          str & " B" & ChrW$(7843) & "y")
     [COLOR=#800080][B] DayInWeek [/B][/COLOR][COLOR=#0000ff][B]= DayWeek(WeekDay(TheDate)) [/B][/COLOR][COLOR=#ff0000][B]& " " & TheDate[/B][/COLOR]
End Function

(Với hàm này ta có thể mở rộng ra làm kiểu định dạng chung cho ngày tháng, như thế này:

Function DayInWeek(ByVal TheDate As Date, Byval KieuDinhDang As String) As String

và cách dùng: DayInWeek(Date,"dd/mm/yyyy") chẳng hạn).

Và cái thủ tục:

Mã:
.Caption = [COLOR=#ff0000]fThu[/COLOR](intCol) & DateSerial(iYear, iMonth, Day)

sẽ được sửa lại như sau:

Mã:
.Caption = [COLOR=#ff0000]DayInWeek[/COLOR](DateSerial(iYear, iMonth, Day))


Và thủ tục xử lý ngày sẽ được loại bỏ công đoạn tìm số ngày trong cột như sau:

Loại bỏ: Dim intCol As Byte

và: intCol = Right(mstrSelected, 1)


Giờ đơn giản hơn một chút với thủ tục dưới đây:

Mã:
Private Sub HandleIndent(strNewSelect As String)
      If ErrHdle = 0 Then
HdleIdnt:
            If Len(mstrSelected) > 0 Then
                  With Me(mstrSelected)
                        .BorderStyle = 0
                        .Font.Size = 11
                        .Font.Bold = False
                        .BackStyle = 1
                  End With
                  Me(Replace(mstrSelected, "lbl", "AL")).Font.Bold = False
            End If
            
            mstrSelected = strNewSelect
            
            Me(Replace(mstrSelected, "lbl", "AL")).Font.Bold = True
            
            With Me(mstrSelected)
                  .Font.Bold = True
                  .Font.Size = 12
                  .BorderStyle = 1
                  
                  If Me(mstrSelected) = mintDayToday And iMonth = mintMonthToday And iYear = mintYearToday Then
                        .BackStyle = 1
                  Else
                        .BackStyle = 0
                  End If
                  
                  Day = .Caption
            End With
            
            With LbSolar
                  [B][COLOR=#0000cd].Caption = [/COLOR][COLOR=#ff0000]DayInWeek[/COLOR][COLOR=#0000cd](DateSerial(iYear, iMonth, Day))[/COLOR][/B]
                  .BackColor = Me(mstrSelected).BackColor
                  .ForeColor = Me(mstrSelected).ForeColor
            End With
            
            With LbLunar
                  .Caption = AmLich(DateSerial(iYear, iMonth, Day))
                  .BackColor = Me(mstrSelected).BackColor
                  .ForeColor = Me(Replace(mstrSelected, "lbl", "AL")).ForeColor
            End With
      Else
            LbSolar_Click
            GoTo HdleIdnt
      End If
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Dạ, rất hay, vậy là ta có thể dùng hàm Evaluate để chuyển hàm Text trong Excel thay vì phải dùng đến WorksheetFunction. Có một điều em vẫn không thích kiểu định dạng này là vì đối với Excel 2003 trở về trước, thay vì là Chủ Nhật nó viết toàn bộ bằng chữ thường chủ nhật (phải thêm hàm PROPER vào nữa). Điều thứ hai em vẫn muốn nó xài rộng hơn cả Excel nên em không muốn lệ thuộc vào hàm của Excel.

Tùy chuyện, tùy theo mức độ ứng dụng
Bạn thử nghĩ cái calendar của bạn sẽ ứng dụng vào đâu ngoài Excel và ứng dụng như thế nào?
 
Upvote 0
Tùy chuyện, tùy theo mức độ ứng dụng
Bạn thử nghĩ cái calendar của bạn sẽ ứng dụng vào đâu ngoài Excel và ứng dụng như thế nào?

Em cũng chẳng biết, nhưng em vẫn thường nghe Thầy khuyên là đã viết hàm cho VBA, nếu không thể, thì không nên lệ thuộc hoặc dùng hàm của Excel; vì xa hơn có thể dùng trong môi trường VBA khác.

Cho nên em mới nghĩ ra như thế thôi.
 
Upvote 0
Em cũng chẳng biết, nhưng em vẫn thường nghe Thầy khuyên là đã viết hàm cho VBA, nếu không thể, thì không nên lệ thuộc hoặc dùng hàm của Excel; vì xa hơn có thể dùng trong môi trường VBA khác.

Cho nên em mới nghĩ ra như thế thôi.

Ví dụ thế này:
- Bạn viết hàm Sort dữ liệu
- Bạn viết hàm đổi số thành chữ
vân vân... đương nhiên bạn phải nhìn xa hơn để có thể ứng dụng nó ngoài Excel
Còn cái Calendar này nếu muốn ứng dụng xa hơn nữa phải tạo nó thành 1 OCX ---> Ẹc... Ẹc... trình độ của mình chắc hổng chơi được (ít nhất là trình độ của tôi không dám chơi)
------------------
Bây giờ chỉ nói trong nội bộ của Excel thôi, Nghĩa là có thể cho tôi biết cái calendar của Nghĩa ứng dụng vào việc gì không? Hay chỉ để nhìn chơi thôi?
Ví dụ trường hợp tôi không cài được MSCAL.OCX, vậy tôi sẽ dùng cái calendar của Nghĩa như thế nào?
 
Upvote 0
Có 1 nhận xét nho nhỏ:
Mấy cái nút tròn be bé xinh xinh kia (dùng để chọn tháng, năm) nhấn vào nó giựt màn hình cái đùng. Cho nên đẹp thì đẹp nhưng thua cái control scrollbar hoặc Spin Button.
 
Upvote 0
Có 1 nhận xét nho nhỏ:
Mấy cái nút tròn be bé xinh xinh kia (dùng để chọn tháng, năm) nhấn vào nó giựt màn hình cái đùng. Cho nên đẹp thì đẹp nhưng thua cái control scrollbar hoặc Spin Button.

Có thể nó chạy trên nhiều Label quá để tính hơn 84 cái và duyệt màu, duyệt số nên nó cứ phải chớp, em thử dùng me.repaint nhưng nó còn chớp bạo hơn. Cái này bó tay.
 
Upvote 0
Em cũng chẳng biết, nhưng em vẫn thường nghe Thầy khuyên là đã viết hàm cho VBA, nếu không thể, thì không nên lệ thuộc hoặc dùng hàm của Excel; vì xa hơn có thể dùng trong môi trường VBA khác.

Cho nên em mới nghĩ ra như thế thôi.

Tôi thử export Form và module ra và mở bằng VB6:
- Form không thể hiện hết các control
- form size chỉ bằng với 1 hàng control trên cùng

Do đó không test được các chức năng khác. Sau khi sửa 1 tí tẹo cho nó maximize để test thì được.

Calendar01.jpg


Calendar02.jpg


Thực tế mà nhận xét:
- Code quá phức tạp vì cố gắng dùng quá nhiều chức năng trong 1 form như: dấu form control, sử dụng quá nhiều event mouse move, keypress, keydown,
- Chỉ vì 1 chức năng click đóng form mà phải viết 56 sub giống nhau (Có thể dùng Class thay vào)

Quan điểm cá nhân tôi:

- Code càng đơn giản càng tốt
- Chỉ chọn và sử dụng chức năng cần thiết nhất
 
Upvote 0
Ví dụ thế này:
- Bạn viết hàm Sort dữ liệu
- Bạn viết hàm đổi số thành chữ
vân vân... đương nhiên bạn phải nhìn xa hơn để có thể ứng dụng nó ngoài Excel
Còn cái Calendar này nếu muốn ứng dụng xa hơn nữa phải tạo nó thành 1 OCX ---> Ẹc... Ẹc... trình độ của mình chắc hổng chơi được (ít nhất là trình độ của tôi không dám chơi)
------------------
Bây giờ chỉ nói trong nội bộ của Excel thôi, Nghĩa là có thể cho tôi biết cái calendar của Nghĩa ứng dụng vào việc gì không? Hay chỉ để nhìn chơi thôi?
Ví dụ trường hợp tôi không cài được MSCAL.OCX, vậy tôi sẽ dùng cái calendar của Nghĩa như thế nào?

Có thể nói cái lịch này là một tiện ích "có thể" thay thế được với control Caledar của Excel VBA, giao diện thân thiện hơn, dễ chỉnh sửa, nói chung là dễ cá nhân hóa nó theo ý thích.

Nhập ngày tháng nhanh chóng bất cứ ở đâu, trên form hoặc trên sheet

Coi ngày tháng Âm lịch từ ngày 01/02/1900 (DL) đến 14/2/2200 (DL)

Nhập liệu nhanh chóng trên sheet thì chúng ta có thể làm một nút lệnh trên Cell Menu như sau:

Trong Module ThisWorkBook, đặt 2 thủ tục này để tạo Menu:

Mã:
Private Sub Workbook_Activate()
    With Application.CommandBars("Cell")
        .Reset
        .Controls("cut").BeginGroup = True
        .Controls.Add(1, , , 1).Caption = "Calendar"
        With .Controls("Calendar")
            .Style = 3
            .FaceId = 59
            .BeginGroup = True
            .OnAction = "CalShow"
        End With
    End With
End Sub

Private Sub Workbook_Deactivate()
    Application.CommandBars("Cell").Reset
End Sub

Khi click chuột phải sẽ như thế này:

attachment.php


Sau khi chọn vào Calendar thì lịch được show như vầy:

attachment.php


Chỉ việc bấm chọn ngày tháng cần thiết vào ô hoặc khối ô được chọn, chỉ với thủ tục như thế này thôi:

Mã:
Sub CalShow()
      Dim Ftop As Double, Fleft As Double
      With Selection
            Fleft = .Left [COLOR=#ff0000]+ 22[/COLOR] [COLOR=#008000]'Màu đỏ có thể chưa chính xác cho từng loại Window[/COLOR]
            Ftop = .Top + .Height[COLOR=#ff0000] + 110[/COLOR]
            With UsfCalendar
                  .StartUpPosition = 0
                  .Top = Ftop
                  .Left = Fleft
            End With
            .Value = DatePicked(.Value)
      End With
End Sub

=======================================================

Xa hơn nữa, sẽ định cải tiến trên cơ sở dữ liệu (nhỏ thôi) các ghi chú, sinh nhật, nhắc nhở v.v...

Mà thôi, thấy chẳng ai bận tâm, thậm chí chỉ một vài người cám ơn (mặc dù đã tải hơn 120 lần) nên chẳng muốn cải tiến tí nào!
 

File đính kèm

  • Picture1.jpg
    Picture1.jpg
    34.4 KB · Đọc: 198
  • Picture2.jpg
    Picture2.jpg
    17.4 KB · Đọc: 197
Lần chỉnh sửa cuối:
Upvote 0
Tôi thử export Form và module ra và mở bằng VB6:
- Form không thể hiện hết các control
- form size chỉ bằng với 1 hàng control trên cùng

Do đó không test được các chức năng khác. Sau khi sửa 1 tí tẹo cho nó maximize để test thì được.

Calendar01.jpg


Calendar02.jpg


Thực tế mà nhận xét:
- Code quá phức tạp vì cố gắng dùng quá nhiều chức năng trong 1 form như: dấu form control, sử dụng quá nhiều event mouse move, keypress, keydown,
- Chỉ vì 1 chức năng click đóng form mà phải viết 56 sub giống nhau (Có thể dùng Class thay vào)

Quan điểm cá nhân tôi:

- Code càng đơn giản càng tốt
- Chỉ chọn và sử dụng chức năng cần thiết nhất
Thật sự em muốn biết cách viết ClassModule trong trường hợp này như thế nào. Trước nay thấy mọi người dùng, em thích lắm nhưng chưa biết cách vận hành như thế nào.

Sư phụ vui lòng hướng dẫn em trong trường hợp này không? Xin Cảm ơn rất nhiều.
 
Upvote 0
Có thể nói cái lịch này là một tiện ích "có thể" thay thế được với control Caledar của Excel VBA, giao diện thân thiện hơn, dễ chỉnh sửa, nói chung là dễ cá nhân hóa nó theo ý thích.

Không ai phủ nhận những cố gắng và những thành tựu của Nghĩa. Tôi chỉ đưa ra những ý kiến nhận xét riêng. Thêm nữa đây, (có thể đắng):

- Nếu để thay thế calendar có sẵn, thì tại sao không sử dụng cái có sẵn?
- Giao diện đẹp hơn, đúng, nhưng không thấy "thân thiện" hơn: Cũng click chọn ngày, click chọn tháng, click chọn năm, cũng thể hiện thứ, ngày tháng theo thứ tự cùng kiểu.
- Được cái xem ngày âm lịch, nhưng cũng chỉ để xem như nhiều lịch khác trên gpe.
- Code hiện tại có thể nói là đã rất phức tạp, không dễ "cá nhân hóa theo ý thích" đâu.
 
Upvote 0
Class ít sử dụng nên quên mất tiêu rồi. Nhưng trường hợp này không khó, đọc sơ qua code "trúc xanh trên form" của Kyo là làm được, vì nó sử dụng class cho command button tương tự bài này.
 
Upvote 0
Web KT
Back
Top Bottom