Private priArray
Private priColumn As Long
Private priIsFocus As Boolean
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Count = 1 And Target.Row > 2 Then
        Dim e As Long
        Static ArrCode, ArrName
        If Target.Column = 2 Then
            If Not IsArray(ArrCode) Then
                e = Sheet1.Range("B" & Rows.Count).End(xlUp).Row
                ArrCode = Sheet1.Range("B2:C" & e).Value2
            End If
            priColumn = 1
            priArray = ArrCode
            Call HienComboBox
        ElseIf Target.Column = 3 Then
            If Not IsArray(ArrName) Then
                Dim ArrTmp
                Dim r As Long, u As Long
                e = Sheet1.Range("B" & Rows.Count).End(xlUp).Row
                ArrTmp = Sheet1.Range("B2:B" & e).Value2
                ArrName = Sheet1.Range("C2:C" & e).Value2
                u = UBound(ArrName)
                ReDim Preserve ArrName(1 To u, 1 To 2)
                For r = 1 To u
                    ArrName(r, 2) = ArrTmp(r, 1)
                Next
            End If
            priColumn = -1
            priArray = ArrName
            Call HienComboBox
        Else
            Call AnComboBox
        End If
    Else
        Call AnComboBox
    End If
End Sub
Private Sub ComboBox1_Change()
    If priIsFocus Then Exit Sub
    If ComboBox1.MatchFound Then
        ActiveCell.Value = ComboBox1.Text
        ActiveCell.Offset(, priColumn).Value = ComboBox1.Column(1)
    Else
        ActiveCell.Value = ""
        ActiveCell.Offset(, priColumn).Value = ""
    End If
End Sub
Private Sub ComboBox1_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    On Error Resume Next
    Select Case KeyCode
    Case 9, 16, 17, 37 To 40
    Case 13
        ActiveCell.Offset(1).Activate
    Case Else
        Dim strValue As String
        strValue = LCase(ComboBox1.Text)
        ComboBox1.ListRows = 20
        If Trim(strValue) > "" Then
            If IsArray(priArray) Then
                Dim ArrFilter, GetRow()
                Dim c As Long, i As Long, n As Long, r As Long
                For r = 1 To UBound(priArray, 1)
                    If LCase(priArray(r, 1)) Like "*" & strValue & "*" Then
                        n = n + 1
                        ReDim Preserve GetRow(1 To n)
                        GetRow(n) = r
                    End If
                Next
                If n Then
                    Dim u As Byte
                    u = UBound(priArray, 2)
                    ReDim ArrFilter(1 To n, 1 To u)
                    For r = 1 To n
                        For c = 1 To u
                            ArrFilter(r, c) = priArray(GetRow(r), c)
                        Next
                    Next
                    ComboBox1.List = ArrFilter
                Else
                    ComboBox1.Clear
                    ComboBox1.ListRows = 0
                End If
                ComboBox1.DropDown
            End If
        Else
            If ComboBox1.ListCount <> UBound(priArray) Then
                ComboBox1.List = priArray
                ComboBox1.DropDown
            End If
        End If
    End Select
End Sub
Private Sub HienComboBox()
    priIsFocus = True
    With ComboBox1
        .Visible = False
        .Visible = True
        .Left = ActiveCell.Left
        .Top = ActiveCell.Top
        .Width = ActiveCell.Width
        .ListWidth = .Width + ActiveCell.Offset(, priColumn).Width
        .ColumnWidths = .Width - 4
        .Height = ActiveCell.Height
        .List = priArray
        .Text = ""
        .Text = ActiveCell.Value
        .Activate
        .SelStart = 0
        .SelLength = Len(.Text)
    End With
    priIsFocus = False
End Sub
Private Sub AnComboBox()
    With ComboBox1
        If .Visible Then
            .Visible = False
        End If
    End With
End Sub