@JohnSUN, filterRange() is simple & good.
bUseLikeOperator (optional) & my comments added.
Function FilterRange(aData, nColumn%, sCriterion$, Optional bUseLikeOperator As Boolean)
Dim i&, j&, nCount& 'row & column indices, filtered row count
Dim bOK As Boolean
If IsMissing(bUseLikeOperator) Then bUseLikeOperator = False
' Move rows that meet criterion to beginning of array.
nCount = 1 'skips header row (colum titles)
For i = LBound(aData) + 1 To UBound(aData)
If bUseLikeOperator Then
bOK = aData(i, nColumn) Like sCriterion
Else
bOK = (aData(i, nColumn) = sCriterion)
End If
If bOK Then
nCount = nCount + 1
For j = LBound(aData, 2) To UBound(aData, 2)
aData(nCount, j) = aData(i, j) 'copies column values of this row
Next j
End If
Next i
' Clear rest of array.
For i = nCount + 1 To UBound(aData)
For j = LBound(aData, 2) To UBound(aData, 2)
aData(i, j) = ""
Next j
Next i
FilterRange = aData
End Function
{=FILTERRANGE($A$1:$C$7;3;"US")}
Same result, but more freedom (bUseLikeOperator:=True):
{=FILTERRANGE($A$1:$C$7;3;"U?";1)}