Código VBA para localizar células num ficheiro range

O método Find da classe Range é utilizado para encontrar células que contêm um determinado valor ou formato num intervalo.

Encontrar em feuille de calcul

Na sua forma básica, Find é chamado como o código abaixo, que selecciona a célula encontrada. O código só funcionará se o valor estiver efetivamente presente na folha de cálculo.


ActiveSheet.UsedRange.Find(What:="x").Select

O objeto de classe Range é obtido a partir do procedimento Worksheet UsedRange.

O procedimento devolve um objeto do tipo Range que é opcionalmente atribuído a uma variável rngFound. Geralmente, utiliza-se uma variável, aqui: strWhat para atribuir o parâmetro What.


Dim strWhat As String: strWhat = 
Dim rngFound As Range
Set rngFound = ActiveSheet.UsedRange.Find(What:=strWhat)

O método Find devolve Nothing se não for encontrada nenhuma correspondência.

Encontrar em range

Procurar valor na coluna

O código abaixo permite-lhe encontrar uma célula que contenha o valor numa determinada coluna.


Dim rngColumn As Range
Set rngColumn = ActiveSheet.Columns(3)
Dim rngFound As Range
Set rngFound = rngColumn.Find(What:="x").Select

Procurar valor na linha

Utilize o seguinte código para encontrar uma célula que contenha o valor numa linha.


Dim rngRow As Range
Set rngRow = ActiveSheet.Rows(8)
Dim rngFound As Range
Set rngFound = rngRow.Find(What:="x")

Descobrir o que

Os dados a pesquisar. Pode ser uma cadeia de caracteres ou qualquer tipo de dados do Microsoft Excel. Alguns conselhos sobre valores de parâmetros adequados:

  • Ao pesquisar valores numéricos utilização Lookin:=xlFormulas e LookAt:=xlWhole
  • Ao pesquisar valores de data utilização Lookin:=xlFormulas e LookAt:=xlWhole. A data fornecida deve ser do tipo 25/02/2024 que pode ser obtido utilizando FormatDateTime(dtDate, vbGeneralDate)

Depois: célula de início da pesquisa

Se After tiver sido especificado, a pesquisa começa depois desta célula; a célula especificada não é pesquisada até o método voltar a esta célula.

O código abaixo inicia a pesquisa após a célula ativa, imitando a caixa de diálogo Localizar


Dim rngFound As Range
Set rngFound = ws.UsedRange.Find(What:="x", After:=ActiveCell)

LookIn: Fórmulas, valores, notas, comentários

Pode ser uma das seguintes constantes XlFindLookIn: xlFormulas (Fórmulas), xlValues (Valores), xlComments (Notas) ou xlCommentsThreaded (Comentários).


Dim rngFound As Range
Set rngFound = ActiveSheet.UsedRange.Find(What:="x", LookIn:=xlComments)

xlFormulas vs xlValues

A diferença entre Encontrar Fórmulas ou Valores pode ser observada experimentalmente. Coloque em A1 o valor x e em B1 a fórmula =A1. Na caixa de diálogo Procurar, prima Find All. Com a opção Fórmulas selecionada, apenas A1 é encontrado, enquanto que com a opção Valores, tanto A1 como B1 são encontrados.

Opções da caixa de diálogo Localizar
Diferença entre xlFormulas e xlValues

Ver: Corresponder todo o conteúdo da célula

Pode ser uma das seguintes constantes XlLookAt: xlWhole ou xlPart. Utilize xlWhole se precisar de encontrar uma célula com um texto específico.

Acrescente MatchCase:=True se for necessário encontrar uma correspondência exacta em range (sensível a maiúsculas e minúsculas).


Dim rngFound As Range
Set rngFound = ActiveSheet.UsedRange.Find(What:="x", LookAt:=xlWhole, MatchCase:=True)

Utilização de wildcards

No Excel, existe uma utilização limitada de caracteres curinga no argumento Localizar:

  • um ponto de interrogação (?) corresponde a um carácter se estiver dentro de uma cadeia;
  • colocar um ponto de interrogação no início ou no fim também corresponde se houver mais de 1 carácter.
  • Um asterisco (*) corresponde a qualquer série de caracteres.

Como exemplo, o código abaixo encontra qualquer célula que corresponda a "x".


Set rngFound = ActiveSheet.UsedRange.Find(What:="?x*")

O procedimento TestFindAll (parte inferior da página) ajuda-o a determinar que resultados podem ser esperados com determinados argumentos find. Ele escreve o Address do range na janela Immediate: $B$1:$C$1,$C$2

dados básicos para testar quais as células que correspondem aos critérios

SearchOrder: Linhas ou Colunas

Pode ser uma das seguintes constantes XlSearchOrder: xlByRows ou xlByColumns.

  • Pesquisar por coluna significa pesquisar primeiro todas as células da coluna A, depois da coluna B, etc.
  • Pesquisar por linha significa pesquisar primeiro todas as células da linha 1, depois da linha 2, etc.

Dim rngFound As Range
Set rngFound = ActiveSheet.UsedRange.Find(What:="x", SearchOrder:=xlByRows)

SearchDirection: Procurar próximo

A direção de pesquisa juntamente com SearchOrder determinará quais serão as células seguintes. A combinação abaixo mover-se-á para cima em colunas ascendentes, por exemplo, assumindo que a última célula de UsedRange é B6: B6, B5, B4...


Dim rngFound As Range
Set rngFound = ActiveSheet.UsedRange.Find(What:="x", SearchOrder:=xlByColumns, _
											SearchDirection:=xlPrevious)

Pesquisa de intervalo com vários critérios

Para encontrar células que correspondam a padrões mais complicados, pode utilizar uma instrução For Each...Next com:

  • o operador Like,
  • Aplicar testes booleanos combinados com E, Ou, etc.

Por exemplo, o seguinte código procura todas as células no range A1:C5 que utilizam um tipo de letra cujo nome comece com as letras Cour. Quando o Microsoft Excel encontra uma correspondência, ele altera a fonte para Times New Roman.


Dim rngCells As Range
Set rngCells = ActiveSheet.UsedRange.Cells
Dim rngCell As Range
Dim rngFound As Range
For Each rngCell In rngCells
	If rngCell.Font.Name Like "Cour*" Then
		Set rngFound = rngCell
		Exit For
	End If
Next rngCell	

PesquisarFormato: Formato...

Devolver células apenas com determinada formatação aplicada (tipo de letra, cor de fundo,...). O exemplo abaixo mostra que pode encontrar todas as células que têm uma cor de fundo utilizando uma cadeia vazia para o parâmetro What. Retire o comentário .Color = 65535 para obter as células marcadas a amarelo. Em alternativa, pode filtrar as células criadas Font.Bold ou outras propriedades da célula.


Sub Demo()
With Application.FindFormat
	.Clear
'    .Font.Bold = True
	With .Interior
		.Pattern = xlSolid
        '.Color = 65535 'rgbYellow 
	End With
End With
ActiveSheet.UsedRange.Find(After:=ActiveCell, What:="", SearchFormat:=True).Select
Application.FindFormat.Clear
End Sub

MatchByte: por exemplo, japonês e chinês

Utilizado apenas se tiver selecionado ou instalado o suporte de idioma de byte duplo. Verdadeiro para que os caracteres de byte duplo correspondam apenas a caracteres de byte duplo. Falso para que os caracteres de byte duplo correspondam aos seus equivalentes de byte único.


Autor: Mark Uildriks
Referência: Range.Find(Excel) | Microsoft Learn

Percorra as células utilizando Localizar e LocalizarSeguinte para obter vários resultados de pesquisa.

O método Range FindNext

Pode utilizar o método abaixo para repetir a pesquisa discutida anteriormente. FindNext/a> continua uma pesquisa que foi iniciada com o método Find. Encontra a célula seguinte que corresponde às mesmas condições e devolve um objeto Range que representa essa célula.

O código abaixo mostra um loop que continua até que a pesquisa esteja completa. Quando a pesquisa atinge o fim do intervalo de pesquisa especificado, volta ao início do intervalo. Para interromper uma pesquisa quando esta quebra ocorre, guarde o endereço da primeira célula encontrada, e, em seguida, teste cada endereço sucessivo de célula encontrada em relação a este endereço guardado.


Dim rngToSearch As Range: Set rngToSearch = ActiveSheet.UsedRange
Dim strWhat As String: strWhat = "test"
Dim rngFound As Range
Set rngFound = rngToSearch.Find(What:=strWhat)
If Not rngFound Is Nothing Then
	Dim FirstFoundCell As String
	FirstFoundCell = rngFound.Address
	Do
		Debug.Print rngFound.Address
		Set rngFound = rngToSearch.FindNext(After:=rngFound)
	Loop While FirstFoundCell <> rngFound.Address
End If

Tratamento de erros

Antes de continuar a pesquisa, o código acima evita o erro verificando se a variável foi instanciada: If Not rngFound Is Nothing Then. Se isso não for feito, mais cedo ou mais tarde quando aplicar alguns dos procedimentos da classe, o código deparar-se-á com o erro 91: Variável de objeto ou Com variável de bloco não definida.

O argumento After tem de ser uma única célula no intervalo. Caso contrário, obtém-se error 13: Type mismatch.

Um método Range FindAll

Não existe um método FindAll incorporado. Dito isto, com base no código acima, fornecemos uma função FindAll que devolve um range com todas as células que correspondem aos critérios de pesquisa e um procedimento para testar FindAll com diferentes definições, código abaixo.


Public Function FindAll(Range As Range, What As Variant, _
    Optional LookIn As XlFindLookIn = xlValues, _
    Optional LookAt As XlLookAt = xlWhole, _
    Optional SearchOrder As XlSearchOrder = xlByRows, _
    Optional MatchCase As Boolean = False) As Range
    Dim FoundCell As Range, FirstFound As Range, ResultRange As Range
    Dim LastCell As Range: Set LastCell = Range.Cells(Range.Cells.Count)
    Set FoundCell = Range.Find(What:=What, After:=LastCell, LookIn:=LookIn, LookAt:=LookAt, _
                                SearchOrder:=SearchOrder, MatchCase:=MatchCase)
    If Not FoundCell Is Nothing Then
        Set FirstFound = FoundCell
        Set ResultRange = FoundCell
        Set FoundCell = Range.FindNext(After:=FoundCell)
        Do Until (FoundCell.Address = FirstFound.Address)
            Set ResultRange = Application.Union(ResultRange, FoundCell)
            Set FoundCell = Range.FindNext(After:=FoundCell)
        Loop
    End If
    Set FindAll = ResultRange
End Function

Sub TestFindAll(What As Variant, _
                Optional LookIn As XlFindLookIn = xlValues, _
                Optional LookAt As XlLookAt = xlWhole, _
                Optional SearchOrder As XlSearchOrder = xlByRows, _
                Optional MatchCase As Boolean = False)
    Dim rngUsedRange As Range: Set rngUsedRange = ActiveSheet.UsedRange
    Dim rngSearchResults As Range
    Set rngSearchResults = FindAll(Range:=rngUsedRange, What:=What, LookIn:=LookIn, _
                            LookAt:=LookAt, SearchOrder:=SearchOrder, MatchCase:=MatchCase)
    Debug.Print rngSearchResults.Address
    rngSearchResults.Select
End Sub
ee

Experimente o suplemento do editor Code VBA