Tìm kiếm trên Listbox bằng tiếng Việt không dấu

Liên hệ QC

ThaiDieuAnh

Thành viên hoạt động
Tham gia
8/8/16
Bài viết
139
Được thích
24
Nghề nghiệp
Xây dựng
Em có file excel gồm 1 sheet Data và 1 form gồm 1 Listbox và 1 Textbox. Em muốn khi gõ vào Textbox mà không gõ dấu tiếng Việt thì listbox vẫn hiểu được. Ví dụ em gõ vào Textbox là "Viet Nam" thì nó sẽ hiểu là Việt Nam để tìm kiếm. Mong các anh chị giúp đỡ, em xin cảm ơn
 

File đính kèm

Em có file excel gồm 1 sheet Data và 1 form gồm 1 Listbox và 1 Textbox. Em muốn khi gõ vào Textbox mà không gõ dấu tiếng Việt thì listbox vẫn hiểu được. Ví dụ em gõ vào Textbox là "Viet Nam" thì nó sẽ hiểu là Việt Nam để tìm kiếm. Mong các anh chị giúp đỡ, em xin cảm ơn
Code của bạn đã có phần tìm kiếm gì đâu? bạn muốn mọi người làm luôn cho bạn hay bạn muốn hướng dẫn vậy?
 
Upvote 0
Do dữ liệu nhiều nên tốc độ sẽ chậm nhé bạn.
Vì khi sự kiện TextBox_Change, bạn phải lo thêm phần "dịch" từ có dấu sang không dấu nên chậm là phải rồi
Giải pháp:
- Mở file, chạy 1 code "dịch" có dấu sang không dấu, tung lên biến public
- Từ giờ bạn sẽ làm việc trong cái đã có sẵn
Code ví dụ:
1> Code trong Module
Mã:
Public arrNoMark
Sub CreateData()
  Dim arrSource
  Dim idx As Long
  With Sheets("Data")
    arrSource = Sheets("Data").Range("B3", .Range("B60000").End(xlUp)).Value
  End With
  ReDim arrNoMark(1 To UBound(arrSource, 1))
  For idx = 1 To UBound(arrSource, 1)
    If arrSource(idx, 1) <> Empty Then arrNoMark(idx) = TV(arrSource(idx, 1))
  Next
End Sub
Trong Module có luôn hàm TV gì gì đó
2> Code trong UserForm
Mã:
Private Sub UserForm_Initialize()
  If Not IsArray(arrNoMark) Then CreateData
End Sub
Private Sub TextBox1_Change()
  Dim aRes
  aRes = Filter(arrNoMark, TextBox1.Text, True, vbTextCompare)
  If IsArray(aRes) Then Me.ListBox1.List = aRes
End Sub
Chạy thử xem có nhanh không?
 
Upvote 0
Vì khi sự kiện TextBox_Change, bạn phải lo thêm phần "dịch" từ có dấu sang không dấu nên chậm là phải rồi
Giải pháp:
- Mở file, chạy 1 code "dịch" có dấu sang không dấu, tung lên biến public
- Từ giờ bạn sẽ làm việc trong cái đã có sẵn
Code ví dụ:
1> Code trong Module
Mã:
Public arrNoMark
Sub CreateData()
  Dim arrSource
  Dim idx As Long
  With Sheets("Data")
    arrSource = Sheets("Data").Range("B3", .Range("B60000").End(xlUp)).Value
  End With
  ReDim arrNoMark(1 To UBound(arrSource, 1))
  For idx = 1 To UBound(arrSource, 1)
    If arrSource(idx, 1) <> Empty Then arrNoMark(idx) = TV(arrSource(idx, 1))
  Next
End Sub
Trong Module có luôn hàm TV gì gì đó
2> Code trong UserForm
Mã:
Private Sub UserForm_Initialize()
  If Not IsArray(arrNoMark) Then CreateData
End Sub
Private Sub TextBox1_Change()
  Dim aRes
  aRes = Filter(arrNoMark, TextBox1.Text, True, vbTextCompare)
  If IsArray(aRes) Then Me.ListBox1.List = aRes
End Sub
Chạy thử xem có nhanh không?
Cách này nhanh quá anh nhưng sau khi filter thì kết quả là không dấu, vậy có cách nào sau khi filter thì kết quả vẫn có dấu được không vậy?
 
Upvote 0
Cách này nhanh quá anh nhưng sau khi filter thì kết quả là không dấu, vậy có cách nào sau khi filter thì kết quả vẫn có dấu được không vậy?
Chắc là làm cái mảng 5 cột đi anh, 4 cột có dấu, 1 cột không dấu. Khi tìm thì tìm trên cột không dấu, còn khi đưa vào list thì lấy thông tin từ 4 cột kia. Thực chất thì mình cũng chỉ tìm trên 1 cột nên đâu cần thiết phải bỏ dấu hết đâu.
 
Upvote 0
Em muốn này cơ. Gõ vào một textbox, khi có dấu hay khi không có dấu đều tìm được ấy.
Vậy thì theo phương án ở bài #7, trong đó cột thứ 5 ghép cả phần có dấu và phần đã bỏ dấu lại với nhau luôn, tìm trên cột thứ 5 này.
 
Upvote 0
Vậy thì theo phương án ở bài #7, trong đó cột thứ 5 ghép cả phần có dấu và phần đã bỏ dấu lại với nhau luôn, tìm trên cột thứ 5 này.
Ý, vậy cũng hay. Nhưng hình như sẽ cho số lượng kết quả như nhau. Lý ra không dấu cho số luợng kết quả tìm được nhiều hơn có dấu. :)
.
 
Upvote 0
Ý, vậy cũng hay. Nhưng hình như sẽ cho số lượng kết quả như nhau. Lý ra không dấu cho số luợng kết quả tìm được nhiều hơn có dấu. :)
.
Tại sao không dấu lại cho kết quả tìm được nhiều hơn nhỉ? Vì với cách nối chuỗi như vậy thì có dấu hay không dấu thì cũng tìm thấy như nhau mà. Tất nhiên là sẽ cần phải có một dấu hiệu gì đó để phân cách phần có dấu và phần không dấu để tránh trường hợp tìm thấy chuỗi con nằm ở phần giao nhau này (một vài từ nằm ở phần có dấu, các từ còn lại nằm ở phần không dấu).
 
Upvote 0
Tại sao không dấu lại cho kết quả tìm được nhiều hơn nhỉ?
Gõ Google hàng ngày mà không để ý chỗ này...
Ví dụ:
- Dữ liệu cho các từ: "không, khống, khộng, khồng,khỗng, khổng"
- Từ khóa khi gõ có dấu: "không" => Kết quả chỉ có một từ "không".
- Từ khóa khi gõ không có dấu: "khong" => Kết quả là cả cụm đã cho.
 
Upvote 0
Gõ Google hàng ngày mà không để ý chỗ này...
Ví dụ:
- Dữ liệu cho các từ: "không, khống, khộng, khồng,khỗng, khổng"
- Từ khóa khi gõ có dấu: "không" => Kết quả chỉ có một từ "không".
- Từ khóa khi gõ không có dấu: "khong" => Kết quả là cả cụm đã cho.
À, vậy thì ở đây cũng vậy thôi chứ. Rõ ràng tìm có dấu thì kết quả tìm phải chính xác hơn, dẫn đến kết quả ít hơn. Anh cứ thử khởi tạo dữ liệu "khong, không, khống, khộng, khồng, khỗng, khổng" (mỗi từ sẽ là 1 dòng trong listbox) rồi tìm kiếm theo 2 trường hợp có dấu, không dấu xem kết quả có giống vậy không. Tất nhiên nếu tìm từ "không" thì không thể ra kết quả "khong" được rồi, cũng như tìm "bố em rất đảm đang" thì không thể ra "bo em rat dam dang" được, chắc gì đã là thế :)
 
Upvote 0
Lúc trước tôi cũng tự hỏi sao Google nó sờ gét kết quả tài thế cứ như thể nó đi guốc vô bụng mình vậy? Rồi tôi cũng nghĩ là nó chuyển kho nội dung của nó ra không dấu và so sánh với từ khóa ngay thời điểm gõ nhưng mà kho nội dung của nó khổng lồ quá chuyển đổi tức thì cũng không nhanh được. Cuối cùng tôi nghĩ đến khả năng Google dùng một kho dữ liệu không dấu song song.

Lúc này thì việc tìm kết quả phù hợp rất đơn giản nhất là với SQL.
SQL:
SELECT CONTENT
FROM DATAs
WHERE CONTENT LIKE '*' & KEY_WORK & '*' OR PLAIN_CONTENT LIKE '*' & KEY_WORK & '*'
(PLAIN_CONTENTS là cột dữ liệu chỉ dùng ký tự không dấu)

Với cách này gần tương tự thì các bác cũng dễ dàng giải quyết luôn cái chủ đề gợi tên địa chỉ nếu có CSDL về phường xã huyện tỉnh thành.
Bảo đảm ra được cả kết quả có dấu hay không dấu. Với trình độ tù mù thì đây là võ đoán sơ sài của tôi về cách thức còn hiển nhiên là Google họ phức tạp hơn rất nhiều. Nói luôn là SQL với "inh líc" em cũng không rành nên mấy bác uyên thâm về khoản soi mói bỏ qua cho em:vava:
 
Lần chỉnh sửa cuối:
Upvote 0
Vậy thì theo phương án ở bài #7, trong đó cột thứ 5 ghép cả phần có dấu và phần đã bỏ dấu lại với nhau luôn, tìm trên cột thứ 5 này.
Thực tế em cũng đang dùng cách này ạ. Dùng hàm bỏ dấu tiếng Việt trong cột thứ 5. Tuy nhiên em thấy hơi rườm rà nên muốn nhờ các anh chị có giải pháp tối ưu hơn
 
Upvote 0
Em có file excel gồm 1 sheet Data và 1 form gồm 1 Listbox và 1 Textbox. Em muốn khi gõ vào Textbox mà không gõ dấu tiếng Việt thì listbox vẫn hiểu được. Ví dụ em gõ vào Textbox là "Viet Nam" thì nó sẽ hiểu là Việt Nam để tìm kiếm. Mong các anh chị giúp đỡ, em xin cảm ơn
Mình không rành về code trên VBA, nhưng giải pháp của mình đó là dùng nguyên 1 sheet trên excel để giải quyết toàn bộ việc này, sau đó mang những gì đã giải quyết lên listbox và textbox thôi.
1535691319938.png
 
Upvote 0
Loay hoay để nắm lại cú pháp cái Instr() với Like cuối cùng tôi cũng nghĩ ra cách thức của riêng mình:victory:
PHP:
Function xKey(text As String) As String
    Dim i, s, k
    text = LCase(text)
    For i = 1 To Len(text)
        k = Mid(text, i, 1)
        If InStr("aeiouyd", k) > 0 Or AscW(k) > 128 Then
            s = s & "[!bc,f-h,j-n,p-t,v-x,z, ]" 'thử chơi liều ;))
        Else
            s = s & k
        End If
    Next
    xKey = s
End Function

Private Sub TextBox1_Change()
    Dim sArray(), i As Integer, k As Integer, j As Integer, Arr(), dArr(), key

    sArray = Sheet_Data.Range("A3:D" & Sheet_Data.[A65536].End(xlUp).Row).Value
    ReDim Arr(1 To UBound(sArray), 1 To 4)
   
    key = "*" & xKey(TextBox1.text) & "*"
   
    For i = 1 To UBound(sArray)
        If LCase(sArray(i, 2)) Like key Then
            k = k + 1
            For j = 1 To 4
                Arr(k, j) = sArray(i, j)
            Next
        End If
    Next
   
    If k > 0 Then
        ReDim dArr(1 To k, 1 To 4)
        For i = 1 To k
            For j = 1 To 4
                dArr(i, j) = Arr(i, j)
            Next
        Next
        ListBox1.Clear
        ListBox1.List() = dArr
    End If
End Sub
Bạn có thể kết hợp cả các wildchar ?, * để mở rộng kết quả tìm kiếm ("vai bac * lim lao" sẽ ra Vai bậc cầu thang gỗ lim Lào"). Bác nào đem so với Google để chê bai tiểu tốt em thì em cũng pó phép :wow:
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Web KT

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

Back
Top Bottom