La fonction Excel RECHERCHEV est, à ce jour, la 3ème fonction la plus utilisée dans les classeurs Excel. Et vous êtes nombreux à se demander: "Comment reproduire RECHERCHEV en VBA?" Voici donc les explications et les codes VBA qui vous permettront d'utiliser cette fonction plus que pratique directement en VBA – qui n'a pas d'équivalent direct de cette fonction (comme vous pouvez le constater dans la Liste de toutes les fonctions VBA que je vous propose également).
Je me permets donc de vous proposer l'équivalent de la fonction RECHERCHEV en VBA, simple, efficace et prête à l'emploi (il vous suffit de la copier / coller dans votre projet) !
Sommaire
- Comment faire? Il faut passer par Application.WorksheetFunction
- Remarque importante: Solution à WorksheetFunction qui ne sait pas gérer les erreurs #N/A
- Equivalent complet de RECHERCHEV en VBA
- Exemple d'utilisation de la fonction RECHERCHEV en VBA
- Fonction améliorée: le choix de la colonne contenant la valeur à retourner
- Et question vitesse de RECHERCHEV en VBA? Mieux qu'un TGV!
- Pour aller plus loin en VBA…
Comment faire? Il faut passer par Application.WorksheetFunction
Il est finalement relativement simple d'accéder à RECHERCHEV – il faut pour cela passer par Application.WorksheetFunction
.
Si vous n'êtes pas familiers avec les WorksheetFunction
, vous pouvez en apprendre plus dans le tutoriel que j'ai fait à ce sujet (ou vous pouvez aussi visiter la page Microsoft dédiée). Sachez que ce n'est pas bien compliqué – faites juste attention au fait qu'il faut utiliser les noms ANGLAIS des fonctions Excel et pas les noms en français. L'équivalent anglais de RECHERCHEV est "VLOOKUP", c'est donc VLOOKUP
qu'il faudra évoquer dans le code VBA.
Astuce: Vous trouverez le nom anglais de n'importe quelle fonction Excel dans la Liste de toutes les fonctions Excel
Le code VBA officiel à utiliser a la forme suivante:
1 |
MonResultat = Application.WorksheetFunction.VLookup(Argument1, Argument2, Argument3, Argument4) |
Le petit bémol de la commande WorksheetFunction
est que dans l'éditeur VBA, vous ne verrez pas à quoi correspondent les arguments comme vous pouvez le voir directement dans Excel. Vous verrez uniquement le nombre d'arguments qui peuvent / doivent être utilisés ainsi que le fait s'ils sont obligatoires ou facultatifs…
Voici donc ce que vous verrez dans l'éditeur VBA:
Comme vous pouvez le constater, le Application.WorksheetFunction.VLookup
s'attends à 4 arguments dont 1 (le dernier) est facultatif. Et ceci correspond évidemment aux arguments de la fonction RECHERCHEV…
Il faut donc se souvenir quel argument correspond à quel valeur. Ou bien jeter un coup d’œil dans Excel – et cela est valable pas seulement pour RECHERCHEV mais pour toutes les fonctions Excel utilisées en VBA via WorksheetFunction
.
Remarque importante: Solution à WorksheetFunction qui ne sait pas gérer les erreurs #N/A
Je viens de découvrir que si l'on passe par Application.WorksheetFunction.VLookup
, le code VBA va bloquer si la valeur recherchée n'est pas trouvée. Là où la fonction RECHERCHEV d'Excel renvoie l'erreur #N/A
, le code VBA s'arrête et même la gestion d'erreur n'y fera rien.
MAIS… Il y a une solution. Et elle est même assez simple: j'ai trouvé qu'il était possible d'appeler la fonction VLookup directement à partir de Application.
sans passer par WorksheetFunction.
Et étonnamment, une valeur non trouvée ne bloque plus le code et la fonction sait la gérer correctement.
Les codes VBA qui suivent tiennent désormais compte de ce comportement.
Equivalent complet de RECHERCHEV en VBA
Pour pallier au désavantage cité plus haut, on peut réécrire le RECHERCHEV en VBA en tant que fonction complète. Le code est assez simple et concis.
1 2 3 4 5 6 7 8 9 10 11 |
Function RECHERCHEV(Valeur_Cherchee As Variant, Table_matrice As Range, No_index_col As Single, Optional Valeur_proche As Boolean) 'par Excel-Malin.com ( https://excel-malin.com/ ) On Error GoTo RECHERCHEVerror RECHERCHEV = Application.VLookup(Valeur_Cherchee, Table_matrice, No_index_col, Valeur_proche) If IsError(RECHERCHEV) Then RECHERCHEV = "#N/A" Exit Function RECHERCHEVerror: RECHERCHEV = "#N/A" End Function |
Quand vous allez appeler cette fonction dans l'éditeur VBA, elle se comportera exactement comme en Excel! C'est bien plus lisible et agréable à utiliser, vous ne trouvez pas?
Exemple d'utilisation de la fonction RECHERCHEV en VBA
Et voici un exemple de l'utilisation de la fonction RECHERCHEV – n'oubliez pas de copier dans votre projet non seulement cet exemple mais aussi la fonction dont le code se trouve plus haut.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Sub Exemple_d_utilisation_de_RECHERCHEV() 'par Excel-Malin.com ( https://excel-malin.com ) Dim MaValeur As Variant Dim MaPlage As Range Dim MaColonne As Single Dim ValeurProche As Boolean MaValeur = "x" Set MaPlage = ThisWorkbook.Sheets("Feuil1").Range("B:E") MaColonne = 4 ValeurProche = False MsgBox RECHERCHEV(MaValeur, MaPlage, MaColonne, ValeurProche) End Sub |
Remarque 1: n'oubliez pas de déclarer vos variables ( Dim ... As ...
) et d'attribuer la plage avec la table à utiliser ( Set ... = ...
)
Remarque 2: contrairement à Excel, la fonction en VBA retourne une valeur "fixe". C'est à dire que la fonction fait le calcul (recherche) avec les données qu'elle a à disposition au moment de son utilisation. Si les données changent, le résultat ne va pas s'adapter comme une fonction Excel. Cela a ses avantages et désavantages. Tout dépend la situation et de l'utilisation que vous en faites.
–> Si vous changez les données, il faudra recalculer. Par contre le fait d'avoir une valeur plutôt qu'une formule Excel rend votre fichier plus petit et plus rapide…
Fonction améliorée: le choix de la colonne contenant la valeur à retourner
Nous pouvons dévier de la fonction de base et la rendre plus efficace – c'est l'avantage de VBA de pouvoir adapter les fonctions selon ses besoins…
On peut imaginer que plutôt que le numéro de colonne à retourner, vous voudriez utiliser la lettre de la colonne – cela semble assez logique. Pas de problème! Et on peut même aller encore un peu plus loin: on peut avoir les deux dans une seule fonction! Soit vous pouvez utiliser l'index de la colonne (comme dans Excel) soit le nom de la colonne. La version suivante de la fonction va reconnaître vos intentions et retourner d'office le bon résultat!
Voici le code VBA de la fonction RECHERCHEV améliorée:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
Function RECHERCHEV(Valeur_Cherchee As Variant, Table_matrice As Range, Colonne_a_retourner As Variant, Optional Valeur_proche As Boolean) 'par Excel-Malin.com ( https://excel-malin.com ) On Error GoTo RECHERCHEVerror If IsNumeric(Colonne_a_retourner) = True Then RECHERCHEV = Application.VLookup(Valeur_Cherchee, Table_matrice, Colonne_a_retourner, Valeur_proche) Else Dim ColonneDebut As Single Dim ColonneRecherchee As Single ColonneDebut = Table_matrice.Cells(1).Column ColonneRecherchee = Range(Colonne_a_retourner & "1").Column Colonne_Index = ColonneRecherchee - ColonneDebut + 1 RECHERCHEV = Application.VLookup(Valeur_Cherchee, Table_matrice, Colonne_Index, Valeur_proche) End If If IsError(RECHERCHEV) Then RECHERCHEV = "#N/A" Exit Function RECHERCHEVerror: RECHERCHEV = "#N/A" End Function |
Cette fonction a donc deux fonctionnalités en ce qui concerne le choix de la colonne qui contient le résultat à renvoyer. Soit vous utilisez le n° de la colonne de la table comme dans Excel, soit vous indiquez le nom de la colonne (la lettre: par ex. "D" ou "BA").
Voici donc les exemples de l'utilisation de cette fonction améliorée:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Sub Exemple_d_utilisation_de_RECHERCHEV() 'par Excel-Malin.com ( https://excel-malin.com ) Dim MaValeur As Variant Dim MaPlage As Range Dim MaColonne As Variant Dim ValeurProche As Boolean MaValeur = "x" Set MaPlage = ThisWorkbook.Sheets("Feuil1").Range("B:E") MaColonne = 4 ValeurProche = False MsgBox RECHERCHEV(MaValeur, MaPlage, MaColonne, ValeurProche) 'avec le n° de la colonne - ici 4 (à partir de "B") donc colonne "E" MsgBox RECHERCHEV(MaValeur, MaPlage, "C", ValeurProche) 'ici, le résultat provient de la colonne "C" End Sub |
Comme vous pouvez voir, les deux fonctionnent!
Remarque: si vous voulez ajouter dans votre Projet VBA les deux fonctions, n'oubliez pas de changer le nom d'une d'elles car dans un Projet, il ne peut pas y avoir plusieurs fonctions avec le même nom…
Et question vitesse de RECHERCHEV en VBA? Mieux qu'un TGV!
Si vous vous demandez si cela vaut la peine d'utiliser RECHERCHEV en VBA plutôt que des boucles, soyez rassurés: RECHERCHEV est beaucoup plus rapide!
Je voulais en avoir le cœur net donc j'ai fait un test. Très simple: deux tableaux, tout deux avec 10.000 lignes. On recherche pour chaque ligne de la table A une valeur correspondante de la table B.
Et les résultats?
- deux boucles
For
…Next
imbriquées: 6 minutes 37 secondes - une boucle
For
…Next
avec la fonction RECHERCHEV: 0 minutes 5 secondes!
Le résultat est tout à fait sans appel! Donc oui, servez vous des fonctions Excel dès que vous le pouvez! Attention, le code avec les deux boucles fonctionnera dans toutes les applications de Office. Le code avec la fonction RECERCHEV ne fonctionnera que dans VBA d'Excel…
Voilà, j'espère que cette fonction vous sera utile et qu'elle va rendre votre travail encore plus efficace!Pour aller plus loin en VBA…
Voici quelques articles qui pourrait vous intéresser en relation avec le VBA, Excel, etc.
- Formation en ligne gratuite – "VBA: droit au but!"
- Liste de toutes les fonctions disponibles en VBA
- Différent manières d'effectuer une SOMME en VBA
- Envoyer un email avec VBA
- D'autres codes sources VBA prêts à l'emploi
- Tant que l'on parle de RECHECHEV, vous trouverez tout les détails su cette fonction dans le tutoriel sur la "recherche verticale"
- Et pour terminer, vous pouvez découvrir la nouvelle fonction Excel RECHERCHEX
19 commentaires sur “RECHERCHEV en VBA: Tutoriel et code VBA déjà prêt”
Bonjour,
c'est quoi le bug car il n'y a pas de resultat? 🙁
Sub rechechev()
Dim maplage As Range
Dim i, fin As Long
Set maplage = ThisWorkbook.Sheets("Feuil1").Range("a:b")
fin = Cells(Rows.Count, 1).End(xlUp).Row
For i = 1 To fin – 2
Cells(2 + i, 2) = Application.WorksheetFunction.VLookup(Cells(2 + i, 1).Value, maplage, 2, False)
Next i
End Sub
Bonjour Debutant,
je viens d'apprendre que
WorksheetFunction.VLookup
bloque sur l'erreur#N/A
.Essayez avec ce code:
cela devrait fonctionner…
Je vais modifier le contenu de ce tutoriel pour qu'il reflète ce comportement.
Cordialement, Martin
Bonjour,
J'utilise la fonction Vlookup à plusieurs reprises dans une boucle FOR i = 0 to xx ….NEXT et cela fonctionne très bien tant que la donnée cherchée est présente dans la colonne. Or, j'utilise le paramètre FAUX pour Valeur_proche car je ne veux que des valeurs exactes. Et, bien entendu, j'ai un message d'erreur "normal" (1004) si la valeur n'existe pas ! Pour traiter cette erreur, je voudrais simplement sauter les instructions suivantes jusqu'au NEXT puis continuer la boucle avec le i suivant…. Que mettre dans le On Error "traitement"….. et où le placer ?
Merci de votre aide.
Bonsoir Botanicus,
c'est le même problème que celui de "Debutant" plus haut.
Le problème est que dans ce cas précis, le
On Error
ne va pas fonctionner très bien.J'ai essayé plein de combinaisons pour pouvoir répondre à la question précédente.
Et ce qui marche le mieux, c'est d'utiliser
Application.VLookup
à la place deApplication.WorksheetFunction.VLookup
. Avec ce changement, la fonction renvoie le#N/A
classique et du coup, vous n'avez pas besoin de passer par la gestion d'erreurs.Je vais modifier mon tutoriel dans ce sens dès que j'ai un peu de temps.
Cordialement, Martin
Voilà, j'ai mis à jour le tutoriel et les codes VBA…
Bonjour,
Merci pour votre site et vos tutos très utiles.
J'ai une bête question, j'ai une colonne avec des numéro (d'ordre) et une avec des noms. j'aimerai faire une recherche sur le nom, et récupérer le numéro. j'ai essayé avec find et votre fonction recherchev, mais je n'y arrive pas. il faut savoir que mes colonnes sont dynamique et qu'elles augmentent (automatiquement) au fur et à mesure du travail sur ma feuille. Je suis également débutant en VBA. Si vous avez une solution, je suis preneur et vous remercie par avance. Bonne soirée.
Bonjour,
Merci pour votre site et vos tutos très utiles. j'y vais très régulièrement.
J'ai une bête question, j'ai une colonne avec des numéro (d'ordre) et une avec des noms. j'aimerai faire une recherche sur le nom, et récupérer le numéro. j'ai essayé avec find et votre fonction recherchev, mais je n'y arrive pas. il faut savoir que mes colonnes sont dynamique et qu'elles augmentent (automatiquement) au fur et à mesure du travail sur ma feuille. Je suis également débutant en VBA. Si vous avez une solution, je suis preneur et vous remercie par avance. Bonne soirée.
COMMENT FAIRE POUR RECHERCHER PLUSIEURS VALEURS POUR UNE SEULE RECHERCHE
Aide très précieuse ca a fonctionné du premier coup. Merci.
Bonjour,
J'ai trouvé votre code super utile pour un fichier sur lequel je travaille, cependant, est-il possible d'insérer ce code dans une userform ? et donc la valeur cherchée serait une entrée de la UserForm ? Merci d'avance
Bonjour,
Fonction super pratique. Par contre, je pense qu'il faudrait mieux gérer la valeur #N/A.
Pour l'affecter à une variable, il faut utiliser : CVErr(xlErrNA)
Pour la tester, il faut utiliser la fonction : Application.WorksheetFunction.IsNA(xxx)
En tout cas, merci pour ce bout de code
Merci pour ce contenu généreux, clair et opérationnel.
Vous souhaitant le plus grand plaisir dans votre action.
Cordialement.
Merci beaucoup. Cela fait plaisir de lire que mon travail est apprécié! Martin
Bonjour Excel-malin et surtout un grand merci pour cette fonction très utiles et rapide !
En plus du résultat de recherche, j'aimerais récupérer les coordonnées de cellule mais je ne trouve pas la bonne syntaxe…
ou du moins je ne sais pas ou l'intégrer (code ou fonction…)
Auriez-vous une idée ? En vous remerciant
J'utilise cette version de votre code avec la fonction "code amélioré" que vous proposer
MaValeur = REX
Set MaPlage = ThisWorkbook.Sheets(7).Range("A1:B5000")
MaColonne = 2
ValeurProche = False
TextBoxREX = RechercheV(MaValeur, MaPlage, MaColonne, ValeurProche)
merci
Bonjour Sebastien,
On peut utiliser la fonction
MATCH
. Voici le code:J'espère que cela répond à votre question.
Bàv, Martin
Bonjour et merci pour ce retour. oui cela fonctionne (en déclarant la variable "adresseREX"). Merci à vous !
Moi je déconseille l'utilisation de cette fonction sur une grosse volumétrie de données.
Il faut passer la déclaration d'un dictionnaire et ensuite interroger l'existence d'une correspondance.
exemple pour une feuille d'administration d'utilisateur :
Dim wKs As Worksheet
Dim sFichier As String, sFind As String
Dim iRow As Long
On Error GoTo GestionErr
Set wKs = ThisWorkbook.Worksheets("ADMIN")
Set DictUsers = New Scripting.Dictionary: iRow = 2
Do While wKs.Cells(iRow, 1).Value ""
' On ajoute dans le dictionnaire [DictUsers] le profil de tous les utilisateurs renseignés
If wKs.Cells(iRow, 4).Value = "Actif" And Not DictUsers.Exists(wKs.Cells(iRow, 1).Value) Then
DictUsers.Add CStr(wKs.Cells(iRow, 1).Value), wKs.Cells(iRow, 2).Value & "|" & wKs.Cells(iRow, 3).Value & _
"|" & wKs.Cells(iRow, 5).Value & "|" & wKs.Cells(iRow, 6).Value & "|" & wKs.Cells(iRow, 7).Value & _
"|" & wKs.Cells(iRow, 8).Value & "|" & wKs.Cells(iRow, 9).Value
End If
iRow = iRow + 1
Loop
Fin:
If Not wKs Is Nothing Then Set wKs = Nothing
Exit Sub
GestionErr:
Select Case Err.Number
Case Else
MsgBox "Erreur n°" & Err.Number & " : " & Err.Description, vbCritical, _
"Processus mémorisation dictionnaire users interrompu :"
End Select
Resume Fin
' Lecture des droits de l'utilisateur en cours
If DictUsers.Exists(LCase(Environ("UserName"))) Then
' On stock le prénom et le NOM de l'utilisateurs en cours dans une variable globale
sUser = Split(DictUsers.Item(LCase(Environ("UserName"))), "|")(0)
' On autorise les profils administrateurs à consulter et modifier les données de l'onglet 'ADMIN'
If Split(DictUsers.Item(LCase(Environ("UserName"))), "|")(1) = "Admin" Then
wKs.Visible = xlSheetVisible
End If
End If
Merci pour le cours
J'ai besoin d'aide. J'ai un fichier Excel, je veux faire une compilation additive. je prends les données d'un tableau que je colle dans la feuille "B" et dans la feuille "A" j'ai la compilation. Si j'ai "n" données, comment avoir le code VBA pour avoir la synthèse dans la feuille "A". J'ai le fichier , comment le joindre pour plus de compréhension.