Nhờ cả nhà hỗ trợ giúp cách kiểm tra thời gian theo điều kiện cho trước

Liên hệ QC

tangoctuan

Thành viên hoạt động
Tham gia
22/4/08
Bài viết
153
Được thích
19
Nhờ các bạn hỗ trợ giúp. Mình muốn kiểm tra việc khai báo của các nhân viên có đúng hay không.
Thông tin khai báo từ cột A đến D của sheet "Khai báo". Kết quả kiểm tra tại cột E của sheet "Khai báo", hiện mình đang làm thủ công (nhìn bằng mắt) và có giải thích vì sao lại ra kết quả như thế ở cột F. Vậy nhờ các bạn hỗ trợ giúp một đoạn VBA để check tự động được ở cột E với ạ.
Cảm ơn mọi người!
 

File đính kèm

  • Export.xlsx
    12.7 KB · Đọc: 12
Nhờ các bạn hỗ trợ giúp. Mình muốn kiểm tra việc khai báo của các nhân viên có đúng hay không.
Thông tin khai báo từ cột A đến D của sheet "Khai báo". Kết quả kiểm tra tại cột E của sheet "Khai báo", hiện mình đang làm thủ công (nhìn bằng mắt) và có giải thích vì sao lại ra kết quả như thế ở cột F. Vậy nhờ các bạn hỗ trợ giúp một đoạn VBA để check tự động được ở cột E với ạ.
Cảm ơn mọi người!
Bấm nút để chạy thủ tục kiểm tra.
 

File đính kèm

  • Export_KiemTraThoiGian_tangoctuan.xlsm
    23.4 KB · Đọc: 9
Bấm nút để chạy thủ tục kiểm tra.
Cám ơn bác rất nhiều. Nhưng nhờ bác thay đổi code lại giúp mình chỗ trường thời gian cột F sheet Data có thay đổi định dạng một chút từ file xuất của hệ thống (thành ra tương tự trường thời gian trong sheet Khai báo). Cám ơn bác!
 

File đính kèm

  • Export_KiemTraThoiGian_tangoctuan.xlsm
    23.3 KB · Đọc: 6
Cám ơn bác rất nhiều. Nhưng nhờ bác thay đổi code lại giúp mình chỗ trường thời gian cột F sheet Data có thay đổi định dạng một chút từ file xuất của hệ thống (thành ra tương tự trường thời gian trong sheet Khai báo). Cám ơn bác!
Bạn xem lại thử.
 

File đính kèm

  • Export_KiemTraThoiGian_tangoctuan.xlsm
    22.6 KB · Đọc: 10
Nếu không có ngày đi thì xem là ngày hiện tại
Bạn ơi, cho mình nhờ chút. Mình có chạy dữ liệu như file gửi kèm thì kiểm tra thấy báo kết quả chưa đúng. Cụ thể, nếu như không có dòng thứ 2 của sheet Data thì code chạy ra kết quả chính xác bên Khai báo là Ok. Nhưng nếu có dòng thứ 2 đó thì bên Khai báo sẽ là NOK.
Vậy nhờ bạn chỉnh lại giúp mình ở chỗ là: Nếu thời điểm đi trước thời điểm đến thì có nghĩa thiết bị mang đến đã có tại tỉnh từ thời điểm đến rồi.
Ví dụ như trong file thì sẽ hiểu là: Ở sheet Data, thiết bị A mang đi khỏi Hà Giang từ năm 2018, nhưng đã lại mang đến Hà Giang vào năm 2019 => Bên sheet Khai báo, thiết bị A vận hành tại Hà Giang vào năm 2020 là hợp lý (Ok).
Nhờ bạn điều chỉnh giúp mình với nhé. Cám ơn bạn nhiều!
 

File đính kèm

  • File_vi_du.xlsm
    23 KB · Đọc: 3
Bạn ơi, cho mình nhờ chút. Mình có chạy dữ liệu như file gửi kèm thì kiểm tra thấy báo kết quả chưa đúng. Cụ thể, nếu như không có dòng thứ 2 của sheet Data thì code chạy ra kết quả chính xác bên Khai báo là Ok. Nhưng nếu có dòng thứ 2 đó thì bên Khai báo sẽ là NOK.
Vậy nhờ bạn chỉnh lại giúp mình ở chỗ là: Nếu thời điểm đi trước thời điểm đến thì có nghĩa thiết bị mang đến đã có tại tỉnh từ thời điểm đến rồi.
Ví dụ như trong file thì sẽ hiểu là: Ở sheet Data, thiết bị A mang đi khỏi Hà Giang từ năm 2018, nhưng đã lại mang đến Hà Giang vào năm 2019 => Bên sheet Khai báo, thiết bị A vận hành tại Hà Giang vào năm 2020 là hợp lý (Ok).
Nhờ bạn điều chỉnh giúp mình với nhé. Cám ơn bạn nhiều!
Có 2 vấn đề cần xác định lại:
1/ Vấn đề 1 liên quan đến giải thuật: Dữ liệu thiết bị mang đến, mang đi có theo khi nào không theo trình tự thời gian không? Ví dụ: Thiết bị A đến 2018 đi 2019 và đến 2020 đi 2021 nhưng trên data lại xếp: đến 2018 đi 2021 và đến 2020 đi 2019 ... Khi đó code sẽ nhận định nhầm khoảng thời gian => sai kết quả cuối cùng.
2/ Vấn đề 2 liên quan đến thời gian thực thi code: Nếu thiết bị A chỉ có 1 dòng đến và đi thì khi dò đến đúng dòng đó kiểm tra rồi thoát. Còn nếu có nhiều thiết bị có nhiều dòng đến và đi thì buộc phải dò tiếp hoặc dò đến hết array (chưa biết kiểu nào vì tạm thời tôi chưa nghĩ đến giải thuật), lúc đó code sẽ chạy lâu gấp rưỡi đến gấp đôi so với hiện tại (ước chừng thế thôi). Mà hiện tại có thể chạy đến hàng mấy giờ rồi thì sắp đến không biết lâu đến chừng nào nữa.

Do vậy, thành viên nào có giải thuật tốt hơn thì quan tâm giải quyết trường hợp này với chứ tôi chỉ biết đến đó thôi.
 
Lần chỉnh sửa cuối:
Có 2 vấn đề cần xác định lại:
1/ Vấn đề 1 liên quan đến giải thuật: Dữ liệu thiết bị mang đến, mang đi có theo khi nào không theo trình tự thời gian không? Ví dụ: Thiết bị A đến 2018 đi 2019 và đến 2020 đi 2021 nhưng trên data lại xếp: đến 2018 đi 2021 và đến 2020 đi 2019 ... Khi đó code sẽ nhận định nhầm khoảng thời gian => sai kết quả cuối cùng.
2/ Vấn đề 2 liên quan đến thời gian thực thi code: Nếu thiết bị A chỉ có 1 dòng đến và đi thì khi dò đến đúng dòng đó kiểm tra rồi thoát. Còn nếu có nhiều dòng đến và đi thì buộc phải dò tiếp hoặc dò đến hết array (chưa biết kiểu nào vì tạm thời tôi chưa nghĩ đến giải thuật), lúc đó code sẽ chạy lâu gấp rưỡi đến gấp đôi so với hiện tại (ước chừng thế thôi). Mà hiện tại có thể chạy đến hàng mấy giờ rồi thì sắp đến không biết lâu đến chừng nào nữa.

Do vậy, thành viên nào có giải thuật tốt hơn thì quan tâm giải quyết trường hợp này với chứ tôi chỉ biết đến đó thôi.
Mình xin trả lời:
1/ Dữ liệu thiết bị mang đến và đi là theo trình tự thời gian.
Ví dụ: Thiết bị A mang đến năm 2017, mang đi 2018, rồi lại mang đến 2019.
Và nếu như không có thời gian mang đi thì có thể hiểu là từ 2019 đến hiện tại thiết bị A vẫn đang đặt tại tỉnh đó (chưa mang đi).
Còn nếu chỉ có thông tin: Thiết bị A mang đi khỏi tỉnh năm 2017, thì hiểu rằng từ 2017 trở về trước thiết bị A luôn đặt tại tỉnh đó. Chỉ có điều dữ liệu xuất ra không hết đến lịch sử quá khứ xa hơn nên thông tin thiết bị A mang đến tỉnh (giả sử năm 2016) không có trong Data thôi.
2/ Thiết bị A sẽ có nhiều dòng đến và đi. Vì thực tế như trên bạn đang ví dụ đó, A đến 2018, đi 2019, rồi lại quay về 2020, rồi lại đi 2021. Do đó mới cần kiểm tra thời gian máy A chạy tại tỉnh trong sheet Khai báo có chính xác, phù hợp với thông tin trong Data hay không. Lấy thông tin Data làm chuẩn để xét.
Để đảm bảo chính xác như vậy thì nhờ bạn điều chỉnh code để dò tiếp đến hết giúp mình, vì dù có lâu thì mình còn có thể đợi chờ được, nhưng kết quả khi chạy xong là tin tưởng được chính xác, còn hơn chạy nhanh nhưng kết quả lại không đúng, không sử dụng được.
Và mình có thể sẽ tối ưu lại Data để chạy nhanh hơn.

Vậy bạn xem hỗ trợ giúp mình nhé!
 
Mình xin trả lời:
1/ Dữ liệu thiết bị mang đến và đi là theo trình tự thời gian.
Ví dụ: Thiết bị A mang đến năm 2017, mang đi 2018, rồi lại mang đến 2019.
Và nếu như không có thời gian mang đi thì có thể hiểu là từ 2019 đến hiện tại thiết bị A vẫn đang đặt tại tỉnh đó (chưa mang đi).
Còn nếu chỉ có thông tin: Thiết bị A mang đi khỏi tỉnh năm 2017, thì hiểu rằng từ 2017 trở về trước thiết bị A luôn đặt tại tỉnh đó. Chỉ có điều dữ liệu xuất ra không hết đến lịch sử quá khứ xa hơn nên thông tin thiết bị A mang đến tỉnh (giả sử năm 2016) không có trong Data thôi.
2/ Thiết bị A sẽ có nhiều dòng đến và đi. Vì thực tế như trên bạn đang ví dụ đó, A đến 2018, đi 2019, rồi lại quay về 2020, rồi lại đi 2021. Do đó mới cần kiểm tra thời gian máy A chạy tại tỉnh trong sheet Khai báo có chính xác, phù hợp với thông tin trong Data hay không. Lấy thông tin Data làm chuẩn để xét.
Để đảm bảo chính xác như vậy thì nhờ bạn điều chỉnh code để dò tiếp đến hết giúp mình, vì dù có lâu thì mình còn có thể đợi chờ được, nhưng kết quả khi chạy xong là tin tưởng được chính xác, còn hơn chạy nhanh nhưng kết quả lại không đúng, không sử dụng được.
Và mình có thể sẽ tối ưu lại Data để chạy nhanh hơn.

Vậy bạn xem hỗ trợ giúp mình nhé!
1/ Tôi nói chưa rõ chỗ trình tự thời gian, chừ nói để xác nhận lại: tất nhiên là phải đúng như bạn nói rồi nhưng có bao giờ dữ liệu được sắp trên Excel từ trên xuống dưới thế này không:
STTTỉnhThiết bị mang đếnThiết bị mang điTrạng tháiThời điểm đến/đi
1Hà GiangA29/06/2018 13:38
...
100Hà GiangA30/08/2019 15:03:30
...
...
200Hà GiangA29/07/2018 13:38:56
...
350Hà GiangA30/07/2019 15:03:30
mà lẽ ra chúng phải ở trong 2 khoảng: 29/06/2018 13:38 -> 29/07/2018 13:38:56 và 30/07/2019 15:03:30 -> 30/08/2019 15:03:30
 
Lần chỉnh sửa cuối:
1/ Tôi nói chưa rõ chỗ trình tự thời gian, chừ nói để xác nhận lại: tất nhiên là phải đúng như bạn nói rồi nhưng có bao giờ dữ liệu được sắp trên Excel từ trên xuống dưới thế này không:
STTTỉnhThiết bị mang đếnThiết bị mang điTrạng tháiThời điểm đến/đi
1Hà GiangA29/06/2018 13:38
...
100Hà GiangA30/08/2019 15:03:30
...
...
200Hà GiangA29/07/2018 13:38:56
...
350Hà GiangA30/07/2019 15:03:30
mà lẽ ra chúng phải ở trong 2 khoảng: 29/06/2018 13:38 -> 29/07/2018 13:38:56 và 30/07/2019 15:03:30 -> 30/08/2019 15:03:30
Mình cũng không rõ, vì Data dưới dạng logfile xuất ra từ hệ thống, và có rất nhiều tỉnh hay thiết bị có thông tin đan xen nhau.
Hay nếu cần thì trước khi cho chạy code thì mình sẽ sắp xếp cột thời gian theo thứ tự, thì có được không nhỉ?
 
Mình cũng không rõ, vì Data dưới dạng logfile xuất ra từ hệ thống, và có rất nhiều tỉnh hay thiết bị có thông tin đan xen nhau.
Hay nếu cần thì trước khi cho chạy code thì mình sẽ sắp xếp cột thời gian theo thứ tự, thì có được không nhỉ?
À, việc đó không cần, để code làm luôn. Chừ phát sinh ra việc không có thời điểm đến nữa, công với việc có nhiều khoảng thời gian đến - đi mới hơi căng đây
 
À, việc đó không cần, để code làm luôn. Chừ phát sinh ra việc không có thời điểm đến nữa, công với việc có nhiều khoảng thời gian đến - đi mới hơi căng đây
Vâng, chính vì như thế nên mình cũng mới rất khổ sở để kiểm tra việc khai báo có chính xác hay không mà.
Rất mong bạn hỗ trợ!
 
Dữ liệu trong file không tin cậy bạn à!
Tôi cố tìm giải thuật để chạy ra mảng data làm căn cứ kiểm tra khai báo nhưng code báo lỗi, lọc ra thì thấy thế này:
A3997THGCBEK-1018707
07/02/2018 08:11​
A3997THGCBEK-1018707
07/02/2018 08:13​
A3997THGCBEK-1018707
07/02/2018 12:13​
A3997THGCBEK-1018707
07/02/2018 08:11​
A3997THGCBEK-1018707
07/02/2018 08:13​
A3997THGCBEK-1018707
07/02/2018 08:18​
A3997THGCBEK-1018707
02/09/2020 14:44​
Có 1 thiết bị được ghi nhận liên tiếp 3 lần đến và liên tiếp 4 lần đi + 1 lần đi sau đó 2 năm rưỡi => Có 3 vấn đề:
1/ Tại sao lại ghi nhận liên tiếp như thế, cái data này có đáng tin cậy không?
2/ Hai cặp đầu đều cùng giờ 07/02/2018 08:11 và 07/02/2018 08:13. Cặp thứ 3 đáng ngại hơn là đến 07/02/2018 12:13 nhưng đi 07/02/2018 08:18 -> đi trước giờ đến
2/ Cái giờ đi thứ 4 bị lẻ làm sao tạo thành cặp đến - đi được?
Không những chỉ có mã đó mà còn nhiều mã khác cũng tình trạng y vậy.

Dữ liệu thiếu tin cậy thế này thì tôi bó tay, không thể lường được dẫn đến code thế nào cũng sai kết quả.
 
Dữ liệu trong file không tin cậy bạn à!
Tôi cố tìm giải thuật để chạy ra mảng data làm căn cứ kiểm tra khai báo nhưng code báo lỗi, lọc ra thì thấy thế này:
A3997THGCBEK-1018707
07/02/2018 08:11​
A3997THGCBEK-1018707
07/02/2018 08:13​
A3997THGCBEK-1018707
07/02/2018 12:13​
A3997THGCBEK-1018707
07/02/2018 08:11​
A3997THGCBEK-1018707
07/02/2018 08:13​
A3997THGCBEK-1018707
07/02/2018 08:18​
A3997THGCBEK-1018707
02/09/2020 14:44​
Có 1 thiết bị được ghi nhận liên tiếp 3 lần đến và liên tiếp 4 lần đi + 1 lần đi sau đó 2 năm rưỡi => Có 3 vấn đề:
1/ Tại sao lại ghi nhận liên tiếp như thế, cái data này có đáng tin cậy không?
2/ Hai cặp đầu đều cùng giờ 07/02/2018 08:11 và 07/02/2018 08:13. Cặp thứ 3 đáng ngại hơn là đến 07/02/2018 12:13 nhưng đi 07/02/2018 08:18 -> đi trước giờ đến
2/ Cái giờ đi thứ 4 bị lẻ làm sao tạo thành cặp đến - đi được?
Không những chỉ có mã đó mà còn nhiều mã khác cũng tình trạng y vậy.

Dữ liệu thiếu tin cậy thế này thì tôi bó tay, không thể lường được dẫn đến code thế nào cũng sai kết quả.
Vâng bạn,
Data này xuất theo dạng logfile từ hệ thống phần mềm xuất ra. Sau khi sắp xếp lại thời gian cho đúng theo thứ tự thì mình giải thích như ở dưới đây (có sắp xếp đánh STT theo cặp đến-đi). Do thời điểm là tính đến mức giây bạn ạ.
Vị trí tỉnh thực ra là dưới dạng một vị trí tọa độ trong công việc của bên mình.
Vậy nhờ bạn xem giúp!
TTVị tríThiết bị ĐếnThiết bị ĐiThời gianGiải thích
4.2A3997THGCBEK-101870702/09/2020 14:44:00Thiết bị mang đi khỏi tỉnh (và sẽ hiểu rằng thiết bị này từ thời điểm này đến hiện tại không có tại tỉnh)
4.1A3997THGCBEK-101870707/02/2018 12:13:16Thiết bị mang đến vào tỉnh
3.2A3997THGCBEK-101870707/02/2018 08:18:10Thiết bị mang đi khỏi tỉnh
3.1A3997THGCBEK-101870707/02/2018 08:13:58Thiết bị mang đến vào tỉnh
2.2A3997THGCBEK-101870707/02/2018 08:13:00Thiết bị mang đi khỏi tỉnh
2.1A3997THGCBEK-101870707/02/2018 08:11:56Thiết bị mang đến vào tỉnh
1A3997THGCBEK-101870707/02/2018 08:11:06Dòng log này chỉ có đi, hiểu là dòng đến có từ trước đó nhưng do không xuất dữ liệu ra tới thời điểm đấy nên không có ở đây
 
Bạn thay code cũ bằng code này. (Nhìn nhận lại là dữ liệu làm căn cứ check không tăng bao nhiêu nên thời gian chạy cũng không chênh lệch nhiều)
=> code lại lần này tôi sửa được 1 lỗi sai cơ bản của code trước và thêm được 1 cách vận dụng Dictionary để tạo được nhiều khóa giống nhau chứa các khoảng thời gian khác nhau như trong dữ liệu của bạn.
P/S: QUAN TRỌNG: Bạn cần sort thủ công trên trang tính với điều kiện là cột F tăng dần, cột C giảm dần. Khi Excel hỏi sort text as number thì cứ OK. LÝ DO: Viết code y như thế nhưng kết quả lại không giống sort thủ công, ngày tháng không theo trình tự từ nhỏ đến lớn. => Chép lại code bên dưới do tôi đã bỏ dòng Sort
Rich (BB code):
Sub KiemTraKhaiBao_Fix()
Dim dic As Object, sKey As String
Dim arrD, arrTmp, arrChk, arrN
Dim i As Long, k As Long
Dim tmr As Double, DDate As Date

Application.ScreenUpdating = False

arrTmp = Sheet2.Range("B2:F" & Sheet2.Range("B" & Rows.Count).End(xlUp).Row)
Set dic = CreateObject("Scripting.Dictionary")
ReDim arrD(1 To UBound(arrTmp, 1), 1 To 4)
For i = 1 To UBound(arrTmp, 1)
    sKey = UCase(Trim(arrTmp(i, 1)) & "|" & IIf(arrTmp(i, 2) <> "", Trim(arrTmp(i, 2)), Trim(arrTmp(i, 3))))
    If Not dic.Exists(sKey & "-" & 1) Then
        k = k + 1
        dic.Add (sKey & "-" & "1"), k
        arrD(k, 1) = sKey
        arrD(k, 4) = 1
        If arrTmp(i, 2) <> "" Then
            arrD(k, 2) = CDate(arrTmp(i, 5))
            arrD(k, 3) = Date
        Else
            arrD(k, 3) = CDate(arrTmp(i, 5))
            arrD(k, 2) = CDate(arrTmp(1, 5))
        End If
    Else
        If arrTmp(i, 2) = "" Then
            arrD(dic.Item(sKey & "-" & arrD(dic.Item(sKey & "-" & 1), 4)), 3) = CDate(arrTmp(i, 5))
        Else
            k = k + 1
            dic.Add (arrD(dic.Item(sKey & "-" & 1), 1) & "-" & (arrD(dic.Item(sKey & "-" & 1), 4) + 1)), k
            arrD(k, 1) = sKey
            arrD(k, 2) = CDate(arrTmp(i, 5))
            arrD(k, 3) = Date
            arrD(dic.Item(sKey & "-" & 1), 4) = arrD(dic.Item(sKey & "-" & 1), 4) + 1
        End If
    End If
Next

Set dic = Nothing

arrN = Sheet1.Range("A2:D" & Sheet1.Range("A" & Rows.Count).End(xlUp).Row)
ReDim arrChk(1 To UBound(arrN, 1), 1 To 1)
For i = 1 To UBound(arrN, 1)
    sKey = UCase(Trim(arrN(i, 1)) & "|" & Trim(arrN(i, 2)))
    For k = 1 To UBound(arrD, 1)
        If sKey = arrD(k, 1) Then
            If CDate(arrN(i, 3)) >= arrD(k, 2) And CDate(arrN(i, 3)) <= arrD(k, 3) And _
               CDate(arrN(i, 4)) >= arrD(k, 2) And CDate(arrN(i, 4)) <= arrD(k, 3) Then
                arrChk(i, 1) = "OK"
                Exit For
            End If
        End If
    Next
    If arrChk(i, 1) = "" Then arrChk(i, 1) = "NOK"
Next
Sheet1.Range("E2").Resize(UBound(arrN, 1), 1) = arrChk

End Sub
 
Lần chỉnh sửa cuối:
Bạn thay code cũ bằng code này. (Nhìn nhận lại là dữ liệu làm căn cứ check không tăng bao nhiêu nên thời gian chạy cũng không chênh lệch nhiều)
=> code lại lần này tôi sửa được 1 lỗi sai cơ bản của code trước và thêm được 1 cách vận dụng Dictionary để tạo được nhiều khóa giống nhau chứa các khoảng thời gian khác nhau như trong dữ liệu của bạn.
P/S: QUAN TRỌNG: Bạn cần sort thủ công trên trang tính với điều kiện là cột F tăng dần, cột C giảm dần. Khi Excel hỏi sort test as number thì cứ OK. LÝ DO: Viết code y như thế nhưng kết quả lại không giống sort thủ công, ngày tháng không theo trình tự từ nhỏ đến lớn. => Chép lại code bên dưới do tôi đã bỏ dòng Sort
Rich (BB code):
Sub KiemTraKhaiBao_Fix()
Dim dic As Object, sKey As String
Dim arrD, arrTmp, arrChk, arrN
Dim i As Long, k As Long
Dim tmr As Double, DDate As Date

Application.ScreenUpdating = False

arrTmp = Sheet2.Range("B2:F" & Sheet2.Range("B" & Rows.Count).End(xlUp).Row)
Set dic = CreateObject("Scripting.Dictionary")
ReDim arrD(1 To UBound(arrTmp, 1), 1 To 4)
For i = 1 To UBound(arrTmp, 1)
    sKey = UCase(Trim(arrTmp(i, 1)) & "|" & IIf(arrTmp(i, 2) <> "", Trim(arrTmp(i, 2)), Trim(arrTmp(i, 3))))
    If Not dic.Exists(sKey & "-" & 1) Then
        k = k + 1
        dic.Add (sKey & "-" & "1"), k
        arrD(k, 1) = sKey
        arrD(k, 4) = 1
        If arrTmp(i, 2) <> "" Then
            arrD(k, 2) = CDate(arrTmp(i, 5))
            arrD(k, 3) = Date
        Else
            arrD(k, 3) = CDate(arrTmp(i, 5))
            arrD(k, 2) = CDate(arrTmp(1, 5))
        End If
    Else
        If arrTmp(i, 2) = "" Then
            arrD(dic.Item(sKey & "-" & arrD(dic.Item(sKey & "-" & 1), 4)), 3) = CDate(arrTmp(i, 5))
        Else
            k = k + 1
            dic.Add (arrD(dic.Item(sKey & "-" & 1), 1) & "-" & (arrD(dic.Item(sKey & "-" & 1), 4) + 1)), k
            arrD(k, 1) = sKey
            arrD(k, 2) = CDate(arrTmp(i, 5))
            arrD(k, 3) = Date
            arrD(dic.Item(sKey & "-" & 1), 4) = arrD(dic.Item(sKey & "-" & 1), 4) + 1
        End If
    End If
Next

Set dic = Nothing

arrN = Sheet1.Range("A2:D" & Sheet1.Range("A" & Rows.Count).End(xlUp).Row)
ReDim arrChk(1 To UBound(arrN, 1), 1 To 1)
For i = 1 To UBound(arrN, 1)
    sKey = UCase(Trim(arrN(i, 1)) & "|" & Trim(arrN(i, 2)))
    For k = 1 To UBound(arrD, 1)
        If sKey = arrD(k, 1) Then
            If CDate(arrN(i, 3)) >= arrD(k, 2) And CDate(arrN(i, 3)) <= arrD(k, 3) And _
               CDate(arrN(i, 4)) >= arrD(k, 2) And CDate(arrN(i, 4)) <= arrD(k, 3) Then
                arrChk(i, 1) = "OK"
                Exit For
            End If
        End If
    Next
    If arrChk(i, 1) = "" Then arrChk(i, 1) = "NOK"
Next
Sheet1.Range("E2").Resize(UBound(arrN, 1), 1) = arrChk

End Sub
Vô cùng cảm ơn bạn!
 
Bạn thay code cũ bằng code này. (Nhìn nhận lại là dữ liệu làm căn cứ check không tăng bao nhiêu nên thời gian chạy cũng không chênh lệch nhiều)
=> code lại lần này tôi sửa được 1 lỗi sai cơ bản của code trước và thêm được 1 cách vận dụng Dictionary để tạo được nhiều khóa giống nhau chứa các khoảng thời gian khác nhau như trong dữ liệu của bạn.
P/S: QUAN TRỌNG: Bạn cần sort thủ công trên trang tính với điều kiện là cột F tăng dần, cột C giảm dần. Khi Excel hỏi sort text as number thì cứ OK. LÝ DO: Viết code y như thế nhưng kết quả lại không giống sort thủ công, ngày tháng không theo trình tự từ nhỏ đến lớn. => Chép lại code bên dưới do tôi đã bỏ dòng Sort
Rich (BB code):
Sub KiemTraKhaiBao_Fix()
Dim dic As Object, sKey As String
Dim arrD, arrTmp, arrChk, arrN
Dim i As Long, k As Long
Dim tmr As Double, DDate As Date

Application.ScreenUpdating = False

arrTmp = Sheet2.Range("B2:F" & Sheet2.Range("B" & Rows.Count).End(xlUp).Row)
Set dic = CreateObject("Scripting.Dictionary")
ReDim arrD(1 To UBound(arrTmp, 1), 1 To 4)
For i = 1 To UBound(arrTmp, 1)
    sKey = UCase(Trim(arrTmp(i, 1)) & "|" & IIf(arrTmp(i, 2) <> "", Trim(arrTmp(i, 2)), Trim(arrTmp(i, 3))))
    If Not dic.Exists(sKey & "-" & 1) Then
        k = k + 1
        dic.Add (sKey & "-" & "1"), k
        arrD(k, 1) = sKey
        arrD(k, 4) = 1
        If arrTmp(i, 2) <> "" Then
            arrD(k, 2) = CDate(arrTmp(i, 5))
            arrD(k, 3) = Date
        Else
            arrD(k, 3) = CDate(arrTmp(i, 5))
            arrD(k, 2) = CDate(arrTmp(1, 5))
        End If
    Else
        If arrTmp(i, 2) = "" Then
            arrD(dic.Item(sKey & "-" & arrD(dic.Item(sKey & "-" & 1), 4)), 3) = CDate(arrTmp(i, 5))
        Else
            k = k + 1
            dic.Add (arrD(dic.Item(sKey & "-" & 1), 1) & "-" & (arrD(dic.Item(sKey & "-" & 1), 4) + 1)), k
            arrD(k, 1) = sKey
            arrD(k, 2) = CDate(arrTmp(i, 5))
            arrD(k, 3) = Date
            arrD(dic.Item(sKey & "-" & 1), 4) = arrD(dic.Item(sKey & "-" & 1), 4) + 1
        End If
    End If
Next

Set dic = Nothing

arrN = Sheet1.Range("A2:D" & Sheet1.Range("A" & Rows.Count).End(xlUp).Row)
ReDim arrChk(1 To UBound(arrN, 1), 1 To 1)
For i = 1 To UBound(arrN, 1)
    sKey = UCase(Trim(arrN(i, 1)) & "|" & Trim(arrN(i, 2)))
    For k = 1 To UBound(arrD, 1)
        If sKey = arrD(k, 1) Then
            If CDate(arrN(i, 3)) >= arrD(k, 2) And CDate(arrN(i, 3)) <= arrD(k, 3) And _
               CDate(arrN(i, 4)) >= arrD(k, 2) And CDate(arrN(i, 4)) <= arrD(k, 3) Then
                arrChk(i, 1) = "OK"
                Exit For
            End If
        End If
    Next
    If arrChk(i, 1) = "" Then arrChk(i, 1) = "NOK"
Next
Sheet1.Range("E2").Resize(UBound(arrN, 1), 1) = arrChk

End Sub
Bạn cho mình hỏi chút mình hiểu như này có đúng không nhỉ?

Cột F và cột C là của cùng 1 sheet Data hay cột C của sheet Khai báo, cột F sheet Data nhỉ? Vì nếu trong cùng 1 sheet mà sort cột này xong lại sort tiếp cột kia sẽ khiến cột sort trước bị mất sort. Chắc ý bạn cột C là của sheet Khai báo nhỉ, vì cột C sheet Khai báo là cột thời gian.
F tăng dần: Càng xuống các dòng dưới là càng gần hiện tại.
C giảm dần: Càng xuống dưới là quá khứ càng xa.
 
Bạn cho mình hỏi chút mình hiểu như này có đúng không nhỉ?

Cột F và cột C là của cùng 1 sheet Data hay cột C của sheet Khai báo, cột F sheet Data nhỉ? Vì nếu trong cùng 1 sheet mà sort cột này xong lại sort tiếp cột kia sẽ khiến cột sort trước bị mất sort. Chắc ý bạn cột C là của sheet Khai báo nhỉ, vì cột C sheet Khai báo là cột thời gian.
F tăng dần: Càng xuống các dòng dưới là càng gần hiện tại.
C giảm dần: Càng xuống dưới là quá khứ càng xa.
F và C của data bạn à, tôi quên nói, sorry! Và cả 2 đk trong cùng 1 lần sort (tức là And)

Sort F tăng dần AND C giảm dần của Excel đảm bảo cột F theo đúng trình tự thời gian trước đã, sau đó mới xét cột C để các ô rỗng ở C xếp xuống dưới cùng. Bạn Sort xong sẽ thấy cột F luôn luôn nhất quán trình tự thời gian từ cũ đến mới.
 
Web KT
Back
Top Bottom