Điền x và Bảng liệu theo nhiều điều kiện

Liên hệ QC

Excel365

Thành viên tích cực
Tham gia
29/10/10
Bài viết
862
Được thích
125
Giới tính
Nam
Chào các Anh, chị
Hiện đang dùng công thức sau để đánh x vào bảng chấm công.
Mã:
Function Ngay(MSNV As Variant, NgayChamCong As Date, Thu As String) As Variant
    Dim NgayHS As Date
    Dim CSDL As Range:     Set CSDL = Range("DATA")
    NgayHS = Application.WorksheetFunction.VLookup(MSNV, CSDL, 3)
        If CDate(NgayHS) <= CDate(NgayChamCong) And Thu <> "CN" Then
            Ngay = "x"
        Else
            Ngay = ""
           End If
End Function

Nay em muốn bổ sung thêm điều kiện sau:
Dựa vào cột Ngày công ban đầu, đánh x sao cho tổng x = Tổng ngày công ban đầu, với điều kiện.
1. Không đánh x những ngày nghỉ việc riêng (Dựa vào Bảng nghỉ việc riêng).
2. Không đánh x những ngày chủ nhật

* Nếu trường hợp bên nghỉ việc riêng không có tên thì vẫn đánh x cho Tổng x vẫn bằng Tổng ngày công ban đầu
P/s:
Do sơ ý, em quên diễn tả thêm ý: đánh x phải sau ngày nhận hồ sơ.
VD: Trường hợp của Nguyễn Hoài Khanh, ngày nhận hồ sơ là 12/8/2019, thì phải đánh x sau ngày này
Nhờ các anh, chị giúp đỡ.
Trân trọng cảm ơn!
 

File đính kèm

  • Cong_GPE.xlsm
    26.9 KB · Đọc: 20
Lần chỉnh sửa cuối:
Yêu cầu của bạn có thể làm được. Nhưng mình thấy thiết kế chưa tốt.

Tại sao phải dùng một bảng riêng để lưu việc riêng. Tại sao không thiết kế nó cùng với bảng chấm công. Việc riêng ra ngoài vài tiếng, hay cắt phép cả ngày, hay cắt phép nửa ngày, hay làm thêm… tất cả những cái đó đều có thể thiết kế trên cùng bảng chấm công.



Theo thiết kế hiện nay, thì cứ phải điền công thức bằng tay, tháng nào cũng 31 ngày, việc này có thể cải thiện để tự động, và tự động luôn cả xác định thứ 7 và CN.



Vậy bạn vẫn muốn làm theo cái form của bạn hay muốn chúng ta bàn lại thiết kế.
 
Upvote 0
Yêu cầu của bạn có thể làm được. Nhưng mình thấy thiết kế chưa tốt.
Tại sao phải dùng một bảng riêng để lưu việc riêng. Tại sao không thiết kế nó cùng với bảng chấm công. Việc riêng ra ngoài vài tiếng, hay cắt phép cả ngày, hay cắt phép nửa ngày, hay làm thêm… tất cả những cái đó đều có thể thiết kế trên cùng bảng chấm công.
Theo thiết kế hiện nay, thì cứ phải điền công thức bằng tay, tháng nào cũng 31 ngày, việc này có thể cải thiện để tự động, và tự động luôn cả xác định thứ 7 và CN.
Vậy bạn vẫn muốn làm theo cái form của bạn hay muốn chúng ta bàn lại thiết kế.

Tại sao phải dùng một bảng riêng để lưu việc riêng. Tại sao không thiết kế nó cùng với bảng chấm công. Việc riêng ra ngoài vài tiếng, hay cắt phép cả ngày, hay cắt phép nửa ngày, hay làm thêm… tất cả những cái đó đều có thể thiết kế trên cùng bảng chấm công.
- Cái này mình để bảng Việc riêng cho tiện theo dõi, khi cần chỉnh sữa, định dạng để In ấn không ảnh hưởng đến bảng Công
- Phần việc riêng này thì mình chỉ tính nghỉ trọn ngày, hoặc nữa ngày

Theo thiết kế hiện nay, thì cứ phải điền công thức bằng tay, tháng nào cũng 31 ngày, việc này có thể cải thiện để tự động, và tự động luôn cả xác định thứ 7 và CN.
Cái này nhờ bạn khongtu19bk

Riêng phần form mẩu thì theo bạn cách nào hợp lý hơn thi bạn triển khai theo cách đó giúp mình. Nhưng Bảng Việc riêng thì để riêng 1 sheet giúp mình.
Trân trọng cảm ơn
 
Upvote 0
1. Mình thấy file của bạn đưa ra ví dụ chưa đúng.
224665
Cụ thể người này tháng 9 mới nghỉ cho nên bảng chấm công tháng 8 không thể coi đây là ngày họ nghỉ mà không chấm công cho họ.
2. Về code hiện tại của bạn dùng VLOOKUP tức là cột A ở trên, theo mình hiểu mã nhân viên chỉ được xuất hiện một lần.
Nếu mình hiểu sai hãy phản hồi lại cho mình biết.
Như vậy tình huống thực tế sẽ có trường hợp:
Người A nghỉ ngày 10/8/2019 việc riêng
Người A nghỉ ngày 20/8/2019 việc riêng
Như thế người A sẽ xuất hiện hai lần. Vì thế VLOOKUP lúc này là không ổn.

3. Về bài toán của bạn hình như hơi ngược với với thực tế, người ta chấm công hàng ngày, rồi người quản lý list lọc ra dữ liệu cần.
Còn bạn, từ danh sách ngày nghỉ, tự điền vào chấm công.
4. Vì không biết khả năng của bạn muốn như thế nào, cho nên mình code ở mức đơn giản nhất để bạn dễ đọc, mà không ưu tiên tốc độ.
Mã:
Function ngay(ByVal msnv As String, ByVal ngaychamcong As Date, ByVal thu As String) As String
    Dim i           As Long
    Dim rend        As Long
    'Dim arrtemp     As Variant  => Update: khong dung cai nay, dung truc tiep cells cho ban de hieu
    Dim dtemp1      As Date
    Dim dtemp2      As Date
    Dim temp        As String
    Dim f1 As Boolean, f2 As Boolean
    Const rstart    As Long = 2 'Dong bat dau
    Application.ScreenUpdating = False
    If thu = "CN" Then
        ngay = ""
        Exit Function 'Ket thuc chuong trinh, khong can kiem tra ngay phep nua.
    End If
  
    rend = ThisWorkbook.Sheets("VR").Cells(Rows.Count, 1).End(xlUp).Row
   
   
    If rend < 2 Then    'Neu khong co du lieu viec rieng
        ngay = "x"
        Exit Function ' Ket thuc chuong trinh
    End If
 
    ngay = "x" 'Mac dinh la OK
    'Tim kiem ma nhan vien
    For i = rstart To rend Step 1
        f1 = False
        f2 = False
       
        If ThisWorkbook.Sheets("VR").Cells(i, 1) = msnv Then
            temp = ThisWorkbook.Sheets("VR").Cells(i, 3)
            If IsDate(temp) = True Then 'Du lieu nhap la ngay thang, khong co loi gi
                dtemp1 = Format(temp, "dd/mm/yyyy")
                f1 = True
            End If
            temp = ThisWorkbook.Sheets("VR").Cells(i, 4)
            If IsDate(temp) = True Then 'Du lieu nhap la ngay thang, khong co loi gi
                dtemp2 = Format(temp, "dd/mm/yyyy")
                f2 = True
            End If
            If f1 = True And f2 = True Then
                If IsDate(dtemp1) = True And IsDate(dtemp2) = True Then 'Kiem tra lan nua cho chac, minh nghi la khong can thiet
                    If dtemp1 <= ngaychamcong And ngaychamcong <= dtemp2 Then
                        ngay = ""
                        Exit Function
                    End If
                End If
            End If
        End If
    Next i
    Application.ScreenUpdating = True
End Function
Tôi nhận thức rằng box này của diễn đàn là không dẫn link. Trong code trên có sử dụng một số hàm mà tôi nghĩ người đọc nếu có link tham khảo thì sẽ hiểu hơn. Do đó tôi inbox riêng cho bạn.
Kết quả thực tế:
224668

Về việc thảo luận thiết kế, cho phép mình không bàn ở topic này.
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn xem file
 

File đính kèm

  • BCC.rar
    16.6 KB · Đọc: 15
Upvote 0
Cảm ơn anh.
Do sơ ý, em quên diễn tả thêm ý: đánh x phải sau ngày nhận hồ sơ.
VD: Trường hợp của Nguyễn Hoài Khanh, ngày nhận hồ sơ là 12/8/2019, thì phải đánh x sau ngày này
Nhờ anh chỉnh sữa bổ sung giúp em
Trân trọng cảm ơn
Bài đã được tự động gộp:



1. Mình thấy file của bạn đưa ra ví dụ chưa đúng.
View attachment 224665
Cụ thể người này tháng 9 mới nghỉ cho nên bảng chấm công tháng 8 không thể coi đây là ngày họ nghỉ mà không chấm công cho họ.

Phần này do mình sơ ý, đánh lộn tháng 9, nhưng mình cũng có thể mình dùng dữ liệu Việc riêng này cho bảng công tháng 9, cho nên nếu không thỏa điều kiện thì sẽ không đánh x

2. Về code hiện tại của bạn dùng VLOOKUP tức là cột A ở trên, theo mình hiểu mã nhân viên chỉ được xuất hiện một lần.
Nếu mình hiểu sai hãy phản hồi lại cho mình biết.
Như vậy tình huống thực tế sẽ có trường hợp:
Người A nghỉ ngày 10/8/2019 việc riêng
Người A nghỉ ngày 20/8/2019 việc riêng
Như thế người A sẽ xuất hiện hai lần. Vì thế VLOOKUP lúc này là không ổn.
Phần này, đúng là có thể xảy ra người A xuất hiện 2, 3 lần nghỉ việc riêng / tháng. Nhờ bạn xử lý trường hợp này dùm

3. Về bài toán của bạn hình như hơi ngược với với thực tế, người ta chấm công hàng ngày, rồi người quản lý list lọc ra dữ liệu cần.
Còn bạn, từ danh sách ngày nghỉ, tự điền vào chấm công.
Do công việc đặc thù hàng ngày nên buộc mình phải làm ngược vậy

4. Vì không biết khả năng của bạn muốn như thế nào, cho nên mình code ở mức đơn giản nhất để bạn dễ đọc, mà không ưu tiên tốc độ.
Phần này mình có 1 số ý kiến sau ạ
- Tổng x chưa bằng Tổng Ngày công đã cho ban đầu
- Đánh x phải từ bằng hoặc sau ngày nhận hồ sơ. Nếu Tổng ngày công cho ban đầu nhiều hơn nếu tính từ ngày nhận hồ sơ thì xuất hiện Thông báo lỗi

VD: trường hợp của Nguyễn Hoài Khanh, ngày hồ sơ 12/8/2019
Tổng công ban đầu là 18, Nghỉ việc riêng ngày 12/8/2019

Như vậy nếu nhân viên này đi làm đủ công kể từ ngày nhận hồ sơ là 17 ngày ( không tính Chủ nhật). Nhưng nhân viên này nghỉ việc riêng thêm 1 ngày nữa vậy số công cần đánh x chỉ là 16, nhưng đề ra là 18. Vì vậy sẽ xuất hiện thông báo lỗi cho biết số ngày bị dư

Tôi nhận thức rằng box này của diễn đàn là không dẫn link. Trong code trên có sử dụng một số hàm mà tôi nghĩ người đọc nếu có link tham khảo thì sẽ hiểu hơn. Do đó tôi inbox riêng cho bạn.
Về việc thảo luận thiết kế, cho phép mình không bàn ở topic này.
Ok bạn
 
Lần chỉnh sửa cuối:
Upvote 0
Ngày vào công ty thì phải chấm công cho người ta chứ bạn, chứ sao lại chấm công sau ngày đó.
Trường hợp này thì lại dùng được VLOOKUP vì sheet DT mỗi người chỉ xuất hiện một lần:
Mã:
Function ngay(ByVal msnv As String, ByVal ngaychamcong As Date, ByVal thu As String) As String
    Dim i           As Long
    Dim rend        As Long
    'Dim arrtemp     As Variant  => Update: khong dung cai nay, dung truc tiep cells cho ban de hieu
    Dim dtemp1      As Date
    Dim dtemp2      As Date
    Dim temp        As String
    Dim f1 As Boolean, f2 As Boolean
    Const rstart    As Long = 2 'Dong bat dau
    Application.ScreenUpdating = False
    If thu = "CN" Then
        ngay = ""
        Exit Function 'Ket thuc chuong trinh, khong can kiem tra ngay phep nua.
    End If
 
    rend = ThisWorkbook.Sheets("VR").Cells(Rows.Count, 1).End(xlUp).Row
  
  
    If rend < rstart Then    'Neu khong co du lieu viec rieng
        ngay = "x"
        Exit Function ' Ket thuc chuong trinh
    End If

    ngay = ngayvaocongty(msnv, ngaychamcong) '"x" 'Mac dinh la OK
    'Tim kiem ma nhan vien
    For i = rstart To rend Step 1
        f1 = False
        f2 = False
      
        If ThisWorkbook.Sheets("VR").Cells(i, 1) = msnv Then
            temp = ThisWorkbook.Sheets("VR").Cells(i, 3)
            If IsDate(temp) = True Then 'Du lieu nhap la ngay thang, khong co loi gi
                dtemp1 = Format(temp, "dd/mm/yyyy")
                f1 = True
            End If
            temp = ThisWorkbook.Sheets("VR").Cells(i, 4)
            If IsDate(temp) = True Then 'Du lieu nhap la ngay thang, khong co loi gi
                dtemp2 = Format(temp, "dd/mm/yyyy")
                f2 = True
            End If
            If f1 = True And f2 = True Then
                If IsDate(dtemp1) = True And IsDate(dtemp2) = True Then 'Kiem tra lan nua cho chac, minh nghi la khong can thiet
                    If dtemp1 <= ngaychamcong And ngaychamcong <= dtemp2 Then
                        ngay = ""
                        Exit Function
                    End If
                End If
            End If
        End If
    Next i
    Application.ScreenUpdating = True
End Function
Function ngayvaocongty(ByVal msnv As String, ByVal ngaychamcong As Date) As String
    'Dim j   As Long  => update: không cần, dùng VLOOKUP để tìm
    Dim rend2   As Long
    Dim NgayHS As Date
    Dim CSDL As Range
    Const rstart2   As Long = 2
   
    ngayvaocongty = "x"
    rend = ThisWorkbook.Sheets("DT").Cells(Rows.Count, 1).End(xlUp).Row
    If rend < rstart2 Then Exit Function 'ket thuc vi khong co du lieu
   
    On Error Resume Next
    Set CSDL = Range("Table1")
    NgayHS = Application.WorksheetFunction.VLookup(msnv, CSDL, 3)
    If ngaychamcong < CDate(NgayHS) Then ngayvaocongty = ""
End Function
Kết quả:
224737
 
Upvote 0
Ngày vào công ty thì phải chấm công cho người ta chứ bạn, chứ sao lại chấm công sau ngày đó.
Trường hợp này thì lại dùng được VLOOKUP vì sheet DT mỗi người chỉ xuất hiện một lần:
Mã:
Function ngay(ByVal msnv As String, ByVal ngaychamcong As Date, ByVal thu As String) As String
    Dim i           As Long
    Dim rend        As Long
    'Dim arrtemp     As Variant  => Update: khong dung cai nay, dung truc tiep cells cho ban de hieu
    Dim dtemp1      As Date
    Dim dtemp2      As Date
    Dim temp        As String
    Dim f1 As Boolean, f2 As Boolean
    Const rstart    As Long = 2 'Dong bat dau
    Application.ScreenUpdating = False
    If thu = "CN" Then
        ngay = ""
        Exit Function 'Ket thuc chuong trinh, khong can kiem tra ngay phep nua.
    End If

    rend = ThisWorkbook.Sheets("VR").Cells(Rows.Count, 1).End(xlUp).Row
 
 
    If rend < rstart Then    'Neu khong co du lieu viec rieng
        ngay = "x"
        Exit Function ' Ket thuc chuong trinh
    End If

    ngay = ngayvaocongty(msnv, ngaychamcong) '"x" 'Mac dinh la OK
    'Tim kiem ma nhan vien
    For i = rstart To rend Step 1
        f1 = False
        f2 = False
     
        If ThisWorkbook.Sheets("VR").Cells(i, 1) = msnv Then
            temp = ThisWorkbook.Sheets("VR").Cells(i, 3)
            If IsDate(temp) = True Then 'Du lieu nhap la ngay thang, khong co loi gi
                dtemp1 = Format(temp, "dd/mm/yyyy")
                f1 = True
            End If
            temp = ThisWorkbook.Sheets("VR").Cells(i, 4)
            If IsDate(temp) = True Then 'Du lieu nhap la ngay thang, khong co loi gi
                dtemp2 = Format(temp, "dd/mm/yyyy")
                f2 = True
            End If
            If f1 = True And f2 = True Then
                If IsDate(dtemp1) = True And IsDate(dtemp2) = True Then 'Kiem tra lan nua cho chac, minh nghi la khong can thiet
                    If dtemp1 <= ngaychamcong And ngaychamcong <= dtemp2 Then
                        ngay = ""
                        Exit Function
                    End If
                End If
            End If
        End If
    Next i
    Application.ScreenUpdating = True
End Function
Function ngayvaocongty(ByVal msnv As String, ByVal ngaychamcong As Date) As String
    'Dim j   As Long  => update: không cần, dùng VLOOKUP để tìm
    Dim rend2   As Long
    Dim NgayHS As Date
    Dim CSDL As Range
    Const rstart2   As Long = 2
  
    ngayvaocongty = "x"
    rend = ThisWorkbook.Sheets("DT").Cells(Rows.Count, 1).End(xlUp).Row
    If rend < rstart2 Then Exit Function 'ket thuc vi khong co du lieu
  
    On Error Resume Next
    Set CSDL = Range("Table1")
    NgayHS = Application.WorksheetFunction.VLookup(msnv, CSDL, 3)
    If ngaychamcong < CDate(NgayHS) Then ngayvaocongty = ""
End Function
Kết quả:
View attachment 224737
Chổ Nguyễn Hoài Khanh, ngày 12 nghỉ việc riêng nên không đánh x bạn ơi. với lại
Nếu Tổng ngày công cho ban đầu nhiều hơn nếu tính từ ngày nhận hồ sơ thì xuất hiện Thông báo lỗi
VD: trường hợp của Nguyễn Hoài Khanh, ngày hồ sơ 12/8/2019
Tổng công ban đầu là 18, Nghỉ việc riêng ngày 12/8/2019
Như vậy nếu nhân viên này đi làm đủ công kể từ ngày nhận hồ sơ là 17 ngày ( không tính Chủ nhật). Nhưng nhân viên này nghỉ việc riêng thêm 1 ngày nữa vậy số công cần đánh x chỉ là 16, nhưng đề ra là 18. Vì vậy sẽ xuất hiện thông báo lỗi cho biết số ngày bị dư
 
Upvote 0
Do sơ ý, em quên diễn tả thêm ý: đánh x phải sau ngày nhận hồ sơ.
VD: Trường hợp của Nguyễn Hoài Khanh, ngày nhận hồ sơ là 12/8/2019, thì phải đánh x sau ngày này
Nhờ anh chỉnh sữa bổ sung giúp em
Chuyện 'quên diễn tả thêm ý' này khiến bạn phải tìm cách tự sửa hàm tự tạo SCong(Dat As Date) As String
theo hướng dẫn của mình đi vậy
Hàm cũ đã được mình sửa lại như sau:
PHP:
Function SCong(Dat As Date) As String
Dim J As Integer
For J = 0 To 30
    If Month(J + Dat) <> Month(Dat) Then Exit For   'Mói Thêm Để Thoát Vòng Lặp Khi Hết Tháng   '
    If Weekday(J + Dat) > 1 Then
        If J < 9 Then
            SCong = SCong & "0" & CStr(Day(J + Dat))
        Else
            If J Mod 2 = 1 Then                          'Mói Thêm       '
                SCong = SCong & CStr(Day(J + Dat))
            Else                                         'Mói Thêm       '
                SCong = CStr(Day(J + Dat)) & SCong      'Mói Thêm       '
            End If                                       'Mói Thêm   '
        End If
    End If
Next J
End Function
Hàm này có mục đích là nối chuỗi các ngày trong tháng trừ (bỏ) ngày chủ nhật (của tháng đó)
Hàm hiện tại nhận tham biến là ngày đầu (của tháng đang khảo sát)

Bạn phải tìm cách sửa lại là tham biến gởi đến hàm là ngày sau ngay ngày nhận hồ sơ

& lúc đó là vòng lập từ ngày chứa trong tham biến cho đến cuối tháng (tất nhiên là trừ những ngày chủ nhật khi đang duyệt vòng lặp)
Bạn có thời hạn 03 ngày để làm việc này & chúc thành công!
 
Lần chỉnh sửa cuối:
Upvote 0
Còn 1 vấn đề nữa trong thực tế có thể diễn ra nhưng tác giả bài đăng chưa đề cập tới: Đó là 1 nhân vật có thể nghỉ việc riêng 2 hay hơn 2 lần trong tháng (nghỉ đứt đoạn). Mình ví dụ:

MSNVHOVATENBATDAUKET THUCMSNVHOVATENNgày ĐầuNgày Cuối
HTA00Huỳnh Thị Thu An8/17/20198/17/2019HTA00Huỳnh Thị Thu An8/17/20198/17/2019
HTA01Hoàng Thanh Ẩn8/18/20198/18/2019HTA01Hoàng Thanh Ẩn8/18/20198/18/2019
HTA02Hồ Thị Ánh8/19/20198/19/2019HTA02Hồ Thị Ánh8/19/20198/19/2019
NHD00Nguyễn Hồng Diễm8/20/20198/20/2019NHD00Nguyễn Hồng Diễm8/20/20198/20/2019
NTN00Nguyễn Thị Nị8/25/20198/29/2019NTN00Nguyễn Thị Nị8/25/20198/26/2019
NHD00Nguyễn Hồng Diễm8/26/20198/27/2019

Mình nghĩ là vấn đề này có thể xài phương thức FindNext là đơn giản hơn các cách thức khác; & những mong tác giả tiếp tục giả quyết
 
Upvote 0
Chổ Nguyễn Hoài Khanh, ngày 12 nghỉ việc riêng nên không đánh x bạn ơi. với lại
224961

Bạn có thể chỉ ra, cái người này nghỉ việc riêng được thể hiện ở đâu hay không, sao nhìn vào sheet VR không thấy người này nghỉ việc riêng?

Thông báo lỗi như thế nào, nội dung thông báo lỗi là gì? Tôi nghĩ nếu đã tính ra x rồi, thì bạn có thể dùng COUNTIF để đếm số x trên mỗi hàng và so sánh với ô ngày công, kết hợp với Condition Format, bạn có thể tô màu thông báo tùy ý.
Code o bai viet #7 đã làm đúng theo yêu cầu của bạn. Bạn phản hồi ngày 12 Hoài Khanh nghỉ việc riêng nhưng sheet VR không có ghi người này nghỉ việc riêng. Trong file demo bạn đưa ra cũng thể hiện là ngày 12 người này đi làm. Khi phản hồi, hãy đưa ra dẫn chứng.

Sai. Lý do: ngày 12 Hoài Khanh phải nghỉ.

Việc Hoài Khanh phải nghỉ được thể hiện ở đâu?

Tại sao trên sheet VR không tìm thấy Hoài Khanh?

Sheet VR nếu nhận thức là ghi nghỉ việc riêng, nhận thức đó là đúng hay sai?

Còn 1 vấn đề nữa trong thực tế có thể diễn ra nhưng tác giả bài đăng chưa đề cập tới: Đó là 1 nhân vật có thể nghỉ việc riêng 2 hay hơn 2 lần trong tháng (nghỉ đứt đoạn).
Tac gia da phan hoi o bai viet #6:
Phần này, đúng là có thể xảy ra người A xuất hiện 2, 3 lần nghỉ việc riêng / tháng. Nhờ bạn xử lý trường hợp này dùm

Code ở #7 đã đáp ứng yêu cầu này. Hiện đang phản hồi sai là tại sao ngày 12 Hoài Khanh đi làm.

Phản hồi ngược: Hoài Khanh nghỉ việc riêng ngày 12 được thể hiện ở đâu, đang chờ tác giả phản hồi
 
Lần chỉnh sửa cuối:
Upvote 0
View attachment 224961

Bạn có thể chỉ ra, cái người này nghỉ việc riêng được thể hiện ở đâu hay không, sao nhìn vào sheet VR không thấy người này nghỉ việc riêng?
Sai. Lý do: ngày 12 Hoài Khanh phải nghỉ.
Việc Hoài Khanh phải nghỉ được thể hiện ở đâu?
Tại sao trên sheet VR không tìm thấy Hoài Khanh?
Xin lỗi, mình xem nhầm chổ này.
Thông báo lỗi như thế nào, nội dung thông báo lỗi là gì? Tôi nghĩ nếu đã tính ra x rồi, thì bạn có thể dùng COUNTIF để đếm số x trên mỗi hàng và so sánh với ô ngày công, kết hợp với Condition Format, bạn có thể tô màu thông báo tùy ý.
Ok, mình sẽ xử lý bằng Condition Format,

Sheet VR nếu nhận thức là ghi nghỉ việc riêng, nhận thức đó là đúng hay sai?
Trường hợp này đôi khi không phải là nghỉ việc riêng không mà còn nhiều lý do khác như Ốm, Con ốm, ... nhưng do để đơn giản mình chỉ ghi vậy thôi. Nếu làm đúng ra là phải ghi cả ký hiệu nghỉ việc riêng lên bảng chấm công. Khi đó bên bảng Việc riêng sẽ bổ sung thêm cột Ký hiệu nghỉ việc khi, và lấy ký hiệu này điền lên Bảng chấm công, ....

Bạn phải tìm cách sửa lại là tham biến gởi đến hàm là ngày sau ngay ngày nhận hồ sơ
& lúc đó là vòng lập từ ngày chứa trong tham biến cho đến cuối tháng (tất nhiên là trừ những ngày chủ nhật khi đang duyệt vòng lặp)
Bạn có thời hạn 03 ngày để làm việc này & chúc thành công!
Hic hic
 
Upvote 0
Xin lỗi, mình xem nhầm chổ này.
Nhu vay toi nhan thuc rang bai viet #7 da dap ung yeu cau cua ban.
Bạn đưa ra yêu cầu thì nên giải thích tường tận. Giải thích thiếu thông tin là điều không nên.
Phản hồi sai lại là điều không nên nữa. Bạn là người hiểu rõ nhất mình muốn gì, việc kiểm tra lại code phải tỉ mỉ. Nhưng ngay cả điều này bạn cũng không làm được. Người ta code và lại còn check lại để phản hồi lại là bạn check sai. Tôi thì thấy lo cho tổ chức của bạn. Và lo cho cấp dưới của bạn, khi họ nhận chỉ thị từ người cấp trên như thế này, cứ như thể anh/chị làm việc không có trách nhiệm vậy.
 
Upvote 0
Còn 1 vấn đề nữa trong thực tế có thể diễn ra nhưng tác giả bài đăng chưa đề cập tới: Đó là 1 nhân vật có thể nghỉ việc riêng 2 hay hơn 2 lần trong tháng (nghỉ đứt đoạn).
Đúng là có nghỉ đứt đoạn, phần này em có đề cập ở bài #6
 
Upvote 0
Nhu vay toi nhan thuc rang bai viet #7 da dap ung yeu cau cua ban.
Có 1 vấn đề là trong code ở bài #7 chưa xử lý được là Tổng x = Tổng Ngày công đã cho ban đầu.

VD: Trường hợp Huỳnh Thị Thu An, nghỉ việc riêng 1 ngày, Tổng ngày công ban đầu là 22, bây giờ muốn điều chỉnh Tổng ngày công ban đầu thành 21 ngày => nghỉ việc riêng thêm 1 ngày, và ngày này không được cập nhật bên danh sách nghỉ việc riêng (do đặc thù công việc nên buộc phải làm vậy), Như vậy Tổng x sẽ là 21 (Code của anh SA_DQ đã xử lý rất tốt vấn đề này)
 
Upvote 0
MSNVHOVATENBATDAUKET THUC
HTA00Huỳnh Thị Thu An8/17/20198/17/2019
NTN00Nguyễn Thị Nị8/19/20198/19/2019
NHD00Nguyễn Hồng Diễm20/08/201920/08/2019
NTN00Nguyễn Thị Nị8/25/20198/28/2019
Đúng là có nghỉ đứt đoạn, phần này em có đề cập ở bài #6
PHP:
Sub ChamCongLao()
Dim Rng As Range, sRng As Range
Dim J As Integer, Dat As Date, Col As Integer, W As Integer
Dim StrC As String, CNg As String, MyAdd As String

With Sheets("VR")
    Set Rng = .Range(.[A1], .[A1].End(xlDown))
End With
1 StrC = SCong([c1].Value)                   'Loai Công Chu Nhât '
For J = 5 To [A5].End(xlDown).Row
2    CNg = TronChuoi(StrC)                  'Trôn Ngày Công Còn Lai     *'
3    Cells(J, "D").Resize(, 31).ClearContents   'Xóa Du Liêu Cua Dòng Dang Khao Sát '
4    Set sRng = Rng.Find(Cells(J, "A").Value, , xlFormulas, xlWhole)    'Tìm Trong Trang "VR"       '
41    If sRng Is Nothing Then                       'Nêu Không Tìm Tháy     '
        For W = 1 To Cells(J, "AK").Value
            Col = CInt(Mid(CNg, 2 * W - 1, 2))
            Cells(J, "C").Offset(, Col).Value = "X"
        Next W
42    Else                                                  'Khi Tìm Thây       '
        MyAdd = sRng.Address
        Do
            Dat = sRng.Offset(, 2).Value
5            For W = Day(Dat) To 31                         'Duyêt Theo Các Ngày Da Nghi        '
6                CNg = Replace(CNg, CStr(W), "")       'Xóa Các Ngày Theo Danh Sách VR  '
                If W = Day(sRng.Offset(, 3).Value) Then Exit For
            Next W
            Set sRng = Rng.FindNext(sRng)
        Loop While Not sRng Is Nothing And sRng.Address <> MyAdd
7        For W = 1 To Cells(J, "AK").Value              'Chám Công Cho Nhung Ngày Còn Lai       '
            Col = CInt(Mid(CNg, 2 * W - 1, 2))                 '*  '
            Cells(J, "C").Offset(, Col).Value = "X"
        Next W
    End If
Next J
End Sub
TỔNG111213141516171819202122232425262728293031
MSNVHỌ VÀ TÊNCÔNGCNT2T3T4T5T6T7CNT2T3T4T5T6T7CNT2T3T4T5T6T7
HTA00Huỳnh Thị Thu An 22.0XXXXXXXXXXXXX
NHK00Nguyễn Hoài Khanh 18.0XXXXXXXXXXX
BTM00Bạch Thị My 15.0XXXXXXX
THC00Trần Hồng Chi 14.0XXXXXXXXXXXXXX
NHD00Nguyễn Hồng Diễm 22.0XXXXXXXXXXXXXX
NTN00Nguyễn Thị Nị 19.0XXXXXXXXXXXX
HNH00Huỳnh Thị Như Huỳnh 12.0XXXXXXXXXXXX
TCH00Tạ Chí Hiếu 11.0XXXX
LTT00Lê Trung Toàn 10.0XXXXXX
 
Lần chỉnh sửa cuối:
Upvote 0
Có 1 vấn đề là trong code ở bài #7 chưa xử lý được là Tổng x = Tổng Ngày công đã cho ban đầu.

VD: Trường hợp Huỳnh Thị Thu An, nghỉ việc riêng 1 ngày, Tổng ngày công ban đầu là 22, bây giờ muốn điều chỉnh Tổng ngày công ban đầu thành 21 ngày => nghỉ việc riêng thêm 1 ngày, và ngày này không được cập nhật bên danh sách nghỉ việc riêng (do đặc thù công việc nên buộc phải làm vậy), Như vậy Tổng x sẽ là 21 (Code của anh SA_DQ đã xử lý rất tốt vấn đề này)
Đọc cái này tôi chẳng hiểu gì cả. Ngày nào người ta nghỉ thì không ghi vào chấm công, thì điều này đã làm rồi.

Việc code làm tốt hay không thì vấn đề nó nằm ở chỗ cách bạn đưa ra yêu cầu và trình bày thông tin như thế nào ấy.
Người như bạn, chắc người ta không dám giao cho công việc có tính trách nhiệm cao. Chẳng hạn bảo bạn đặt hàng 1 triệu cái bóng đèn. Phía đối tác người ta làm sắp xong thì bạn bảo bạn nhầm hoặc đưa thiếu thông tin, tổ chức không chỉ thiết hại kinh tế mà còn tổn hại uy tín.

Hơn 700 bài viết, tham gia diễn đàn gần chục năm, một bài như thế này không tự làm được! Tôi không còn biết nói gì.
 
Upvote 0
(1) Đọc cái này tôi chẳng hiểu gì cả. Ngày nào người ta nghỉ thì không ghi vào chấm công, thì điều này đã làm rồi.
(2) Việc code làm tốt hay không thì vấn đề nó nằm ở chỗ cách bạn đưa ra yêu cầu và trình bày thông tin như thế nào ấy.
(3)
Người như bạn, chắc người ta không dám giao cho công việc có tính trách nhiệm cao. Chẳng hạn bảo bạn đặt hàng 1 triệu cái bóng đèn. Phía đối tác người ta làm sắp xong thì bạn bảo bạn nhầm hoặc đưa thiếu thông tin, tổ chức không chỉ thiết hại kinh tế mà còn tổn hại uy tín.
(4) Hơn 700 bài viết, tham gia diễn đàn gần chục năm, một bài như thế này không tự làm được! Tôi không còn biết nói gì.

(1) Vấn đề ở đây là tạo BCC (bảng chấm công) đổi phó; Trong thực tiển có hiện tượng này trong 1 số ngành sản xuất hay kinh doanh; Mình thường thấy ở ngành xây dựng. . . .

(2) Việc viết code có tốt hay không phụ thuộc vô chủ quan của các bên liên quan:
* Người đưa ra iêu cầu có mô tả như IZO đòi hỏi hay không, có nắm bắt được công việc đang phụ trách hay không; Có kiến thức ít nhiều về vấn đề iêu cầu hay không?
* Người tiếp nhận & giải quyết iêu cầu có kiến thức về lĩnh vực iêu cầu hay không; Khả năng giải quyết vấn đề tới đâu & quan trọng là đưa ra giải pháp phù hợp với trình độ của người iêu cầu hay không nữa.
* . . . .

(3) Mọi giả dụ đều là giả dụ; Còn chuyện làm ăn lớn thì sẽ có hợp đồng & nếu không vừa lòng nhau thì đưa nhau ra Tòa; . . . .

(4) Bạn không nên nói như vậy; Như mình có hàng vạn bài viết ở đây đi nữa vẫn là dốt đặt về lĩnh vực công thức; Vẫn cuối đầu khâm phục những 'Siêu công thức' của diễn đàn thân thương của chúng ta!
& Ngay trong VBA mình cũng tự đánh giá là trình độ trung bình cao mà thôi. Tuy nhiên mình có thực tiển của hơn 30 năm công tác trong môi trường SX nên có thể hiểu vài vấn đề trong thực tế cuộc sống cần đáp ứng hay thích ứng.

Xin chào trân trọng & chúc vui!
 
Upvote 0
Gợi ý:

Trước tiên là sửa lại hàm đã viết này:
Mã:
Function SCong(Dat As Date) As String
Dim J As Integer
For J = 0 To 30
    If Month(J + Dat) <> Month(Dat) Then Exit For   'Mói Thêm   '
    If Weekday(J + Dat) > 1 Then
        If J < 9 Then
            SCong = SCong & "0" & CStr(Day(J + Dat))
        Else
            If J Mod 2 = 1 Then                                 'Mói Thêm       '
                SCong = SCong & CStr(Day(J + Dat))
            Else                                                        'Mói Thêm       '
                SCong = CStr(Day(J + Dat)) & SCong      'Mói Thêm       '
            End If                                                      'Mói Thêm   '
        End If
    End If
Next J
End Function

thành như sau:
PHP:
Function SCong(Dat As Date, Optional Ngay As Byte = 0) As String
Dim J As Integer
For J = Ngay To 30
    If Month(J + Dat) <> Month(Dat) Then Exit For
    If Weekday(J + Dat) > 1 Then
        If J < 9 Then
            SCong = SCong & "0" & CStr(Day(J + Dat))
        Else
            If J Mod 2 = 1 Then
                SCong = SCong & CStr(Day(J + Dat))
            Else
                SCong = CStr(Day(J + Dat)) & SCong
            End If
        End If
    End If
Next J
End Function

Lúc đó, người nào mới vô trong tháng thì ta gởi tham biến Ngay là Day([Ngày Vô CQ])
VD: Trường hợp của Nguyễn Hoài Khanh, ngày nhận hồ sơ là 12/8/2019, thì phải đánh x sau ngày này
Như vậy ta gọi hàm SCong() với 2 tham biến cho người này:
SCong(#08/01/2019#, 13)
Còn những người nhận hồ sơ trước tháng 8 thì cú pháp chỉ là (như cũ):
SCong(#08/01/2019#)
 
Upvote 0
Gợi ý:

Trước tiên là sửa lại hàm đã viết này:
Mã:
Function SCong(Dat As Date) As String
Dim J As Integer
For J = 0 To 30
    If Month(J + Dat) <> Month(Dat) Then Exit For   'Mói Thêm   '
    If Weekday(J + Dat) > 1 Then
        If J < 9 Then
            SCong = SCong & "0" & CStr(Day(J + Dat))
        Else
            If J Mod 2 = 1 Then                                 'Mói Thêm       '
                SCong = SCong & CStr(Day(J + Dat))
            Else                                                        'Mói Thêm       '
                SCong = CStr(Day(J + Dat)) & SCong      'Mói Thêm       '
            End If                                                      'Mói Thêm   '
        End If
    End If
Next J
End Function

thành như sau:
PHP:
Function SCong(Dat As Date, Optional Ngay As Byte = 0) As String
Dim J As Integer
For J = Ngay To 30
    If Month(J + Dat) <> Month(Dat) Then Exit For
    If Weekday(J + Dat) > 1 Then
        If J < 9 Then
            SCong = SCong & "0" & CStr(Day(J + Dat))
        Else
            If J Mod 2 = 1 Then
                SCong = SCong & CStr(Day(J + Dat))
            Else
                SCong = CStr(Day(J + Dat)) & SCong
            End If
        End If
    End If
Next J
End Function

Lúc đó, người nào mới vô trong tháng thì ta gởi tham biến Ngay là Day([Ngày Vô CQ])

Như vậy ta gọi hàm SCong() với 2 tham biến cho người này:
SCong(#08/01/2019#, 13)
Còn những người nhận hồ sơ trước tháng 8 thì cú pháp chỉ là (như cũ):
SCong(#08/01/2019#)
Nhờ anh giúp đỡ phần còn lại, em hết biết rồi ạ.
Cảm ơn anh nhiều


Ps: Em tìm ra được Ngày Hồ sơ của từng người, không biết vậy có đúng không ạ?
Như vậy ta gọi hàm SCong() với 2 tham biến cho người này:
SCong(#08/01/2019#, 13)
Còn những người nhận hồ sơ trước tháng 8 thì cú pháp chỉ là (như cũ):
SCong(#08/01/2019#)
Phần này em không biết cách đưa vô như thế nào? Nhờ anh chỉ giúp
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT
Back
Top Bottom