ongke0711 > 25-07-18, 12:41 PM
Option Compare Database
Option Explicit
Private faytCbHoTen As New clsFAYTCombo
Private Sub Form_Load()
Dim rsHoTen As DAO.Recordset
Set rsHoTen = CurrentDb.OpenRecordset(Me.cboNhanVien.RowSource)
Set Me.cboNhanVien.Recordset = rsHoTen
faytCbHoTen.InitalizeFilterCombo Me.cboNhanVien, "HoTen", False
End Sub
Option Compare Database
Option Explicit
'TÊN Class Module: clsFAYTCombo
'NOI DUNG: Tìm kiem, loc thong tin records ngay trong Combobox - "Find As You Type"
' Dùng Recordset và thuoc tinh Filter cua no thay the cho câu lenh SQL.
'TAC GIA: Duoc chinh sua tu code cua MajP ben Tek-tips.com
'
'CÁC THAM SÔ:
' faytComBoName: Tên cua Combobox ma ban muon áp dung
' FilterFieldName: Tên Field mà ban dung de loc du lieu - dang Chuoi (String)
' FilterFromStart: Xác dinh muon loc chuoi "text" tu dau dòng hay o bat ky doan nào cua dòng.
' TRUE: tìm tu dau dong/ FALSE: tìm o vi trí bat ky.
'
'*******CODE dùng trong FORM*******************
'
' Option Compare Database
' Option Explicit
' Priavte faytCBX As New clsFAYTCombo
'
' Private Sub Form_Load()
' faytCbHoTen.InitalizeFilterCombo Me.cboNhanVien, "HoTen", False
' End Sub
'
'**********************************************
Private WithEvents mCombo As Access.ComboBox
Private WithEvents mForm As Access.Form
Private mFilterFieldName As String
Private mRsOriginalList As DAO.Recordset
Private mFilterFromStart As Boolean
Private Sub mCombo_Change()
If Len(Nz(Trim(mCombo.Text), "")) <> 0 Then
Call FilterList
Else
Call unFilterList 'không set muc nay cung ok'
End If
End Sub
Private Sub mCombo_GotFocus()
mCombo.Dropdown
End Sub
Private Sub mCombo_AfterUpdate()
Call unFilterList
End Sub
Private Sub mCombo_Click()
Call unFilterList
End Sub
Private Sub mForm_Current() 'De reset lai combobox vê RowSource ban dau'
Call unFilterList
End Sub
Private Sub FilterList()
On Error GoTo errHandler
Dim rsTemp As DAO.Recordset
Dim strText As String
Dim strFilter As String
'Không chay Filter khi chon item tu trong list combobox; Giai quyet van de: khi KeyDown tu dong chon dong dau tien'
If mCombo.ListCount > 0 And mCombo.ListIndex >= 0 Then Exit Sub
strText = Trim(mCombo.Text)
If mFilterFieldName = "" Then
MsgBoxUni "Ph" & ChrW(7843) & "i cung c" & ChrW(7845) & "p tham s" & ChrW(7889) & " [Tên Field] " & ChrW(273) & ChrW(7875) & " l" & ChrW(7885) & "c d" & ChrW(7919) & " li" & ChrW(7879) & "u."
Exit Sub
End If
If mFilterFromStart = True Then
strFilter = mFilterFieldName & " Like '" & strText & "*'"
Else
strFilter = mFilterFieldName & " Like '*" & strText & "*'"
End If
Set rsTemp = mRsOriginalList.OpenRecordset
rsTemp.Filter = strFilter
Set rsTemp = rsTemp.OpenRecordset
If rsTemp.RecordCount > 0 Then
Set mCombo.Recordset = rsTemp
mCombo.Dropdown
Else
' Khi khong tìm thay record, không dropdown list cua combobox.'
mCombo.RowSource = ""
Beep
End If
'Set rsTemp = Nothing'
Exit Sub
errHandler:
If Err.Number = 3061 Then
MsgBoxUni "Không l" & ChrW(7885) & "c " & ChrW(273) & ChrW(432) & ChrW(7907) & "c d" & ChrW(7919) & " li" & ChrW(7879) & "u." & vbCrLf _
& "Ki" & ChrW(7875) & "m tra l" & ChrW(7841) & "i tên tr" & ChrW(432) & ChrW(7901) & "ng (Field) c" & ChrW(7847) & "n l" & ChrW(7885) & "c.", vbCritical, "L" & ChrW(7895) & "i l" & ChrW(7885) & "c d" & ChrW(7919) & " li" & ChrW(7879) & "u"
Else
MsgBoxUni "Có l" & ChrW(7895) & "i phát sinh. Vui lòng liên h" & ChrW(7879) & " ng" & ChrW(432) & ChrW(7901) & "i qu" & ChrW(7843) & "n tr" & ChrW(7883) & " h" & ChrW(7879) & " th" & ChrW(7889) & "ng." & vbCrLf _
& "Mã l" & ChrW(7895) & "i:" & Err.Number & vbCrLf _
& "N" & ChrW(7897) & "i dung l" & ChrW(7895) & "i:" & Err.Description, vbCritical, "Thông báo"
End If
End Sub
Private Sub unFilterList()
On Error GoTo errHandler
Set mCombo.Recordset = mRsOriginalList
Exit Sub
errHandler:
If Err.Number = 3061 Then
MsgBoxUni "Không l" & ChrW(7885) & "c " & ChrW(273) & ChrW(432) & ChrW(7907) & "c d" & ChrW(7919) & " li" & ChrW(7879) & "u." & vbCrLf _
& "Ki" & ChrW(7875) & "m tra l" & ChrW(7841) & "i tên tr" & ChrW(432) & ChrW(7901) & "ng (Field) c" & ChrW(7847) & "n l" & ChrW(7885) & "c.", vbCritical, "L" & ChrW(7895) & "i l" & ChrW(7885) & "c d" & ChrW(7919) & " li" & ChrW(7879) & "u"
Else
MsgBoxUni "Có l" & ChrW(7895) & "i phát sinh. Vui lòng liên h" & ChrW(7879) & " ng" & ChrW(432) & ChrW(7901) & "i qu" & ChrW(7843) & "n tr" & ChrW(7883) & " h" & ChrW(7879) & " th" & ChrW(7889) & "ng." & vbCrLf _
& "Mã l" & ChrW(7895) & "i:" & Err.Number & vbCrLf _
& "N" & ChrW(7897) & "i dung l" & ChrW(7895) & "i:" & Err.Description, vbCritical, "Thông báo"
End If
End Sub
Public Property Get FilterFieldName() As String
FilterFieldName = mFilterFieldName
End Property
Public Property Let FilterFieldName(ByVal theFieldName As String)
mFilterFieldName = theFieldName
End Property
Private Sub Class_Terminate()
Set mForm = Nothing
Set mCombo = Nothing
Set mRsOriginalList = Nothing
End Sub
Public Sub InitalizeFilterCombo(faytComBoName As Access.ComboBox, FilterFieldName As String, Optional FilterFromStart = True)
On Error GoTo errHandler
If Not faytComBoName.RowSourceType = "Table/Query" Then
MsgBoxUni "Class ch" & ChrW(7881) & " ho" & ChrW(7841) & "t " & ChrW(273) & ChrW(7897) & "ng khi Combobox có RowSource là Table ho" & ChrW(7863) & "c Query."
Exit Sub
End If
Set mCombo = faytComBoName
Set mForm = faytComBoName.Parent
mFilterFieldName = FilterFieldName
mFilterFromStart = FilterFromStart
mForm.OnCurrent = "[Event Procedure]"
mCombo.OnGotFocus = "[Event Procedure]"
mCombo.OnChange = "[Event Procedure]"
mCombo.AfterUpdate = "[Event Procedure]"
mCombo.OnNotInList = "[Event Procedure]"
With mCombo
If .ListCount Then Else
.SetFocus
.AutoExpand = True
End With
Set mRsOriginalList = mCombo.Recordset.Clone
Exit Sub
errHandler:
MsgBoxUni "Có l" & ChrW(7895) & "i phát sinh. Vui lòng liên h" & ChrW(7879) & " ng" & ChrW(432) & ChrW(7901) & "i qu" & ChrW(7843) & "n tr" & ChrW(7883) & " h" & ChrW(7879) & " th" & ChrW(7889) & "ng." & vbCrLf _
& "Mã l" & ChrW(7895) & "i:" & Err.Number & vbCrLf _
& "N" & ChrW(7897) & "i dung l" & ChrW(7895) & "i: " & Err.Description, vbCritical, "Thông báo"
End Sub
Private Sub mCombo_NotInList(NewData As String, Response As Integer)
MsgBoxUni "D" & ChrW(7919) & " li" & ChrW(7879) & "u b" & ChrW(7841) & "n tìm không có." & vbCrLf _
& "Vui lòng ch" & ChrW(7885) & "n trong danh sách.", vbInformation, "Thông báo"
Response = acDataErrContinue
End Sub
huuduy.duy > 25-07-18, 02:13 PM
ongke0711 > 25-07-18, 03:32 PM
(25-07-18, 02:13 PM)huuduy.duy Đã viết: Em gỏ thử
DD thì ra chủ DĐ
Trần thì ra Traần
Ghi chú: dùng bộ gỏ EVkey 3.3.0
huuduy.duy > 26-07-18, 01:00 AM
(25-07-18, 03:32 PM)ongke0711 Đã viết:(25-07-18, 02:13 PM)huuduy.duy Đã viết: Em gỏ thử
DD thì ra chủ DĐ
Trần thì ra Traần
Ghi chú: dùng bộ gỏ EVkey 3.3.0
Cái lỗi font chữ này không liên quan đến Class.
Lỗi này là khi gõ tiếng Việt trong Combobox có RowSource là chính cái table Nhân viên thì bị lỗi, nếu Rowsource là table khác hoặc không có Source thì không bị lỗi font chữ này. Tôi cũng chưa biết cách khắc phục lỗi này. Có file thì bị lỗi này, có file không bị. Không biết Access phiên bản khác có bị không? Máy tôi Access 2013.
Nhiều khi Access nó cũng trời thần lắm.
(PS: Đã thay table Nhân Viên)
thanhtruong > 01-08-18, 12:30 PM
ongke0711 > 01-08-18, 01:00 PM
ongke0711 > 25-09-18, 12:21 AM
tranthanhan1962 > 25-09-18, 07:43 AM
(25-07-18, 02:13 PM)huuduy.duy Đã viết: Em gỏ thử
DD thì ra chủ DĐ
Trần thì ra Traần
Ghi chú: dùng bộ gỏ EVkey 3.3.0
Xuân Thanh > 25-09-18, 10:10 AM
ledangvan > 25-09-18, 12:00 PM
(25-07-18, 12:41 PM)ongke0711 Đã viết: Chào các bạn,
Trong thực tế có những Combobox có RowSource lên tới chục ngàn dòng do vậy, việc chỉ cần gõ từ khóa trực tiếp ngay trong Combobox thì nó sẽ tự động lọc dữ liệu liên quan đến từ khóa đó để chọn sẽ nhanh hơn rất nhiều.
Trên mạng cũng đã có nhiều bài hướng dẫn cách tạo "Smart combobox" như vậy rồi. Kỹ thuật xử lý thì cũng không khác gì mấy, chủ yếu là làm sao để chạy trơn tru khi thao tác tìm kiếm ngay trong combobox. Lần này tôi giới thiệu với các bạn cách xử lý thông qua class module.
Cách làm:
- Dùng sự kiện On Change của combobox để bắt chuỗi tìm kiếm khi gõ.
- Thay thế RecordSource của combobox bằng Recordset mới đã lọc dữ liệu theo chuỗi tìm kiếm vừa gõ.
- Trong demo này tôi dùng Class module để có thể gọi sử dụng lại cho nhiều combobox trong cùng 1 Form (nếu có).
- Tôi mượn dữ liệu mẫu của bạn thanhtruong để làm RecordSource cho combobox <=> 17.000 dòng để test.
Lưu ý: Class này dùng Recordset của Combobox nên bắt buộc combobox phải có RowSource là "Table hoăc Query " mới chạy được.
Tôi thấy nó cũng chưa chạy thực sự trơn tru lắm nhưng cũng đáp ứng yêu cầu đặt ra.
Các bạn test thử và cùng đóng góp các kiểu code khác để cải tiến cho hiệu quả hơn.
- Code gọi trong Form chứa Combobox cần áp dụng: chỉ cần gọi class ở sự kiện On Load() của Form.
Mã PHP:Option Compare Database
Option Explicit
Private faytCbHoTen As New clsFAYTCombo
Private Sub Form_Load()
Dim rsHoTen As DAO.Recordset
Set rsHoTen = CurrentDb.OpenRecordset(Me.cboNhanVien.RowSource)
Set Me.cboNhanVien.Recordset = rsHoTen
faytCbHoTen.InitalizeFilterCombo Me.cboNhanVien, "HoTen", False
End Sub
Mã PHP:Option Compare Database
Option Explicit
'TÊN Class Module: clsFAYTCombo
'NOI DUNG: Tìm kiem, loc thong tin records ngay trong Combobox - "Find As You Type"
' Dùng Recordset và thuoc tinh Filter cua no thay the cho câu lenh SQL.
'TAC GIA: Duoc chinh sua tu code cua MajP ben Tek-tips.com
'
'CÁC THAM SÔ:
' faytComBoName: Tên cua Combobox ma ban muon áp dung
' FilterFieldName: Tên Field mà ban dung de loc du lieu - dang Chuoi (String)
' FilterFromStart: Xác dinh muon loc chuoi "text" tu dau dòng hay o bat ky doan nào cua dòng.
' TRUE: tìm tu dau dong/ FALSE: tìm o vi trí bat ky.
'
'*******CODE dùng trong FORM*******************
'
' Option Compare Database
' Option Explicit
' Priavte faytCBX As New clsFAYTCombo
'
' Private Sub Form_Load()
' faytCbHoTen.InitalizeFilterCombo Me.cboNhanVien, "HoTen", False
' End Sub
'
'**********************************************
Private WithEvents mCombo As Access.ComboBox
Private WithEvents mForm As Access.Form
Private mFilterFieldName As String
Private mRsOriginalList As DAO.Recordset
Private mFilterFromStart As Boolean
Private Sub mCombo_Change()
If Len(Nz(Trim(mCombo.Text), "")) <> 0 Then
Call FilterList
Else
Call unFilterList 'không set muc nay cung ok'
End If
End Sub
Private Sub mCombo_GotFocus()
mCombo.Dropdown
End Sub
Private Sub mCombo_AfterUpdate()
Call unFilterList
End Sub
Private Sub mCombo_Click()
Call unFilterList
End Sub
Private Sub mForm_Current() 'De reset lai combobox vê RowSource ban dau'
Call unFilterList
End Sub
Private Sub FilterList()
On Error GoTo errHandler
Dim rsTemp As DAO.Recordset
Dim strText As String
Dim strFilter As String
'Không chay Filter khi chon item tu trong list combobox; Giai quyet van de: khi KeyDown tu dong chon dong dau tien'
If mCombo.ListCount > 0 And mCombo.ListIndex >= 0 Then Exit Sub
strText = Trim(mCombo.Text)
If mFilterFieldName = "" Then
MsgBoxUni "Ph" & ChrW(7843) & "i cung c" & ChrW(7845) & "p tham s" & ChrW(7889) & " [Tên Field] " & ChrW(273) & ChrW(7875) & " l" & ChrW(7885) & "c d" & ChrW(7919) & " li" & ChrW(7879) & "u."
Exit Sub
End If
If mFilterFromStart = True Then
strFilter = mFilterFieldName & " Like '" & strText & "*'"
Else
strFilter = mFilterFieldName & " Like '*" & strText & "*'"
End If
Set rsTemp = mRsOriginalList.OpenRecordset
rsTemp.Filter = strFilter
Set rsTemp = rsTemp.OpenRecordset
If rsTemp.RecordCount > 0 Then
Set mCombo.Recordset = rsTemp
mCombo.Dropdown
Else
' Khi khong tìm thay record, không dropdown list cua combobox.'
mCombo.RowSource = ""
Beep
End If
'Set rsTemp = Nothing'
Exit Sub
errHandler:
If Err.Number = 3061 Then
MsgBoxUni "Không l" & ChrW(7885) & "c " & ChrW(273) & ChrW(432) & ChrW(7907) & "c d" & ChrW(7919) & " li" & ChrW(7879) & "u." & vbCrLf _
& "Ki" & ChrW(7875) & "m tra l" & ChrW(7841) & "i tên tr" & ChrW(432) & ChrW(7901) & "ng (Field) c" & ChrW(7847) & "n l" & ChrW(7885) & "c.", vbCritical, "L" & ChrW(7895) & "i l" & ChrW(7885) & "c d" & ChrW(7919) & " li" & ChrW(7879) & "u"
Else
MsgBoxUni "Có l" & ChrW(7895) & "i phát sinh. Vui lòng liên h" & ChrW(7879) & " ng" & ChrW(432) & ChrW(7901) & "i qu" & ChrW(7843) & "n tr" & ChrW(7883) & " h" & ChrW(7879) & " th" & ChrW(7889) & "ng." & vbCrLf _
& "Mã l" & ChrW(7895) & "i:" & Err.Number & vbCrLf _
& "N" & ChrW(7897) & "i dung l" & ChrW(7895) & "i:" & Err.Description, vbCritical, "Thông báo"
End If
End Sub
Private Sub unFilterList()
On Error GoTo errHandler
Set mCombo.Recordset = mRsOriginalList
Exit Sub
errHandler:
If Err.Number = 3061 Then
MsgBoxUni "Không l" & ChrW(7885) & "c " & ChrW(273) & ChrW(432) & ChrW(7907) & "c d" & ChrW(7919) & " li" & ChrW(7879) & "u." & vbCrLf _
& "Ki" & ChrW(7875) & "m tra l" & ChrW(7841) & "i tên tr" & ChrW(432) & ChrW(7901) & "ng (Field) c" & ChrW(7847) & "n l" & ChrW(7885) & "c.", vbCritical, "L" & ChrW(7895) & "i l" & ChrW(7885) & "c d" & ChrW(7919) & " li" & ChrW(7879) & "u"
Else
MsgBoxUni "Có l" & ChrW(7895) & "i phát sinh. Vui lòng liên h" & ChrW(7879) & " ng" & ChrW(432) & ChrW(7901) & "i qu" & ChrW(7843) & "n tr" & ChrW(7883) & " h" & ChrW(7879) & " th" & ChrW(7889) & "ng." & vbCrLf _
& "Mã l" & ChrW(7895) & "i:" & Err.Number & vbCrLf _
& "N" & ChrW(7897) & "i dung l" & ChrW(7895) & "i:" & Err.Description, vbCritical, "Thông báo"
End If
End Sub
Public Property Get FilterFieldName() As String
FilterFieldName = mFilterFieldName
End Property
Public Property Let FilterFieldName(ByVal theFieldName As String)
mFilterFieldName = theFieldName
End Property
Private Sub Class_Terminate()
Set mForm = Nothing
Set mCombo = Nothing
Set mRsOriginalList = Nothing
End Sub
Public Sub InitalizeFilterCombo(faytComBoName As Access.ComboBox, FilterFieldName As String, Optional FilterFromStart = True)
On Error GoTo errHandler
If Not faytComBoName.RowSourceType = "Table/Query" Then
MsgBoxUni "Class ch" & ChrW(7881) & " ho" & ChrW(7841) & "t " & ChrW(273) & ChrW(7897) & "ng khi Combobox có RowSource là Table ho" & ChrW(7863) & "c Query."
Exit Sub
End If
Set mCombo = faytComBoName
Set mForm = faytComBoName.Parent
mFilterFieldName = FilterFieldName
mFilterFromStart = FilterFromStart
mForm.OnCurrent = "[Event Procedure]"
mCombo.OnGotFocus = "[Event Procedure]"
mCombo.OnChange = "[Event Procedure]"
mCombo.AfterUpdate = "[Event Procedure]"
mCombo.OnNotInList = "[Event Procedure]"
With mCombo
If .ListCount Then Else
.SetFocus
.AutoExpand = True
End With
Set mRsOriginalList = mCombo.Recordset.Clone
Exit Sub
errHandler:
MsgBoxUni "Có l" & ChrW(7895) & "i phát sinh. Vui lòng liên h" & ChrW(7879) & " ng" & ChrW(432) & ChrW(7901) & "i qu" & ChrW(7843) & "n tr" & ChrW(7883) & " h" & ChrW(7879) & " th" & ChrW(7889) & "ng." & vbCrLf _
& "Mã l" & ChrW(7895) & "i:" & Err.Number & vbCrLf _
& "N" & ChrW(7897) & "i dung l" & ChrW(7895) & "i: " & Err.Description, vbCritical, "Thông báo"
End Sub
Private Sub mCombo_NotInList(NewData As String, Response As Integer)
MsgBoxUni "D" & ChrW(7919) & " li" & ChrW(7879) & "u b" & ChrW(7841) & "n tìm không có." & vbCrLf _
& "Vui lòng ch" & ChrW(7885) & "n trong danh sách.", vbInformation, "Thông báo"
Response = acDataErrContinue
End Sub
Link file demo: http://www.mediafire.com/file/a4dq717q7u...accdb/file
----------------------------------------------------------------------------------------
BỔ SUNG TÌM KIẾM NHIỀU FIELD TRONG COMBOBOX
Bạn gõ ký tự tìm kiếm và Combobox sẽ tự động tìm trong tất cả các field của combobox để tìm. Field nào cần đưa vào để tìm kiếm phải khai báo ở sự kiện Form_Load()
Link file demo: http://www.mediafire.com/file/0spbf2rsshjronf/FAYTComboboxMultiFields_Class.mdb/file