Tìm kiếm dữ liệu trong form

Liên hệ QC

doanhhoang79

Thành viên hoạt động
Tham gia
31/3/08
Bài viết
142
Được thích
18
Có ai có mẫu tìm kiếm dữ liệu trong Form không? Tôi đang muốn tham khảo

Ai biết chỉ cho tôi với,

Cảm ơn,
 
Có ai có mẫu tìm kiếm dữ liệu trong Form không? Tôi đang muốn tham khảo

Ai biết chỉ cho tôi với,

Cảm ơn,
Thuật toán TÌM KIẾM thì nhiều lắm, chẳng hạn như có thể dùng Find, AutoFilter, Advanced Filter... hoặc các hàm tìm kiếm của Excel...
Quan trọng là sau khi tìm ta sẽ làm gì
Dù sao, bạn phải có file và nói rõ mục đích mới có thể giải quyết vấn đề
 
Upvote 0
vẫn xung quanh cái vụ của bác Nguyen Duy Long thôi anh ndu ạ,
Mặc dù bác Duy Long đã giúp đỡ nhưng em thấy code này hình như vẫn chưa ổn lắm.
Sau khi click nút tìm kiếm rồi Dblclick vào listbox nó vẫn báo lỗi và cho kết quả không chính xác. Anh ndu kiểm tra code giúp em với, xem cần bổ sung gì thêm không?

Em gửi file VD đính kèm,

Cơm ơn anh,

- -- - - - - - - - - - -

Nó báo lỗi ở dòng này:
rg = Sheet1.Range("A1:A10000").Find(UserForm2.ListBox1.List(a - 1, 0)).Row
 

File đính kèm

  • Vi du.xls
    45 KB · Đọc: 146
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Nó báo lỗi ở dòng này:
rg = Sheet1.Range("A1:A10000").Find(UserForm2.ListBox1.List(a - 1, 0)).Row
Xem file của bạn, tôi nghĩ nếu nó báo lổi thì chăng qua là do ta chưa khai báo biến mà thôi!
Thử thêm dòng:
Dim rg As Range
Rồi test lại xem!
Ngoài ra hãy thêm dòng:
On Error Resume Next
vào đầu code, phòng trường hợp tìm không thấy sẽ báo lổi
-----------
Tuy nhiên, nhìn mấy Form này thấy nó sao sao ấy ---> Tìm để làm cái gì mới được chứ ---> Sao bạn không đưa file thực tế của bạn lên (file này tôi nghĩ chỉ là giả lập, không thực tế tí nào)
 
Lần chỉnh sửa cuối:
Upvote 0
Cái chính là cái Form của bạn và cơ chế tìm kiếm của bạn không thực tế thôi. Cái Form điều kiện tìm kiếm y chang cái form gốc vậy thì thà tìm luôn trên Form gốc cho nhanh.Mình xin tham gia như sau:

1/Form điều kiện thường nhập tìm mã bắt đầu bằng ký tự gì, có chứa ký tự gì, kết thúc ký tự gì hay đúng mã nào đó.

2/Cơ chế tìm kiếm có 2 dạng:
-Chuyển nhanh đến dòng đầu tiên thỏa mãn điều kiện.
-Lọc và chỉ để lại trên Form những dòng fù hợp, như vậy lựa chọn rất nhanh.
 
Upvote 0
Cái chính là cái Form của bạn và cơ chế tìm kiếm của bạn không thực tế thôi. Cái Form điều kiện tìm kiếm y chang cái form gốc vậy thì thà tìm luôn trên Form gốc cho nhanh.Mình xin tham gia như sau:

1/Form điều kiện thường nhập tìm mã bắt đầu bằng ký tự gì, có chứa ký tự gì, kết thúc ký tự gì hay đúng mã nào đó.

2/Cơ chế tìm kiếm có 2 dạng:
-Chuyển nhanh đến dòng đầu tiên thỏa mãn điều kiện.
-Lọc và chỉ để lại trên Form những dòng fù hợp, như vậy lựa chọn rất nhanh.

Anh nói đúng, File em đưa là VD giả thiết thôi,
thực tế nó chỉ lọc ra những dòng cần thiết thôi.
Em muốn sau khi tìm ra những dòng mong muốn rồi thì mình Dblclick vào dòng đó, nó sẽ đưa con chuột đến đúng dữ liệu đó ở Listbox trong Form1

Xem file của bạn, tôi nghĩ nếu nó báo lổi thì chăng qua là do ta chưa khai báo biến mà thôi!
Thử thêm dòng:
Dim rg As Range
Rồi test lại xem!
Ngoài ra hãy thêm dòng:
On Error Resume Next
vào đầu code, phòng trường hợp tìm không thấy sẽ báo lổi
-----------
Tuy nhiên, nhìn mấy Form này thấy nó sao sao ấy ---> Tìm để làm cái gì mới được chứ ---> Sao bạn không đưa file thực tế của bạn lên (file này tôi nghĩ chỉ là giả lập, không thực tế tí nào)

Em giải thích thế này:
Giả sử anh có 01 Form1 trong đó có 01 listbox với hàng nghìn dòng dữ liệu. Làm thế nào để anh tìm đến dữ liệu cần tìm một cách nhanh nhất. Anh không thể dò tìm từng dữ liệu, sẽ mất rất nhiều thời gian.
Vì vậy em phải dùng thêm 01 form tìm kiếm với 01 listbox hiện kết quả, sau khi tìm được dữ liệu rồi thì chỉ cần Dblclick vào dữ liệu đó, nó sẽ đưa chỏ chuột đến dữ liệu trong listbox ở Form1. Như vậy sẽ nhanh và pro hơn không???
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Bạn tham khảo cách lọc Auto Filter trong phần Custom ấy. Đấy là 1 dạng Form điều kiện lọc tiêu biểu đấy
P/S: Với yêu cầu của bạn chả có lý gì mà lại tất cả đều bắt đầu bằng M cả Nếu vậy phần mã này thừa. Mình ví dụ danh sách nhân viên ta có mã Phòng Kế toán: KT001, KT002..., Phòng Nhân sự NS001, NS002... Quầy hàng số 1 : 1Q001, 1Q002... Quầy số 2 2Q001, 2Q002
Như vậy ta thiết lập MatchRequired=True thì bạn chỉ cần gõ ký tự đầu tiên của nhóm thì List hay Comb sẽ nhảy nhanh đến dòng đầu tiên của nhóm. Bạn xem chính Form của bạn chỉ cần gõ chữ cái đầu lađến rồi
 

File đính kèm

  • Copy of Vi du-11.xls
    45 KB · Đọc: 274
Lần chỉnh sửa cuối:
Upvote 0
Em giải thích thế này:
Giả sử anh có 01 Form1 trong đó có 01 listbox với hàng nghìn dòng dữ liệu. Làm thế nào để anh tìm đến dữ liệu cần tìm một cách nhanh nhất. Anh không thể dò tìm từng dữ liệu, sẽ mất rất nhiều thời gian.
Vì vậy em phải dùng thêm 01 form tìm kiếm với 01 listbox hiện kết quả, sau khi tìm được dữ liệu rồi thì chỉ cần Dblclick vào dữ liệu đó, nó sẽ đưa chỏ chuột đến dữ liệu trong listbox ở Form1. Như vậy sẽ nhanh và pro hơn không???
Nếu là tôi thì tôi làm khác ---> Gõ 1 vài ký tự gợi nhớ vào TextBox, bấm nút TÌM, nó sẽ Show vào ListBox những Record có liên quan (giống như tra từ điển ấy) ---> Và đúng như anh Sealand nhận xét, trò này AutoFilter làm ngon lành (chứ ai lại thiết kế ra 2 cái Form kỳ dị như bạn thế kia)
 
Upvote 0
Nếu là tôi thì tôi làm khác ---> Gõ 1 vài ký tự gợi nhớ vào TextBox, bấm nút TÌM, nó sẽ Show vào ListBox những Record có liên quan (giống như tra từ điển ấy) ---> Và đúng như anh Sealand nhận xét, trò này AutoFilter làm ngon lành (chứ ai lại thiết kế ra 2 cái Form kỳ dị như bạn thế kia)

Em đồng ý quan điểm của các bác,
Các bác có file mẫu cụ thể không gửi em tham khảo với. Lưu ý các tháo tác hoàn toàn thực hiện trên form (không thực hiện ở trong sheet)

Em cảm ơn,
 
Upvote 0
Để đáp ứng đươc việc lọc với cơ chế chứa 1 vài ký tự gợi ý như Ndu thì ta nên viết sub nạp Item cho List hay Comb chứ không gán đơn giản được. Như vậy, mã nào thỏa mãn thì nạp.

Có 1 cách là RemoveItem không thỏa mãn nhưng khi reset (Hủy lọc) khônglấy lại tất cả các mã được mà chỉ load lại Form mới đwợc
 
Upvote 0
Để đáp ứng đươc việc lọc với cơ chế chứa 1 vài ký tự gợi ý như Ndu thì ta nên viết sub nạp Item cho List hay Comb chứ không gán đơn giản được. Như vậy, mã nào thỏa mãn thì nạp.

Có 1 cách là RemoveItem không thỏa mãn nhưng khi reset (Hủy lọc) khônglấy lại tất cả các mã được mà chỉ load lại Form mới đwợc

Nếu load lại form em thấy có vẻ không Pro cho lắm.
Nếu thực hiện công việc này trực tiếp trên sheet em nghĩ nó sẽ đơn giản hơn. Nhưng đây phải thực hiện trên form nên em phải nhờ các cao thủ giúp đỡ.
 
Lần chỉnh sửa cuối:
Upvote 0
Em đồng ý quan điểm của các bác,
Các bác có file mẫu cụ thể không gửi em tham khảo với. Lưu ý các tháo tác hoàn toàn thực hiện trên form (không thực hiện ở trong sheet)

Em cảm ơn,
Đây là 1 mẫu vừa làm xong! Bạn thử xem!
Gọi Form lên, cần tìm cái gì cứ gõ vào TextBox ---> Ví dụ bạn gõ AAB thì lập tức tất cả những mã nào có 3 ký tự đầu là AAB sẽ hiện ra trong ListBox ---> Làm gì nữa tiếp sau đó là tùy bạn
code:
PHP:
Private Sub TextBox1_Change()
  Dim Clls As Range
  Application.ScreenUpdating = False
  With Sheet1.Range(Sheet1.[A1], Sheet1.[A65536].End(xlUp))
    ListBox1.Clear
    .AutoFilter 1, TextBox1.Value & "*"
    For Each Clls In .Offset(1).SpecialCells(12).SpecialCells(2)
      ListBox1.AddItem (Clls)
    Next
    .AutoFilter
  End With
  Application.ScreenUpdating = True
End Sub
Bạn thấy đấy, thuật toán chính là AutoFilter, phần râu ria còn lại quá đơn giản luôn!
 

File đính kèm

  • Form_Timkiem_1.xls
    50 KB · Đọc: 260
Upvote 0
Đây là 1 mẫu vừa làm xong! Bạn thử xem!
Gọi Form lên, cần tìm cái gì cứ gõ vào TextBox ---> Ví dụ bạn gõ AAB thì lập tức tất cả những mã nào có 3 ký tự đầu là AAB sẽ hiện ra trong ListBox ---> Làm gì nữa tiếp sau đó là tùy bạn
code:
PHP:
Private Sub TextBox1_Change()
  Dim Clls As Range
  Application.ScreenUpdating = False
  With Sheet1.Range(Sheet1.[A1], Sheet1.[A65536].End(xlUp))
    ListBox1.Clear
    .AutoFilter 1, TextBox1.Value & "*"
    For Each Clls In .Offset(1).SpecialCells(12).SpecialCells(2)
      ListBox1.AddItem (Clls)
    Next
    .AutoFilter
  End With
  Application.ScreenUpdating = True
End Sub
Bạn thấy đấy, thuật toán chính là AutoFilter, phần râu ria còn lại quá đơn giản luôn!

Phương pháp của anh ndu rất hay, em sẽ áp dụng vào ứng dụng thực tế của mình,
cảm ơn bác,
Chủ nhật mà bác vẫn vất vả quá nhưng vui bác nhỉ,
 
Upvote 0
Phương pháp của anh ndu rất hay, em sẽ áp dụng vào ứng dụng thực tế của mình,
cảm ơn bác,
Chủ nhật mà bác vẫn vất vả quá nhưng vui bác nhỉ,

Bạn lưu ý
: Để việc tìm kiếm hiệu quả hơn, bạn nên thêm phần Sort vào ListBox
Thuật toán về Sort ListBox (hay Sort bất cứ thứ gì) có lẽ ai cũng biết
- Quét qua từng Item
- So sánh Item1 với Item2 ---> Nếu Item1> Item2 thì đổi chổ chúng với nhau
- Và cứ thế tiếp tục

Tuy nhiên phương pháp này làm cho tốc độ tính toán chậm hẳn đi
Trong Excel đã có công cụ Sort, ta tận dụng nó vào code là nhanh nhất...
Thuật toán:
- Lưu vùng dử liệu vào 1 biến tạm
- Sort dử liệu theo trật tự
- Chạy code gì đó
(với file của ta là chạy AutoFilter và AddItem vào ListBox)
- Sau khi code xong, lấy biến tạm (đã lưu) áp ngược vào vùng dử liệu (tức trả mọi thứ về như ban đầu)
===> Phương pháp này tỏ ra mạnh về mặt tốc độ nhưng chỉ áp dụng được với vùng dử liệu thô (không chứa công thức)
Bạn thử xem
---------------
Nói thêm 1 chút: Với Form đã tạo như trên, bạn có thể biến nó thành phần mềm tra từ điển được đấy (chỉ cần có Data)
 
Lần chỉnh sửa cuối:
Upvote 0

Bạn lưu ý
: Để việc tìm kiếm hiệu quả hơn, bạn nên thêm phần Sort vào ListBox
Thuật toán về Sort ListBox (hay Sort bất cứ thứ gì) có lẽ ai cũng biết
- Quét qua từng Item
- So sánh Item1 với Item2 ---> Nếu Item1> Item2 thì đổi chổ chúng với nhau
- Và cứ thế tiếp tục

Tuy nhiên phương pháp này làm cho tốc độ tính toán chậm hẳn đi
Trong Excel đã có công cụ Sort, ta tận dụng nó vào code là nhanh nhất...
Thuật toán:
- Lưu vùng dử liệu vào 1 biến tạm
- Sort dử liệu theo trật tự
- Chạy code gì đó
(với file của ta là chạy AutoFilter và AddItem vào ListBox)
- Sau khi code xong, lấy biến tạm (đã lưu) áp ngược vào vùng dử liệu (tức trả mọi thứ về như ban đầu)
===> Phương pháp này tỏ ra mạnh về mặt tốc độ nhưng chỉ áp dụng được với vùng dử liệu thô (không chứa công thức)
Bạn thử xem
---------------
Nói thêm 1 chút: Với Form đã tạo như trên, bạn có thể biến nó thành phần mềm tra từ điển được đấy (chỉ cần có Data)

Anh Giúp em luôn đi, em còn lơ tơ mơ cái món này lắm,

Cảm ơn anh,
 
Upvote 0
Anh Giúp em luôn đi, em còn lơ tơ mơ cái món này lắm,

Cảm ơn anh,
Sửa lại có tí thôi mà (thêm phần Sort vào)
PHP:
Private Sub TextBox1_Change()
  Dim Clls As Range, Temp As Variant
  Application.ScreenUpdating = False
  With Sheet1.Range(Sheet1.[A1], Sheet1.[A65536].End(xlUp))
    Temp = .Value
    .Sort .Cells(2, 1), 1, Header:=xlGuess 
    .AutoFilter 1, TextBox1.Value & "*"
    ListBox1.Clear
    For Each Clls In .Offset(1).SpecialCells(12).SpecialCells(2)
      ListBox1.AddItem (Clls)
    Next
    .AutoFilter
    .Value = Temp
  End With
  Application.ScreenUpdating = True
End Sub
Với code mới có phần Sort này thì chắc ăn việc tìm kiếm của bạn cũng trở nên dể dàng hơn rất nhiều
Bạn hãy tự so sánh xem code mới và cũ có điểm nào khác nhau
 
Upvote 0
To Ndu:
Mình cho cách sử lý nạp Comb. của Ndu rất hay. Nhưng có vấn đề 1 chút là nếu gõ ký tự không có dòng nào thỏa thì nó nạp tất cả (Thậm chí cả tiêu đề, nếu có vài cột nưa có cũng nạp tất). Bạn hiệu chỉnh chút nữa cho hoàn thiện.
P/S:Mình tham gia cách "bình dân" nhất (Ý mình nói là không sử dụng chức năng nâng cao của Exc)
 

File đính kèm

  • Copy of Form_Timkiem_1-11.xls
    68 KB · Đọc: 140
Lần chỉnh sửa cuối:
Upvote 0
To Ndu:
Mình cho cách sử lý nạp Comb. của Ndu rất hay. Nhưng có vấn đề 1 chút là nếu gõ ký tự không có dòng nào thỏa thì nó nạp tất cả (Thậm chí cả tiêu đề, nếu có vài cột nưa có cũng nạp tất). Bạn hiệu chỉnh chút nữa cho hoàn thiện.
P/S:Mình tham gia cách "bình dân" nhất (Ý mình nói là không sử dụng chức năng nâng cao của Exc)
Vâng... em thấy... và cái này dể sửa mà anh!
Thêm đoạn:
If Len(Trim(TextBox1.Value)) = 0 Then Exit Sub
vào đầu code!
Thay đoạn:
For Each Clls In .Offset(1).SpecialCells(12).SpecialCells(2)
thành:
For Each Clls In .Offset(1).SpecialCells(12)
===> Vậy là xong!
Vòng lập For duyệt qua các cell đã được Filter sẽ nhanh hơn rất nhiều so với duyệt qua toàn bộ ---> Điều này dể nhận thấy khi anh gõ nhiều ký tự vào khung tìm kiếm
Em lấy ví dụ:
- Khi em gõ chữ ABB thì qua bộ lọc AutoFilter, số dòng dử liệu chỉ còn lại 4, tương đương vòng lập For sẽ chỉ duyệt qua 4 lần... Trong khi đó với code của anh nó vẫn phải duyệt 500 lần
 
Upvote 0
Vâng... em thấy... và cái này dể sửa mà anh!
Thêm đoạn:
If Len(Trim(TextBox1.Value)) = 0 Then Exit Sub
vào đầu code!
Thay đoạn:
For Each Clls In .Offset(1).SpecialCells(12).SpecialCells(2)
thành:
For Each Clls In .Offset(1).SpecialCells(12)
===> Vậy là xong!
Vòng lập For duyệt qua các cell đã được Filter sẽ nhanh hơn rất nhiều so với duyệt qua toàn bộ ---> Điều này dể nhận thấy khi anh gõ nhiều ký tự vào khung tìm kiếm
Em lấy ví dụ:
- Khi em gõ chữ ABB thì qua bộ lọc AutoFilter, số dòng dử liệu chỉ còn lại 4, tương đương vòng lập For sẽ chỉ duyệt qua 4 lần... Trong khi đó với code của anh nó vẫn phải duyệt 500 lần

Quá tuyệt, cảm ơn các bác cao thủ đã giúp đỡ em,

Các bác cho em hỏi thêm: Nếu muốn hiển thị nhiều cột ở trong ListBox thì làm thế nào nhỉ?
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Các bác cho em hỏi nếu muốn hiển thị nhiều cột ở trong ListBox thì làm thế nào nhỉ?
File ở bài số #19 của anh Sealand là dạng ListBox với 2 cột đấy, bạn tải về mà nghiên cứu ---> Tôi nghĩ rất dể (mò tí là ra)
-------------
Nói riêng với bạn: Nhớ không lầm thì với chủ đề này bạn đã gữi lên rất nhiều lần, nhưng cho đến nay mới tạm giải quyết được... Nguyên nhân là vì bạn đã "dẩn dắt" mọi người đi theo hướng mà bạn cho là đúng (tạo 2 form).. mà đáng lý ra, ngay từ đầu bạn nên mô tả mục đích để mọi người gợi ý cho bạn 1 hướng đi tốt
Bạn thấy đấy, cứ lòng vòng với thiết kế 2 cái Form mà có được gì đâu ---> Khi mọi người hiểu được ý đồ tổng thể, sẽ dể dàng giúp bạn hơn
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT
Back
Top Bottom