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,
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...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,
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!Nó báo lỗi ở dòng này:
rg = Sheet1.Range("A1:A10000").Find(UserForm2.ListBox1.List(a - 1, 0)).Row
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.
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)
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 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)
Để đá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
Đây là 1 mẫu vừa làm xong! Bạn thử xem!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,
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
Đâ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:
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!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
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)
Sửa lại có tí thôi mà (thêm phần Sort vào)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,
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âng... em thấy... và cái này dể sửa mà anh!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
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)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ỉ?
Bạn xem file này nhé: Tìm kiếm với 3 điều kiện MÃ, TÊN và ĐƠN VỊEm "mò" rồi nhưng vẫn không ra nên mới nhờ các bác hi..hi,
Theo cách của các bác đúng là hay lắm nhưng nhiều khi lĩnh vực này em thấy cũng khá phức tạp, chẳng han:
Kết hợp rất nhiều điều kiện để đang dạng hoá việc tìm kiếm như: gõ mã số; nếu không nhớ mã số thì gõ họ tên, hoặc chỉ cần gõ tên vào textbox,...
các cách của các bác mới chỉ có một ý thôi. Như vậy bắt buộc người nhập phải nhớ một thứ gì đó.
Private Sub TextBox1_Change()
Dim Clls As Range, Temp As Variant, i As Long, FCol As Long
Application.ScreenUpdating = False
FCol = -(OptionButton1.Value + 2 * OptionButton2.Value + 3 * OptionButton3.Value)
If Len(Trim(TextBox1.Value)) = 0 Then Exit Sub
With Sheet1.Range(Sheet1.[A1], Sheet1.[A65536].End(xlUp)).Resize(, 3)
Temp = .Value
.Sort .Cells(2, FCol), 1, Header:=xlGuess
.AutoFilter FCol, TextBox1.Value & "*"
ListBox1.Clear
For Each Clls In .Offset(1).Resize(, 1).SpecialCells(12)
ListBox1.AddItem (Clls)
ListBox1.List(i, 1) = Clls(, 2)
ListBox1.List(i, 2) = Clls(, 3)
i = i + 1
Next
.AutoFilter
.Value = Temp
End With
Application.ScreenUpdating = True
End Sub
Private Sub UserForm_Initialize()
OptionButton1.Value = 1
End Sub
hì, tội nghiệp bác quá nhỉ, chẳng ai giúp. Code thì giữ nguyên, bạn chỉ cần format toàn bộ vùng dữ liệu đó sang dạng text là ok ngay thôi mà.Mình không thể tìm kiếm bằng số , mã hàng minh toàn bằng số thôi nế không thể tìm đươc thì tức lắm , minh đã kiếm file này lâu lăm rồi&&&%$r
Mình không thể tìm kiếm bằng số , mã hàng minh toàn bằng số thôi nế không thể tìm đươc thì tức lắm , minh đã kiếm file này lâu lăm rồi&&&%$r
hì, tội nghiệp bác quá nhỉ, chẳng ai giúp. Code thì giữ nguyên, bạn chỉ cần format toàn bộ vùng dữ liệu đó sang dạng text là ok ngay thôi mà.
Chúc vui!
Option Explicit
Private Sub UserForm_Initialize()
Application.ScreenUpdating = False
With Sheet1
.[D:D].Clear: .[D1] = "ExtraID"
.[D2].FormulaR1C1 = "=""F"" & RC1": .[D2].Copy
.Range("D2:D" & .Range("A65536").End(xlUp).Row).PasteSpecial
.[A1].Select
End With
End Sub
'==========================================================================
Private Sub UserForm_Terminate()
With Sheet1
.[D:D].Clear
.[A:A].NumberFormat = "General"
End With
Application.ScreenUpdating = True
End Sub
'==========================================================================
Private Sub TextBox1_Change()
Dim Clls As Range, Temp As Variant, i As Long, FCol As Long, Txb
FCol = -(OptionButton1.Value + 2 * OptionButton2.Value + 3 * OptionButton3.Value)
If OptionButton1.Value = True Then FCol = 4: Txb = "F" & TextBox1.Value Else Txb = TextBox1.Text
If Len(Trim(TextBox1)) = 0 Or TextBox1 = "" Then ListBox1.Clear: Exit Sub
With Sheet1.Range(Sheet1.[A1], Sheet1.[A65536].End(xlUp)).Resize(, 4)
Temp = .Value
.Sort .Cells(2, FCol), 1, Header:=xlGuess
.AutoFilter FCol, Txb & "*"
ListBox1.Clear
For Each Clls In .Offset(1).Resize(, 1).SpecialCells(12)
ListBox1.AddItem (Clls)
ListBox1.List(i, 1) = Clls(, 2)
ListBox1.List(i, 2) = Clls(, 3)
i = i + 1
Next
.AutoFilter
.Value = Temp
End With
End Sub
Anh ndu! có thể tạo tiêu đề trong ListBox được không. Tiêu đề giống như trong Sheet1 (Mã|Họ và Tên|Đơn vị). Nếu có tiêu đề thì dễ nhìn dữ liệu hơn, phải không anh.
Anh Trọng Nghĩa! Làm theo cách của anh thì không thể tìm kiếm được khi kết hợp với code tìm kiếm của anh ndu. Thực hiện như code của anh ndu nhưng trong listbox có thêm hàng tiêu đề.
Private Sub TextBox1_Change()
Dim sArray, FindArray, fCol As Long, fRow As Long
sArray = Sheet1.Range(Sheet1.[A1], Sheet1.[A65536].End(xlUp)).Resize(, 3).Value
fCol = -(OptionButton1.Value + 2 * OptionButton2.Value + 3 * OptionButton3.Value)
FindArray = Filter2DArray(sArray, fCol, TextBox1.Text & "*", True)
Source.Range("A:C").Clear
If IsArray(FindArray) Then
fRow = UBound(FindArray)
Source.Range("A1").Resize(fRow, 3).Value = FindArray
ListBox1.RowSource = "Source!A2:C" & fRow
Else
Source.Range("A1:C1").Value = Sheet1.Range("A1:C1").Value
Source.Range("B2").Value = "No match found!"
ListBox1.RowSource = "Source!A2:C2"
End If
End Sub
Anh Hoàng Trọng Nghĩa ơi. File tìm kiếm mới của anh khi nhập theo tên: nhập mấy kí tự đầu tiên thì nó mới search được, còn chỉ nhập mấy từ sau thì không search được. VD: search tên Phạm Minh Tiến -nếu gõ Phạm thì nó ra, còn gõ Minh hay Tiến thì nó báo ko tìm thấy.
Anh có cách nào search chữ Tiến hay chữ Minh thì nó ra luôn tên ko ?
[B]FindArray = Filter2DArray(sArray, fCol, [COLOR=#0000cd]TextBox1.Text [/COLOR][COLOR=#ff0000]& "*"[/COLOR], True)[/B]
[B]FindArray = Filter2DArray(sArray, fCol, [COLOR=#ff0000]"*" & [/COLOR][COLOR=#0000cd]TextBox1.Text[/COLOR][COLOR=#ff0000] & "*"[/COLOR], True)[/B]
anh Hoàng Trọng Nghĩa ơi. Cái hàm của anh tìm kiếm ok hết rồi nhưng chỉ còn 1 cái nữa là không có click tới tên cần tìm kiếm. Trong form có tên tìm kiếm nhưng khi click tên đó nó không nhảy qua excel tới ô đó. Anh coi giúp dùm em cái đó nữa nha!
Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Dim MyID As String
MyID = ListBox1.List(, 0)
Unload Me
Range(Sheet1.[A1], Sheet1.[A65536].End(xlUp)) _
.Find(MyID, LookIn:=xlValues, LookAt:=xlWhole) _
.Resize(, 3).Select
End Sub
Cái này có gì đâu mà khó, chỉ cần double click vào cái ListBox với thủ tục dưới đây:
Mã:Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean) Dim MyID As String MyID = ListBox1.List(, 0) Unload Me Range(Sheet1.[A1], Sheet1.[A65536].End(xlUp)) _ .Find(MyID, LookIn:=xlValues, LookAt:=xlWhole) _ .Resize(, 3).Select End Sub
Xin hỏi?
Làm thế nào trong list ta chọn đối tượng cần tìm (đưa chuột vào đối tượng trong list được to đậm như trong list) khi nhấp đúp chuột thì hiện ra riêng đồi tượng đó trong Sheets hoặc trong form (nếu tạo form). Việc đó VBA Excel có thực hiện được không ? nếu được thì viết Code như thế nào.
Rất mong hướng dẫn, giúp đở thêm. Xin cám ơn.
Để lọc nhiều cột thì bạn thử xem code ở chủ đề sau có đáp ứng được không. Nhân tiện nhờ bạn test hộ và cho biết.
Số tôi không may thì phải. Mình thì sẵn sàng giúp nhiều người nhưng nhờ vả thì không ai giúp.
http://www.giaiphapexcel.com/forum/...cột-lọc-tùy-ý-cột-số-tới-2-điều-kiện
Hic, người khác không hỏi Thầy thì chớ, Thầy mà hỏi thì ai đủ trình độ để trả lời chứ trời?