Untitled
unknown
plain_text
a year ago
4.2 kB
13
Indexable
Option Explicit
'--- Module-level state ---
Dim arrCheDo() As String
Dim isFiltering As Boolean
Dim isSelecting As Boolean
'========================
' USERFORM INIT
'========================
Private Sub UserForm_Initialize()
' Load data first
LoadCheDoFromSheet
' Ensure ComboBox behaves correctly
With Me.cboChedo
.Clear
.ColumnCount = 1 ' single column list
.BoundColumn = 1 ' Value returns the visible text
.MatchEntry = fmMatchEntryNone ' we handle filtering ourselves
.Style = fmStyleDropDownCombo ' allow typing + dropdown
End With
' Fill full list initially
FillChedoCombo ""
End Sub
'========================
' NẠP DỮ LIỆU TỪ SHEET
'========================
Private Sub LoadCheDoFromSheet()
Dim ws As Worksheet, lastR As Long
Dim v As Variant, i As Long, n As Long
On Error Resume Next
Set ws = ThisWorkbook.Sheets("Danhmuc") ' Đổi đúng tên sheet nếu khác
On Error GoTo 0
If ws Is Nothing Then
MsgBox "Không tìm thấy sheet Danhmuc!", vbCritical
Exit Sub
End If
lastR = ws.Cells(ws.Rows.Count, "B").End(xlUp).Row
If lastR < 6 Then
Erase arrCheDo
Exit Sub
End If
v = ws.Range("B6:B" & lastR).Value ' đọc vùng dữ liệu
ReDim arrCheDo(1 To UBound(v, 1))
n = 0
For i = 1 To UBound(v, 1)
If Trim$(CStr(v(i, 1))) <> "" Then
n = n + 1
arrCheDo(n) = CStr(v(i, 1))
End If
Next i
If n = 0 Then
Erase arrCheDo
Else
ReDim Preserve arrCheDo(1 To n)
End If
End Sub
'========================
' ĐỔ DANH SÁCH VÀO COMBO (lọc hoặc full)
'========================
Private Sub FillChedoCombo(ByVal filterText As String)
Dim i As Long, s As String
Me.cboChedo.Clear
If Not IsArray(arrCheDo) Then Exit Sub
filterText = LCase$(Trim$(filterText))
For i = LBound(arrCheDo) To UBound(arrCheDo)
s = arrCheDo(i)
If filterText = "" Then
Me.cboChedo.AddItem s
ElseIf InStr(1, LCase$(s), filterText, vbTextCompare) > 0 Then
Me.cboChedo.AddItem s
End If
Next i
End Sub
'========================
' GÕ CHỮ → LỌC DANH SÁCH
'========================
Private Sub cboChedo_Change()
Dim t As String
' Tránh vòng lặp sự kiện
If isFiltering Or isSelecting Then Exit Sub
' Nếu thay đổi là do chọn từ list, không lọc lại
If Me.cboChedo.ListIndex >= 0 Then Exit Sub
isFiltering = True
t = Me.cboChedo.Text
' Lọc theo phần gõ
FillChedoCombo t
' Khôi phục phần gõ và caret
Me.cboChedo.Text = t
Me.cboChedo.SelStart = Len(t)
' Hiện dropdown nếu có kết quả
If Me.cboChedo.ListCount > 0 Then Me.cboChedo.DropDown
isFiltering = False
End Sub
'========================
' BẤM NÚT XỔ → HIỆN FULL LIST
'========================
Private Sub cboChedo_DropButtonClick()
If isFiltering Then Exit Sub
isFiltering = True
FillChedoCombo "" ' full list
Me.cboChedo.DropDown
isFiltering = False
End Sub
'========================
' CHỌN TRONG LIST → GIỮ GIÁ TRỊ
'========================
Private Sub cboChedo_Click()
If Me.cboChedo.ListIndex >= 0 Then
' Khi chọn, Value sẽ tự là mục đã chọn
' Không cần gán lại Text (tránh mất giá trị)
isSelecting = True
isSelecting = False
End If
End Sub
'========================
' TIỆN ÍCH: LẤY GIÁ TRỊ AN TOÀN
' (Dùng khi cần đọc giá trị đã chọn)
'========================
Public Function GetSelectedChedo() As String
' Ưu tiên lấy từ ListIndex (chắc chắn đúng với BoundColumn=1)
If Me.cboChedo.ListIndex >= 0 Then
GetSelectedChedo = Me.cboChedo.List(Me.cboChedo.ListIndex)
Else
' Nếu người dùng chỉ gõ (chưa chọn), trả về phần đã gõ
GetSelectedChedo = Trim$(Me.cboChedo.Text)
End If
End Function
Editor is loading...
Leave a Comment