Testé sur : Excel 365 v2509 · Excel 2021 · Excel 2019 · dernière vérification le 09/06/2026
En bref — Mid, Left et Right tirent un morceau d'une chaîne par position — un point de départ et une longueur. Left et Right ne sont que Mid épinglé à une extrémité :
Sub SliceDemo()
Dim s As String
s = "INV-2026-0042"
Debug.Print Left(s, 3) ' INV <- les 3 premiers caractères
Debug.Print Right(s, 4) ' 0042 <- les 4 derniers caractères
Debug.Print Mid(s, 5, 4) ' 2026 <- 4 caractères à partir de la position 5
Debug.Print Mid(s, 5) ' 2026-0042 <- sans longueur = jusqu'à la fin
End Sub
Une chose à mémoriser avant tout : les chaînes VBA commencent à la position 1, pas 0.
Le modèle mental : couper à la règle, pas selon le contenu
Mid est une règle. Vous lui dites où commencer et combien de caractères prendre, et il coupe. Il ne regarde pas ce que sont les caractères — il compte des positions. Left(s, n) est « la règle depuis le début », Right(s, n) « la règle depuis la fin », et Mid(s, start, len) est le cas général dont les deux autres sont des raccourcis.
Cette seule idée vous dit exactement quand ils sont le bon outil et quand non. Ils brillent quand ce que vous cherchez se trouve à une position fixe et connue — un préfixe de 3 lettres, les 4 derniers chiffres, une colonne à largeur fixe. Ils s'effondrent dès que le morceau peut se déplacer, car une règle ne s'adapte pas. C'est toute la tension de cet article, et la raison d'être de InStr et Split.
La règle d'or : indexé à partir de 1, et ce décalage est le bug n°1
En venant de presque tout autre langage, vos doigts tapent des positions à partir de 0. VBA ne fonctionne pas ainsi :
Dans
Mid(string, start, length),start = 1désigne le premier caractère.Mid("Excel", 1, 2)vaut"Ex", pas"xc".
Trompez-vous et vous n'obtenez pas d'erreur — vous obtenez les mauvais caractères, décalés d'un, ce qui est bien pire qu'un plantage car cela paraît plausible :
Debug.Print Mid("Excel", 1, 2) ' "Ex" (correct — 1 est le premier caractère)
Debug.Print Mid("Excel", 0, 2) ' erreur d'exécution 5 — la position 0 n'existe pas
Debug.Print Mid("Excel", 2, 2) ' "xc" (départ au 2e caractère)
La règle compagne : Mid sans longueur renvoie tout depuis start jusqu'à la fin. Ce n'est pas un bug à contourner — c'est la façon la plus propre de dire « le reste de la chaîne à partir d'ici » :
extension = Mid(filename, InStrRev(filename, ".") + 1) ' tout ce qui suit le dernier point
Ce que presque personne ne sait : Mid est aussi une instruction
Il y a deux Mid. La fonction lit des caractères. L'instruction écrit des caractères sur place — elle écrase une partie de la chaîne sans en changer la longueur :
Dim s As String
s = "2026-00-15"
Mid(s, 6, 2) = "06" ' écraser 2 caractères à partir de la position 6
Debug.Print s ' "2026-06-15" <- même longueur, corrigé sur place
Mid(s, 6, 2) = "06" à gauche d'un = est l'instruction. Elle est plus rapide que de reconstruire la chaîne avec Left & nouveau & Right, et c'est la manière idiomatique de corriger un champ à largeur fixe. Le piège, cohérent avec le modèle mental : elle ne change jamais la longueur — affectez un remplacement plus long et VBA le tronque simplement à la fenêtre. La règle ne s'étire pas.
La famille Left/Right/Mid en un bloc
Left(s, n) ' les n premiers caractères
Right(s, n) ' les n derniers caractères
Mid(s, start) ' de start jusqu'à la fin
Mid(s, start, len) ' len caractères à partir de start
Len(s) ' nombre total de caractères (pour borner les découpes)
Left et Right ne sont pas des idées distinctes — ce sont Mid avec une coordonnée fixée. Left(s, n) vaut Mid(s, 1, n). Right(s, n) vaut Mid(s, Len(s) - n + 1). Une fois Mid assimilé, les deux autres sont offertes.
L'avis : les positions codées en dur sont la ligne la plus fragile de votre macro
Mid(s, 5, 4) se lit à merveille sur la seule ligne que vous avez testée. Puis une valeur arrive un caractère plus courte, chaque position se décale, et votre extraction de l'« année » renvoie désormais "026-". Les découpes par position encodent une hypothèse — les données ont toujours exactement la forme de mon échantillon — que les vraies données brisent à la première occasion.
Ma règle : n'utilisez Left/Right/Mid que lorsque la position est réellement fixe — un format que vous maîtrisez, un export à largeur fixe, un code à disposition garantie. Dès que la frontière dépend du contenu (le texte avant le premier espace, la partie après le tiret, le bout entre deux repères), cessez de coder des nombres en dur. Trouvez la frontière avec InStr et passez-la à Mid, ou utilisez Split s'il y a un délimiteur propre :
' Fragile : suppose que le tiret est toujours en position 4
code = Left(s, 3)
' Robuste : trouver le tiret, couper là — fonctionne quelle que soit la longueur
code = Left(s, InStr(s, "-") - 1)
La seconde version fait une fonction de plus et survit au contact du réel. Cet échange en vaut presque toujours la peine.
Quand utiliser quoi
| Vous voulez… | Utilisez | Attention à |
|---|---|---|
| Les N premiers caractères | Left(s, n) |
N supérieur à Len(s) renvoie juste toute la chaîne (sans risque) |
| Les N derniers caractères | Right(s, n) |
Pareil — pas d'erreur si N est trop grand |
| N caractères depuis une position fixe | Mid(s, start, n) |
start part de 1 ; start = 0 lève une erreur |
| Tout à partir d'une position | Mid(s, start) |
Omettre entièrement l'argument de longueur |
| Écraser des caractères sur place | Mid(s, start, n) = "…" |
Ne change jamais la longueur — le surplus est jeté |
| Un morceau dont la position peut bouger | InStr + Mid, ou Split |
Ne pas coder le nombre en dur |
Erreurs fréquentes avec Mid/Left/Right (et la solution)
| Symptôme | Cause | Solution |
|---|---|---|
| Résultat décalé d'un caractère | start traité comme base 0 |
start = 1 est le premier caractère |
| « Argument ou appel de procédure incorrect » (erreur 5) | Mid(s, 0, …) ou longueur négative |
start ≥ 1, longueur ≥ 0 |
| L'extraction casse sur les valeurs plus courtes | Position codée en dur Mid(s, 5, 4) |
Localiser d'abord la frontière avec InStr |
| L'instruction Mid n'a pas rallongé la chaîne | C'est voulu — elle écrase sur place | Reconstruire avec Left & nouveau & Right pour changer la longueur |
Toute la chaîne renvoyée par Left(s, 50) |
N a dépassé la longueur | Comportement attendu ; borner avec Len(s) au besoin |
Quand la logique de découpe prend le dessus — décrivez le résultat
Extraire le numéro de facture d'une cellule, c'est deux lignes. L'extraire de 40 000 lignes qui arrivent en trois formats légèrement différents — certaines avec le tiret, d'autres sans, d'autres avec un préfixe en trop — c'est un enchevêtrement de InStr, Mid, vérifications de longueur et solutions de repli qui enterre l'intention réelle. ExcelMaster Agent vous laisse dire « extrais l'année à 4 chiffres du code de facture, quel que soit le format autour » et génère du Python qui gère les variantes et sauvegarde d'abord votre classeur — sans décalage d'indice, sans position codée en dur. Essayez gratuitement →
Guides associés
- VBA Split — Découper une chaîne en tableau
- VBA Replace — Remplacer du texte & les pièges de ses arguments
- VBA InStr — Trouver du texte dans une chaîne
- Boucle For en VBA — 8 exemples concrets
FAQ
Quelle est la différence entre Mid, Left et Right en VBA ?
Les trois extraient une sous-chaîne par position. Left(s, n) prend les n premiers caractères, Right(s, n) les n derniers, et Mid(s, start, len) prend len caractères à partir de start. Left et Right sont des cas particuliers de Mid épinglés à une extrémité de la chaîne.
VBA Mid est-il indexé à 0 ou à 1 ?
À 1. Mid("Excel", 1, 2) renvoie "Ex" — la position 1 est le premier caractère. Utiliser 0 comme départ lève l'erreur d'exécution 5. Ce décalage d'indice est le bug Mid le plus courant pour qui vient de langages indexés à 0.
Comment obtenir tout à partir d'une position avec Mid ?
Omettez l'argument de longueur : Mid(s, start) renvoie la sous-chaîne de start jusqu'à la fin. Combiné à InStr, Mid(s, InStr(s, "-") + 1) vous donne tout ce qui suit le premier tiret.
Qu'est-ce que l'instruction Mid en VBA ?
Mid(s, start, length) = "texte" à gauche d'une affectation écrase des caractères sur place, sans changer la longueur de la chaîne. Plus rapide qu'une reconstruction, idéale pour corriger des champs à largeur fixe — mais un remplacement plus long que la fenêtre est tronqué.
Pourquoi mon extraction Mid est-elle fausse sur certaines lignes ?
Presque toujours une position codée en dur qui suppose que chaque valeur a la même longueur. Quand la frontière dépend du contenu plutôt que d'un décalage fixe, trouvez-la avec InStr et passez-la à Mid, ou utilisez Split s'il y a un délimiteur.
