Kiểm tra ngày công

Liên hệ QC

Masu1991

Thành viên hoạt động
Tham gia
21/3/20
Bài viết
110
Được thích
14
Chào Anh/Chị,
Em có 1 file chấm công từ hệ thống, em cần kiểm tra cho chính xác để tính lương.
- Dựa vào mã số thẻ và ngày vào để kiểm tra xem người công nhân bị chấm công thiếu ngày nào so với sheet CÔNG ở cột NGÀY CHẤM CÔNG.
- Ví dụ: mã số thẻ 22005919 vào ngày 06/17/2022 thì kiểm tra từ ngày 06/17 đến cuối tháng bị chấm công thiếu ngày nào.
22005186 sheet CÔNG cột ngày chấm công (Cột ) bị thiếu ngày 06/04, 06/16 đến 06/30
1659442586892.png
- kết quả trả về: Nếu bị thiếu ngày nào thì điền vào ngày đó là LỖI, nếu có dữ liệu ngày chấm công thì trả về TRỐNG.

Em xin cảm ơn anh chị đã hỗ trợ.
 

File đính kèm

  • KIEM TRA CONG.xlsb
    420.7 KB · Đọc: 16
Chào Anh/Chị,
Em có 1 file chấm công từ hệ thống, em cần kiểm tra cho chính xác để tính lương.
- Dựa vào mã số thẻ và ngày vào để kiểm tra xem người công nhân bị chấm công thiếu ngày nào so với sheet CÔNG ở cột NGÀY CHẤM CÔNG.
- Ví dụ: mã số thẻ 22005919 vào ngày 06/17/2022 thì kiểm tra từ ngày 06/17 đến cuối tháng bị chấm công thiếu ngày nào.
22005186 sheet CÔNG cột ngày chấm công (Cột ) bị thiếu ngày 06/04, 06/16 đến 06/30
View attachment 279517
- kết quả trả về: Nếu bị thiếu ngày nào thì điền vào ngày đó là LỖI, nếu có dữ liệu ngày chấm công thì trả về TRỐNG.

Em xin cảm ơn anh chị đã hỗ trợ.
Trong khi chờ các giải pháp khác, hãy thử xem, hy vọng đúng.
Mã:
Option Explicit

Sub Cong()
Dim i&, j&, d&, t&, k&, Lr&
Dim Arr(), Res()
Dim Dic As Object, Key, Temp

With Sheets("CONG")
Lr = .Cells(Rows.Count, 12).End(xlUp).Row
Arr = .Range("H2:N" & Lr).Value
End With
ReDim Res(1 To UBound(Arr), 34)
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(Arr)
    k = Day(Arr(i, 7)) + 3
        Key = Arr(i, 5) & "|" & Arr(i, 7)
            If Not Dic.exists(Key) Then
                t = t + 1: Dic.Add (Key), t
                    Res(t, 1) = Arr(i, 5)
                    Res(t, 2) = Arr(i, 1)
                    Res(t, 3) = Arr(i, 2)
                    Res(t, k) = Arr(i, 7)
            End If
Next i
With Sheets("KIEMTRA")
For i = 2 To .Cells(Rows.Count, 1).End(xlUp).Row
    If Month(.Cells(i, 3)) = 6 Then
        d = Day(.Cells(i, 3))
    Else
        d = 4
    End If
        For j = d To 34
            If Weekday(.Cells(1, j), 1) <> 1 Then
                Temp = .Cells(i, 1) & "|" & .Cells(1, j)
                If Not Dic.exists(Temp) Then
                    .Cells(i, j) = "LOI"
                End If
            End If
        Next j
Next i
End With
End Sub
 
Upvote 0
Trong khi chờ các giải pháp khác, hãy thử xem, hy vọng đúng.
Mã:
Option Explicit

Sub Cong()
Dim i&, j&, d&, t&, k&, Lr&
Dim Arr(), Res()
Dim Dic As Object, Key, Temp

With Sheets("CONG")
Lr = .Cells(Rows.Count, 12).End(xlUp).Row
Arr = .Range("H2:N" & Lr).Value
End With
ReDim Res(1 To UBound(Arr), 34)
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(Arr)
    k = Day(Arr(i, 7)) + 3
        Key = Arr(i, 5) & "|" & Arr(i, 7)
            If Not Dic.exists(Key) Then
                t = t + 1: Dic.Add (Key), t
                    Res(t, 1) = Arr(i, 5)
                    Res(t, 2) = Arr(i, 1)
                    Res(t, 3) = Arr(i, 2)
                    Res(t, k) = Arr(i, 7)
            End If
Next i
With Sheets("KIEMTRA")
For i = 2 To .Cells(Rows.Count, 1).End(xlUp).Row
    If Month(.Cells(i, 3)) = 6 Then
        d = Day(.Cells(i, 3))
    Else
        d = 4
    End If
        For j = d To 34
            If Weekday(.Cells(1, j), 1) <> 1 Then
                Temp = .Cells(i, 1) & "|" & .Cells(1, j)
                If Not Dic.exists(Temp) Then
                    .Cells(i, j) = "LOI"
                End If
            End If
        Next j
Next i
End With
End Sub
Dạ Chào Anh, sau khi áp dụng code của anh thì em thấy bị lỗi 1 chỗ ạ,

- Ví dự như: mst: 22005915 họ vào xưởng ngày 06/17/20022 thì từ ngày 1 - 16 phải là TRỐNG vì những ngày đó họ chưa làm tại công ty nên không có dữ liệu chấm công vì thế nên phải xét từ ngày 06/17 trở về sau mới đúng.

1659487272084.png
- Chỗ code này em có sửa = 6 thành >12 thì không biết có lỗi gì không ạ:
1659487373606.png

Em cảm ơn ạ.
 

File đính kèm

  • KIEM TRA CONG.xlsb
    475.8 KB · Đọc: 2
Upvote 0
Dạ Chào Anh, sau khi áp dụng code của anh thì em thấy bị lỗi 1 chỗ ạ,

- Ví dự như: mst: 22005915 họ vào xưởng ngày 06/17/20022 thì từ ngày 1 - 16 phải là TRỐNG vì những ngày đó họ chưa làm tại công ty nên không có dữ liệu chấm công vì thế nên phải xét từ ngày 06/17 trở về sau mới đúng.

View attachment 279529
- Chỗ code này em có sửa = 6 thành >12 thì không biết có lỗi gì không ạ:
View attachment 279530

Em cảm ơn ạ.
1,/Lỗi à, sao trên máy tôi thì chạy mà. bạn kiểm tra lại dữ liệu ngày tháng của cột ngày vào của máy bạn lại xem.
2/Hàm Month(...) trả về là số tháng của ngày tháng cho trước. Vậy Month(.Cells(i,3)) sẽ trả về số tháng của ô Bi, Làm gì có tháng 13 mà bạn cho nó If month(...)>12
Vấn đề sửa lại code bạn cứ sửa và chạy lại là biết ngay mà.
P/S: Ai thì không biết chứ là tôi thì trước khi đăng bài trả lời thì cũng đã phải cho chạy thử rất nhiều lần, thấy đúng mới đăng bài lên, và tôi nghĩ rằng (theo thiển ý chủ quan của mình) là 100% người viết code và đăng bài trả lời thì họ cũng làm như vậy.
3/Bạn thử lại file này của mình.code có sửa lại chút ít. Nó chỉ căn cứ vào MST (cột A/Sh KIEMTRA) để làm các công việc theo yêu cầu.
 

File đính kèm

  • KIEM TRA CONG.xlsb
    432.9 KB · Đọc: 10
Upvote 0
1,/Lỗi à, sao trên máy tôi thì chạy mà. bạn kiểm tra lại dữ liệu ngày tháng của cột ngày vào của máy bạn lại xem.
2/Hàm Month(...) trả về là số tháng của ngày tháng cho trước. Vậy Month(.Cells(i,3)) sẽ trả về số tháng của ô Bi, Làm gì có tháng 13 mà bạn cho nó If month(...)>12
Vấn đề sửa lại code bạn cứ sửa và chạy lại là biết ngay mà.
P/S: Ai thì không biết chứ là tôi thì trước khi đăng bài trả lời thì cũng đã phải cho chạy thử rất nhiều lần, thấy đúng mới đăng bài lên, và tôi nghĩ rằng (theo thiển ý chủ quan của mình) là 100% người viết code và đăng bài trả lời thì họ cũng làm như vậy.
3/Bạn thử lại file này của mình.code có sửa lại chút ít. Nó chỉ căn cứ vào MST (cột A/Sh KIEMTRA) để làm các công việc theo yêu cầu.
Đã tìm thấy heo pờ (helper) có tâm nhất nhì GPE!
_)(#;
 
Upvote 0
1,/Lỗi à, sao trên máy tôi thì chạy mà. bạn kiểm tra lại dữ liệu ngày tháng của cột ngày vào của máy bạn lại xem.
2/Hàm Month(...) trả về là số tháng của ngày tháng cho trước. Vậy Month(.Cells(i,3)) sẽ trả về số tháng của ô Bi, Làm gì có tháng 13 mà bạn cho nó If month(...)>12
Vấn đề sửa lại code bạn cứ sửa và chạy lại là biết ngay mà.
P/S: Ai thì không biết chứ là tôi thì trước khi đăng bài trả lời thì cũng đã phải cho chạy thử rất nhiều lần, thấy đúng mới đăng bài lên, và tôi nghĩ rằng (theo thiển ý chủ quan của mình) là 100% người viết code và đăng bài trả lời thì họ cũng làm như vậy.
3/Bạn thử lại file này của mình.code có sửa lại chút ít. Nó chỉ căn cứ vào MST (cột A/Sh KIEMTRA) để làm các công việc theo yêu cầu.
Dạ Chào anh, sau khi em bỏ hết các mã số thẻ từ sheet CONG qua thì lại bị lỗi như này á anh.1659491894582.png
- những người này ngày vào xưởng sau ngày 17 thì đâu có dữ liệu chấm công những ngày trước đó nên không thể bị lỗi được anh. phải xét từ ngày vào xưởng trở về sau mới đúng ạ
1659492149543.png
anh xem giúp em.
 

File đính kèm

  • KIEM TRA CONG.xlsb
    529.1 KB · Đọc: 6
Lần chỉnh sửa cuối:
Upvote 0
Dạ Chào anh, sau khi em bỏ hết các mã số thẻ từ sheet CONG qua thì lại bị lỗi như này á anh.View attachment 279534
- những người này ngày vào xưởng sau ngày 17 thì đâu có dữ liệu chấm công những ngày trước đó nên không thể bị lỗi được anh. phải xét từ ngày vào xưởng trở về sau mới đúng ạ
View attachment 279536
anh xem giúp em.
Bạn sửa lại dòng
Mã:
d = Day(Res(k, 3))
thành
Mã:
d=Day(res(k,3))+3
và chạy thử.
Góp ý vơi bạn nếu lần sau hỏi bài thì nên đưa dữ liệu giả định khoảng 10-20 dòng và chú ý chọn những dòng có nhiều đặc thù nhất, để người viết code có dữ liệu để chạy thử và có thể lường trước các tình huống có thể xảy ra. Đây là ý kiến của riêng tôi
 
Upvote 0
...
Góp ý vơi bạn nếu lần sau hỏi bài thì nên đưa dữ liệu giả định khoảng 10-20 dòng và chú ý chọn những dòng có nhiều đặc thù nhất, để người viết code có dữ liệu để chạy thử và có thể lường trước các tình huống có thể xảy ra. Đây là ý kiến của riêng tôi
Nếu họ chuyên tâm nghĩ đến các trường hợp có thể xảy ra thì ít khi phải hỏi bài lắm.
Những người biết tự nhìn ra những gút mắc vấn đề thi giờ này đã đạt trình độ cao rồi. Lúc hỏi chỉ hỏi những chỗ bí thôi, chứ không phải nhờ làm giùm từ a đến z.
 
Upvote 0
Chào Anh/Chị,
Em có 1 file chấm công từ hệ thống, em cần kiểm tra cho chính xác để tính lương.
- Dựa vào mã số thẻ và ngày vào để kiểm tra xem người công nhân bị chấm công thiếu ngày nào so với sheet CÔNG ở cột NGÀY CHẤM CÔNG.
Sao mình không làm ngược lại là đứa nào có châm công ngày nào thì đánh dấu lại nhỉ
 
Upvote 0
Mấu chốt vấn đề là hình như bạn đang dùng ngày tháng của Mẽo (mm/dd/yyyy).
Nên mình sẽ dùng value2, thay vì value
Lưu ý là trong sheet KIEMTRA, dòng 2, tại 3 cột cuối mình dùng công thức để hạn chế ngày cuối tháng.
Chạy thử code dưới:
PHP:
Option Explicit
Sub tinhcong()
Dim lr&, i&, j&, k&, rng, arr(), nc
Dim dic As Object, key
Set dic = CreateObject("Scripting.Dictionary")
With Worksheets("CONG")
    lr = .Cells(Rows.Count, "H").End(xlUp).Row
    rng = .Range("H2:N" & lr).Value2
End With
    For i = 1 To lr - 1
        If Not dic.exists(rng(i, 5)) Then
            dic.Add rng(i, 5), rng(i, 1) & "-" & rng(i, 2) & "|" & rng(i, 7)
        Else
            dic(rng(i, 5)) = dic(rng(i, 5)) & "-" & rng(i, 7)
        End If
    Next
    ReDim arr(1 To dic.Count, 1 To 2)
    For Each key In dic.items
        k = k + 1
        arr(k, 1) = Split(Split(key, "|")(0), "-")(0)
        arr(k, 2) = Split(Split(key, "|")(0), "-")(1)
    Next
With Worksheets("KIEMTRA")
    .Range("A2:AH10000").ClearContents
    .Range("A2").Resize(dic.Count, 1).Value = WorksheetFunction.Transpose(dic.keys)
    .Range("B2").Resize(k, 2).Value = arr
    rng = .Range("A1:AH" & k + 1).Value
    i = 1
    For Each key In dic.keys
        i = i + 1
        nc = Split(dic(key), "|")(1)
        For j = 4 To 34
            If rng(1, j) >= rng(i, 3) And Weekday(rng(1, j)) <> 1 And InStr(1, nc, Format(rng(1, j), "0")) = 0 Then
                rng(i, j) = "LOI"
            End If
        Next
    Next
    .Range("A1:AH" & k + 1).Value = rng
End With
End Sub
 

File đính kèm

  • KIEM TRA CONG.xlsb
    449.9 KB · Đọc: 10
Upvote 0
Sao mình không làm ngược lại là đứa nào có châm công ngày nào thì đánh dấu lại nhỉ
Mình phát hiện ra là người chấm công không có sai nhưng soa là do hệ thống xuất dữ liệu ra bị sai đó bạn, bên mình đang thảo luận lại phía IT xem họ giải quyết ra sao.
Bài đã được tự động gộp:

Bạn sửa lại dòng
Mã:
d = Day(Res(k, 3))
thành
Mã:
d=Day(res(k,3))+3
và chạy thử.
Góp ý vơi bạn nếu lần sau hỏi bài thì nên đưa dữ liệu giả định khoảng 10-20 dòng và chú ý chọn những dòng có nhiều đặc thù nhất, để người viết code có dữ liệu để chạy thử và có thể lường trước các tình huống có thể xảy ra. Đây là ý kiến của riêng tôi
Dạ, Cảm ơn anh rất nhiều. em xin tiếp thu ý kiến đóng góp của anh ạ.
 
Upvote 0
Mấu chốt vấn đề là hình như bạn đang dùng ngày tháng của Mẽo (mm/dd/yyyy).
Nên mình sẽ dùng value2, thay vì value
Lưu ý là trong sheet KIEMTRA, dòng 2, tại 3 cột cuối mình dùng công thức để hạn chế ngày cuối tháng.
Chạy thử code dưới:
PHP:
Option Explicit
Sub tinhcong()
Dim lr&, i&, j&, k&, rng, arr(), nc
Dim dic As Object, key
Set dic = CreateObject("Scripting.Dictionary")
With Worksheets("CONG")
    lr = .Cells(Rows.Count, "H").End(xlUp).Row
    rng = .Range("H2:N" & lr).Value2
End With
    For i = 1 To lr - 1
        If Not dic.exists(rng(i, 5)) Then
            dic.Add rng(i, 5), rng(i, 1) & "-" & rng(i, 2) & "|" & rng(i, 7)
        Else
            dic(rng(i, 5)) = dic(rng(i, 5)) & "-" & rng(i, 7)
        End If
    Next
    ReDim arr(1 To dic.Count, 1 To 2)
    For Each key In dic.items
        k = k + 1
        arr(k, 1) = Split(Split(key, "|")(0), "-")(0)
        arr(k, 2) = Split(Split(key, "|")(0), "-")(1)
    Next
With Worksheets("KIEMTRA")
    .Range("A2:AH10000").ClearContents
    .Range("A2").Resize(dic.Count, 1).Value = WorksheetFunction.Transpose(dic.keys)
    .Range("B2").Resize(k, 2).Value = arr
    rng = .Range("A1:AH" & k + 1).Value
    i = 1
    For Each key In dic.keys
        i = i + 1
        nc = Split(dic(key), "|")(1)
        For j = 4 To 34
            If rng(1, j) >= rng(i, 3) And Weekday(rng(1, j)) <> 1 And InStr(1, nc, Format(rng(1, j), "0")) = 0 Then
                rng(i, j) = "LOI"
            End If
        Next
    Next
    .Range("A1:AH" & k + 1).Value = rng
End With
End Sub
Da, Em dùng định đạng MM/dd/yyy anh ạ, cảm ơn anh đã hỗ trợ em
 
Upvote 0
Up lộn file
Up lại file cũ
 

File đính kèm

  • KIEM TRA CONG2.xlsb
    450.8 KB · Đọc: 4
Lần chỉnh sửa cuối:
Upvote 0
Web KT

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

Back
Top Bottom