LẬP BẢNG CHẤM CÔNG TRONG EXCEL

Liên hệ QC

nobitaone

Thành viên mới
Tham gia
22/8/21
Bài viết
15
Được thích
0
Nghề nghiệp
bác sỹ RHM
Chào các bạn . mình tạo một file excel bảng chấm công, nhưng rối ở phần vba " thêm tháng mới" mình k biết sai ở đâu, mong các bạn chỉ bảo và chỉnh sửa giúp mình . mình xin cảm ơn
 

File đính kèm

File đính kèm

Bạn kiểm tra thử nhé.
Thủ tục TaoThangMoi nếu người dùng sử dụng nút Thêm để hiện cái InputBox nhưng đột nhiên không muốn thêm nữa mà bấm Cancel hoặc nút Close (X) thì sẽ phát sinh ra lỗi, vì thế bạn cần bẫy lỗi ở chỗ này!

Thay Sub cũ bằng Sub dưới đây:

Mã:
Sub Taothangmoi()
    Dim Tensheetmoi As String, NgayCu As Date
    Tensheetmoi = InputBox("Nhap ten sheet moi")
    If Tensheetmoi = "" Then
        MsgBox "Ban da huy lenh!", vbCritical + vbOKOnly, "Thông Báo"
        Exit Sub
    End If
    NgayCu = Range("R4").Value
    ActiveSheet.Copy after:=Worksheets(Worksheets.Count)
    Worksheets(Worksheets.Count).Name = Tensheetmoi
    With Sheets(Tensheetmoi)
        .Range("C8:AG27").ClearContents
        .Range("R4").Value = WorksheetFunction.EoMonth(NgayCu, 0) + 1
    End With
    MsgBox "Xong!"
End Sub
 
Thủ tục TaoThangMoi nếu người dùng sử dụng nút Thêm để hiện cái InputBox nhưng đột nhiên không muốn thêm nữa mà bấm Cancel hoặc nút Close (X) thì sẽ phát sinh ra lỗi, vì thế bạn cần bẫy lỗi ở chỗ này!

Thay Sub cũ bằng Sub dưới đây:

Mã:
Sub Taothangmoi()
    Dim Tensheetmoi As String, NgayCu As Date
    Tensheetmoi = InputBox("Nhap ten sheet moi")
    If Tensheetmoi = "" Then
        MsgBox "Ban da huy lenh!", vbCritical + vbOKOnly, "Thông Báo"
        Exit Sub
    End If
    NgayCu = Range("R4").Value
    ActiveSheet.Copy after:=Worksheets(Worksheets.Count)
    Worksheets(Worksheets.Count).Name = Tensheetmoi
    With Sheets(Tensheetmoi)
        .Range("C8:AG27").ClearContents
        .Range("R4").Value = WorksheetFunction.EoMonth(NgayCu, 0) + 1
    End With
    MsgBox "Xong!"
End Sub
Cảm ơn anh, em sơ xuất không thử trường hợp đấy anh ạ.
 
Cảm ơn anh, em sơ xuất không thử trường hợp đấy anh ạ.
Bỏ câu lệnh khi nãy tôi sửa cho bạn đi, thay bằng câu lệnh dưới đây, bởi cái thằng InputBox của VBA dưới kiểu dữ liệu String nó ngu chỗ này, nếu OK mà chưa đặt tên sheet thì nó là giá trị rỗng và nếu Cancel nó cũng là giá tri rỗng nên ta thay nó bằng cái của Application, bạn có thể đặt tiếng Việt cho các thông báo của nó, và thích hơn là nó vừa mượt mà đẹp mắt mà còn khi bấm vào Cancel thì giá trị của nó là False! Lợi dụng chỗ này ta sẽ bẫy lỗi, nếu nó trống mà bấm OK thì ta sẽ thông báo để nó đặt tên lại, còn bấm Cancel thì nó sẽ hủy lệnh.

Hãy làm như sau:

Mã:
Sub Taothangmoi()
    Dim Tensheetmoi As String, NgayCu As Date
NhapTenSheet:
    Tensheetmoi = Application.InputBox("Nh" & ChrW(7853) & "p t" & ChrW(234) & "n sheet m" & _
                  ChrW(7899) & "i", "Nh" & ChrW(7853) & "p t" & ChrW(234) & "n sheet")
    
    If Tensheetmoi = "False" Then
        MsgBox "Ban da huy lenh!", vbCritical + vbOKOnly, "Thông Báo"
        Exit Sub
    End If
    
    If Tensheetmoi = "" Then
        MsgBox "Ban phai nhap tên sheet!", vbInformation + vbOKOnly, "Thông Báo"
        GoTo NhapTenSheet
    End If
    
    NgayCu = Range("R4").Value
    ActiveSheet.Copy after:=Worksheets(Worksheets.Count)
    Worksheets(Worksheets.Count).Name = Tensheetmoi
    With Sheets(Tensheetmoi)
        .Range("C8:AG27").ClearContents
        .Range("R4").Value = WorksheetFunction.EoMonth(NgayCu, 0) + 1
    End With
    MsgBox "Xong!"
End Sub
 
Bỏ câu lệnh khi nãy tôi sửa cho bạn đi, thay bằng câu lệnh dưới đây, bởi cái thằng InputBox của VBA dưới kiểu dữ liệu String nó ngu chỗ này, nếu OK mà chưa đặt tên sheet thì nó là giá trị rỗng và nếu Cancel nó cũng là giá tri rỗng nên ta thay nó bằng cái của Application, bạn có thể đặt tiếng Việt cho các thông báo của nó, và thích hơn là nó vừa mượt mà đẹp mắt mà còn khi bấm vào Cancel thì giá trị của nó là False! Lợi dụng chỗ này ta sẽ bẫy lỗi, nếu nó trống mà bấm OK thì ta sẽ thông báo để nó đặt tên lại, còn bấm Cancel thì nó sẽ hủy lệnh.

Hãy làm như sau:

Mã:
Sub Taothangmoi()
    Dim Tensheetmoi As String, NgayCu As Date
NhapTenSheet:
    Tensheetmoi = Application.InputBox("Nh" & ChrW(7853) & "p t" & ChrW(234) & "n sheet m" & _
                  ChrW(7899) & "i", "Nh" & ChrW(7853) & "p t" & ChrW(234) & "n sheet")
   
    If Tensheetmoi = "False" Then
        MsgBox "Ban da huy lenh!", vbCritical + vbOKOnly, "Thông Báo"
        Exit Sub
    End If
   
    If Tensheetmoi = "" Then
        MsgBox "Ban phai nhap tên sheet!", vbInformation + vbOKOnly, "Thông Báo"
        GoTo NhapTenSheet
    End If
   
    NgayCu = Range("R4").Value
    ActiveSheet.Copy after:=Worksheets(Worksheets.Count)
    Worksheets(Worksheets.Count).Name = Tensheetmoi
    With Sheets(Tensheetmoi)
        .Range("C8:AG27").ClearContents
        .Range("R4").Value = WorksheetFunction.EoMonth(NgayCu, 0) + 1
    End With
    MsgBox "Xong!"
End Sub
Hay quá anh, anh cho em hỏi ở code của bài đầu sao nhấn cancel ở inputbox mà vẫn báo lỗi anh nhỉ.
 
Hay quá anh, anh cho em hỏi ở code của bài đầu sao nhấn cancel ở inputbox mà vẫn báo lỗi anh nhỉ.
Tên sheet không được để trống, nếu để trống sẽ bị lỗi.

Như vậy bạn cần phải có những kiểu bẫy lỗi đặc biệt khác như:

1) Trùng tên sheet

2) Ngăn không cho nhập các ký tự đặc biệt mà Excel quy định.

Bạn thử bẫy lỗi cho tôi xem. Coi như bạn học tập về bẫy lỗi trên bài này đi, sai đâu tôi sửa cho bạn.

Dưới đây là hình ảnh các ký tự đặc biệt mà Excel ngăn bạn đặt tên sheet mà dùng chúng:

1631120546849.png
 
Tên sheet không được để trống, nếu để trống sẽ bị lỗi.
Như vậy bạn cần phải có những kiểu bẫy lỗi đặc biệt khác như:
1) Trùng tên sheet
2) Ngăn không cho nhập các ký tự đặc biệt mà Excel quy định.
Bạn thử bẫy lỗi cho tôi xem. Coi như bạn học tập về bẫy lỗi trên bài này đi, sai đâu tôi sửa cho bạn.
Dưới đây là hình ảnh các ký tự đặc biệt mà Excel ngăn bạn đặt tên sheet mà dùng chúng:
View attachment 265692
Em thử bẫy lỗi như trong file đính kèm dưới đây, anh xem giúp và hướng dẫn em với ạ, xin cảm ơn anh.
 

File đính kèm

Em thử bẫy lỗi như trong file đính kèm dưới đây, anh xem giúp và hướng dẫn em với ạ, xin cảm ơn anh.

Tôi khen ngợi tinh thần vừa học vừa thực hành của bạn!

Tuy nhiên ở bài số #7 tôi có chụp cái hình cho bạn và note 2 vấn đề trong 2 ô màu xanh và màu đỏ, bạn mới chỉ thực hiện màu đỏ mà chưa thực hiện màu xanh.

Về phần màu đỏ, có thể bạn chưa dùng hoặc chưa biết về hàm InStr nên bạn xử lý với hàm Mid khá vụng về.

Về phần tên sheet trùng bạn làm rất tốt!

Tuy nhiên tôi đã gợi ý cho bạn dùng nhãn NhapTenSheet để Goto cho nó quay đầu lặp lại việc hiện cái InputBox thay vì dùng Exit Sub để thoát Sub và phải thao tác bấm lại nút lệnh.

Dưới đây là cách mà tôi bẫy lỗi đối với việc nhập tên sheet mới:

Mã:
Sub Taothangmoi_3()
    Dim Tensheetmoi As String, NgayCu As Date
NhapTenSheet:
    Tensheetmoi = Application.InputBox("Nh" & ChrW(7853) & "p t" & ChrW(234) & "n sheet m" & _
                  ChrW(7899) & "i", "Nh" & ChrW(7853) & "p t" & ChrW(234) & "n sheet")
  
    If Tensheetmoi = "False" Then
        MsgBox "Ban da huy lenh!", vbCritical + vbOKOnly, "Thông Báo"
        Exit Sub
    End If
  
    If Tensheetmoi = "" Then
        MsgBox "Ban phai nhap tên sheet!", vbInformation + vbOKOnly, "Thông Báo"
        GoTo NhapTenSheet
    End If
  
    If Len(Tensheetmoi) > 31 Then
        MsgBox "Tên sheet không duoc dài quá 31 ký tu! Ban phai nhap lai!", vbCritical + vbOKOnly, "Thông Báo"
        GoTo NhapTenSheet
    End If
  
    Dim c As Long
    Dim arrSpecChar
  
    arrSpecChar = Array(":", "\", "/", "?", "*", "[", "]")
  
    For c = 0 To 6
        If InStr(Tensheetmoi, arrSpecChar(c)) Then
            MsgBox "Tên sheet không duoc chua các ký tu dac biet:  : \ / ? * [ ]", vbCritical + vbOKOnly, "Thông Báo"
            GoTo NhapTenSheet
        End If
    Next
  
    For c = 1 To Worksheets.Count
        If Sheets(c).Name = Tensheetmoi Then
            MsgBox "Ban không duoc nhap trùng tên sheet da có, vui lòng nhap tên khác!", vbCritical + vbOKOnly, "Thông Báo"
            GoTo NhapTenSheet
        End If
    Next
  
    NgayCu = Range("R4").Value
    ActiveSheet.Copy after:=Worksheets(Worksheets.Count)
    Worksheets(Worksheets.Count).Name = Tensheetmoi
    With Sheets(Tensheetmoi)
        .Range("C8:AG27").ClearContents
        .Range("R4").Value = WorksheetFunction.EoMonth(NgayCu, 0) + 1
    End With
    MsgBox "Xong!"
End Sub
 
Lần chỉnh sửa cuối:
Tôi khen ngợi tinh thần vừa học vừa thực hành của bạn!

Tuy nhiên ở bài số #7 tôi có chụp cái hình cho bạn và note 2 vấn đề trong 2 ô màu xanh và màu đỏ, bạn mới chỉ thực hiện màu đỏ mà chưa thực hiện màu xanh.

Về phần màu đỏ, có thể bạn chưa dùng hoặc chưa biết về hàm InStr nên bạn xử lý với hàm Mid khá vụng về.
Về phần tên sheet trùng bạn làm rất tốt!
Tuy nhiên tôi đã gợi ý cho bạn dùng nhãn NhapTenSheet để Goto để nó quay đầu lặp lại việc hiện lại cái InputBox thay vì dùng Exit Sub để thoát Sub và phải thao tác bấm lại nút lệnh.
Dưới đây là cách mà tôi bẫy lỗi đối với việc nhập tên sheet mới:

Mã:
Sub Taothangmoi_3()
    Dim Tensheetmoi As String, NgayCu As Date
NhapTenSheet:
    Tensheetmoi = Application.InputBox("Nh" & ChrW(7853) & "p t" & ChrW(234) & "n sheet m" & _
                  ChrW(7899) & "i", "Nh" & ChrW(7853) & "p t" & ChrW(234) & "n sheet")
  
    If Tensheetmoi = "False" Then
        MsgBox "Ban da huy lenh!", vbCritical + vbOKOnly, "Thông Báo"
        Exit Sub
    End If
  
    If Tensheetmoi = "" Then
        MsgBox "Ban phai nhap tên sheet!", vbInformation + vbOKOnly, "Thông Báo"
        GoTo NhapTenSheet
    End If
  
    If Len(Tensheetmoi) > 31 Then
        MsgBox "Tên sheet không duoc dai quá 31 ký tu! Ban phai nhap lai!", vbCritical + vbOKOnly, "Thông Báo"
        GoTo NhapTenSheet
    End If
  
    Dim c As Long
    Dim arrSpecChar
  
    arrSpecChar = Array(":", "\", "/", "?", "*", "[", "]")
  
    For c = 0 To 6
        If InStr(Tensheetmoi, arrSpecChar(c)) Then
            MsgBox "Tên sheet không duoc chua các ký tu dac biet:  : \ / ? * [ ]", vbCritical + vbOKOnly, "Thông Báo"
            GoTo NhapTenSheet
        End If
    Next
  
    For c = 1 To Worksheets.Count
        If Sheets(c).Name = Tensheetmoi Then
            MsgBox "Ban không duoc nhap trùng tên sheet da có, vui lòng nhap tên khác!", vbCritical + vbOKOnly, "Thông Báo"
            GoTo NhapTenSheet
        End If
    Next
  
    NgayCu = Range("R4").Value
    ActiveSheet.Copy after:=Worksheets(Worksheets.Count)
    Worksheets(Worksheets.Count).Name = Tensheetmoi
    With Sheets(Tensheetmoi)
        .Range("C8:AG27").ClearContents
        .Range("R4").Value = WorksheetFunction.EoMonth(NgayCu, 0) + 1
    End With
    MsgBox "Xong!"
End Sub
Dạ, xin cảm ơn anh đã nhiệt tình chỉ bảo, em sẽ tìm hiểu code của anh để khắc phục những điểm em còn yếu hoặc chưa biết ạ. Chân thành cảm ơn anh.
 
mình cảm ơn các bạn rất nhiều ah . tiện trên file mình còn một cái đang lỗi mà mình đã viết sẵn code trong sheet . " khi thay đổi tháng các giá trị ngày thừa k bị ẩn đi mà vẫn xuất hiện 01 , 02, 03
vidu thay tháng 9 bằng tháng 2 thì các cột vẫn k mất đi . nhờ các bạn xem lại code mình viết sai ở đâu ah
xin cảm ơn
Bài đã được tự động gộp:

Tôi khen ngợi tinh thần vừa học vừa thực hành của bạn!

Tuy nhiên ở bài số #7 tôi có chụp cái hình cho bạn và note 2 vấn đề trong 2 ô màu xanh và màu đỏ, bạn mới chỉ thực hiện màu đỏ mà chưa thực hiện màu xanh.

Về phần màu đỏ, có thể bạn chưa dùng hoặc chưa biết về hàm InStr nên bạn xử lý với hàm Mid khá vụng về.

Về phần tên sheet trùng bạn làm rất tốt!

Tuy nhiên tôi đã gợi ý cho bạn dùng nhãn NhapTenSheet để Goto cho nó quay đầu lặp lại việc hiện cái InputBox thay vì dùng Exit Sub để thoát Sub và phải thao tác bấm lại nút lệnh.

Dưới đây là cách mà tôi bẫy lỗi đối với việc nhập tên sheet mới:

Mã:
Sub Taothangmoi_3()
    Dim Tensheetmoi As String, NgayCu As Date
NhapTenSheet:
    Tensheetmoi = Application.InputBox("Nh" & ChrW(7853) & "p t" & ChrW(234) & "n sheet m" & _
                  ChrW(7899) & "i", "Nh" & ChrW(7853) & "p t" & ChrW(234) & "n sheet")
 
    If Tensheetmoi = "False" Then
        MsgBox "Ban da huy lenh!", vbCritical + vbOKOnly, "Thông Báo"
        Exit Sub
    End If
 
    If Tensheetmoi = "" Then
        MsgBox "Ban phai nhap tên sheet!", vbInformation + vbOKOnly, "Thông Báo"
        GoTo NhapTenSheet
    End If
 
    If Len(Tensheetmoi) > 31 Then
        MsgBox "Tên sheet không duoc dài quá 31 ký tu! Ban phai nhap lai!", vbCritical + vbOKOnly, "Thông Báo"
        GoTo NhapTenSheet
    End If
 
    Dim c As Long
    Dim arrSpecChar
 
    arrSpecChar = Array(":", "\", "/", "?", "*", "[", "]")
 
    For c = 0 To 6
        If InStr(Tensheetmoi, arrSpecChar(c)) Then
            MsgBox "Tên sheet không duoc chua các ký tu dac biet:  : \ / ? * [ ]", vbCritical + vbOKOnly, "Thông Báo"
            GoTo NhapTenSheet
        End If
    Next
 
    For c = 1 To Worksheets.Count
        If Sheets(c).Name = Tensheetmoi Then
            MsgBox "Ban không duoc nhap trùng tên sheet da có, vui lòng nhap tên khác!", vbCritical + vbOKOnly, "Thông Báo"
            GoTo NhapTenSheet
        End If
    Next
 
    NgayCu = Range("R4").Value
    ActiveSheet.Copy after:=Worksheets(Worksheets.Count)
    Worksheets(Worksheets.Count).Name = Tensheetmoi
    With Sheets(Tensheetmoi)
        .Range("C8:AG27").ClearContents
        .Range("R4").Value = WorksheetFunction.EoMonth(NgayCu, 0) + 1
    End With
    MsgBox "Xong!"
End Sub
em cảm ơn các anh rất nhiều. anh xem lại giúp em phần code e viết sẵn trong sheet, nhưng bi lỗi. " code do đai loại là em muốn khắc phục lỗi khi nhập tháng khác thì sẽ ẩn đi những cột trong tháng đó k có" như tháng 9 có 30 ngày nhưng vẫn hiện ngày 01. em muốn ẩn hiện cột đó theo tháng đủ và thiếu ah . xin cảm ơn
 

File đính kèm

Lần chỉnh sửa cuối:
mình cảm ơn các bạn rất nhiều ah . tiện trên file mình còn một cái đang lỗi mà mình đã viết sẵn code trong sheet . " khi thay đổi tháng các giá trị ngày thừa k bị ẩn đi mà vẫn xuất hiện 01 , 02, 03
vidu thay tháng 9 bằng tháng 2 thì các cột vẫn k mất đi . nhờ các bạn xem lại code mình viết sai ở đâu ah
xin cảm ơn
Bạn đã mặc định vùng in rồi, nếu xóa bỏ cột thừa của tháng không đủ 31 ngày thì sẽ sai vùng in. Theo mình thì chỉ nên ẩn những cột đó đi thôi. Mà trong code của bạn mình có thấy đoạn nào viết về việc bỏ cột đâu mà bảo là có lỗi được bạn nhỉ.
Ghi chú: Không nên viết tắt trong bài bạn nhé.
 
Lần chỉnh sửa cuối:
Bạn đã mặc định vùng in rồi, nếu xóa bỏ cột thừa của tháng không đủ 31 ngày thì sẽ sai vùng in. Theo mình thì chỉ nên ẩn những cột đó đi thôi. Mà trong code của bạn mình có thấy đoạn nào viết về việc bỏ cột đâu mà bảo là có lỗi được bạn nhỉ.
Ghi chú: Không nên viết tắt trong bài bạn nhé.
mình viết trong sheet , bi loi nen minh nhớ lai thôi. minh viết để ẩn nhưng cột đó mà k ẩn dc ah
 
các bạn cho mình hỏi nếu mình muốn tạo một nút khi " In " đồng thời reset lai bảng chấm công k ah nếu có cho minh xin đoan code ah
minh xin cam ơn
 
các bạn cho mình hỏi nếu mình muốn tạo một nút khi " In " đồng thời reset lai bảng chấm công k ah nếu có cho minh xin đoan code ah
minh xin cam ơn
Bạn vẫn viết tắt sau 2 lần mình đã lưu ý bạn. Mình dừng ở đây, bạn chịu khó chờ bạn khác giúp nhé.
 
Bài #15 bạn ghi tắt và không dấu đó bạn, nhiều khi bạn ghi thành thói quen rồi nên không nhận ra: ah, k, ... cho minh xin đoan code ah minh xin cam.."
các bạn cho mình hỏi nếu mình muốn tạo một nút khi " In " đồng thời reset lai bảng chấm công k ah nếu có cho minh xin đoan code ah
minh xin cam ơn
 
Chào các bạn . mình tạo một file excel bảng chấm công, nhưng rối ở phần vba " thêm tháng mới" mình k biết sai ở đâu, mong các bạn chỉ bảo và chỉnh sửa giúp mình . mình xin cảm ơn
Tên sheet mới phải theo qui luật, không nên tự nhập Chạy code tạo sheet mới
Mã:
Sub CopyChamCong()
  Dim shName$, iDay As Date, i&, j&, sCol&

  iDay = Range("R4").Value
  iDay = DateSerial(Year(iDay), Month(iDay), 1)
  For i = 1 To 100
    shName = "Thang " & Format(DateAdd("m", i, iDay), "m") 'Nen thay bang lenh duoi
    'shName = "Thang " & Format(DateAdd("m", i, iDay), "m-yy")
    For j = 1 To Worksheets.Count
      If Sheets(j).Name = shName Then Exit For
    Next j
    If j = Worksheets.Count + 1 Then
      ActiveSheet.Copy after:=Worksheets(Worksheets.Count)
      Worksheets(Worksheets.Count).Name = shName
      With Sheets(shName)
        .Range(.Cells(1, 30), .Cells(1, 33)).EntireColumn.Hidden = False
        .Range("C8:AG27").ClearContents
        .Range("R4").Value = DateAdd("m", i, iDay)
        sCol = DateAdd("m", i + 1, iDay) - DateAdd("m", i, iDay)
        If sCol < 31 Then .Range(.Cells(1, sCol + 3), .Cells(1, 33)).EntireColumn.Hidden = True
      End With
      MsgBox "Xong!"
      Exit For
    End If
  Next i
End Sub
Không nên viết tắt "viết tắt là sao bạn . mình chưa hiểu lắm . mình viết chữ có câu nào viết tắt đâu ah"
 
cảm ơn các bạn nhe . nút them sheet mình thấy có một nhược điểm, đến tháng cũ trùng lặp sẽ bi lỗi sheet . nên mình nghĩ tạo nút " in" đồng thời reset lại bảng chấm công lại ban đầu . có viết được code như thế k các bạn
 
Web KT

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

Back
Top Bottom