Lọc và tách dữ liệu theo điều kiện?

Liên hệ QC

Hoàng Nhật Phương

Thành viên gắn bó
Tham gia
5/11/15
Bài viết
1,894
Được thích
1,213
Xin chào các Bạn,
Hiện tôi đang có dữ liệu trong Sheet "DuLieu" như sau:
222337

Nhờ các bạn giúp đỡ đoạn code xử lý tách dữ liệu trong cột MaID ngăn cách nhau bởi dấu "/" thành nhiều dòng
và lọc theo cột thời gian và cột ca, lọc duy nhất 4 cột cho ra Sheet"KQ" như sau:
222341
 

File đính kèm

  • Tach va Loc Duy Nhat.xlsx
    132.5 KB · Đọc: 25
Lần chỉnh sửa cuối:
@batman1: Em nghĩ không cần dùng tới trường TenSP đâu anh, MaSP là đủ đại diện rồi.
Tôi không làm những việc đó nên không rõ thế nào. Vậy khi người ta nói là lọc duy nhất theo 4 cột thì tôi làm theo 4 cột. Nếu không cần TenSP thì sao người ta không nói lọc theo 3 cột mà lại nói theo 4 cột? Mình không làm chuyên môn của người ta thì cứ theo yêu cầu mà làm. Có góp ý thì góp ý cho người ta chứ không phải cho tôi.
 
Upvote 0
Cảm ơn Bác Siwtom nhiều ạ,
Đến đây con có thể tự xử lý theo ý mình được rồi ạ.
Lọc duy nhất 4, 3, 2 hay 1 cột thì nguyên tắc như nhau thôi.

Vd. lọc duy nhất theo MaID, MaSP, MaKH.

text có dạng <khúc dành cho MaID><ký tự 0><khúc dành cho MaSP><ký tự 0><khúc dành cho MaKH>

Trong đó
<khúc dành cho MaID> dùng để ghi MaID và có độ lớn = max(MaID)
<khúc dành cho MaSP> dùng để ghi MaSP và có độ lớn = max(MaSP)
<khúc dành cho MaKH> dùng để ghi MaKH và có độ lớn = max(MaKH)

Mã:
text = String("độ lớn", Chr(0))
với "độ lớn" = max(MaID) + max(MaSP) + max(MaKH) + 2 (2 ký tự 0 phân cách 3 khúc)

MaID được copy vào text bắt đầu từ 1

MaSP được copy vào text bắt đầu từ max(MaID) + 2 (trước khúc 2 có khúc 1 với độ lớn = max(MaID) và 1 ký tự 0. Vậy khúc 2 bắt đầu từ max(MaID) + 2)

MaKH được copy vào text bắt đầu từ max(MaID) + max(MaSP) + 3 (trước khúc 3 có khúc 1 với độ lớn = max(MaID), khúc 2 với độ lớn = max(MaSP), và 2 ký tự 0. Vậy khúc 3 bắt đầu từ max(MaID) + max(MaSP) + 3)

Cứ nhìn vào dạng của text rồi đếm như đứa trẻ thôi. :D
 
Upvote 0
Để minh họa cho 2 topic của tui về Undocument VBA và Optimize VBA, tui xin mạn phép lấy file của bạn OT để minh họa kết quả áp dụng.
Dù thấy cái tên OT là muốn chạy làng, tránh ra xa rồi :) Nhưng file bạn OverTime có data dài, bự bự, nên tui khoái.

File tui up lên là file data của bạn OT, có code của bác batman1 và tui thêm 1 code của tui, chỉ dùng đôla Mẽo $ thần thánh và vài tips Optimize nho nhỏ, xíu xíu. Áp dụng vào code của bác batman1 100%, không hề thay đổi gì cả, kết quả như nhau 100%.

Và, kết quả, xin chia "BUỒM", code đôla Mẽo của bác Trump nhanh gấp đôi code của bác batman1. Tui chọn máy trong VP chậm nhất để test, code bác batman1 chạy mất khoang 2500 ms, code bác Trump đôla chỉ chạy có 1200 ms à :)


Đố các bạn tìm ra chổ mấu chốt làm đẩy nhanh tốc độ lên vậy, dùng nhiều tips, có tips chỉ giảm vài %, có 2 tip quan trong kéo xuống tới 50%.

Bạn OT cứ tiếp tục dùng code của bác batman1, nhanh hơn vậy không quan trong. Đèn đỏ vài giây còn không chờ được mà :p Optimize thì biết cho vui thôi.

File bạn OT bự quá, up lên diễn đàn không cho, ai chỉ tui chổ nào úp với
 
Lần chỉnh sửa cuối:
Upvote 0
Phiền ơi nà phiền, có chút xíu đó mà không xong :)
Các bạn làm ơn download lại nhé. Sorry nhiều.
 
Upvote 0
Ai là người chủ xướng việc tách riêng mấy bài "không liên quan chủ đề" này ra thành thớt khác vậy?
Tôi xin gửi lời với chủ thớt "Lọc và tách dữ liệu theo điều kiện?"
Nếu do bạn chủ xướng việc này thì cứ nói thẳng ra, kể từ rày tôi không tham gia bất cứ thớt nào của bạn nữa.
 
Upvote 0
Ai là người chủ xướng việc tách riêng mấy bài "không liên quan chủ đề" này ra thành thớt khác vậy?
Tôi xin gửi lời với chủ thớt "Lọc và tách dữ liệu theo điều kiện?"
Nếu do bạn chủ xướng việc này thì cứ nói thẳng ra, kể từ rày tôi không tham gia bất cứ thớt nào của bạn nữa.
Con chào Bác VetMini,
Dạ, đúng là do con Bác ạ.
Con thấy không khí đang dần nóng lên mà trước đó con cũng có thông tin là vấn đề khó khăn của con đã đã được giải quyết. VÌ vậy mà con đã thông tin nhờ sự hỗ trợ của BQT.
Có thể do con quá lo xa vì thiếu kinh nghiệm... Tất cả mọi vấn đề xuất phát từ con, kính mong Bác và tất cả mọi người bỏ qua ạ..
Con cảm ơn Bác.
Oanh Thơ
Bài đã được tự động gộp:

Con cảm ơn Bác VetMini đã góp ý về việc tiếp xúc với CSDL ạ. Thực sự khi tiếp xúc với CSDL con cảm thấy như bước sang một thế giới mới chuẩn chỉnh và ngăn lắp hơn.
Mong từ nay về sau được Bác chỉ dẫn cho con hiểu hơn.
Con chúc Bác nhiều sức khỏe.
Oanh Thơ
 
Lần chỉnh sửa cuối:
Upvote 0
He he, ngọt quá à. Kết cô OT này rồi đó :)
Cho xin số zalo nhen. Hì hì, nói thật, người yêu cũ hồi xưa thật là xưa của mình trùng tên 100% với OT. Nên giờ mà thấy OT là loạn nhịp, lộn tùng phèo.
Đăng lộn chỗ rồi, OT move qua kia giúp nhé
 
Lần chỉnh sửa cuối:
Upvote 0
Con chào Bác VetMini,
Dạ, đúng là do con Bác ạ.
Con thấy không khí đang dần nóng lên mà trước đó con cũng có thông tin là vấn đề khó khăn của con đã đã được giải quyết. VÌ vậy mà con đã thông tin nhờ sự hỗ trợ của BQT.
Có thể do con quá lo xa vì thiếu kinh nghiệm... Tất cả mọi vấn đề xuất phát từ con, kính mong Bác và tất cả mọi người bỏ qua ạ..
Con cảm ơn Bác.
Oanh Thơ
...
Tôi yêu cầu bạn nhờ BQT xoá luôn cái thớt kia đi.
Những lời tôi nói có ngữ cảnh của nó. Đem sang chỗ khác là làm lạc ngữ cảnh.
Tôi là người văn cho nên lời lẽ đối với tôi rất quan trọng. Trâu ngựa mang đi chuồng nào thì cũng là trâu ngựa nhưng lời mà sửa ngữ cảnh thì chúng là tai hoạ cho người nói.
 
Upvote 0
Tôi yêu cầu bạn nhờ BQT xoá luôn cái thớt kia đi.
Những lời tôi nói có ngữ cảnh của nó. Đem sang chỗ khác là làm lạc ngữ cảnh.
Tôi là người văn cho nên lời lẽ đối với tôi rất quan trọng. Trâu ngựa mang đi chuồng nào thì cũng là trâu ngựa nhưng lời mà sửa ngữ cảnh thì chúng là tai hoạ cho người nói.
Tôi cũng không hiểu chủ thớt.

Người ta lấy bài của tôi ra để biểu diễn mấy hàm đô la. Thực ra người ta có thể tự tạo code của mình để biểu diễn. Nhưng ngưười ta chọn bài của tôi để biểu diễn. Vậy tôi phải có quyền nói lên quan điểm của mình. Rằng nhanh hơn thì đúng, không ai phủ định điều này. Chỉ có điều tôi cho sự nhanh hơn ấy nó ở mức không đáng quan tâm trong Excel văn phòng. Thế rồi người ta lại vu cho tôi là coi thường tốc độ. Tôi cũng từng nói là tốc độ cũng quan trọng nhưng tùy ở mức độ nào. Có những cải thiện nó ở mức quá nhỏ so với tổng thể và không đáng quan tâm. Người ta nói tôi coi thường tốc độ vậy thì viết CPU, compiler, hệ điều hành Windows ... Trời ạ, chủ đề về Excel và người ta thêm vào mấy hàm đô la mà lại nói lái sang CPU, compiler, hđh Windows? Về những cái đó thì thiếu gì diễn đàn khác để biểu diễn. Chỉ có điều chắc chắn ở những diễn đàn về viết compiler, hđh Windows người ta không sử dụng VBA và mấy hàm đô la kia.

Nếu những quan điểm của tôi bị tách rời khỏi ngữ cảnh thì rất buồn cười, khó hiểu, thậm chí bị hiểu sai.

Nếu chủ thớt đã xong việc và không muốn tranh luận thì đừng vào nữa. Hoặc vào nhưng im lặng, chỉ trả lời khi bị "gọi lên bảng". Thế thôi. Tại sao phải yêu cầu tách các bài viết?
---------
Riêng về chủ đề này tôi có lời khuyên cho chủ thớt.
Nếu công việc của bạn chỉ thực hiện với vài nghìn, thậm chí vài chục nghìn dòng dữ liệu thì không đáng quan tâm mấy hàm $ vì chúng chỉ cải thiện ở mức nhỏ hơn cái chớp mắt, bạn không cảm nhận được thay đổi đâu. Chỉ có "đồng hồ" tinh vi mới phát hiện ra. Còn nếu công việc luôn thao tác với hàng trăm nghìn, hàng triệu dòng dữ liệu, và số lần thao tác đó là nhiều trong mỗi ngày làm việc, thì nên làm theo lời khuyên của bác VetMini chứ không phải cải thiện bằng mấy hàm $. Còn nếu có tham vọng viết compiler, hđh gì đó thì nên vào những diễn đàn thích hợp vì khi viết chúng người ta không dùng VBA và mấy hàm $ kia đâu.
 
Lần chỉnh sửa cuối:
Upvote 0
If (CDbl(data(r, 4)) >= ngay) And (CDbl(data(r, 4)) <= ngay + 1) Then
Em xem bài #1 cần lọc theo 1 ngày chỉ định, chỗ này (CDbl(data(r, 4)) <= ngay + 1) sẽ lấy dữ liệu của ngày kế tiếp tại thời điểm 00:00:00 (Thời điểm này là hoàn toàn xảy ra thực tế).
 
Upvote 0
Các bạn làm ơn download lại nhé
Bài của anh có chỗ chưa đúng ấy. :)
Gợi ý cho anh.
PHP:
Sub vidu()
    Dim a As Long
    a = 1.5
    MsgBox a
End Sub
.
---------------
Giờ đăng 2 bài liên tiếp phải ngồi chờ 20 phút không lại bị gộp bài. Khổ nhục kế. :((
Em tự nói với em, không nói với anh đâu nhé, hiểu lầm thì tội em.
 
Upvote 0
Tôi cũng không hiểu chủ thớt.

Người ta lấy bài của tôi ra để biểu diễn mấy hàm đô la. Thực ra người ta có thể tự tạo code của mình để biểu diễn. Nhưng ngưười ta chọn bài của tôi để biểu diễn. Vậy tôi phải có quyền nói lên quan điểm của mình. Rằng nhanh hơn thì đúng, không ai phủ định điều này. Chỉ có điều tôi cho sự nhanh hơn ấy nó ở mức không đáng quan tâm trong Excel văn phòng. Thế rồi người ta lại vu cho tôi là coi thường tốc độ. Tôi cũng từng nói là tốc độ cũng quan trọng nhưng tùy ở mức độ nào. Có những cải thiện nó ở mức quá nhỏ so với tổng thể và không đáng quan tâm. Người ta nói tôi coi thường tốc độ vậy thì viết CPU, compiler, hệ điều hành Windows ... Trời ạ, chủ đề về Excel và người ta thêm vào mấy hàm đô la mà lại nói lái sang CPU, compiler, hđh Windows? Về những cái đó thì thiếu gì diễn đàn khác để biểu diễn. Chỉ có điều chắc chắn ở những diễn đàn về viết compiler, hđh Windows người ta không sử dụng VBA và mấy hàm đô la kia.

Nếu những quan điểm của tôi bị tách rời khỏi ngữ cảnh thì rất buồn cười, khó hiểu, thậm chí bị hiểu sai.

Nếu chủ thớt đã xong việc và không muốn tranh luận thì đừng vào nữa. Hoặc vào nhưng im lặng, chỉ trả lời khi bị "gọi lên bảng". Thế thôi. Tại sao phải yêu cầu tách các bài viết?
---------
Riêng về chủ đề này tôi có lời khuyên cho chủ thớt.
Nếu công việc của bạn chỉ thực hiện với vài nghìn, thậm chí vài chục nghìn dòng dữ liệu thì không đáng quan tâm mấy hàm $ vì chúng chỉ cải thiện ở mức nhỏ hơn cái chớp mắt, bạn không cảm nhận được thay đổi đâu. Chỉ có "đồng hồ" tinh vi mới phát hiện ra. Còn nếu công việc luôn thao tác với hàng trăm nghìn, hàng triệu dòng dữ liệu, và số lần thao tác đó là nhiều trong mỗi ngày làm việc, thì nên làm theo lời khuyên của bác VetMini chứ không phải cải thiện bằng mấy hàm $. Còn nếu có tham vọng viết compiler, hđh gì đó thì nên vào những diễn đàn thích hợp vì khi viết chúng người ta không dùng VBA và mấy hàm $ kia đâu.
Xin chào Bác Siwtom,
Vâng, con biết thế nào Bác cũng sẽ tham gia nên con cũng đã chuẩn bị tinh thần để được nghe mắng thêm một lần nữa ạ.

Thực sự do con quá lo xa vì thiếu kinh nghiệm.. nên con đã nhờ BQT can thiệp xóa các bài viết nhưng BQT xét thấy mức độ chưa có gì nên mới tách ra như vậy..
Dù sao tất cả mọi vấn đề xuất phát từ con, kính mong Bác và tất cả mọi người bỏ qua ạ.

Về vấn đề tốc độ nhanh chậm và giây con cũng đâu có để ý, đối với con code nào dễ dùng dễ hiểu thì con sẽ dùng thôi ạ chứ đâu có tính toán đến đơn vị ms đâu ạ.

Cảm ơn Bác đã luôn quan tâm và giúp đỡ ạ.
Chúc Bác nhiều sức khỏe.
Oanh Thơ
 
Upvote 0
Em xem bài #1 cần lọc theo 1 ngày chỉ định, chỗ này (CDbl(data(r, 4)) <= ngay + 1) sẽ lấy dữ liệu của ngày kế tiếp tại thời điểm 00:00:00 (Thời điểm này là hoàn toàn xảy ra thực tế).
Cái này dễ hiểu. Đúng là sơ ý. Bạn chủ thớt sửa thành
Mã:
If (CDbl(data(r, 4)) >= ngay) And (CDbl(data(r, 4)) < ngay + 1) Then
Tức bỏ dấu =
 
Upvote 0
Hì hì, hoan hô bạn @befaint, vậy là có người chịu khó tìm tòi, đọc code và so sánh 2 code rồi đó.
Như cu anh tui đã nói ban đầu, code và thuật toán của người ta, tui giữ nguyên 100%, không đụng, change gì cả, cả mấy cái dấu >= <=. Mục đích minh họa là cùng 1 code, cùng 1 thuật toán, nếu cách khai báo biến, cách dùng hàm đúng thì sẽ cải thiện đáng kể tốc độ, mà hoàn toàn không phải làm gì cao xa cả.
Thực tế đa dạng, nên sẽ còn gặp nhiều. Các bạn có nhớ bài toán đọc file text 600 ngàn dòng của bạn nào đó không ? Bạn ấy đã nói là trên máy bạn ấy chạy mất 60s. Nhưng tiếc là bạn ấy không úp data và code được. Nên thua. Nếu optimize theo cách dùng khai báo biến đúng, dùng hàm đúng thì may lắm xuống được 1/2, còn 30s thôi. Trong VBA có những cái ngưỡng giới hạn phải chấp nhận, không thể vượt qua được nếu dùng thuần và đúng VBA. Nên tôi mới nghĩ giải pháp dùng DLL viết = C hay Delphi, memory mapping file đó và parse trực tiếp trên map file, không phải read all lên bộ nhớ, trả về Variant array, thì mới hy vọng cải tiến tốc độ xuống ngưỡng 1/3 hay dưới được.
Quay lại vấn đề bạn @befaint phát hiện, đúng đấy @befaint. Thật ra là lúc đầu code mình comment nhiều lắm, nhưng sau đó nghĩ lại, thôi xóa hết đi,để các bạn vọc, đo và tìm ra, nó mới thú.

Về vấn đề Long, Double, có các chú ý sau:
1. Tại sao không dùng Double mà dùng Long: Hì hì, dùng Long thì VBA xử lý trên nó phải nhanh hơn xử lý số thực rồi chứ.
2. Thế dùng Long bị ép từ kiểu Date về có đúng không. Hì hì, đúng chứ, vì các bạn không xem kỹ document của VBA. Date trong VBA lưu thành số Double 8 byte, phần nguyên chứa ngày, phần lẽ chứa time. Mà ở đây mình chỉ quan tâm tới ngày, nên lấy phần nguyên, đưa qua biến Long thôi.
3. Thế tại sao không dùng hàm CDbl hay hàm CLng. Dùng làm chi, dùng thì VBA phải truyền vào stack biến variant rồi gọi hàm convert, trả về gán vào Long. Còn viết thằng l = data(xxx, xxx) thì VBA tự chuyển kiểu cho mình luôn, đỡ tốn time cho lời gọi.
4. Thế nếu data(xxx, xxx) không phải kiểu Date thì sao. Thì văng hết chứ sao, Long, Double, CLng, CDbl gì văng hết :)
5. Thế tại sao đưa biến Long ra ngoài, trên lệnh If. Vì tránh nó bị tính, convert 2 lần từ trong lệnh If. Các bạn có nhớ topic về VBA không nối tắt logic chứ ? Và VBA compiler nó đâu đủ thông minh để cache giá trị đã tính từ lần 1 dùng cho lần 2 đâu.
VBA thì biểu sao nó làm vậy à, chính xác 100% như những gì các bạn viết ra thôi.
6. Mới nhớ ra, bổ sung thêm: Thế dùng hàm VBA Val được không. Nếu dữ liệu sai Val không chết. OK, nhưng cuối cùng Val lại chậm hơn hết, vì tham số của Val là Val(String): Double. Nên VBA phải convert data(xxx, xxx) từ Variant sang string, call Val, convert ngược double lại thành Long.
Nên châm, bỏ :)

Còn rất nhiều cái nho nhỏ trong đó nữa, mà mình đã xóa hết comment. Các bạn phải chịu khó dùng beginTiming và EndTiming đặt vào từng đoạn để xem thời gian chạy cho từng đoạn đó hết bao nhiêu, chiếm bao nhiêu % trong tổng thời gian cả hàm. Một cái thay đổi, thêm bớt nhỏ chạy mất bao nhiêu, nhanh hơn hay chậm hơn, được bao nhiêu %. Nhưng đừng đặt vào bên trong vòng For nhé, click OK mệt nghĩ luôn đó.

Vòng For nhìn tưởng chậm nhất, nhưng không phải, nó chỉ chiếm gần 1/3 thôi. Trong vòng for đó, 2 cái chạy chậm nhất là ông nội VBA InStr và vòng While tìm Pos. Mình có thể viết lại nhanh hơn nhiều, nhưng không được vì phải dùng đúng code của người ta, không thì người ta la làng lên là đổi thuật toán. Như InStr thay bằng StrStrI API của shlwapi.dll chẳng hạn, While thì thay bằng Split, nhanh hơn nhiều.

Ngoài các cách chính thống, còn nhiều cách "tà đạo" nữa để giảm xuống nữa, 1/3 thôi, nhưng sẽ làm rắc rối code, bạn OT xinh đẹp sẽ không hiểu và fix được nếu bug khi dị dạng dữ liệu hay phát sinh thêm yêu cầu. Nên mình giữ nguyên và đã nói bạn OT giữ nguyên, cứ dùng code cũ. Code optimize xem để biết chơi thôi, kkk :p

Chỉ có 2 điểm thay đổi rất rất nhỏ thôi mà cải thiện tốc độ đáng kể nhất, các bạn cố tìm ra nhé.
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn @befaint nói mình mới nhìn kỹ lại đoạn If này. Hì hì, nếu đổi là Long rồi thì so sánh = 1 cái luôn chứ >= với < + 1 gì nữa ? :)
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi cũng không hiểu chủ thớt.

Người ta lấy bài của tôi ra để biểu diễn mấy hàm đô la. Thực ra người ta có thể tự tạo code của mình để biểu diễn. Nhưng ngưười ta chọn bài của tôi để biểu diễn. Vậy tôi phải có quyền nói lên quan điểm của mình. ...
Xin lỗi bác, tôi nghĩ có lẽ tại tôi mà xảy ra chuyện "loãng bài".

Xin phép cho trần tình, diễn đàng này mang tên Excel, và cái tên đó tạo cho tôi ấn tượng rằng quản lý dữ liệu là tiêu chí chung.
Hồi tôi còn làm việc với các đồ án, nhìn những người chung quanh hăm hở với cơ hội học hỏi CSDL nói chung và CSDLLH nói riêng mà tôi thong cảm cho họ. Thấy ở đây có người cơ hội ấy ngay trước mắt mà lo chú vào chỗ khác thì tôi thử cảnh tỉnh.
SQL Server thì không hiếm. Nhưng đó là nếu bạn chịu học với cái Northwind (hay tương tự); một cái CSDL với dữ liệu thực tế và cho phép bạn truy vấn sửa đổi tuỳ ý là cơ hội hiếm có.
Nhưng thôi, người ta đã tỏ rõ ý thức về con đường sự nghiệp của mình hướng khác rồi.

Anh tưởng giếng sâu anh nối sợi dây dài,
Ai ngờ giếng cạn anh tiếc hoài sợi dây. (Ca Dao)


Lời nhắn thêm cho các bạn còn phân vân chọn lựa con đường để học:
- Đào sâu vào code là con đường đi lên vinh quang. Nhưng cần nhớ rằng nếu con đường ấy ai cũng theo được thì ai cũng vinh quang hết rồi.
- Con đường tôi đi là con đường chẳng có gì cao cả. Nhưng chính vì sự tầm thường ấy mà nó bảo đảm bất cứ ai có đủ kiên nhẫn là theo được.
 
Upvote 0
Web KT
Back
Top Bottom