Testé sur : Excel 365 v2509 · Excel 2021 · Excel 2019 · dernière vérification le 12/06/2026
En bref — Il existe deux façons d'appeler VLOOKUP (RECHERCHEV dans l'Excel français) depuis VBA, et la différence décide si une valeur absente fait planter votre macro. Application.WorksheetFunction.VLookup déclenche une erreur d'exécution quand la valeur n'est pas trouvée ; Application.VLookup (sans WorksheetFunction) renvoie une valeur d'erreur que vous testez avec IsError. Et dès que vous bouclez sur des milliers de lignes, la bonne réponse n'est généralement ni l'une ni l'autre — c'est un Dictionary.
Sub VLookupTwoWays()
Dim tbl As Range
Set tbl = Sheet1.Range("A:B")
' (1) WorksheetFunction — PLANTE (erreur 1004) si "Acme" est absent
Debug.Print Application.WorksheetFunction.VLookup("Acme", tbl, 2, False)
' (2) Application — renvoie une VALEUR D'ERREUR si introuvable, sans planter
Dim r As Variant
r = Application.VLookup("Ghost", tbl, 2, False)
If IsError(r) Then Debug.Print "introuvable" Else Debug.Print r
End Sub
Le modèle mental : VLOOKUP est une fonction de feuille en visite dans VBA
VLOOKUP a été conçu pour vivre dans une cellule. En l'appelant depuis VBA, vous empruntez une fonction de feuille — et ce prêt a deux conditions dont aucune formule de cellule ne vous avertit : son comportement quand la valeur est absente, et sa mauvaise montée en charge quand vous l'appelez dans une boucle. Gardez cette image, et les deux pièges de cet article cessent d'être des surprises.
La première question n'est donc pas « comment écrire VLOOKUP en VBA ? » — c'est la partie facile, une ligne. La vraie question est quel VLOOKUP, car VBA en expose deux au comportement d'erreur opposé, puis si vous devriez l'appeler tout court dès qu'une boucle entre en jeu.
La seule règle : WorksheetFunction.VLookup plante, Application.VLookup renvoie une erreur
C'est la distinction derrière le problème VBA VLOOKUP le plus signalé — la redoutable erreur d'exécution 1004 « Impossible de lire la propriété VLookup » :
Appelé via
WorksheetFunction, une valeur absente déclenche une erreur d'exécution qui stoppe net votre macro. Appelé directement viaApplication, une valeur absente revient comme une valeur d'erreur (du typeErreur 2042) que vous testez avecIsError— sans plantage.
Aucun n'est « correct » ; ce sont des outils pour deux situations. Utilisez WorksheetFunction quand une valeur absente est vraiment un bug et que vous voulez que la macro s'arrête (ou que vous l'avez enveloppée dans On Error). Utilisez Application.VLookup quand « introuvable » est un résultat normal et attendu que vous voulez gérer proprement.
' (A) WorksheetFunction + On Error — arrêter ou bifurquer sur une vraie erreur
Dim price As Double
On Error Resume Next
price = Application.WorksheetFunction.VLookup(code, tbl, 2, False)
If Err.Number <> 0 Then
price = 0 ' valeur par défaut, et on continue
Err.Clear
End If
On Error GoTo 0
' (B) Application.VLookup + IsError — le motif plus propre pour "peut être absent"
Dim res As Variant
res = Application.VLookup(code, tbl, 2, False)
If IsError(res) Then price = 0 Else price = res
Le motif (B) se lit mieux et ne détourne pas la gestion d'erreur pour un flux de contrôle ordinaire — privilégiez Application.VLookup chaque fois qu'un échec est attendu. (Voir VBA On Error pour comprendre pourquoi un On Error Resume Next dispersé est un fardeau.)
Le piège qui coûte vraiment : VLOOKUP dans une boucle est en O(n²)
Voici celui que les tutoriels sautent. Un seul VLOOKUP parcourt la colonne de recherche jusqu'à trouver une correspondance. Placez cet appel dans une boucle sur vos lignes, et vous reparcourez toute la colonne à chaque itération :
' ⚠ LENT — 10 000 lignes, chacune cherchant dans une table de 10 000 lignes.
' Jusqu'à 100 000 000 de comparaisons, et il relit la feuille à chaque passage.
Dim i As Long
For i = 2 To 10000
Cells(i, "C").Value = Application.WorksheetFunction.VLookup( _
Cells(i, "A").Value, Sheet2.Range("A:B"), 2, False)
Next i
C'est un travail quadratique, et sur de vraies données cela transforme « pourquoi ma macro est figée ? » en pause-café de plusieurs minutes. Le nombre de comparaisons croît avec le carré du nombre de lignes — doublez les lignes, quadruplez l'attente.
La solution est d'arrêter de chercher en boucle. Lisez la table de recherche une fois dans un Dictionary — c'est une table de hachage, donc chaque accès est en O(1) au lieu de O(n) — et tout le travail devient linéaire :
Sub LookupAvecDictionary()
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
' Lire les deux colonnes en mémoire en UN coup — voir VBA Array, pourquoi ça compte
Dim lookup As Variant
lookup = Sheet2.Range("A2:B10000").Value
Dim i As Long
For i = 1 To UBound(lookup, 1)
dict(lookup(i, 1)) = lookup(i, 2) ' clé = colonne A, valeur = colonne B
Next i
' Lire les clés, résoudre en mémoire, réécrire en UN coup
Dim keys As Variant, out() As Variant, n As Long
keys = Sheet1.Range("A2:A10000").Value
n = UBound(keys, 1)
ReDim out(1 To n, 1 To 1)
For i = 1 To n
If dict.Exists(keys(i, 1)) Then out(i, 1) = dict(keys(i, 1)) Else out(i, 1) = "n/a"
Next i
Sheet1.Range("C2").Resize(n, 1).Value = out ' une écriture, pas 10 000
End Sub
Même résultat, mais il lit la feuille deux fois au lieu de 20 000, et la correspondance est par hachage. Sur 10 000 lignes, c'est la différence entre « instantané » et « va chercher un café ». (L'autre moitié du gain — lire et écrire des tableaux en un coup plutôt que cellule par cellule — est une habitude à part qui en vaut la peine.)
Quand utiliser quoi
| Votre situation | Utilisez | Pourquoi |
|---|---|---|
| Recherche unique, la valeur doit toujours exister | WorksheetFunction.VLookup |
Un échec est un bug — laissez-le se déclencher |
| Recherche unique, la valeur peut manquer | Application.VLookup + IsError |
Gérer « introuvable » sans On Error |
| Rechercher beaucoup de lignes dans une table | Un Dictionary construit une fois | O(1) au lieu de O(n) par recherche |
| Vous voulez la position de ligne, pas une valeur | Application.Match |
VLOOKUP ne renvoie pas d'adresse |
| La colonne de recherche est à gauche du résultat | Index/Match ou un Dictionary |
VLOOKUP ne regarde qu'à droite |
L'opinion : si vous appelez VLOOKUP dans une boucle, vous voulez en fait un Dictionary
La ligne que je défends : VLOOKUP appartient aux cellules, pas aux boucles. Appeler une fonction de feuille une fois depuis VBA pour récupérer une seule valeur est tout à fait bien. Dès qu'elle est dans une boucle For sur vos données, vous avez demandé à une opération conçue pour une recherche de reparcourir une colonne des milliers de fois — et vous le sentirez.
Le réflexe « prends juste VLOOKUP, je connais » est exactement ce qui garde les macros lentes. Le geste professionnel est de reconnaître la forme du problème : beaucoup de recherches dans une table, c'est à cela que sert un Dictionary. Construisez la table en mémoire une fois, résolvez chaque ligne contre elle, réécrivez les réponses d'un coup. Votre macro passe de quadratique à linéaire, et le code pour le faire est plus court que la gestion d'erreur que vous enrouleriez sinon autour d'un VLOOKUP en boucle.
Erreurs courantes de VBA VLOOKUP (et la solution)
| Symptôme | Cause | Solution |
|---|---|---|
| Erreur 1004 « Impossible de lire la propriété VLookup » | WorksheetFunction.VLookup n'a pas trouvé la valeur |
Application.VLookup + IsError, ou envelopper dans On Error |
| La macro se fige sur de grandes données | VLOOKUP appelé dans une boucle de lignes (O(n²)) | Construire un Dictionary une fois, résoudre en mémoire |
| Renvoie la mauvaise valeur | 4ᵉ argument omis → correspondance approximative par défaut | Toujours passer False pour une correspondance exacte |
#N/A alors que la valeur est là |
La colonne de recherche a des espaces / Chr(160) en fin |
Nettoyer la clé d'abord — voir VBA Trim |
| Impossible de chercher vers la gauche | VLOOKUP ne cherche que dans la première colonne, vers la droite | Index/Match ou un Dictionary |
| Incompatibilité de type au stockage | Le résultat peut être une valeur d'erreur | Stocker dans un Variant, tester IsError avant usage |
Quand les recherches s'accumulent — décrivez plutôt le rapprochement
Vous ne vouliez pas d'un débat WorksheetFunction contre Application. Vous vouliez « rapprocher l'export de ce mois de ma liste de prix et signaler les codes qui n'existent pas ». Le temps de choisir le bon VLOOKUP, de protéger les échecs et de réécrire la boucle en Dictionary pour qu'elle finisse avant la fin de la décennie, la plomberie est la macro. ExcelMaster Agent vous laisse décrire le rapprochement en français clair — « cherche chaque code de la colonne A dans la feuille de prix, mets le prix en C et liste ceux sans correspondance » — et écrit du Python qui fait tout en une passe, en sauvegardant d'abord votre classeur. Essayer gratuitement →
Guides associés
- VBA Dictionary — des recherches O(1) en mémoire
- VBA Array — lire et écrire une plage en un coup
- VBA Copy Paste — éviter le presse-papiers pour des macros plus rapides
- VBA On Error — Resume Next vs GoTo & pourquoi les macros cachent les bugs
- VBA boucle For dans Excel — 8 exemples concrets
FAQ
Comment utiliser VLOOKUP en VBA ?
Appelez-le via l'objet application : Application.WorksheetFunction.VLookup(valeurCherchée, plageTable, indiceColonne, False). Passez toujours False comme quatrième argument pour une correspondance exacte. Si la valeur peut manquer, utilisez plutôt Application.VLookup (sans WorksheetFunction) et testez le résultat avec IsError, pour qu'un échec renvoie une valeur d'erreur au lieu de faire planter la macro.
Pourquoi VBA VLOOKUP donne l'erreur d'exécution 1004 ?
Parce que vous l'avez appelé via WorksheetFunction et que la valeur n'a pas été trouvée — cette voie déclenche une erreur au lieu de renvoyer #N/A. Soit enveloppez l'appel dans On Error Resume Next et vérifiez Err.Number, soit utilisez Application.VLookup, qui renvoie une valeur d'erreur testable que vous gérez avec If IsError(résultat).
Quelle est la différence entre Application.VLookup et WorksheetFunction.VLookup ?
Ils font la même recherche mais échouent différemment. WorksheetFunction.VLookup déclenche une erreur d'exécution si rien ne correspond ; Application.VLookup renvoie une valeur d'erreur (comme Erreur 2042) que vous testez avec IsError. Utilisez WorksheetFunction quand un échec est un vrai bug, et Application quand « introuvable » est attendu.
VLOOKUP est-il lent en VBA ?
Un seul appel est correct. L'appeler dans une boucle sur de nombreuses lignes est lent car chaque appel reparcourt la colonne de recherche, et le travail croît avec le carré du nombre de lignes. Pour de nombreuses recherches, chargez la table dans un Scripting.Dictionary une fois et résolvez chaque ligne en O(1) — bien plus rapide sur de grandes données.
VBA VLOOKUP peut-il chercher une valeur dans une autre feuille ?
Oui — qualifiez la plage de la table avec la feuille : Application.WorksheetFunction.VLookup(clé, Worksheets("Prix").Range("A:B"), 2, False). Utilisez une référence pleinement qualifiée Worksheets("nom").Range(...) pour que la recherche ne lise pas par accident la feuille active.
