🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA Mid, Left & Right dans Excel — Extraire une sous-chaîne par position

|

VBA Mid, Left & Right dans Excel — Extraire une sous-chaîne par position

Testé sur : Excel 365 v2509 · Excel 2021 · Excel 2019 · dernière vérification le 09/06/2026

En brefMid, 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 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 = 1 dé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

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.