Nhờ tạo code xóa những dòng trùng nhau

MinhKhai

Giải pháp Ếc-xào
Tham gia ngày
16 Tháng tư 2008
Bài viết
718
Được thích
498
Điểm
735
Em có file như đính kèm, đang loay hoay mà không xử lý được, nhờ giúp
1. Xóa dòng trùng
Trong file có 1 số dòng trùng đến phần phút (không tính phần giây), em muốn xóa nó đi là không biết cách
Em đã thử cho NumberFormat = "dd/mm/yyyy hh:mm" rồi dùng Remove Duplicates nhưng có vẻ sai cách.

219924

2. File đính kèm được dùng để nhập dữ liệu từ txt file, sau khi nhập xong thì làm mấy việc như trong file đã nêu. Quá trình này trên máy em chạy mất 5-7s. Em nghĩ trong file có những đoạn code ngô nghê nên khiến máy chạy chậm. Anh chị nào rảnh rỗi vui lòng sửa lại code để tăng tốc giúp em.

3. Quá trình nhập dữ liệu từ Text file, luôn xuất hiện thêm Name. Em không rõ nguyên nhân vì sao nhưng xóa Name đi cũng không làm sao nên tạo đoạn code để xóa Name. Ai biết xin giải thích giúp

Xin cảm ơn
 

File đính kèm

Lần chỉnh sửa cuối:

befaint

|||||||||||||
Tham gia ngày
6 Tháng một 2011
Bài viết
8,584
Được thích
9,742
Điểm
560
1.
Mã:
O4=TEXT(C4,"dd/mm/yyyy hh:mm")
'Fill down
'Copy/paste value
'Xóa trùng...
3.
PHP:
    With ActiveSheet.QueryTables.Add(Connection:="TEXT;" & fName, Destination:=Range("$B$4"))
        .Name = "VungLV"
Sửa:
1*:
219934

2*:
Bỏ XoaName và thêm
PHP:
...
        .TextFileTrailingMinusNumbers = True
        .Refresh BackgroundQuery:=False
    End With
'thêm đoạn này
    Dim Cn As Variant
    For Each Cn In ThisWorkbook.Connections
        Cn.Delete
    Next Cn
    For Each Cn In ActiveSheet.QueryTables
        Cn.Delete
    Next Cn
Nguyên tắc: Luôn luôn nhớ dọn QueryTables sau khi Add (hoặc xóa phiên trước trước khi Add mới).
 

ongke0711

Thành viên thường trực
Tham gia ngày
7 Tháng chín 2006
Bài viết
276
Được thích
258
Điểm
710
View attachment 219924

2. File đính kèm được dùng để nhập dữ liệu từ txt file, sau khi nhập xong thì làm mấy việc như trong file đã nêu. Quá trình này trên máy em chạy mất 5-7s. Em nghĩ trong file có những đoạn code ngô nghê nên khiến máy chạy chậm. Anh chị nào rảnh rỗi vui lòng sửa lại code để tăng tốc giúp em.
Tôi có một giải pháp khác bạn xem thử.
Đây là file chấm công vân tay In Out đúng không? Thường thì sẽ lấy dòng có thời gian sớm nhất nếu là [IN]. Vậy có thể xử lý ngay khi import file text vào Excel dùng ADODB và Query kiểu "SELECT First([Time]), Date, ID,.....FROM ...GROUP BY [Time]" sau đó mới gán xuống Excel.
Tôi nghĩ cách làm là vậy :)
 

MinhKhai

Giải pháp Ếc-xào
Tham gia ngày
16 Tháng tư 2008
Bài viết
718
Được thích
498
Điểm
735
3.
PHP:
    With ActiveSheet.QueryTables.Add(Connection:="TEXT;" & fName, Destination:=Range("$B$4"))
        .Name = "VungLV"
Sửa:
1*:
View attachment 219934

2*:
Bỏ XoaName và thêm
PHP:
...
        .TextFileTrailingMinusNumbers = True
        .Refresh BackgroundQuery:=False
    End With
'thêm đoạn này
    Dim Cn As Variant
    For Each Cn In ThisWorkbook.Connections
        Cn.Delete
    Next Cn
    For Each Cn In ActiveSheet.QueryTables
        Cn.Delete
    Next Cn
Nguyên tắc: Luôn luôn nhớ dọn QueryTables sau khi Add (hoặc xóa phiên trước trước khi Add mới).
Xin cảm ơn @befaint
Vấn đề tạo Name đã được xử lý

O4=TEXT(C4,"dd/mm/yyyy hh:mm")
'Fill down
'Copy/paste value
'Xóa trùng...
Không biết befain gợi ý cách làm manual hay bằng Code
Mình thử làm thủ công rồi record macro, sau thử chạy macro đã record nhưng thấy chậm quá. Dữ liệu nhập từ text file có thể đến 15.000 bản ghi mà.
Như trong mục 2 của câu hỏi có nêu việc máy xử lý tất cả các việc đó khá lâu. Nhờ anh code giúp đoạn gợi ý trên sao cho tốc độ tốt nhất.
Bài đã được tự động gộp:

Tôi có một giải pháp khác bạn xem thử.
Đây là file chấm công vân tay In Out đúng không? Thường thì sẽ lấy dòng có thời gian sớm nhất nếu là [IN]. Vậy có thể xử lý ngay khi import file text vào Excel dùng ADODB và Query kiểu "SELECT First([Time]), Date, ID,.....FROM ...GROUP BY [Time]" sau đó mới gán xuống Excel.
Tôi nghĩ cách làm là vậy :)
Cảm ơn anh. Ý em cũng muốn như vậy nhưng không biết cách làm. Anh thử làm giúp được không ?
Text file đúng là lấy từ máy chấm công. Thường thì mua MCC thì có phần mềm kèm theo và hình như PM khi xuất dữ liệu cũng thực hiện như ý của anh nêu. Tuy nhiên, MCC này đã cũ nên không có PM kèm theo mới phải thủ công vậy.
 

ongke0711

Thành viên thường trực
Tham gia ngày
7 Tháng chín 2006
Bài viết
276
Được thích
258
Điểm
710
Text file đúng là lấy từ máy chấm công. Thường thì mua MCC thì có phần mềm kèm theo và hình như PM khi xuất dữ liệu cũng thực hiện như ý của anh nêu. Tuy nhiên, MCC này đã cũ nên không có PM kèm theo mới phải thủ công vậy.
Tôi cũng mới test thử dùng ADODB. Tốc độ nhanh hơn rồi đó nhưng có một vấn đề nhỏ chưa giải quyết được mà phải đi đường vòng đó là: khi dùng ADO đọc dữ liệu file Text hiện tại của bạn thì nó không đọc được thành từng cột mà gom hết vô 1 cột (dùng TabDelimited) => không dùng cáhc đọc trực tiếp được mà phải import vô Excel (tôi đoán như cách bạn đang làm vì file bạn khoá vba- Get External Data) sau đó mới dùng câu lệnh SQL để tổng hợp dữ liệu.

Nếu bạn có thể xuất lại file text dạng CSV (các cột cách nhau dấu phẩy " , " thì tôi nghĩ ADO sẽ đọc trực tiếp được.

Link file demo: http://www.mediafire.com/file/soolbqsm0z6qclm/GPE_v1.rar/file
 

MinhKhai

Giải pháp Ếc-xào
Tham gia ngày
16 Tháng tư 2008
Bài viết
718
Được thích
498
Điểm
735
Tôi cũng mới test thử dùng ADODB. Tốc độ nhanh hơn rồi đó nhưng có một vấn đề nhỏ chưa giải quyết được mà phải đi đường vòng đó là: khi dùng ADO đọc dữ liệu file Text hiện tại của bạn thì nó không đọc được thành từng cột mà gom hết vô 1 cột (dùng TabDelimited) => không dùng cáhc đọc trực tiếp được mà phải import vô Excel (tôi đoán như cách bạn đang làm vì file bạn khoá vba- Get External Data) sau đó mới dùng câu lệnh SQL để tổng hợp dữ liệu.

Nếu bạn có thể xuất lại file text dạng CSV (các cột cách nhau dấu phẩy " , " thì tôi nghĩ ADO sẽ đọc trực tiếp được.

Link file demo: http://www.mediafire.com/file/soolbqsm0z6qclm/GPE_v1.rar/file
Chân thành xin lỗi mọi người vì file gửi lên vẫn còn pass VBA. Em đã up lại file không còn pass để các anh chị khác có thể xem và góp ý thêm
Dù đi đường vòng, nhưng tốc độ đã nhanh hơn hẳn. Để em test thêm rồi hỏi tiếp nhé
 

ongke0711

Thành viên thường trực
Tham gia ngày
7 Tháng chín 2006
Bài viết
276
Được thích
258
Điểm
710
Tôi dùng code VBA chuyển file Text dạng TabDelimited sang CSV rồi dùng ADO xử lý tốc độ nhanh hơn nhiều lần cách trên (chừng 2s) và khỏi phải dùng tới Named range, Get External Data.
Còn việc xử lý bằng mảng thì thấy khó quá, đang ngâm cứu từ từ :)

Trong việc loại bỏ dòng trùng ngày giờ phút, có phát sinh những dòng trùng nhưng khác mã MCC (102,103) nên tôi vẫn giữ lại, nếu không tính đến cột MCC thì sẽ bỏ thêm một số dòng trùng nữa.

Code ADO truy vấn:

Mã:
Private Sub cmdGetDataCSV_Click()
    Application.ScreenUpdating = False

   
    Dim sTxtFolder As String, sTxtFileName As String, sFullPath As String
    Dim SQLStatement As String
   
    sFullPath = BrowseFile
   
    sTxtFolder = ParseFileName(sFullPath, 1)
    sTxtFileName = ParseFileName(sFullPath, 4)
   
    'Xu ly du lieu = SQL
    SQLStatement = "SELECT A.F1, First(A.F2) AS FirstOfF2, A.F3, A.F4, A.F5, A.F6, A.F7, A.F8, Format([F2],'mm/dd/yyyy') AS Ngay, " & _
                   "IIf([F6]='I',(Format([F2],'Short Time')),0) AS I, IIf([F6]='O',(Format([F2],'Short Time')),0) AS O " & _
                   "FROM [" & sTxtFileName & "] As A " & _
                   "GROUP BY A.F1, Format([F2],'mm/dd/yyyy hh:nn'), A.F3, A.F4, A.F5, A.F6, A.F7, A.F8, Format([F2],'mm/dd/yyyy'), " & _
                   "IIf([F6]='I',(Format([F2],'Short Time')),0), IIf([F6]='O',(Format([F2],'Short Time')),0)"

    Sheet1.Range("B4:M" & Sheet1.Cells(Sheet1.Rows.Count, "B").End(xlUp).Row).ClearContents
    Sheet1.Range("B4").CopyFromRecordset GetADORecordset(SQLStatement, sTxtFolder, "txt")
   
    Application.ScreenUpdating = True
    MsgBox "Tong hop du lieu xong"
   
End Sub


- Hàm kết nối ADO: dùng cho kết nối 2 loại file: Text và Excel.

Mã:
Function GetADORecordset(strRst As String, strWBFullName As String, DataSourceType As String, Optional strSortFld As String) As Object

    Dim oCnn As Object
    Dim oRst As Object

    Const adOpenForwardOnly = 0
    Const adOpenStatic = 3
    Const adLockOptimistic = 3
    Const adLockReadOnly = 1
    Const adCmdText = &H1

    Set oCnn = CreateObject("ADODB.Connection")
    Set oRst = CreateObject("ADODB.Recordset")

    With oCnn
        Select Case DataSourceType
        Case "Excel"
            .Provider = "Microsoft.ACE.OLEDB.12.0"
            .ConnectionString = "Data Source=" & strWBFullName & ";" & _
                                "Extended Properties=""Excel 12.0 Xml;HDR=No;"";"

        Case "txt"  'Chi dùng duong dan den Folder
            .Provider = "Microsoft.Jet.OLEDB.4.0"
            .ConnectionString = "Data Source=" & strWBFullName & ";" & _
                                "Extended Properties= ""text;HDR=No;FMT=Delimited(,)"";Persist Security Info=False"
        End Select

        .Open
    End With

    oRst.CursorLocation = 3    'adUseClient
    oRst.Open strRst, oCnn, adOpenForwardOnly, adLockReadOnly, adCmdText
    'oRst.Sort = strSortFld
    Set GetADORecordset = oRst

End Function


Link file: http://www.mediafire.com/file/6h2j71z6yh684lg/GPE_v2_CSV.rar/file
 
Lần chỉnh sửa cuối:

MinhKhai

Giải pháp Ếc-xào
Tham gia ngày
16 Tháng tư 2008
Bài viết
718
Được thích
498
Điểm
735
Tôi dùng code VBA chuyển file Text dạng TabDelimited sang CSV rồi dùng ADO xử lý tốc độ nhanh hơn nhiều lần cách trên (chừng 2s) và khỏi phải dùng tới Named range, Get External Data.
Còn việc xử lý bằng mảng thì thấy khó quá, đang ngâm cứu từ từ :)

Trong việc loại bỏ dòng trùng ngày giờ phút, có phát sinh những dòng trùng nhưng khác mã MCC (102,103) nên tôi vẫn giữ lại, nếu không tính đến cột MCC thì sẽ bỏ thêm một số dòng trùng nữa.

Link file: http://www.mediafire.com/file/6h2j71z6yh684lg/GPE_v2_CSV.rar/file
Em đang ngâm cứu bản V1 của anh thì anh đã ra lò bản V2
1. Bản V2 của anh khi mở ra đã bị lỗi này là sao ạ ? Em đang dùng Office 2016 (x64)

220195

2. Xin hỏi anh về bản V1 (Em thấy tốc độ của version này vẫn chấp nhận được)
a/ Khi mở hộp thoại chọn đường dẫn file txt để import, lúc này người dùng hủy việc chọn file thì bị báo lỗi. Em đã thử Google cách bẫy lỗi mà không thành công? Anh có cách gì không ?
b/ Em chưa biết cái Function createDynamicNamedRange để làm gì? Ngoài ra cái lệnh lngLastColRng = .Find(What:="*" trong cái Function này có kết quả như thế nào ?
c/ Em muốn hỏi lại là Query chỉ lấy thời gian sớm nhất cho cùng lượt I hoặc O thuộc cùng ngày phải không ? Trường hợp nhân viên bấm cùng I hoặc O cho cả lượt vào và lượt ra thì dữ liệu bị mất phải không anh? Nếu đúng thế thì cần xem xét lại cái này
d/ Nếu sheet TongHop đang trong trạng thái được Filter mà người dùng tiến hành Get Data thì code vẫn chạy nhưng dữ liệu bị thiếu mà người dùng không biết
e/ Căn cứ vào chú thích của anh, em đã Google và xin phép thực hiện việc sửa đổi như dưới đây.
220197
220198
 
Lần chỉnh sửa cuối:

ThangCuAnh

Thành viên tiêu biểu
Tham gia ngày
1 Tháng mười hai 2017
Bài viết
504
Được thích
382
Điểm
235
Nơi ở
Phờ lây cu
Bạn up cái file txt thiệt bự lên đi, để mọi người test tốc độ thử.
Data nhỏ thường không thấy sự khác biệt đâu
 

ThangCuAnh

Thành viên tiêu biểu
Tham gia ngày
1 Tháng mười hai 2017
Bài viết
504
Được thích
382
Điểm
235
Nơi ở
Phờ lây cu
ADO nó viết = C/C++, tốc độ chắc đã tối ưu lắm rồi, dùng VBA ReadAll, parse từng line, nhưng chắc không lại nó đâu.
Cũng muốn thử nhưng ngại công cốc... ;)
File 222.txt của MinhKhai có 10,632 dòng, sao file testfile.csv của ongke có 9,716 dòng à ?
 

VetMini

Chuyên gia GPE
Tham gia ngày
21 Tháng mười hai 2012
Bài viết
6,625
Được thích
7,718
Điểm
560
ADO nó viết = C/C++, tốc độ chắc đã tối ưu lắm rồi, ...
1. hồi xưa thì C/C++ là quan trọng. Nhưng bây giờ thì chúng chuyên giải thuật thôi. Mấy cái database engines hơn thua nhau ở cái execution plan.
ADO chỉ là cái object giao diện. ACE/JET mới là bộ máy bên trong.

2. ACE/JET engines dùng phiên bản SQL của Access cho nên chưa chắc đã tối ưu. Tuy bất cứ engine nào cũng tối ưu cho lệnh Join, Union, Group, và Order; nhưng execution plan của Access rất dở về hàm.
Câu lệnh SQL trên có cả đống hàm (First, Format, và nhất là IIF) cho nên chưa chắc là code của bạn không có cơ hội.

Chú: ACE/JET được viết để chạy file dạng ISAM (I=Indexed, S=Sequential). Đem qua đọc bảng tính thì nó chỉ là đọc Sequential, hoàn toàn không có Index cho nên nó chưa chắc có lợi điểm hơn code ta tự viết.
 
Lần chỉnh sửa cuối:

ThangCuAnh

Thành viên tiêu biểu
Tham gia ngày
1 Tháng mười hai 2017
Bài viết
504
Được thích
382
Điểm
235
Nơi ở
Phờ lây cu
Hì hì, cảm ơn bác VetMini, tui code gần xong rồi, nay thứ 7 rãnh.
Tạm thời chạy nhanh hơn 4 lần code bác ongke, trên máy tui, code đọc CSV của bác ongke chay gần 5000 ms, code đọc TXT của tui chạy gần 1000ms
 

ongke0711

Thành viên thường trực
Tham gia ngày
7 Tháng chín 2006
Bài viết
276
Được thích
258
Điểm
710
Hì hì, cảm ơn bác VetMini, tui code gần xong rồi, nay thứ 7 rãnh.
Tạm thời chạy nhanh hơn 4 lần code bác ongke, trên máy tui, code đọc CSV của bác ongke chay gần 5000 ms, code đọc TXT của tui chạy gần 1000ms
:) bạn là người rất chi tiết và tìm mọi cách tối ưu hoá nếu có thể.
Cái file MCC_v2 của tôi dùng ADO đọc file CSV và xử lý luôn yêu cầu truy vấn để ra kết quả luôn chứ không phải đọc không thôi nên tốc độ nó bị ảnh hưởng. Như anh Vetmini có đề cập là có các hàm First, Format, IIF kèm theo câu lệnh SQL để trả về kết quả theo y/c của chủ thớt đó.
Theo tôi như tôi hiểu thì cùng một lượng dữ liệu, khi đọc dữ liệu lưu vào ADO recordset, chắc chắn nó tốn tài nguyên hơn mảng vì nó sẽ kèm theo đủ các thứ để thao tác dữ liệu ngay trên bộ nhớ như AddNew, Edit, Sort, Filter.... còn Mảng thì nó chỉ lưu dữ liệu thô không thôi nên sẽ nhẹ nhàng hơn nhiều.
Bạn ngâm cứu xong thì chia sẽ để học hỏi nhé.

File 222.txt của MinhKhai có 10,632 dòng, sao file testfile.csv của ongke có 9,716 dòng à ?
Cái file tôi dùng convert sang CSV là file cũ của thớt chỉ có nhiêu đó dòng. Tôi lấy file mới convert lại cũng vẫn đảm bảo đúng số dòng so với Text.

Code convert CSV:
Mã:
Function TabToCsv()

    Const ForReading = 1, ForWriting = 2
    Dim fso, MyTabFile, MyCsvFile, FileName
    Dim strFileContent As String
    Set fso = CreateObject("Scripting.FileSystemObject")

    'Duong dan file text can chuyen doi
    Set MyTabFile = fso.OpenTextFile("\\Mac\Home\Downloads\GPE\222_new.txt", ForReading)

    'Doc file
    strFileContent = MyTabFile.ReadAll
    MyTabFile.Close

    ' Thay the tab = ","
    strFileContent = Replace(expression:=strFileContent, _
                             Find:=vbTab, Replace:=",")

    ' Duong dan + Ten file xuat ra CSV.
    Set MyCsvFile = fso.OpenTextFile("\\Mac\Home\Downloads\GPE\testfile.csv", ForWriting, True)
    MyCsvFile.Write strFileContent
    MyCsvFile.Close

End Function
 

ThangCuAnh

Thành viên tiêu biểu
Tham gia ngày
1 Tháng mười hai 2017
Bài viết
504
Được thích
382
Điểm
235
Nơi ở
Phờ lây cu
Xong rồi, đang đợi chủ thớt up file txt bự nhất lên để test. Sau khi sort và remove duplicate thì code mình chạy = 1/3 - 1/4 code bạn.
Code bạn ongke có lỗi, khi có lỗi xảy ra, nó cứ xóa mất tiêu cái header, làm phải gõ lại hoài.
Các bạn test lại giùm, cũng chưa ưng ý lắm và chắc còn lỗi.
 

File đính kèm

Lần chỉnh sửa cuối:

ThangCuAnh

Thành viên tiêu biểu
Tham gia ngày
1 Tháng mười hai 2017
Bài viết
504
Được thích
382
Điểm
235
Nơi ở
Phờ lây cu
Nội cái vụ sort và remove duplicate thôi, đã chiếm mất 1/3 tổng thời gian của hàm GetDataTxt, hơn 1/3 lại là parse lines.
Code có bug ở lRow + 4, phải là lRow + 3 mới đúng. Lỗi off by one thường gặp
Và thiếu assign strFileContent = vbNullString để free memory file content
 
Lần chỉnh sửa cuối:

ongke0711

Thành viên thường trực
Tham gia ngày
7 Tháng chín 2006
Bài viết
276
Được thích
258
Điểm
710
1. Bản V2 của anh khi mở ra đã bị lỗi này là sao ạ ? Em đang dùng Office 2016 (x64)
Do máy tui cùi bắp đời cũ nên chỉ có 32bit à, chưa bò lên được 64 bit nên bạn tự sửa lại khai báo các hàm theo 64bit nhé.
Bạn xem bài hướng dẫn của Hesanbi ở đây.
Link: https://www.giaiphapexcel.com/diendan/threads/kĩ-thuật-lập-trình-vba-đa-nền-tảng-và-lập-trình-tương-tác-window.142800/

a/ Khi mở hộp thoại chọn đường dẫn file txt để import, lúc này người dùng hủy việc chọn file thì bị báo lỗi. Em đã thử Google cách bẫy lỗi mà không thành công? Anh có cách gì không ?
Chỉ cần thêm dòng này vô:
sFullPath = BrowseFile
--> If Len(sFullPath) = 0 Then Exit Sub


b/ Em chưa biết cái Function createDynamicNamedRange để làm gì? Ngoài ra cái lệnh lngLastColRng = .Find(What:="*" trong cái Function này có kết quả như thế nào ?
Cái phiên bản này nó lằng nhằng vì như tôi nói phải import vô Excel rồi mới dùng ADO xử lý nên phải thiết lập Named range (NRg) cho khối dữ liệu text vừa Import rồi mới đưa nó vào câu lệnh SQL được. Khi dùng "QueryTables.Add..." thì nó có tạo Namee range rồi ("VungLV" trong file của bạn) nhưng tầm vực của NRg này chỉ có trong Sheet chứ không phải Workbook nên không gọi được vào SQL khi nằm ở sheet khác. Giải pháp có thể là:
- Chuyển Scope thành Workbook. Cách này tôi đã thử nhưng nó cũng phát sinh lỗi nếu người dùng bấm nút [Get Data] liên tục. Tôi cũng đã test việc xoá Nrg nhưng không bẫy được cái lỗi thao tác trên nên mới chọn cách thứ 2 bên dưới.
- Tạo Nrg động riêng co giãn tuỳ theo số dòng, cột dữ liệu import.

Cái lệnh lngLastColRng là tìm cột có dữ liệu cuối cùng để đưa vô Range. Nên sửa lại chút: LookIn:=xlValues (chứ không phải xlFormula).


c/ Em muốn hỏi lại là Query chỉ lấy thời gian sớm nhất cho cùng lượt I hoặc O thuộc cùng ngày phải không ? Trường hợp nhân viên bấm cùng I hoặc O cho cả lượt vào và lượt ra thì dữ liệu bị mất phải không anh? Nếu đúng thế thì cần xem xét lại cái này
d/ Nếu sheet TongHop đang trong trạng thái được Filter mà người dùng tiến hành Get Data thì code vẫn chạy nhưng dữ liệu bị thiếu mà người dùng không biết
Cái vụ này mới phải thảo luận nhiều đây.

Cái query của anh phải sửa lại chút để: lấy Giờ vào Sớm nhất và giờ ra Trễ nhất.
"SELECT A.F1, IIF([F6]='I',First(A.F2),Last(A.F2)) AS GioInOut, A.F3,...

Cái vụ lấy dữ liệu từ MCC để xử lý thì tôi chắc chắc sẽ phải có xử lý thủ công ở một số trường hợp mà mình không thể lập trình để nó đủ thông minh nhận ra trường hợp nào với trường hợp nào. Có thể tôi không đủ khả năng để code cho nó nhưng đảm bảo là sẽ phức tạp ở nhiều trường hợp thò ngón tay bấm trong thực tế.
- Trường hợp như bạn nói: NV quên đổi sang chế độ O khi bấm ra và ngược lại.
- NV thò vô 1 cái, chưa chắc ăn, thò tiếp lần 2 lần 3, nghe "chít"... "chít" vài lần cho chắc ăn.
- NV kênh thị trường, đi ra vào nhiều lần trong ngày.quên bấm in out, in out lẫn lộn.
- NV quên bấm In, hoặc out, có dữ liệu vào mà không có ra và ngược lại.
- Máy bị lỗi
Từ nguyên nhân trên dẫn đến dữ liệu IN OUT của nhân viên sẽ lộn xộn, mức độ tin cậy giảm 50%
Tôi thấy mấy cty có làm là gửi dữ liệu chấm công cho từng nhân viên trước ngày chốt công để họ tự kiểm tra ngày công, nếu phát hiện sai thì sẽ la làng lên khi đó nhân sự sẽ kiểm tra và sửa dữ liệu công của người đó thay vì phải kiểm tra hết toàn bộ nhân viên. Còn giải pháp nào khác nữa thì tôi chưa biết :)
Mình chỉ có thể lường trước vài trường hợp để hệ thống highlight lên các dòng nghi ngờ rồi sửa thủ công.
- Giờ IN, OUT có mấy dòng trùng nhau thì chọn 1 như y/c của bạn.
- Thiếu giờ IN hoặc OUT trong cùng 1 ngày.
- Dựa trên các giấy xin phép ra/vào cty của từng NV để đối chiếu dữ liệu chấm công.
- ...
Nói chung vụ này tôi cũng lùng bùng lắm hehe.. :)

Vụ Sheet đang Filter thì buộc bạn phải "Clear Filter" rồi mới ghi dữ liệu xuống thôi, chứ không dữ liệu sẽ bị sai.
 
Lần chỉnh sửa cuối:

ongke0711

Thành viên thường trực
Tham gia ngày
7 Tháng chín 2006
Bài viết
276
Được thích
258
Điểm
710
Xong rồi, đang đợi chủ thớt up file txt bự nhất lên để test. Sau khi sort và remove duplicate thì code mình chạy = 1/3 - 1/4 code bạn.
Code bạn ongke có lỗi, khi có lỗi xảy ra, nó cứ xóa mất tiêu cái header, làm phải gõ lại hoài.
Các bạn test lại giùm, cũng chưa ưng ý lắm và chắc còn lỗi.
2 ongke: Mình nói rồi, mình là người cầu toàn mà. Hồi xưa, chỉ review code cho các team, member dưới quyền, mình đã khó, bắt từng cái space, dấu phẩy... đấy ;)
Tốc độ đáng nể thật.
Học hỏi được nhiều thứ. :)
 

ThangCuAnh

Thành viên tiêu biểu
Tham gia ngày
1 Tháng mười hai 2017
Bài viết
504
Được thích
382
Điểm
235
Nơi ở
Phờ lây cu
Bạn optimize lại câu SQL đi, tui nghĩ nó sẽ nhanh hơn.
Tôi bỏ SQL lâu quá rồi, quên hết. Với lại mảng database tôi kg chuyên
 
Lần chỉnh sửa cuối:

VetMini

Chuyên gia GPE
Tham gia ngày
21 Tháng mười hai 2012
Bài viết
6,625
Được thích
7,718
Điểm
560
@ongke0711:
Ở đây chỉ lọc trùng chứ không cần tổng cho nên có thể Group nhiều trường có function làm cho bạn bị chậm.
Bạn thử cải tiến bằng Select Distinct/DistinctRow xem sao?

Chú: một lựa chọn nữa là dùng Union
Select f1, f2, f3 From bang1
Union
(Select f1, f2, f3 From bang1 where 1=0)
Cái subquery chỉ là cái bù nhìn, trả về 0 dòng. Mục đích là lợi dụng Union để lọc duy nhất.
 
Top