TL;DR —
Application.Run "MacroName", arg1, arg2exécute une macro que vous nommez par une chaîne : c'est donc le code qui décide quelle macro lancer pendant qu'il s'exécute, et non au moment où vous l'écrivez. Utilisez-le comme instruction (sans parenthèses) ou capturez la valeur de retour d'uneFunctionavecx = Application.Run("MyFunc", 5). Le piège : le nom est du texte, donc une faute de frappe donne une erreur d'exécution 1004, pas un soulignement rouge à la compilation. Sortez-le du tiroir quand le nom de la macro n'est connu qu'à l'exécution — une table d'aiguillage, un nom dans une cellule, un plugin. Si vous connaissez déjà la macro, appelez-la directement.
Sub RunByName()
' Choisit le nom de la macro a l'execution, puis la lance
Dim macroName As String
macroName = Range("Config!B2").Value ' par ex. "BuildMonthlyReport"
Application.Run macroName, Date, "Finance" ' passe les arguments par position
End Sub
La plupart du temps, vous appelez une macro de la manière évidente : vous tapez son nom, BuildReport,
et elle s'exécute. Cela ne fonctionne que parce que vous connaissez le nom au moment où vous écrivez le
code. Application.Run sert à l'autre cas de figure — quand le nom vit dans une cellule, une feuille de
réglages ou une variable, et que vous ne le connaissez pas avant que la macro tourne déjà. C'est le
premier de trois outils qui partagent une même idée, et autant l'énoncer d'emblée :
Application.Run, CallByName et Evaluate
transforment tous une chaîne en une action exécutée à l'exécution. Run exécute une macro désignée
par une chaîne, CallByName appelle un membre d'objet désigné par une chaîne, et Evaluate calcule une
expression Excel conservée sous forme de texte. La puissance vient de l'indirection ; le prix à payer,
c'est que vous renoncez au compilateur, si bien qu'une faute de frappe devient une erreur d'exécution au
lieu d'un trait ondulé. La règle qui gouverne les trois : ne leur passez jamais une chaîne que vous
n'avez pas vous-même construite ou vérifiée.
Ce que vous allez apprendre
- Le modèle mental qui relie
Application.Run,CallByNameetEvaluate - La forme instruction face à la capture de la valeur de retour d'une
Function - Le passage des arguments par position — jusqu'à 30, et pourquoi les objets arrivent sous forme de valeurs
- Lancer une macro qui vit dans un autre classeur ouvert
- Pourquoi un nom mal orthographié échoue à l'exécution, pas à la compilation, et comment s'en prémunir
- La seule situation qui justifie vraiment
Application.Run: une table d'aiguillage
Le modèle mental : un standard téléphonique qui retrouve la macro par son nom
Imaginez une opératrice de standard téléphonique. Un appel direct, BuildReport, est une ligne privée
câblée droit vers un seul bureau — rapide, mais figée pour toujours. Application.Run, c'est
l'opératrice : vous prononcez un nom à voix haute et elle vous met en relation avec celui que ce nom
désigne à cet instant précis. Le nom peut venir de n'importe où — une cellule, une feuille de
configuration, une boucle sur une liste — parce que la connexion se fait à l'exécution, et non soudée
une fois pour toutes quand vous écrivez le code.
BuildReport ' appel direct : nom fige a l'ecriture
Application.Run "BuildReport" ' appel indirect : nom resolu a l'execution
Ces deux lignes font la même chose aujourd'hui. La différence n'apparaît que lorsque le nom n'est pas une
constante. Dès l'instant où vous écrivez Application.Run someVariable, vous vous êtes offert
l'indirection — et endossé la responsabilité de vérifier que someVariable contient bien un vrai nom de
macro. Tout le sujet tient dans ce marché.
La syntaxe : forme instruction ou capture d'une valeur de retour
Comme MsgBox, Application.Run a deux formes, et ce sont les parenthèses qui
décident de celle que vous obtenez. En tant qu'instruction, supprimez les parenthèses :
Application.Run "FormatSheet", ActiveSheet.Name ' lance un Sub, ignore tout resultat
Pour capturer ce que renvoie une Function, entourez tout l'appel de parenthèses et affectez-le :
Dim total As Double
total = Application.Run("SumColumn", "B") ' capture la valeur de retour de la Function
La règle est la même que celle qui piège les gens avec MsgBox : les parenthèses signifient ceci est une
expression dont je veux la valeur. Utilisez la forme instruction pour un Sub ;
utilisez la forme fonction pour une Function dont vous avez besoin du résultat.
Passer des arguments — par position, jusqu'à 30, sous forme de valeurs
Vous passez les arguments après le nom, séparés par des virgules. Deux limites strictes méritent d'être mémorisées :
Application.Run "PostEntry", 2026, "March", 4820.5 ' les args vont par POSITION, pas par nom
D'abord, les arguments sont uniquement positionnels — vous ne pouvez pas utiliser d'arguments
named:= ici, si bien que l'ordre dans votre appel doit correspondre exactement à l'ordre de la
signature de la macro cible. Ensuite, il existe un plafond de 30 arguments, ce qui, en pratique,
signifie ceci : si vous en approchez, passez un tableau ou un Dictionary
plutôt qu'une longue liste d'arguments.
Une surprise discrète : les objets sont passés par valeur, non comme des références vivantes. Si vous
passez un Range, la cible reçoit sa .Value, pas la plage elle-même. Quand une macro doit agir sur un
véritable objet, mettez le nom dans la chaîne et laissez la cible résoudre l'objet elle-même, plutôt que
d'essayer de faire transiter l'objet à travers Application.Run.
Lancer une macro dans un autre classeur ouvert
C'est là que Application.Run justifie un usage régulier : appeler une macro qui vit dans un autre
classeur — un complément partagé, un classeur d'outils, un modèle de rapport. Qualifiez le nom avec le
classeur :
Application.Run "'Monthly Tools.xlsm'!Module1.RefreshData"
Trois détails déterminent si cela fonctionne. Le classeur doit être ouvert — Application.Run ne
l'ouvrira pas à votre place. Entourez le nom du classeur de guillemets simples s'il contient des
espaces ('Monthly Tools.xlsm'). Et la macro cible doit être Public (la valeur par défaut pour un
Sub dans un module standard) ; une macro Private est invisible depuis l'extérieur de son propre
module. Trompez-vous sur l'un de ces trois points et vous tombez sur l'erreur même dont parle la section
suivante.
Le piège : le nom est une chaîne, donc une faute de frappe est une erreur d'exécution
Voici le coût de l'indirection, et la ligne la plus importante de toute cette page. Quand vous appelez
une macro directement et que vous l'orthographiez mal, le compilateur VBA vous arrête avant que quoi que
ce soit ne s'exécute. Quand vous vous trompez dans la chaîne passée à Application.Run, le compilateur
n'a rien à vérifier — ce n'est que du texte — si bien que l'erreur ne se manifeste qu'au moment où cette
ligne s'exécute, sous la forme de l'erreur d'exécution 1004, « Impossible d'exécuter la macro » :
Sub SafeRun(macroName As String)
On Error GoTo NotFound
Application.Run macroName
Exit Sub
NotFound:
MsgBox "Macro not found or failed: " & macroName, vbExclamation
End Sub
Puisque le compilateur ne peut rien pour vous, c'est à vous de le faire. Chaque fois que le nom de la
macro vient de l'extérieur de votre code — une cellule, un fichier, une saisie utilisateur — enveloppez
l'appel dans une gestion On Error et traitez le « macro introuvable » comme un
résultat normal, pas comme un plantage. Un appel piloté par une chaîne, sans garde-fou d'erreur, est un
bug qui attend la première faute de frappe dans une feuille de configuration.
Quand Application.Run mérite vraiment sa place : une table d'aiguillage
Si vous connaissez la macro à l'écriture, appelez-la directement — Application.Run "BuildReport" est
plus lent à lire et plus facile à casser que BuildReport. La méthode ne devient payante que lorsque le
nom est réellement dynamique. L'exemple le plus net est une table d'aiguillage : associez un ensemble
de noms à un ensemble d'actions, puis lancez celle que la situation réclame.
Sub RunAction(actionName As String)
' Tout un Select Case se reduit a une seule ligne :
' le Tag du bouton, une cellule ou une ligne de config decide quelle macro tourne.
Application.Run "Actions." & actionName ' "Actions.Export", "Actions.Refresh", ...
End Sub
Cette seule ligne remplace un Select Case qui ne cesse de grossir et qu'il
vous faudrait sinon modifier à chaque nouvelle action. C'est le motif derrière les architectures de
plugins, les boutons du ruban qui portent le nom de leur gestionnaire dans un Tag, et les macros dont
le comportement est piloté par une feuille de réglages. Le test pour savoir si vous devez utiliser
Application.Run est simple : le nom est-il une constante ? Si oui, appelez directement. Si non, c'est
l'outil qu'il vous faut.
Application.Run, appel direct ou CallByName
Trois façons d'invoquer du code, trois métiers. Un appel direct est fait pour une macro dont vous
connaissez le nom à l'écriture — préférez-le toujours quand vous le pouvez. Application.Run est
fait pour une macro dont le nom est une chaîne décidée à l'exécution, y compris dans un autre classeur.
CallByName est la même idée, dirigée cette fois vers la propriété ou la
méthode d'un objet plutôt que vers une macro autonome. Si vous vous surprenez à construire une chaîne
pour atteindre un membre d'un objet précis (un contrôle, une forme, une classe), c'est le travail de
CallByName, pas celui de Run.
Comment ExcelMaster vous aide
La défaillance de cette page est silencieuse par nature : un nom juste aujourd'hui et faux dès l'instant
où quelqu'un modifie une feuille de configuration, qui remonte sous forme d'erreur 1004 au beau milieu
d'une exécution. Protéger chaque appel piloté par une chaîne, mettre entre guillemets les noms de
classeurs, vérifier qu'une cible est bien Public — il est facile de se tromper sur l'un de ces points.
ExcelMaster vous laisse
décrire le but en mots simples — « lance la macro nommée dans cette cellule, et dis-moi clairement si
elle n'existe pas » — et il écrit le code Application.Run avec le garde-fou d'erreur, le qualificateur
de classeur et la gestion du retour déjà en place. Vous conservez le classeur et le code, et vous évitez
le 1004.
Questions fréquentes
Comment lancer une macro par son nom sous forme de chaîne en VBA ?
Utilisez Application.Run "MacroName". En tant qu'instruction, vous omettez les parenthèses ; pour
capturer le résultat d'une Function, écrivez x = Application.Run("MyFunc", arg). Comme le nom est une
chaîne, le compilateur ne peut pas le vérifier : enveloppez donc l'appel dans une gestion
On Error — une faute de frappe apparaît sous forme d'erreur d'exécution 1004
plutôt que d'erreur à la compilation.
Comment passer des arguments à une macro avec Application.Run ?
Énumérez-les après le nom, séparés par des virgules : Application.Run "PostEntry", 2026, "March". Les
arguments sont uniquement positionnels — vous ne pouvez pas utiliser la syntaxe named:= — et la limite
est de 30. Les objets sont passés par valeur (un Range arrive sous forme de sa .Value), donc pour
tout ce qui dépasse, passez un tableau ou un Dictionary.
Comment lancer une macro dans un autre classeur ?
Qualifiez le nom avec le classeur : Application.Run "'Tools.xlsm'!Module1.RefreshData". L'autre
classeur doit déjà être ouvert, utilisez des guillemets simples autour de son nom s'il contient des
espaces, et la macro cible doit être Public. Application.Run n'ouvre pas le classeur à votre place.
Pourquoi Application.Run renvoie-t-il l'erreur 1004, impossible d'exécuter la macro ?
Presque toujours, la chaîne du nom ne correspond à aucune macro exécutable : elle est mal orthographiée,
le classeur qui la contient n'est pas ouvert, ou la macro est Private. Comme le nom est du texte, cela
ne peut être détecté qu'à l'exécution. Vérifiez l'orthographe, confirmez que le classeur est ouvert, et
assurez-vous que la cible est Public.
Quand faut-il utiliser Application.Run plutôt que d'appeler simplement la macro ?
Uniquement quand le nom n'est pas connu avant l'exécution — il vient d'une cellule, d'une feuille de
configuration, d'une variable ou d'une boucle, ou bien la macro vit dans un autre classeur. Si vous
connaissez le nom de la macro au moment où vous écrivez le code, appelez-la directement : BuildReport
est plus clair et le compilateur détectera les fautes de frappe. Pour invoquer un membre d'un objet
par son nom, utilisez plutôt CallByName.
Testé dans
Testé dans : Excel 365 (Windows 11), VBA 7.1 — dernière vérification le 27/09/2026.
Guides associés : VBA CallByName · VBA Evaluate · VBA Sub · VBA Function · VBA On Error · VBA Select Case · VBA Dictionary
