Tu vuoi applicare un filtro, mentre quella routine si posiziona solo sulla prima occorrenza, e per inciso è pure sbagliata (il contatore di riga è N ma viene usato X ed è per quello che non funziona ed è case sensitive).
Oltretutto non ha alcun senso nascondere la griglia con .Visible = False (bruttissimo), caso mai si dovrebbe usare .Redraw = False.
Ad ogni modo la struttura della routine che ti serve non è difficile, dovrebbe essere più o meno così:
Dim i as long
Dim sString As String
sString = UCase$(Trim$(TrovaContatto.Text))
With .FLEX
.Redraw = False
For i = 1 to .Rows -1
If Left$(UCase$(.TextMatrix(i, 2)), Len(sString) = sString Then
.RowIsVisible(i) = True
Else
.RowIsVisible(i) = False
End If
Next i
.Redraw = True
End With
Considera comunque il fatto che l'utente deve per forza ricordarsi i primi caratteri della stringa da cercare, e non sempre è così.
La ricerca è senz'altro più utile se l'utente deve digitare 'alcuni caratteri' ovvero eseguire una ricerca sul 'contenuto' della stringa anziché sull'inizio.
Per ipotesi, se hai Cognome + Nome nel campo e l'utente non ricorda il Cognome ma solo il Nome allora la ricerca sul contenuto è più semplice. In tal caso, invece di usare:
If Left$(UCase$(.TextMatrix(i, 2)), Len(sString) = sString Then
dovrai usare:
If InStr(UCase$(.TextMatrix(i, 2)), sString) > 0 Then
Ovviamente: SE&O. 