Nhờ giúp đỡ code tìm kiếm với nhiều điều kiện trên Listview (Userform). (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

phucbugis

Thành viên tích cực
Tham gia
22/6/13
Bài viết
1,270
Được thích
981
Em có 1 file lương tháng và thường xuyên phải tìm kiếm mã CNV dựa vào họ, tên, bộ phận, nơi làm việc, nhóm lương.

Trước kia em hay sử dụng Listbox để cho ra kết quả tìm kiếm , nhưng từ khi dùng Listview thì ko biết phải cài đặt như thế nào để code đơn giản hơn.

Hiện tại trong file đã xử lý được 2 trường hợp
#1: họ ="" và tên <>""
#2: họ <>"" và tên <>""

các trường hợp còn lại:
'# Ho = ""
'#1 ho ="", ten<>"", bo phan<>""
'#2 ho ="", ten<>"", noi lam viec<>""
'#3 ho ="", ten<>"", nhom luong<>""
'# Ho <> ""
'#1 ho <>"", ten<>"", bo phan<>""
'#2 ho <>"", ten<>"", noi lam viec<>""
'#3 ho <>"", ten<>"", nhom luong<>""
'# Ho ="" va ten =""
'#1 ho ="", ten="", bo phan<>""
'#2 ho ="", ten="", noi lam viec<>""
'#3 ho ="", ten="", nhom luong<>""

Bài toán này e bó tay từ khi dùng listbox và lại gặp nó khi đụng đến Listview.
Xin các cao thủ chỉ dùm hướng giải quyết.
Thanks! --=0

Link MediaFire: Search ListView (GPE)
 
Lần chỉnh sửa cuối:
Em có 1 file lương tháng và thường xuyên phải tìm kiếm mã CNV dựa vào họ, tên, bộ phận, nơi làm việc, nhóm lương.

Trước kia em hay sử dụng Listbox để cho ra kết quả tìm kiếm , nhưng từ khi dùng Listview thì ko biết phải cài đặt như thế nào để code đơn giản hơn.

Hiện tại trong file đã xử lý được 2 trường hợp
#1: họ ="" và tên <>""
#2: họ <>"" và tên <>""

các trường hợp còn lại:
'# Ho = ""
'#1 ho ="", ten<>"", bo phan<>""
'#2 ho ="", ten<>"", noi lam viec<>""
'#3 ho ="", ten<>"", nhom luong<>""
'# Ho <> ""
'#1 ho <>"", ten<>"", bo phan<>""
'#2 ho <>"", ten<>"", noi lam viec<>""
'#3 ho <>"", ten<>"", nhom luong<>""
'# Ho ="" va ten =""
'#1 ho ="", ten="", bo phan<>""
'#2 ho ="", ten="", noi lam viec<>""
'#3 ho ="", ten="", nhom luong<>""

Bài toán này e bó tay từ khi dùng listbox và lại gặp nó khi đụng đến Listview.
Xin các cao thủ chỉ dùm hướng giải quyết.
Thanks! --=0

Bạn nên nhớ là cho dù bạn có liệt kê nhiều trường hợp thì chưa chắc đó là tất cả các trường hợp. Luôn luôn phải miêu tả. Và nếu vấn đề phức tạp thì thêm ví dụ.
Câu hỏi: bạn liệt kê 5 điều kiên là: họ, tên, bộ phận, nơi làm việc, nhóm lương. Tôi xem tập tin thì có cả nghỉ việc/chưa nghỉ việc. Đk đó là luôn có. Thế còn 5 đk kia thì có đk nào bắt buộc không hay có thể bỏ trống? Đó là những đk nào?
Hãy nói sao cho người khác hiểu. Đó là đk cần để nhận được sự giúp đỡ. Đk đủ là vd. người ta có thời gian, có hứng, ...
 
Upvote 0
Bạn nên nhớ là cho dù bạn có liệt kê nhiều trường hợp thì chưa chắc đó là tất cả các trường hợp. Luôn luôn phải miêu tả. Và nếu vấn đề phức tạp thì thêm ví dụ.
Câu hỏi: bạn liệt kê 5 điều kiên là: họ, tên, bộ phận, nơi làm việc, nhóm lương. Tôi xem tập tin thì có cả nghỉ việc/chưa nghỉ việc. Đk đó là luôn có. Thế còn 5 đk kia thì có đk nào bắt buộc không hay có thể bỏ trống? Đó là những đk nào?
Hãy nói sao cho người khác hiểu. Đó là đk cần để nhận được sự giúp đỡ. Đk đủ là vd. người ta có thời gian, có hứng, ...

Cảm ơn Siwtom đã góp ý.
Mình đã tập hợp lại các điều kiện để sát với thực tế và chỉnh sửa lại code (thêm For next => code rút gọn hơn 1 chút).

9 trường hợp sau thường hay xảy ra, các trường hợp còn lại thì không cần thiết.
(mình đã bỏ bớt đk nhóm lương)
'#1 tbxho = "", tbxten <> ""
1a. cbxbophan = "" And cbxnoilamviec = ""
1b. cbxbophan <> "" And cbxnoilamviec = ""
1c. cbxbophan = "" And cbxnoilamviec <> ""
'#2 tbxho <> "", tbxten <> ""
2a. cbxbophan = "" And cbxnoilamviec = ""
2b. cbxbophan <> "" And cbxnoilamviec = ""
2c. cbxbophan = "" And cbxnoilamviec <> ""
'#3 tbxho = "", tbxten = ""
3a. cbxbophan <> "" And cbxnoilamviec = ""
3b. cbxbophan = "" And cbxnoilamviec <> ""
3c. cbxbophan <> "" And cbxnoilamviec <> ""

+ Trường hợp CNV nghỉ việc. Khi Userform2.checkbox1=True thì chỉ tìm các CNV đang làm việc, còn False thì chỉ tìm các CNV đã nghỉ việc. Mình có cài đk này vào hotro_cmdSearch Private Sub CheckBox1_Click

Bạn xem giúp mình có thể rút gọn code hơn được ko? Nếu cần thì thay thế toàn bộ code đang có.
Thanks! --=0

Link MediaFire: Search Listview (GPE)1
 
Lần chỉnh sửa cuối:
Upvote 0
Cảm ơn Siwtom đã góp ý.
Mình đã tập hợp lại các điều kiện để sát với thực tế và chỉnh sửa lại code (thêm For next => code rút gọn hơn 1 chút).

9 trường hợp sau thường hay xảy ra, các trường hợp còn lại thì không cần thiết.
(mình đã bỏ bớt đk nhóm lương)
'#1 tbxho = "", tbxten <> ""
1a. cbxbophan = "" And cbxnoilamviec = ""
1b. cbxbophan <> "" And cbxnoilamviec = ""
1c. cbxbophan = "" And cbxnoilamviec <> ""
'#2 tbxho <> "", tbxten <> ""
2a. cbxbophan = "" And cbxnoilamviec = ""
2b. cbxbophan <> "" And cbxnoilamviec = ""
2c. cbxbophan = "" And cbxnoilamviec <> ""
'#3 tbxho = "", tbxten = ""
3a. cbxbophan <> "" And cbxnoilamviec = ""
3b. cbxbophan = "" And cbxnoilamviec <> ""
3c. cbxbophan <> "" And cbxnoilamviec <> ""

+ Trường hợp CNV nghỉ việc. Khi Userform2.checkbox1=True thì chỉ tìm các CNV đang làm việc, còn False thì chỉ tìm các CNV đã nghỉ việc. Mình có cài đk này vào hotro_cmdSearch Private Sub CheckBox1_Click

Bạn xem giúp mình có thể rút gọn code hơn được ko? Nếu cần thì thay thế toàn bộ code đang có.
Thanks! --=0

"9 trường hợp sau thường hay xảy ra"??? Cô A THƯỜNG mặc váy đầm và ăn ốc luộc. Nhưng không có nghĩa là không có lần nào mặc quần tây và ăn gà nướng.

Tôi đã nói với bạn mà bạn cứ không nghe. Bạn liệt kê thì tùy bạn nhưng miêu tả thì phải có.

Thôi tôi tự miêu tả, không đúng thì bạn tự miêu tả lại.

"Tôi muốn lọc dữ liệu với nhiều nhất là 6 điều kiện: nghỉ việc/chưa nghỉ, họ, tên, bộ phận, nơi làm việc, nhóm lương. Điều kiện nghỉ việc/chưa nghỉ luôn có do giá trị của nó luôn được xác định. Các đk còn lại không bắt buộc. Nếu đk nào đó trong 5 đk còn lại không nhập - bỏ trống - thì đk đó không "tham gia" vào quá trình lọc"

Tôi làm cho cách miêu tả trên. Nếu chưa đúng ý thì miêu tả lại như cách tôi đã miêu tả ở trên.

1. Có gì thắc mắc thì hỏi, diễn giải cụ thể. Một câu "không chạy" là không được. Đại loại phải là: khi tôi nhập xyz vào ABC, rồi nhấn kml thì nhẩy ra cửa sổ "hichic" - máy treo, Excel bị giết đột ngột ...

2. Tôi không tải tập tin ở bài #3, tôi làm theo tập tin bài #1 do đã có.

3. Tôi thay hàm chuyển mã (vứt module cũ nhập module mới)
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Trên cả tuyệt vời rồi Siwtom ơi. --=0

+ Mình có chỉnh lại điều kiện search 1 tí
If cbxbophan.text <> "" Then PrepareArray ColsSearch, 5, cbxbophan.text
=> If cbxbophan.text <> "" Then PrepareArray ColsSearch, 5, "*" & UCase(Trim(cbxbophan.text)) & "*"
Vì danh sách combobox rất dài nên gõ trực tiếp từ tìm kiếm sẽ nhanh hơn việc chọn.

+ Khi search xong đưa listview thì ko hiển thị tiếng Việt và mình đã sửa lại
.SubItems(1) = SourceToDest(Arr(i, 3), src_uni, dst_windows1258)
=> .SubItems(1) = UniToWindows1258(Arr(i, 3))

Code lúc này rất gọn.
Cảm ơn bạn nhiều ! --=0

Link: https://www.mediafire.com/?dclbdk49gy4yeiy
 
Lần chỉnh sửa cuối:
Upvote 0
1. Có gì thắc mắc thì hỏi, diễn giải cụ thể. Một câu "không chạy" là không được. Đại loại phải là: khi tôi nhập xyz vào ABC, rồi nhấn kml thì nhẩy ra cửa sổ "hichic" - máy treo, Excel bị giết đột ngột ...

Chào anh Siwtom ! --=0

Tuần trước anh có giúp e làm 1 file lọc nhanh trên Listview, hiện tại file chạy rất OK, và có phát sinh thêm vấn đề nhỏ mong được anh giúp:

Trong code Sub hotro_cmdSearch() của Userform2,
có đoạn ghi With Me.list2.ListItems.Add(, , Arr(i, 1)). Hiện tại thì Listview đang điền các giá trị 0 hoặc 1 sau khi Search. E mong muốn nó chuyển thành vị trí row của từng công nhân viên, để hỗ trợ việc Update và Xóa row trên sheet khi cần thiết đó anh.

Kết quả mong muốn

pic1.jpg

Mong sớm nhận tin anh!

Link MediaFire: Search ListView (dao vi tri cot)
 
Lần chỉnh sửa cuối:
Upvote 0
Chào anh Siwtom ! --=0

Tuần trước anh có giúp e làm 1 file lọc nhanh trên Listview, hiện tại file chạy rất OK, và có phát sinh thêm vấn đề nhỏ mong được anh giúp:

Trong code Sub hotro_cmdSearch() của Userform2,
có đoạn ghi With Me.list2.ListItems.Add(, , Arr(i, 1)). Hiện tại thì Listview đang điền các giá trị 0 hoặc 1 sau khi Search. E mong muốn nó chuyển thành vị trí row của từng công nhân viên, để hỗ trợ việc Update và Xóa row trên sheet khi cần thiết đó anh.

Kết quả mong muốn

View attachment 113640

Mong sớm nhận tin anh!

Mảng truyền vào hàm MyFind2DArray là Arr với Arr = Sheet1.Range("Table1").value. Tức là mảng bao gồm cột từ B tới J (bạn nhớ kiểm tra sao cho dòng, cột của vùng Table cho đúng). Tức mảng trả vể bởi hàm MyFind2DArray bao gồm các cột tương ứng với các cột từ B tới J.

Bây giờ bạn có thêm 1 cột trong ListView và bạn muốn thêm cột đó chỉ số dòng trên sheet của mỗi dòng tìm thấy. Muốn có chỉ số dòng thì phải sửa hàm MyFind2DArray để nó trả về "dư" - "thêm" một cột, vd. cột cuối, dùng để nhớ chỉ số dòng trên sheet của dòng dữ liệu được tìm thấy.

Chỉ số dòng trả về trong cột cuối bởi hàm MyFind2DArray là chỉ số tương đối. Chỉ số bạn muốn nhập vào ListView là chỉ số tuyệt đối. Vd. Dòng "536, v, Lê Thị Mỹ, ..." là dòng thứ 6 (chỉ số tuyệt đối) trên sheet nhưng là dòng thứ 2 (chỉ số tương đối đối) trong mảng truyền vào cũng như trả về bởi hàm MyFind2DArray

Mã:
Sub hotro_cmdSearch()
Dim i As Long, Arr, dieukien As Long, ColsSearch()
    Me.list2.ListItems.Clear
    Arr = Sheet1.Range("Table1").value
    ReDim ColsSearch(1 To 2, 1 To 1)
    dieukien = Not UserForm2.CheckBox1
    ColsSearch(1, 1) = [COLOR=#0000ff][B]1[/B][/COLOR]
    ColsSearch(2, 1) = dieukien
    If Trim(tbxho) <> "" Then PrepareArray ColsSearch, 3, "*" & UCase(Trim(tbxho)) & "*"
    If Trim(tbxten) <> "" Then PrepareArray ColsSearch, 4, "*" & UCase(Trim(tbxten)) & "*"
    If cbxbophan.text <> "" Then PrepareArray ColsSearch, 5, cbxbophan.text
    If cbxnoilamviec.text <> "" Then PrepareArray ColsSearch, 8, cbxnoilamviec.text
    If cbxnhomluong.text <> "" Then PrepareArray ColsSearch, 9, cbxnhomluong.text
    Arr = MyFind2DArray(Arr, ColsSearch)
    If IsArray(Arr) Then
        For i = 1 To UBound(Arr)
            With Me.list2.ListItems.Add(, , [B][COLOR=#0000ff]Arr(i, UBound(Arr, 2)) + Sheet1.Range("Table1").Row - 1[/COLOR][/B])
                [COLOR=#0000ff].SubItems(1) = Arr(i, 2)
                .SubItems(2) = SourceToDest(Arr(i, 3), src_uni, dst_windows1258)
                .SubItems(3) = SourceToDest(Arr(i, 4), src_uni, dst_windows1258)
                .SubItems(4) = SourceToDest(Arr(i, 5), src_uni, dst_windows1258)
                .SubItems(5) = SourceToDest(Arr(i, 6), src_uni, dst_windows1258)
                .SubItems(6) = SourceToDest(Arr(i, 7), src_uni, dst_windows1258)
                .SubItems(7) = SourceToDest(Arr(i, 8), src_uni, dst_windows1258)
                .SubItems(8) = SourceToDest(Arr(i, 9), src_uni, dst_windows1258)[/COLOR]
            End With
        Next
    End If
End Sub

Function MyFind2DArray(ByVal sArray As Variant, ColsSearch())
'    1. sArray laĚ maŇng - range chýěa caěc giaě triň câĚn loňc.ChiŇ sôě doĚng vaĚ côňt tiěnh týĚ 1
'    2. ColsSearch laĚ maŇng 2 chięĚu coě 2 doĚng vaĚ k côňt vőěi k laĚ sôě côňt câĚn loňc. DoĚng đâĚu chýěa lâĚn lýőňt chiŇ sôě caěc côňt câĚn loňc - tiěnh týĚ 1.
'       DoĚng 2 chýěa caěc đięĚu kięňn loňc cho týĚng côňt.

    Dim TmpArr, i As Long, j As Long, Arr, Tmp(), sArr As String, res As Boolean
    Dim col As Long, k As Long, TmpcurrRow As Long, count As Long, t As Double
    On Error Resume Next
'    sao dýŢ lięňu týĚ sArray sang TmpArr
    TmpArr = sArray
    
'   đi týĚng doĚng
    For i = 1 To UBound(TmpArr, 1)
        For col = LBound(ColsSearch, 2) To UBound(ColsSearch, 2)
'           chuoi hien hanh - dang xet
            sArr = TmpArr(i, ColsSearch(1, col))
'           ket qua kiem tra
            res = sArr Like ColsSearch(2, col)
            If Not res Then Exit For
        Next col
        If res Then
            ReDim Preserve Tmp(0 To count)
            Tmp(count) = i
            count = count + 1
        End If
    Next i
'         nęěu trong mang tmp coě dýŢ lięňu laĚ caěc chiŇ sôě doĚng đýőňc choňn thiĚ ...
    If count > 0 Then
'             taňo maŇng Arr coě sôě doĚng băĚng sôě chiŇ sôě doĚng đýőňc choňn vaĚ sôě côňt băĚng sôě côt cuŇa maŇng nguôĚn sArray
        ReDim Arr(1 To UBound(Tmp) + 1, 1 To UBound(TmpArr, 2) [B][COLOR=#ff0000]+ 1[/COLOR][/B]) ' <-- them 1 cot
'                 ghi caěc doĚng cuŇa maŇng nguôĚn maĚ coě chiŇ sôě laĚ caěc phâĚn týŇ cua tmp (týěc caěc doĚng đýőňc lâěy) vaĚo maŇng Arr
            For i = 1 To UBound(Tmp) + 1
                TmpcurrRow = Tmp(i - 1)
                For j = 1 To UBound(TmpArr, 2)
                    Arr(i, j) = TmpArr(TmpcurrRow, j)
                Next
                [B][COLOR=#ff0000]Arr(i, UBound(Arr, 2)) = TmpcurrRow[/COLOR][/B]  ' <-- chi so dong tuong doi
            Next
    End If
'         traŇ vęĚ maŇng caěc doĚng đýőňc choňn - loňc
    MyFind2DArray = Arr
End Function

Những chỗ đỏ đỏ là thêm vào. Những chỗ xanh xanh là sửa đổi

Tôi viết "chay" thôi. Lý do như tôi đã nói với bạn.
 
Upvote 0
Mảng truyền vào hàm MyFind2DArray là Arr với Arr = Sheet1.Range("Table1").value. Tức là mảng bao gồm cột từ B tới J (bạn nhớ kiểm tra sao cho dòng, cột của vùng Table cho đúng). Tức mảng trả vể bởi hàm MyFind2DArray bao gồm các cột tương ứng với các cột từ B tới J.

Bây giờ bạn có thêm 1 cột trong ListView và bạn muốn thêm cột đó chỉ số dòng trên sheet của mỗi dòng tìm thấy. Muốn có chỉ số dòng thì phải sửa hàm MyFind2DArray để nó trả về "dư" - "thêm" một cột, vd. cột cuối, dùng để nhớ chỉ số dòng trên sheet của dòng dữ liệu được tìm thấy.

Chỉ số dòng trả về trong cột cuối bởi hàm MyFind2DArray là chỉ số tương đối. Chỉ số bạn muốn nhập vào ListView là chỉ số tuyệt đối. Vd. Dòng "536, v, Lê Thị Mỹ, ..." là dòng thứ 6 (chỉ số tuyệt đối) trên sheet nhưng là dòng thứ 2 (chỉ số tương đối đối) trong mảng truyền vào cũng như trả về bởi hàm MyFind2DArray

E đã test => rất đúng với yêu cầu của em.

Cảm ơn anh nhiều lắm ! --=0
 
Upvote 0
E dựa trên code của Anh Siwtom có chỉnh sửa lại để áp dụng vào file của mình nhưng nó lọc ra không chính xác lắm. Cụ thể ở textbox1 gõ story1, textbox2 e gõ C1 thì nó lại tìm ra cả C10, C11, C12..... mà e chỉ cần nó tìm ra đúng dòng Story1 và C1 thôi. anh chỉ giúp em sửa code lại với!
 

File đính kèm

Upvote 0

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

Back
Top Bottom