Untitled

 avatar
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