Hỏi về cách làm bảng chấm công tự động

Liên hệ QC

ducmagic88

Thành viên chính thức
Tham gia
14/4/20
Bài viết
65
Được thích
4
Em chào các bác! Em đang có vấn đề về bảng chấm công muốn được các bác giúp đỡ ạ. Em muốn nhập dữ liệu vào ô đã tô vàng trong file từ đó sẽ tự động đánh số công như thông tin mình đã điền vào ô vàng ạ, các bác trợ giúp em với, em cảm ơn các bác nhiều ạ!
 

File đính kèm

  • bang_cham_cong_tu_dong.xlsm
    12.2 KB · Đọc: 37
Rút gọn lại và điều chỉnh vài lệnh sai
Mã:
Sub XYZAB()
  Dim sArr(), aNgay(), aThuong(), aT7(), aCN(), arr, res()
  Dim soNgay&, NgayThuong&, soT7&, soCN&
  Dim NgayLV&, lvCH&, lvT7&, NuaNgay#
  Dim sRow&, i&, j&, k&, k2&, k3&, N&, M&

  Randomize
  soNgay = DateAdd("m", 1, Range("E3")) - Range("E3")
  aNgay = Range("E3").Resize(, soNgay)
  sArr = Range("AJ7:AN" & Range("B1000").End(xlUp).Row).Value
  sRow = UBound(sArr)
  ReDim res(1 To sRow + 1, 1 To 31)
  ReDim aThuong(1 To soNgay)
  ReDim aT7(1 To 10):  ReDim aCN(1 To 10)
 
  For j = 1 To soNgay
    res(sRow + 1, j) = Weekday(aNgay(1, j), vbMonday)
    If res(sRow + 1, j) = 7 Then
      soCN = soCN + 1                                 'So ngay CN
      k = k + 1:      aCN(k) = j
    ElseIf res(sRow + 1, j) = 6 Then
      soT7 = soT7 + 1                                 'So ngay Thu 7
      k2 = k2 + 1:      aT7(k2) = j
    Else
      k3 = k3 + 1:      aThuong(k3) = j               'Mang ngay thuong
    End If
  Next j
  For i = 1 To sRow
    If sArr(i, 4) > soT7 Or sArr(i, 5) > soCN Then _
        MsgBox ("So ngay nghi T7 hoac CN sai!"): Exit Sub
    NgayThuong = soNgay - soT7 - soCN                     'So ngay thuong
    sArr(i, 4) = soT7 - sArr(i, 4)                        'So ngay lam viec thu 7
    sArr(i, 5) = soCN - sArr(i, 5)                        'So ngay lam viec CN
    sArr(i, 1) = sArr(i, 1) - sArr(i, 4) - sArr(i, 5)
    NuaNgay = NgayThuong - sArr(i, 1) - sArr(i, 2) - sArr(i, 3)             'So ngay thuong lam nua ngay
    If NuaNgay < 0 Then MsgBox ("So ngay Lam Viec va Nghi qua lon!"): Exit Sub
    NgayLV = sArr(i, 1) - NuaNgay                         'So ngay thuong lam 1 ngay
    NuaNgay = NuaNgay * 2                                 'So ngay thuong lam nua ngay
'Ngay thuong
    arr = UniqueRand(NgayThuong)
    k = 0
    Call AddRes(res, aThuong, arr, k, i, NgayLV, "X") '1 Ngay
    Call AddRes(res, aThuong, arr, k, i, NuaNgay, "X/2") 'Nua ngay
    Call AddRes(res, aThuong, arr, k, i, sArr(i, 2), "0") 'Nghi khong luong
    Call AddRes(res, aThuong, arr, k, i, sArr(i, 3), "L") 'Nghi co luong
'Thu 7
    k = 0
    N = Int(sArr(i, 4))
    M = Int(sArr(i, 4) + 0.5)
    arr = UniqueRand(soT7)
    Call AddRes(res, aT7, arr, k, i, N, "X") '1 ngay
    Call AddRes(res, aT7, arr, k, i, M - N, "X/2") 'Nua ngay
'Chu nhat
    k = 0
    N = Int(sArr(i, 5))
    M = Int(sArr(i, 5) + 0.5)
    arr = UniqueRand(soCN)
    Call AddRes(res, aCN, arr, k, i, N, "X") '1 ngay
    Call AddRes(res, aCN, arr, k, i, M - N, "X/2") 'Nua ngay
  Next i
  Range("E7").Resize(sRow, 31) = res
End Sub

Private Sub AddRes(res, sArr, arr, k, i, ByVal sCol&, ByVal strRes$)
  Dim j&
  For j = 1 To sCol
    k = k + 1
    res(i, sArr(arr(k))) = strRes
  Next j
End Sub

Function UniqueRand(ByVal N As Long) As Variant
Dim arr() As Long, i As Long, RndNum As Long, tmp As Long
ReDim arr(1 To N)
'Randomize
For i = 1 To N
    RndNum = Int(N * Rnd() + 1)
    If arr(RndNum) = 0 Then tmp = RndNum Else tmp = arr(RndNum)
    If arr(N) = 0 Then arr(RndNum) = N Else arr(RndNum) = arr(N)
    arr(N) = tmp
    N = N - 1
Next i
UniqueRand = arr
End Function
Mình thử thay số <15 thì không chạy được, mong bạn điều chỉnh để có những người chí có 10 ngày công cũng được hiển thị
Trân trọng
 

File đính kèm

  • bang_cham_cong_tu_dong (2).xlsm
    27 KB · Đọc: 4
Lần chỉnh sửa cuối:
Upvote 0
Rút gọn lại và điều chỉnh vài lệnh sai
Mã:
Sub XYZAB()
  Dim sArr(), aNgay(), aThuong(), aT7(), aCN(), arr, res()
  Dim soNgay&, NgayThuong&, soT7&, soCN&
  Dim NgayLV&, lvCH&, lvT7&, NuaNgay#
  Dim sRow&, i&, j&, k&, k2&, k3&, N&, M&

  Randomize
  soNgay = DateAdd("m", 1, Range("E3")) - Range("E3")
  aNgay = Range("E3").Resize(, soNgay)
  sArr = Range("AJ7:AN" & Range("B1000").End(xlUp).Row).Value
  sRow = UBound(sArr)
  ReDim res(1 To sRow + 1, 1 To 31)
  ReDim aThuong(1 To soNgay)
  ReDim aT7(1 To 10):  ReDim aCN(1 To 10)
 
  For j = 1 To soNgay
    res(sRow + 1, j) = Weekday(aNgay(1, j), vbMonday)
    If res(sRow + 1, j) = 7 Then
      soCN = soCN + 1                                 'So ngay CN
      k = k + 1:      aCN(k) = j
    ElseIf res(sRow + 1, j) = 6 Then
      soT7 = soT7 + 1                                 'So ngay Thu 7
      k2 = k2 + 1:      aT7(k2) = j
    Else
      k3 = k3 + 1:      aThuong(k3) = j               'Mang ngay thuong
    End If
  Next j
  For i = 1 To sRow
    If sArr(i, 4) > soT7 Or sArr(i, 5) > soCN Then _
        MsgBox ("So ngay nghi T7 hoac CN sai!"): Exit Sub
    NgayThuong = soNgay - soT7 - soCN                     'So ngay thuong
    sArr(i, 4) = soT7 - sArr(i, 4)                        'So ngay lam viec thu 7
    sArr(i, 5) = soCN - sArr(i, 5)                        'So ngay lam viec CN
    sArr(i, 1) = sArr(i, 1) - sArr(i, 4) - sArr(i, 5)
    NuaNgay = NgayThuong - sArr(i, 1) - sArr(i, 2) - sArr(i, 3)             'So ngay thuong lam nua ngay
    If NuaNgay < 0 Then MsgBox ("So ngay Lam Viec va Nghi qua lon!"): Exit Sub
    NgayLV = sArr(i, 1) - NuaNgay                         'So ngay thuong lam 1 ngay
    NuaNgay = NuaNgay * 2                                 'So ngay thuong lam nua ngay
'Ngay thuong
    arr = UniqueRand(NgayThuong)
    k = 0
    Call AddRes(res, aThuong, arr, k, i, NgayLV, "X") '1 Ngay
    Call AddRes(res, aThuong, arr, k, i, NuaNgay, "X/2") 'Nua ngay
    Call AddRes(res, aThuong, arr, k, i, sArr(i, 2), "0") 'Nghi khong luong
    Call AddRes(res, aThuong, arr, k, i, sArr(i, 3), "L") 'Nghi co luong
'Thu 7
    k = 0
    N = Int(sArr(i, 4))
    M = Int(sArr(i, 4) + 0.5)
    arr = UniqueRand(soT7)
    Call AddRes(res, aT7, arr, k, i, N, "X") '1 ngay
    Call AddRes(res, aT7, arr, k, i, M - N, "X/2") 'Nua ngay
'Chu nhat
    k = 0
    N = Int(sArr(i, 5))
    M = Int(sArr(i, 5) + 0.5)
    arr = UniqueRand(soCN)
    Call AddRes(res, aCN, arr, k, i, N, "X") '1 ngay
    Call AddRes(res, aCN, arr, k, i, M - N, "X/2") 'Nua ngay
  Next i
  Range("E7").Resize(sRow, 31) = res
End Sub

Private Sub AddRes(res, sArr, arr, k, i, ByVal sCol&, ByVal strRes$)
  Dim j&
  For j = 1 To sCol
    k = k + 1
    res(i, sArr(arr(k))) = strRes
  Next j
End Sub

Function UniqueRand(ByVal N As Long) As Variant
Dim arr() As Long, i As Long, RndNum As Long, tmp As Long
ReDim arr(1 To N)
'Randomize
For i = 1 To N
    RndNum = Int(N * Rnd() + 1)
    If arr(RndNum) = 0 Then tmp = RndNum Else tmp = arr(RndNum)
    If arr(N) = 0 Then arr(RndNum) = N Else arr(RndNum) = arr(N)
    arr(N) = tmp
    N = N - 1
Next i
UniqueRand = arr
End Function
Mình thử ngày công là 14 hoặc ít hơn thì không chạy, mong bạn kiểm tra
 
Upvote 0
Code viết theo yêu cầu của file là phải nhập đầy đủ và hợp lý các giá trị, nếu bỏ qua tham số ngày nghỉ thì tìm file dạng khác
việc đi làm vẫn có trường hợp người lao động nghỉ việc không làm đủ số ngày trong tháng mà anh, với lại em thấy file này là đỉnh nhất rồi, các file khác không bằng được
 
Lần chỉnh sửa cuối:
Upvote 0
(/ậy bài 29 bạn chưa đọc hay sao? Hay bạn chờ được dọn cỗ khác thi vị hơn?!?
 
Upvote 0
(/ậy bài 29 bạn chưa đọc hay sao? Hay bạn chờ được dọn cỗ khác thi vị hơn?!?
dạ em chưa đọc được bài này bác ạ, nếu có thể bác vui lòng cho em xin link, còn vấn đề cỗ bàn thì em không chờ gì cả, khi đọc được bài này em thấy các bác xây dựng rất hay nên em thấy nếu hoàn thiện được thì tốt hơn cho cộng đồng cũng như bản thân em cũng được nhờ. vì nói thẳng em không giỏi lập trình nên mới lên tiếng nhờ các bác cao nhân. Nếu bác nào cảm thấy bị lợi dụng thì thôi không phải trả lời em đâu ạ
 
Upvote 0
Cần xác định các ngày không làm do nguyên nhân gì, nghỉ có phép hay không phép, hoặc do nguyên nhân khác
Một câu của bác đã làm em thấy trời xanh, xin cảm ơn Bác và các vị cao nhân đã tạo ra sản phẩm này.
Một lần nữa xin cảm ơn và chúc các Bác mạnh khoẻ ạ
 
Lần chỉnh sửa cuối:
Upvote 0
dạ vẫn trên file cũ, khi em thử thay ngày công là 11 hoặc 12 tức là những số nhỏ hơn 16 thì code báo lỗi, mong các bác bổ xung ạ
Thêm thông báo số ngày làm việc và ngày nghỉ quá nhỏ
Mã:
Sub XYZAB()
  Dim sArr(), aNgay(), aThuong(), aT7(), aCN(), arr, res()
  Dim soNgay&, NgayThuong&, soT7&, soCN&, dong$
  Dim NgayLV&, lvCH&, lvT7&, NuaNgay#
  Dim sRow&, i&, j&, k&, k2&, k3&, N&, M&

  Randomize
  soNgay = DateAdd("m", 1, Range("E3")) - Range("E3")
  aNgay = Range("E3").Resize(, soNgay)
  sArr = Range("AJ7:AN" & Range("B1000").End(xlUp).Row).Value
  sRow = UBound(sArr)
  Range("E7").Resize(sRow + 1, 31) = Empty
  ReDim res(1 To sRow + 1, 1 To 31)
  ReDim aThuong(1 To soNgay)
  ReDim aT7(1 To 10):  ReDim aCN(1 To 10)
 
  For j = 1 To soNgay
    res(sRow + 1, j) = Weekday(aNgay(1, j), vbMonday)
    If res(sRow + 1, j) = 7 Then
      soCN = soCN + 1                                 'So ngay CN
      k = k + 1
      aCN(k) = j
    ElseIf res(sRow + 1, j) = 6 Then
      soT7 = soT7 + 1                                 'So ngay Thu 7
      k2 = k2 + 1
      aT7(k2) = j
    Else
      k3 = k3 + 1
      aThuong(k3) = j
    End If
  Next j

  For i = 1 To sRow
    dong = "Dong:    " & i + 6 & Chr(10) & Chr(10)
    If sArr(i, 4) > soT7 Or sArr(i, 5) > soCN Then _
        MsgBox (dong & "So ngay nghi T7 hoac CN sai!"): Exit Sub
'Ngay thuong
    NgayThuong = soNgay - soT7 - soCN                     'So ngay thuong
    sArr(i, 4) = soT7 - sArr(i, 4)                        'So ngay lam viec thu 7
    sArr(i, 5) = soCN - sArr(i, 5)                        'So ngay lam viec CN
    sArr(i, 1) = sArr(i, 1) - Int(sArr(i, 4) + 0.5) - Int(sArr(i, 5) + 0.5)
    NuaNgay = NgayThuong - sArr(i, 1) - sArr(i, 2) - sArr(i, 3)             'So ngay thuong lam nua ngay
    If NuaNgay < 0 Then MsgBox (dong & "So ngay Lam Viec va Nghi qua lon!"): Exit Sub
    NgayLV = sArr(i, 1) - NuaNgay                         'So ngay thuong lam 1 ngay
    If NgayLV < 0 Then MsgBox (dong & "So ngay Lam Viec va Ngay Nghi qua nho!"): Exit Sub
    NuaNgay = NuaNgay * 2                                 'So ngay thuong lam nua ngay
    arr = UniqueRand(NgayThuong)
    k = 0
    For j = 1 To NgayLV       '1 Ngay
      k = k + 1
      jcol = aThuong(arr(k))
      res(i, jcol) = "X"
    Next j
    For j = 1 To NuaNgay      'Nua ngay
      k = k + 1
      jcol = aThuong(arr(k))
      res(i, jcol) = "X/2"
    Next j
    For j = 1 To sArr(i, 2)   'Nghi khong luong
      k = k + 1
      jcol = aThuong(arr(k))
      res(i, jcol) = "0"
    Next j
    For j = 1 To sArr(i, 2)   'Nghi co luong
      k = k + 1
      jcol = aThuong(arr(k))
      res(i, jcol) = "L"
    Next j
'Thu 7
    k = 0
    N = Int(sArr(i, 4))
    M = Int(sArr(i, 4) + 0.5)
    arr = UniqueRand(soT7)
    For j = 1 To N            '1 ngay
      k = k + 1
      jcol = aT7(arr(k))
      res(i, jcol) = "X"
    Next j
    For j = 1 To M - N        'Nua ngay
      k = k + 1
      jcol = aT7(arr(k))
      res(i, jcol) = "X/2"
    Next j
'Chu nhat
    k = 0
    N = Int(sArr(i, 5))
    M = Int(sArr(i, 5) + 0.5)
    arr = UniqueRand(soCN)
    For j = 1 To N            '1 ngay
      k = k + 1
      jcol = aCN(arr(k))
      res(i, jcol) = "X"
    Next j
    For j = 1 To M - N        'Nua ngay
      k = k + 1
      jcol = aCN(arr(k))
      res(i, jcol) = "X/2"
    Next j
  Next i
  Range("E7").Resize(sRow, 31) = res
End Sub

Function UniqueRand(ByVal N As Long) As Variant
Dim arr() As Long, i As Long, RndNum As Long, tmp As Long
ReDim arr(1 To N)
'Randomize
For i = 1 To N
    RndNum = Int(N * Rnd() + 1)
    If arr(RndNum) = 0 Then tmp = RndNum Else tmp = arr(RndNum)
    If arr(N) = 0 Then arr(RndNum) = N Else arr(RndNum) = arr(N)
    arr(N) = tmp
    N = N - 1
Next i
UniqueRand = arr
End Function
 
Upvote 0
Thêm thông báo số ngày làm việc và ngày nghỉ quá nhỏ
Mã:
Sub XYZAB()
  Dim sArr(), aNgay(), aThuong(), aT7(), aCN(), arr, res()
  Dim soNgay&, NgayThuong&, soT7&, soCN&, dong$
  Dim NgayLV&, lvCH&, lvT7&, NuaNgay#
  Dim sRow&, i&, j&, k&, k2&, k3&, N&, M&

  Randomize
  soNgay = DateAdd("m", 1, Range("E3")) - Range("E3")
  aNgay = Range("E3").Resize(, soNgay)
  sArr = Range("AJ7:AN" & Range("B1000").End(xlUp).Row).Value
  sRow = UBound(sArr)
  Range("E7").Resize(sRow + 1, 31) = Empty
  ReDim res(1 To sRow + 1, 1 To 31)
  ReDim aThuong(1 To soNgay)
  ReDim aT7(1 To 10):  ReDim aCN(1 To 10)
 
  For j = 1 To soNgay
    res(sRow + 1, j) = Weekday(aNgay(1, j), vbMonday)
    If res(sRow + 1, j) = 7 Then
      soCN = soCN + 1                                 'So ngay CN
      k = k + 1
      aCN(k) = j
    ElseIf res(sRow + 1, j) = 6 Then
      soT7 = soT7 + 1                                 'So ngay Thu 7
      k2 = k2 + 1
      aT7(k2) = j
    Else
      k3 = k3 + 1
      aThuong(k3) = j
    End If
  Next j

  For i = 1 To sRow
    dong = "Dong:    " & i + 6 & Chr(10) & Chr(10)
    If sArr(i, 4) > soT7 Or sArr(i, 5) > soCN Then _
        MsgBox (dong & "So ngay nghi T7 hoac CN sai!"): Exit Sub
'Ngay thuong
    NgayThuong = soNgay - soT7 - soCN                     'So ngay thuong
    sArr(i, 4) = soT7 - sArr(i, 4)                        'So ngay lam viec thu 7
    sArr(i, 5) = soCN - sArr(i, 5)                        'So ngay lam viec CN
    sArr(i, 1) = sArr(i, 1) - Int(sArr(i, 4) + 0.5) - Int(sArr(i, 5) + 0.5)
    NuaNgay = NgayThuong - sArr(i, 1) - sArr(i, 2) - sArr(i, 3)             'So ngay thuong lam nua ngay
    If NuaNgay < 0 Then MsgBox (dong & "So ngay Lam Viec va Nghi qua lon!"): Exit Sub
    NgayLV = sArr(i, 1) - NuaNgay                         'So ngay thuong lam 1 ngay
    If NgayLV < 0 Then MsgBox (dong & "So ngay Lam Viec va Ngay Nghi qua nho!"): Exit Sub
    NuaNgay = NuaNgay * 2                                 'So ngay thuong lam nua ngay
    arr = UniqueRand(NgayThuong)
    k = 0
    For j = 1 To NgayLV       '1 Ngay
      k = k + 1
      jcol = aThuong(arr(k))
      res(i, jcol) = "X"
    Next j
    For j = 1 To NuaNgay      'Nua ngay
      k = k + 1
      jcol = aThuong(arr(k))
      res(i, jcol) = "X/2"
    Next j
    For j = 1 To sArr(i, 2)   'Nghi khong luong
      k = k + 1
      jcol = aThuong(arr(k))
      res(i, jcol) = "0"
    Next j
    For j = 1 To sArr(i, 2)   'Nghi co luong
      k = k + 1
      jcol = aThuong(arr(k))
      res(i, jcol) = "L"
    Next j
'Thu 7
    k = 0
    N = Int(sArr(i, 4))
    M = Int(sArr(i, 4) + 0.5)
    arr = UniqueRand(soT7)
    For j = 1 To N            '1 ngay
      k = k + 1
      jcol = aT7(arr(k))
      res(i, jcol) = "X"
    Next j
    For j = 1 To M - N        'Nua ngay
      k = k + 1
      jcol = aT7(arr(k))
      res(i, jcol) = "X/2"
    Next j
'Chu nhat
    k = 0
    N = Int(sArr(i, 5))
    M = Int(sArr(i, 5) + 0.5)
    arr = UniqueRand(soCN)
    For j = 1 To N            '1 ngay
      k = k + 1
      jcol = aCN(arr(k))
      res(i, jcol) = "X"
    Next j
    For j = 1 To M - N        'Nua ngay
      k = k + 1
      jcol = aCN(arr(k))
      res(i, jcol) = "X/2"
    Next j
  Next i
  Range("E7").Resize(sRow, 31) = res
End Sub

Function UniqueRand(ByVal N As Long) As Variant
Dim arr() As Long, i As Long, RndNum As Long, tmp As Long
ReDim arr(1 To N)
'Randomize
For i = 1 To N
    RndNum = Int(N * Rnd() + 1)
    If arr(RndNum) = 0 Then tmp = RndNum Else tmp = arr(RndNum)
    If arr(N) = 0 Then arr(RndNum) = N Else arr(RndNum) = arr(N)
    arr(N) = tmp
    N = N - 1
Next i
UniqueRand = arr
End Function
Dạ, em cảm ơn Bác nhiều ạ, kính chúc Bác luôn mạnh khoẻ và nhiều niềm vui ạ
 
Upvote 0
Xin hỏi bảng chấm công này dùng cho mục đích gì vậy mọi người
 
Upvote 0
Xin hỏi bảng chấm công này dùng cho mục đích gì vậy mọi người
Những cơ quan như ngành xây dựng,. . . cần bảng chấm công để đối phó với ngành LĐ, TB & Xã hội.
Cụ thể là cần có 1 bảng chấm công 'Láo' để báo cáo theo yêu cầu í mà!
 
Upvote 0
Web KT

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

Back
Top Bottom