Comment faire une recherche après une cellule ?

Mastering Excel: Finding Values with VBA

17/01/2009

Rating: 4.17 (15619 votes)

In the realm of data management and analysis, precisely locating specific information within large datasets is paramount. Microsoft Excel, with its robust features, offers powerful tools for this task. When dealing with extensive spreadsheets, especially those with numerous rows and columns, manually sifting through data can be incredibly time-consuming and prone to error. This is where Visual Basic for Applications (VBA) comes into play, providing automated solutions to streamline these processes. This article will delve into how you can leverage VBA to effectively search for values within a column, exploring various methods to pinpoint your desired data with accuracy and speed.

Comment rechercher une chaîne où une valeur dans une colonne ?
Cet article présente trois techniques pour rechercher une chaîne ou une valeur dans une colonne. La valeur return est le numéro de ligne où se trouve la chaîne cible. Techniques de recherche de chaînes : Pour tout l’article, cette fiche virtuelle sera la fiche de référence. Valeurs de la feuille 1 : | A | B | C | D |
Table

Navigating Columns with Range.Find and Range.FindNext

One of the most efficient ways to search through a column in VBA is by utilising the Range.Find method in conjunction with Range.FindNext. This powerful combination allows you to iterate through a specified range of cells and identify all occurrences of a particular value or string. The Find method initiates the search, and FindNext continues it, ensuring that no instance is missed.

Consider a scenario where you need to locate all instances of the word "Overdue" within a specific column and highlight them. The following VBA code snippet demonstrates how to achieve this:

Sub FindLoop() Dim strFirstAddress As String Dim rngFindValue As Range Dim rngSearch As Range Dim rngFind As Range ' Define the range to search within (e.g., Column F, rows 1 to 17) Set rngFind = ActiveSheet.Range("F1:F17") ' Set the starting point for the search (the cell after the last cell in the range) Set rngSearch = rngFind.Cells(rngFind.Cells.Count) ' Perform the initial search for "Overdue" Set rngFindValue = rngFind.Find("Overdue", rngSearch, xlValues) ' Check if the value was found If Not rngFindValue Is Nothing Then ' Store the address of the first found cell strFirstAddress = rngFindValue.Address ' Change the font color to red for the found cell rngFindValue.Font.Color = vbRed ' Loop to find subsequent occurrences Do Set rngFindValue = rngFind.FindNext(rngFindValue) ' Change the font color to red for subsequent found cells rngFindValue.Font.Color = vbRed Loop While rngFindValue.Address <> strFirstAddress End If End Sub 

When this code executes, it first searches for the specified value. Upon finding the first match, it records its address in the strFirstAddress variable and then changes the font colour of that cell to red. A Do...Loop structure is then employed to search for subsequent occurrences. Each time the word "Overdue" is found, its text colour is updated to red. The loop continues until the search wraps around and encounters the initial found cell again, thus preventing an infinite loop and ensuring all instances within the defined range have been processed.

Searching for Substrings within a Column

While the Find method is excellent for exact matches, often you need to find a string that might be a part of a larger text in a cell. Standard string functions like Instr(), CStr(), and Split() are typically used for single strings. However, when working with cells in Excel, you need methods that can handle ranges. VBA provides several effective techniques for this:

1. Using the Find() Function for Substrings

The Range.Find method is versatile and can be configured to search for partial matches. By setting the LookAt parameter to xlPart, you instruct Excel to find the specified text even if it's only a part of the cell's content.

Let's illustrate this with a function that returns the row number of a found string:

Function SearchStr(str As String) As Range Dim wb As Workbook Dim s1 As Worksheet Dim rng As Range Set wb = ThisWorkbook Set s1 = wb.Sheets("Sheet1") ' Assuming your data is on Sheet1 Set rng = s1.Columns("A:A") ' Specify the column to search ' Perform the search, looking for the string as part of the cell content Set SearchStr = rng.Find(What:=str, LookIn:=xlFormulas, LookAt:=xlPart, MatchCase:=False) End Function Sub BananaSearch() If SearchStr("Banana") Is Nothing Then Debug.Print "Not in range." Else Debug.Print "Found at row: " & SearchStr("Banana").Row End If End Sub Sub MelonSearch() If SearchStr("Melon") Is Nothing Then Debug.Print "Not in range." Else Debug.Print "Found at row: " & SearchStr("Melon").Row End If End Sub 

If "Banana" is found in column A, BananaSearch will output its row number. If "Melon" is not present, it will report "Not in range." This method is highly effective for finding partial matches within a designated column.

2. Using the Match() Function

The Application.Match function offers a different approach, primarily returning the relative position of an item within a range that matches a specified value. Unlike Find(), which returns a Range object, Match() returns a number indicating the position.

Here's how you can use Match() to find a number in a column:

Function SearchNum(IntToSearch As Integer) As Variant Dim wb As Workbook Dim s1 As Worksheet Set wb = ThisWorkbook Set s1 = wb.Sheets("Sheet1") ' Assuming your data is on Sheet1 ' Use Application.Match for an exact match (MatchType = 0) If Not IsError(Application.Match(IntToSearch, s1.Columns("B:B"), 0)) Then SearchNum = Application.Match(IntToSearch, s1.Columns("B:B"), 0) Else SearchNum = "Not Found" End If End Function Sub LookForSix() Debug.Print "A match is located at row " & SearchNum(6) End Sub Sub LookForZero() Debug.Print "A match is located at row " & SearchNum(0) End Sub 

The SearchNum function attempts to find the integer provided in column B. The third argument, 0, specifies an exact match. If the number 6 is found in column B, LookForSix will output its row number. If 0 is not found, LookForZero will indicate "Not Found".

3. Using Loops for Iteration

While Find() and Match() are efficient, using loops offers greater control and flexibility, especially when you need to perform actions on multiple matches or when the search criteria are more complex. A loop iterates through each cell in a specified range, allowing you to check conditions and execute code accordingly. However, be mindful that for very large datasets, loops can be slower than built-in functions like Find().

The following example demonstrates how to find all occurrences of "Mexico" in column C and return their row numbers:

Function GetAllRows(str As String) As Object Dim wb As Workbook Dim s1 As Worksheet Set wb = ThisWorkbook Set s1 = wb.Sheets("Sheet1") ' Assuming your data is on Sheet1 Dim coll As Object Set coll = CreateObject("System.Collections.ArrayList") ' To store multiple results Dim i As Long Dim lrow As Long ' Determine the last row with data in column C lrow = s1.Cells(s1.Rows.Count, 3).End(xlUp).Row ' Loop through each row in column C For i = 1 To lrow If s1.Cells(i, 3) = str Then ' Add the row number to the ArrayList if a match is found coll.Add (i) End If Next i Set GetAllRows = coll End Function Sub FindForMexico() Dim coll2 As Object Set coll2 = GetAllRows("Mexico") Dim j As Integer For j = 0 To coll2.Count - 1 Debug.Print "A match is found in row: " & coll2(j) Next j End Sub 

The GetAllRows function iterates through column C, identifying all rows containing "Mexico" and storing their numbers in an ArrayList. The FindForMexico subroutine then calls this function and prints each found row number. This approach is particularly useful when you need to collect all matching row indices.

Comment rechercher un mot dans une cellule ?
Lorsqu'il trouve le mot, il marque la cellule en changeant la couleur du texte de la cellule en rouge. Il utilisera ensuite la méthode Range.FindNext pour passer à la cellule suivante et continuer à rechercher le mot, en poursuivant la boucle jusqu'à la fin de la plage de cellules spécifiée.

Searching Across Multiple Columns

Sometimes, your search needs to extend beyond a single column. You might need to find a value across an entire row, multiple columns, or even the whole worksheet. The looping technique can be adapted for this purpose by nesting loops to cover both rows and columns.

This function searches the entire worksheet for a specific value and returns the row and column of each match:

Function GetAllRowsFromSheet(str As String) As Object Dim wb As Workbook Dim s1 As Worksheet Set wb = ThisWorkbook Set s1 = wb.Sheets("Sheet1") ' Assuming your data is on Sheet1 Dim coll As Object Set coll = CreateObject("System.Collections.ArrayList") Dim i, j As Long Dim lrow, lcol As Long ' Determine the last row and last column with data lrow = s1.Cells(s1.Rows.Count, 3).End(xlUp).Row lcol = s1.Cells(1, s1.Columns.Count).End(xlToLeft).Column ' Loop through each column For j = 1 To lcol ' Loop through each row within the current column For i = 1 To lrow If s1.Cells(i, j) = str Then ' Add the row and column number to the ArrayList coll.Add ("Row :" & i & " Column: " & j) End If Next i Next j Set GetAllRowsFromSheet = coll End Function Sub FindFor3() Dim coll2 As Object Set coll2 = GetAllRowsFromSheet(3) ' Search for the value 3 Dim j As Integer For j = 0 To coll2.Count - 1 Debug.Print "A match is found in " & coll2(j) Next j End Sub 

The GetAllRowsFromSheet function iterates through every cell in the worksheet, looking for the specified value. It records the row and column for each match. The FindFor3 subroutine demonstrates how to use this function to find all occurrences of the number 3, printing their locations. This is invaluable for comprehensive data audits.

Understanding the Range.Find Parameters

The Range.Find method has several optional parameters that allow you to fine-tune your search:

Syntax:

expression.Find (What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat) 
ParameterRequired/OptionalData TypeDescription
WhatRequiredVariantThe data to search for. Can be a string or any other Microsoft Excel data type.
AfterOptionalVariantThe cell after which you want to start the search. This corresponds to the active cell's position when a search is performed from the user interface. 'After' must be a single cell within the range. The search begins after this cell; the specified cell is not included in the search until the method wraps around the specified cell range. If omitted, the search begins after the top-left cell of the range.
LookInOptionalVariantCan be one of the XlFindLookIn constants: xlFormulas, xlValues, xlComments, or xlCommentsThreaded.
LookAtOptionalVariantCan be one of the following XlLookAt constants: xlWhole or xlPart.
SearchOrderOptionalVariantCan be one of the following XlSearchOrder constants: xlByRows or xlByColumns.
SearchDirectionOptionalVariantCan be one of the following XlSearchDirection constants: xlNext or xlPrevious.
MatchCaseOptionalVariantTrue to make the search case-sensitive. Default is False.
MatchByteOptionalVariantUsed only if you have selected or installed support for double-byte language. True to have double-byte characters match only double-byte characters. False to have double-byte characters match their single-byte character equivalents.
SearchFormatOptionalVariantThe format of the search.

It's crucial to note that the settings for LookIn, LookAt, SearchOrder, and MatchByte are remembered by Excel after you use the Find method. If you omit these arguments in subsequent calls, Excel will use the previously saved values. To avoid unexpected behaviour, it's best practice to explicitly define these arguments every time you use the Find method.

Best Practices and Considerations

  • Specify Your Range: Always define the exact range you want to search. Searching entire worksheets can be slow if not necessary.
  • Use FindNext Correctly: When using FindNext, ensure you have a mechanism to stop the loop once all occurrences have been found. Storing the first found address and comparing subsequent found addresses against it is a common and effective technique.
  • Error Handling: Implement error handling (e.g., checking if a Find operation returns Nothing) to gracefully manage situations where the searched value is not present in the range.
  • Performance: For extremely large datasets, consider the performance implications of using loops versus the Find method. The Find method is generally more optimised for speed.
  • Clarity: Name your variables descriptively and add comments to your VBA code to make it understandable and maintainable.

Frequently Asked Questions

Q1: How do I find all occurrences of a value in a column using VBA?

A1: You can use the Range.Find method in a loop. Start with Find to locate the first instance, then use FindNext repeatedly. Store the address of the first found cell and exit the loop when FindNext returns the same address.

Q2: Can VBA find a partial string within a cell?

A2: Yes, by setting the LookAt argument of the Range.Find method to xlPart.

Q3: What's the difference between Range.Find and Application.Match?

A3: Range.Find returns a Range object representing the found cell, while Application.Match returns the relative position (row or column number) of the match within the specified range.

Q4: Is it better to use loops or Range.Find for searching?

A4: For simple searches and performance, Range.Find is generally preferred. Loops offer more flexibility for complex criteria or when you need to perform multiple actions on each found item, but can be slower on large datasets.

By mastering these VBA techniques, you can significantly enhance your efficiency when working with Excel, transforming tedious manual searches into automated, reliable processes. Whether you're tracking overdue payments, locating specific product codes, or analysing complex data patterns, VBA provides the tools to search and find with precision.

If you want to read more articles similar to Mastering Excel: Finding Values with VBA, you can visit the Automotive category.

Go up