I did a basic test with a binary search and the cHashList.
Compiled, fast code only, the binary search performs about 15% better compared to cHashList
But I really like the elegancy of cHashList!

Code:
Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long

Private Sub Form_Click()
  Dim t As Long
  Dim sArray() As String
  Dim i As Long, j As Long
  Dim s(999) As String
  Dim lIndex As Long, bExist As Boolean
  
  ReDim sArray(120000 - 1)
  For i = 0 To UBound(sArray)
    sArray(i) = "K:" & Format(CStr(i), "0000000")
  Next i
  
  Dim cHL As clsHashList
  Set cHL = New clsHashList
  cHL.ReInit 120000
  
  For i = 0 To UBound(sArray)
    cHL.Add i, sArray(i)
  Next i
  
  For i = 0 To 999
    s(i) = "K:" & Format(Int(Rnd * 120000), "0000000")
  Next i
  
  t = GetTickCount
  For j = 1 To 1000: For i = 0 To 999
    lIndex = GetIndexStringArray(s(i), sArray)
  Next: Next
  Print "GetIndex: " & GetTickCount - t
  
  t = GetTickCount
  For j = 1 To 1000: For i = 0 To 999
      bExist = cHL.Exists(s(i))
  Next: Next
  Print "HashList: " & GetTickCount - t

End Sub

Public Function GetIndexStringArray(ByVal sID As String, sArray() As String) As Long
  Dim lFirst As Long
  Dim lLast As Long
  Dim lMiddle As Long
  Dim lSteps As Long
  
  ' assume search failed
  GetIndexStringArray = -1
  
  lFirst = 0
  lLast = UBound(sArray)
  
  Do
    'lSteps = lSteps + 1
    lMiddle = (lFirst + lLast) \ 2
    Select Case StrComp(sID, sArray(lMiddle), vbBinaryCompare)
      Case 0
        GetIndexStringArray = lMiddle
        Exit Do
      Case 1
        lFirst = lMiddle + 1
      Case Else
        lLast = lMiddle - 1
    End Select
  Loop Until lFirst > lLast
  
End Function