Filter trong ListBox

Liên hệ QC

NguyenthiH

Thành viên mới đăng ký
Tham gia
11/12/16
Bài viết
950
Được thích
175
Giới tính
Nữ
Chào Mọi Người!
Em có form này, nhờ Các AC giúp đỡ.
TRong file khi nhấn vào nút "SAO" thì hiện Form, trong ListBox sẽ hiện hết dữ liệu của Sheet1.
Em nhờ các AC viết code để khi gỏ vào các TextBox thì sẽ hiện dữ liệu rút gọn theo TextBox đó.
Ví dụ như em gỏ 05/02/2017 vào Tb_Ngay thì dữ liệu trong ListBox chỉ hiện theo ngày 05/02/2017.
và nếu em gỏ tiếp vòa Tb_NCC là Anh Tuấn thì dữ liệu chỉ còn ngày 05/02/2017 và nhà cung cấp là Anh Tuấn.v...vv.
Tức là giống như chức năng Filter của Excell.
Mong các AC giúp đỡ.
 

File đính kèm

  • FilterListbox.xlsb
    21.3 KB · Đọc: 65
Chào Mọi Người!
Em có form này, nhờ Các AC giúp đỡ.
TRong file khi nhấn vào nút "SAO" thì hiện Form, trong ListBox sẽ hiện hết dữ liệu của Sheet1.
Em nhờ các AC viết code để khi gỏ vào các TextBox thì sẽ hiện dữ liệu rút gọn theo TextBox đó.
Ví dụ như em gỏ 05/02/2017 vào Tb_Ngay thì dữ liệu trong ListBox chỉ hiện theo ngày 05/02/2017.
và nếu em gỏ tiếp vòa Tb_NCC là Anh Tuấn thì dữ liệu chỉ còn ngày 05/02/2017 và nhà cung cấp là Anh Tuấn.v...vv.
Tức là giống như chức năng Filter của Excell.
Mong các AC giúp đỡ.
Bạn vào trang chủ GPE sẽ thấy có cái bạn cần
 
Upvote 0
Mong Thầy chỉ rỏ, hoặc cho Link.
Em cám ơn
 
Upvote 0
Dạ em cám ơn Thầy.
Nhưng File đó của Thầy Ndu chỉ có 1 TextBox, còn của em có 5 TextBox.
Em xin ví dụ lại như sau:
1/gỏ ngày vào Tb_Ngay là 05/02/2017 thì dữ liệu trong ListBox1 là 12 dòng.Chỉ có nhà cung cấp là Anh Tuấn và Chị Hoa
2/ vẫn để ngày 05/02/2017 ở Tb_Ngay, gỏ vào Tb_NCC là Anh Tuấn thì dữ liệu chỉ còn 6 dòng.
Em không biết diễn tả sao, nhưng nói chung là lọc theo điều kiện "And" như là "Tb_Ngay" and "Tb_Ncc" and "Tb_NM" and" Tb_SLM"..v.v...vv
 
Upvote 0
Nếu là lọc với điều kiện 2 cột thì thay vì xài TextBox, ta chuyển sang xài ComboBox

Nếu lọc 3 điều kiện thì độ phức tạp sẽ lên gấp bội! Khi í xài AdvancedFilter cho khỏe!
 
Upvote 0
Vậy Anh Hoang2013 có thể giúp em Advanced Filter với.
 
Upvote 0
Dạ em cám ơn Thầy.
Nhưng File đó của Thầy Ndu chỉ có 1 TextBox, còn của em có 5 TextBox.
Em xin ví dụ lại như sau:
1/gỏ ngày vào Tb_Ngay là 05/02/2017 thì dữ liệu trong ListBox1 là 12 dòng.Chỉ có nhà cung cấp là Anh Tuấn và Chị Hoa
2/ vẫn để ngày 05/02/2017 ở Tb_Ngay, gỏ vào Tb_NCC là Anh Tuấn thì dữ liệu chỉ còn 6 dòng.
Em không biết diễn tả sao, nhưng nói chung là lọc theo điều kiện "And" như là "Tb_Ngay" and "Tb_Ncc" and "Tb_NM" and" Tb_SLM"..v.v...vv

Làm cho bạn 3 đk nhé, nhớ thay đổi tiêu đề cột.

Mã:
Private Sub CommandButton1_Click()    
    Dim cnn As Object, rst As Object
    Set cnn = CreateObject("ADODB.Connection")
    Set rst = CreateObject("ADODB.Recordset")
    cnn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 12.0"
    With rst
        .ActiveConnection = cnn
        .Open "Select * From [Sheet1$] where NhaCungCap like '" & Tb_NCC.Text & "%' and DonHang like '" & Tb_DH.Text & "%' and NguoiMua like '" & Tb_NM.Text & "%'"
        If Not (.bof And .EOF) Then
            ListBox1.ColumnCount = .Fields.Count
            ListBox1.Column = .getrows()
        Else
            MsgBox "Khong thoa man dieu kien"
            ListBox1.List = Sheet1.Range("A1:E1").Value
        End If
       .Close
    End With
    
    Set rst = Nothing
    cnn.Close: Set cnn = Nothing


End Sub
 

File đính kèm

  • FilterListbox.xlsb
    25.3 KB · Đọc: 98
Lần chỉnh sửa cuối:
Upvote 0
Chỉ kịp làm cho bạn 2 ComboBox mà thôi

Bạn thử hết các phương án coi sao? -+*/
 

File đính kèm

  • gpeForm.rar
    16.1 KB · Đọc: 71
Upvote 0
Xin lỗi vì em diễn đạt vụng. File của Thầy không đúng ý em.
Em xin nói rỏ là giống chức năng Filter của Excel, nhưng trên ListBox.
1/Ở Sheet1 của em đã Filter hết 5 cột. Khi chọn dấu xổ ở cột Ngày thì có select all và các ngày: 02, 05, 07, 10, 12 của tháng 2 năm 2017. giờ em bỏ stick select All, stick vào ô 05 thì sẽ lọc ngày 05/02/2017.(Tương đương việc gỏ ngày vào Tb_Ngay trong Form)
2/Bây giờ vẫn còn lọc ngày 05/02/2017, em chọn dấu xổ Nhà cung cấp thì có Anh Tuấn và Chị Hoa, em bỏ chọn Select All stick Anh tuấn thì sẽ lọc theo ngày 05/02/2017 và anh Tuấn(Tương đương việc gỏ tên Nhà cung cấp vào Tb_NCC(Anh Tuấn) và lúc này Tb_Ngay vẫn là 05/02/2017)
3/Tiếp Em chọn lọc cột Số lượng mua là "100" thì chỉ cón Ngày 05/02/2017, nhà cung cấp là Anh Tuấn, Đơn Hàng là PT012, người Mua là Chị Thủy và số lượng mua là 100(Tương đương Tb_Ngay là "05/02/2017", Tb_NCC là "Anh Tuấn" tb_NM là "", Tb_SLM là "100" )
Và nếu em xóa hết các TextBox thì ListBox1 lại hiện tất cả dữ liệu của sheet1, và em gỏ vào Tb_NM là chị thủy thì lại lọc theo chị Thủy.
Mong các AC hiểu ý em.
 
Upvote 0
Cám ơn Anh Hoang2013, File của Anh cũng chưa đúng. Em có thử chọn ngày 05/02/2017 trong cb_ngay thì có hiện ra theo ngày 05/02/2017, và em chọn tiếp Anh Tuấn trong cb_NCC thì có lọc theo ngày 05/02/2017 và nhà cung cấp là Anh Tuấn, nhưng em quay lại chon ngày 07/02/2017 thì cũng lọc theo ngày 07/02/2017, nhưng sai là lúc đó cb_NCC vẫn còn là Anh Tuấn(mà anh Tuấn không có Ngày 07/02/2017) ý của em là sẽ lọc theo giá trị các cb_nào <>""
 
Upvote 0
Dạ em cám ơn Thầy.
Nhưng File đó của Thầy Ndu chỉ có 1 TextBox, còn của em có 5 TextBox.
Em xin ví dụ lại như sau:
1/gỏ ngày vào Tb_Ngay là 05/02/2017 thì dữ liệu trong ListBox1 là 12 dòng.Chỉ có nhà cung cấp là Anh Tuấn và Chị Hoa
2/ vẫn để ngày 05/02/2017 ở Tb_Ngay, gỏ vào Tb_NCC là Anh Tuấn thì dữ liệu chỉ còn 6 dòng.
Em không biết diễn tả sao, nhưng nói chung là lọc theo điều kiện "And" như là "Tb_Ngay" and "Tb_Ncc" and "Tb_NM" and" Tb_SLM"..v.v...vv

Trời đất ơi! 1 TextBox hay nhiều gì cũng vậy thôi
Đầu tiên ta có code Filter như sau: (code đặt trong module)
Mã:
Function Filter2DArray(ByVal SourceArray, ByVal ColIndex As Long, ByVal FindStr As String, ByVal HasTitle As Boolean)
  Dim aTmpArr, i As Long, j As Long, Arr, dic, TmpStr, Tmp, Chk As Boolean, TmpVal As Double
  On Error Resume Next
  Set dic = CreateObject("Scripting.Dictionary")
  aTmpArr = SourceArray
  ColIndex = ColIndex + LBound(aTmpArr, 2) - 1
  Chk = (InStr("><=", Left(FindStr, 1)) > 0)
  For i = LBound(aTmpArr, 1) - HasTitle To UBound(aTmpArr, 1)
    If Chk And FindStr <> "" Then
      TmpVal = CDbl(aTmpArr(i, ColIndex))
      If Evaluate(TmpVal & FindStr) Then dic.Add i, ""
    Else
      If Left(FindStr, 1) = "!" Then
        If Not (UCase(aTmpArr(i, ColIndex)) Like UCase(Mid(FindStr, 2, Len(FindStr)))) Then dic.Add i, ""
      Else
        If UCase(aTmpArr(i, ColIndex)) Like UCase(FindStr) Then dic.Add i, ""
      End If
    End If
  Next
  If dic.Count > 0 Then
    Tmp = dic.Keys
    ReDim Arr(LBound(aTmpArr, 1) To UBound(Tmp) + LBound(aTmpArr, 1) - HasTitle, LBound(aTmpArr, 2) To UBound(aTmpArr, 2))
    For i = LBound(aTmpArr, 1) - HasTitle To UBound(Tmp) + LBound(aTmpArr, 1) - HasTitle
      For j = LBound(aTmpArr, 2) To UBound(aTmpArr, 2)
        Arr(i, j) = aTmpArr(Tmp(i - LBound(aTmpArr, 1) + HasTitle), j)
      Next
    Next
    If HasTitle Then
      For j = LBound(aTmpArr, 2) To UBound(aTmpArr, 2)
        Arr(LBound(aTmpArr, 1), j) = aTmpArr(LBound(aTmpArr, 1), j)
      Next
    End If
  End If
  Filter2DArray = Arr
End Function
--------------------------------
Giờ code lọc dành cho Tb_Ngay được viết như sau:
Mã:
Private Sub Tb_Ngay_Change()
  Dim aSrc, aDes
  aSrc = Me.ListBox1.List
  aDes = Filter2DArray(aSrc, [COLOR=#ff0000]1[/COLOR], Me.[COLOR=#ff0000]Tb_Ngay.Text[/COLOR], False)
  If IsArray(aDes) Then Me.ListBox1.List = aDes
End Sub
Các TextBox khác viết tương tự, chỉ khác chỗ màu đỏ. Chẳng hạn code filter cho Tb_NCC được viết:
Mã:
Private Sub Tb_NCC_Change()
  Dim aSrc, aDes
  aSrc = Me.ListBox1.List
  aDes = Filter2DArray(aSrc, [COLOR=#ff0000]2[/COLOR], Me.[COLOR=#ff0000]Tb_NCC.Text[/COLOR], False)
  If IsArray(aDes) Then Me.ListBox1.List = aDes
End Sub
Vậy thôi
 

File đính kèm

  • FilterListbox.xlsb
    25.1 KB · Đọc: 86
Upvote 0
[thongbao]nhưng em quay lại chon ngày 07/02/2017 thì cũng lọc theo ngày 07/02/2017, nhưng sai là lúc đó cb_NCC vẫn còn là Anh Tuấn(mà anh Tuấn không có Ngày 07/02/2017) ý của em là sẽ lọc theo giá trị các cb_nào <>""[/thongbao]

Thì chịu khó thêm chút đi: Lại chọn trong ComboBox NCC là ai đó để có lần lọc đúng theo iêu cầu;

Vậy bạn đã kịp dịch macro tại ComboBox NCC để hiểu chưa đã?
 
Upvote 0
Ah! Cải tiến lại chút có thể hợp lý hơn:
Mã:
Private aSrc
Private Sub UserForm_Initialize()
  aSrc = Sheet1.Range("A2:E" & Sheet1.Range("A65536").End(xlUp).Row).Value
  ListBox1.ColumnCount = 5
  ListBox1.ColumnWidths = "90;90;90;90;60"
  ListBox1.List = aSrc
End Sub
Private Sub Tb_Ngay_Change()
  Dim aDes
  aDes = FilterMain(aSrc)
  If IsArray(aDes) Then Me.ListBox1.List = aDes
End Sub
Private Sub Tb_NCC_Change()
  Dim aDes
  aDes = FilterMain(aSrc)
  If IsArray(aDes) Then Me.ListBox1.List = aDes
End Sub
Private Sub Tb_DH_Change()
  Dim aDes
  aDes = FilterMain(aSrc)
  If IsArray(aDes) Then Me.ListBox1.List = aDes
End Sub

Private Sub Tb_NM_Change()
  Dim aDes
  aDes = FilterMain(aSrc)
  If IsArray(aDes) Then Me.ListBox1.List = aDes
End Sub
Private Sub Tb_SLM_Change()
  Dim aDes
  aDes = FilterMain(aSrc)
  If IsArray(aDes) Then Me.ListBox1.List = aDes
End Sub
Private Function FilterMain(ByVal SrcArray)
  Dim sFind1 As String, sFind2 As String, sFind3 As String, sFind4 As String, sFind5 As String
  sFind1 = Me.Tb_Ngay.Text: If Len(sFind1) = 0 Then sFind1 = "*"
  sFind2 = Me.Tb_NCC.Text: If Len(sFind2) = 0 Then sFind2 = "*"
  sFind3 = Me.Tb_DH.Text: If Len(sFind3) = 0 Then sFind3 = "*"
  sFind4 = Me.Tb_NM.Text: If Len(sFind4) = 0 Then sFind4 = "*"
  sFind5 = Me.Tb_SLM.Text: If Len(sFind5) = 0 Then sFind5 = "*"
  Dim aDes
  aDes = SrcArray
  aDes = Filter2DArray(aDes, 1, sFind1, False)
  aDes = Filter2DArray(aDes, 2, sFind2, False)
  aDes = Filter2DArray(aDes, 3, sFind3, False)
  aDes = Filter2DArray(aDes, 4, sFind4, False)
  aDes = Filter2DArray(aDes, 5, sFind5, False)
  FilterMain = aDes
End Function
Toàn bộ code trên nằm trong UserForm
Lưu ý: Code trên cho phép Filter theo ký tự đại diện nha. Ví dụ tai Tb_NCC bạn gõ Chị* có nghĩa là tìm những phần tử bắt đầu bằng chữ Chị
 

File đính kèm

  • FilterListbox.xlsb
    25.9 KB · Đọc: 174
Upvote 0
quá đúng ý em rồi Thầy Ndu ơi, Cám ơn Thầy nhiều.
Nhưng mong Thầy chỉnh code lại cho trong ListBox1 cột ngày thể hiện là 02/02/2017 chứ không hiện là 02/Feb/2017 nữa (vì em quen gỏ tháng là số chứ không phải là chữ.) và cũng mong Thầy chỉnh lại cột Số lượng mua trong ListBox1 có dấu phân cách hang ngàn.
 
Upvote 0
quá đúng ý em rồi Thầy Ndu ơi, Cám ơn Thầy nhiều.
Nhưng mong Thầy chỉnh code lại cho trong ListBox1 cột ngày thể hiện là 02/02/2017 chứ không hiện là 02/Feb/2017 nữa (vì em quen gỏ tháng là số chứ không phải là chữ.) và cũng mong Thầy chỉnh lại cột Số lượng mua trong ListBox1 có dấu phân cách hang ngàn.

Hiển thị thế nào là do thiết lập trong control panel bạn à! Trên máy tôi listbox hiện theo kiểu d/m/yy, máy bạn khác hơn cứ vào control panel chỉnh lại nhé
 
Upvote 0
Dạ đúng là phải chỉnh trong Control Panel lại định dạng ngày tháng, thế còn định dạng dấu phân cách hang ngàn của cột số lượng mua Thầy giúp em với.
 
Upvote 0
Dạ đúng là phải chỉnh trong Control Panel lại định dạng ngày tháng, thế còn định dạng dấu phân cách hang ngàn của cột số lượng mua Thầy giúp em với.

Cái đó thì phải duyệt qua 1 vòng lập, hiệu chỉnh trực tiếp trên listbox bạn à
Chẳng hạn phải sửa hàm FilterMain thành:
Mã:
Private Function FilterMain(ByVal SrcArray)
  Dim sFind1 As String, sFind2 As String, sFind3 As String, sFind4 As String, sFind5 As String
  [COLOR=#ff0000]On Error Resume Next[/COLOR]
  sFind1 = Me.Tb_Ngay.Text: If Len(sFind1) = 0 Then sFind1 = "*"
  sFind2 = Me.Tb_NCC.Text: If Len(sFind2) = 0 Then sFind2 = "*"
  sFind3 = Me.Tb_DH.Text: If Len(sFind3) = 0 Then sFind3 = "*"
  sFind4 = Me.Tb_NM.Text: If Len(sFind4) = 0 Then sFind4 = "*"
  sFind5 = Me.Tb_SLM.Text: If Len(sFind5) = 0 Then sFind5 = "*"
  Dim aDes
  aDes = SrcArray
  aDes = Filter2DArray(aDes, 1, sFind1, False)
  aDes = Filter2DArray(aDes, 2, sFind2, False)
  aDes = Filter2DArray(aDes, 3, sFind3, False)
  aDes = Filter2DArray(aDes, 4, sFind4, False)
  aDes = Filter2DArray(aDes, 5, sFind5, False)
[COLOR=#ff0000]  Dim lR As Long, lCol As Long
  lCol = UBound(aDes, 2)
  For lR = LBound(aDes, 1) To UBound(aDes, 1)
    aDes(lR, lCol) = Format(aDes(lR, lCol), "#,##0.00")
  Next[/COLOR]
  FilterMain = aDes
End Function
Và sửa sự kiện UserForm_Initialize thành:
Mã:
Private Sub UserForm_Initialize()
  aSrc = Sheet1.Range("A2:E" & Sheet1.Range("A65536").End(xlUp).Row).Value
  ListBox1.ColumnCount = 5
  ListBox1.ColumnWidths = "90;90;90;90;60"
  ListBox1.List = [COLOR=#ff0000]FilterMain(aSrc)[/COLOR]
End Sub
Những chỗ màu đỏ là chỗ sửa lại
Tuy nhiên, việc làm này sẽ khiến tốc độ giảm đi 1 chút. Vậy tùy bạn cân nhắc mà sử dụng hợp lý nhé
 
Upvote 0
Cám Ơn Thầy Ndu nhiều!
Chúc Thầy ngày nghỉ Vui Vẻ.
 
Upvote 0
Ah! Cải tiến lại chút có thể hợp lý hơn:
Mã:
Private aSrc
Private Sub UserForm_Initialize()
  aSrc = Sheet1.Range("A2:E" & Sheet1.Range("A65536").End(xlUp).Row).Value
  ListBox1.ColumnCount = 5
  ListBox1.ColumnWidths = "90;90;90;90;60"
  ListBox1.List = aSrc
End Sub
Private Sub Tb_Ngay_Change()
  Dim aDes
  aDes = FilterMain(aSrc)
  If IsArray(aDes) Then Me.ListBox1.List = aDes
End Sub
Private Sub Tb_NCC_Change()
  Dim aDes
  aDes = FilterMain(aSrc)
  If IsArray(aDes) Then Me.ListBox1.List = aDes
End Sub
Private Sub Tb_DH_Change()
  Dim aDes
  aDes = FilterMain(aSrc)
  If IsArray(aDes) Then Me.ListBox1.List = aDes
End Sub

Private Sub Tb_NM_Change()
  Dim aDes
  aDes = FilterMain(aSrc)
  If IsArray(aDes) Then Me.ListBox1.List = aDes
End Sub
Private Sub Tb_SLM_Change()
  Dim aDes
  aDes = FilterMain(aSrc)
  If IsArray(aDes) Then Me.ListBox1.List = aDes
End Sub
Private Function FilterMain(ByVal SrcArray)
  Dim sFind1 As String, sFind2 As String, sFind3 As String, sFind4 As String, sFind5 As String
  sFind1 = Me.Tb_Ngay.Text: If Len(sFind1) = 0 Then sFind1 = "*"
  sFind2 = Me.Tb_NCC.Text: If Len(sFind2) = 0 Then sFind2 = "*"
  sFind3 = Me.Tb_DH.Text: If Len(sFind3) = 0 Then sFind3 = "*"
  sFind4 = Me.Tb_NM.Text: If Len(sFind4) = 0 Then sFind4 = "*"
  sFind5 = Me.Tb_SLM.Text: If Len(sFind5) = 0 Then sFind5 = "*"
  Dim aDes
  aDes = SrcArray
  aDes = Filter2DArray(aDes, 1, sFind1, False)
  aDes = Filter2DArray(aDes, 2, sFind2, False)
  aDes = Filter2DArray(aDes, 3, sFind3, False)
  aDes = Filter2DArray(aDes, 4, sFind4, False)
  aDes = Filter2DArray(aDes, 5, sFind5, False)
  FilterMain = aDes
End Function
Toàn bộ code trên nằm trong UserForm
Lưu ý: Code trên cho phép Filter theo ký tự đại diện nha. Ví dụ tai Tb_NCC bạn gõ Chị* có nghĩa là tìm những phần tử bắt đầu bằng chữ Chị
Anh ndu96081631 cho em hỏi một chút vấn đề với textbox " Tb_SLM" với ạ
Hiện tại là khi ta gõ giá trị chính xác vào Tb_SLM thì chỉ lọc xuất hiện giá trị đó.
Bây giờ có cách nào để tìm được trong khoảng không ạ. Ví dụ: khi em điền số 20 vào thì chỉ lọc các giá trị lớn hơn hoặc bằng 20 không ạ
Cảm ơn anh!
 
Upvote 0
Web KT

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

Back
Top Bottom