TL;DR —
Application.Run "MacroName", arg1, arg2ejecuta una macro que usted nombra con una cadena, de modo que el código decide cuál macro ejecutar mientras corre, no cuando usted lo escribe. Úselo como instrucción (sin paréntesis) o capture el valor que devuelve unaFunctionconx = Application.Run("MyFunc", 5). La trampa: el nombre es texto, así que un error de escritura es un error en tiempo de ejecución 1004, no un subrayado rojo en tiempo de compilación. Recurra a él cuando el nombre de la macro no se conozca hasta el tiempo de ejecución: una tabla de despacho, un nombre en una celda, un complemento. Si ya conoce la macro, simplemente llámela directamente.
Sub RunByName()
' Decidir el nombre de la macro en tiempo de ejecucion y luego ejecutarla
Dim macroName As String
macroName = Range("Config!B2").Value ' p. ej. "BuildMonthlyReport"
Application.Run macroName, Date, "Finance" ' pasar argumentos por posicion
End Sub
La mayoría de las veces usted llama a una macro de la forma evidente: escribe su nombre, BuildReport,
y se ejecuta. Eso solo funciona porque conoce el nombre al escribir el código. Application.Run es
para el otro caso: cuando el nombre vive en una celda, en una hoja de ajustes o en una variable, y usted
no lo conoce hasta que la macro ya está en marcha. Esta es la primera de tres herramientas que comparten
una misma idea, así que conviene enunciarla desde el principio: Application.Run,
CallByName y Evaluate convierten, todas, una
cadena en una acción ejecutada en tiempo de ejecución. Run ejecuta una macro nombrada por una
cadena, CallByName invoca un miembro de un objeto nombrado por una cadena, y Evaluate calcula una
expresión de Excel guardada como texto. El poder está en la indirección; el precio es que usted
renuncia al compilador, de modo que un error de escritura se convierte en un error en tiempo de
ejecución en lugar de un subrayado ondulado. La regla que gobierna las tres: nunca les entregue una
cadena que usted mismo no haya construido o comprobado.
Lo que aprenderá
- El modelo mental que une
Application.Run,CallByNameyEvaluate - La forma de instrucción frente a capturar el valor que devuelve una
Function - Cómo pasar argumentos por posición —hasta 30— y por qué los objetos llegan como valores
- Cómo ejecutar una macro que reside en otro libro abierto
- Por qué un nombre mal escrito falla en tiempo de ejecución, no de compilación, y cómo protegerse
- La única situación que realmente justifica
Application.Run: una tabla de despacho
El modelo mental: una centralita que busca la macro por su nombre
Piense en un operador de centralita telefónica. Una llamada directa, BuildReport, es una línea privada
cableada directamente a una sola oficina: rápida, pero fija para siempre. Application.Run es el
operador: usted dice un nombre en voz alta y él lo conecta con quienquiera que ese nombre señale en ese
preciso momento. El nombre puede venir de cualquier parte —una celda, una hoja de configuración, un
bucle sobre una lista— porque la conexión se establece en tiempo de ejecución, no queda soldada cuando
usted escribe el código.
BuildReport ' llamada directa: nombre fijado al escribir el codigo
Application.Run "BuildReport" ' llamada indirecta: nombre resuelto en tiempo de ejecucion
Esas dos líneas hacen hoy lo mismo. La diferencia solo aparece cuando el nombre no es una constante. En
el momento en que usted escribe Application.Run someVariable, ha adquirido indirección, y con ella la
responsabilidad de asegurarse de que someVariable contenga un nombre de macro real. Ese intercambio es
de lo que trata toda esta página.
La sintaxis: forma de instrucción frente a capturar un valor de retorno
Al igual que MsgBox, Application.Run tiene dos formas, y los paréntesis
deciden cuál obtiene. Como instrucción, prescinda de los paréntesis:
Application.Run "FormatSheet", ActiveSheet.Name ' ejecutar un Sub, ignorar cualquier resultado
Para capturar lo que devuelve una Function, envuelva toda la llamada entre paréntesis y asígnela:
Dim total As Double
total = Application.Run("SumColumn", "B") ' capturar el valor devuelto por la Function
La regla es la misma que hace tropezar a la gente con MsgBox: los paréntesis significan esto es una
expresión cuyo valor quiero. Use la forma de instrucción para un Sub; use la
forma de función para una Function cuyo resultado necesita.
Pasar argumentos: por posición, hasta 30, como valores
Los argumentos se pasan después del nombre, separados por comas. Vale la pena memorizar dos límites estrictos:
Application.Run "PostEntry", 2026, "March", 4820.5 ' los argumentos van por POSICION, no por nombre
Primero, los argumentos son solo posicionales: aquí no puede usar argumentos con named:=, así que
el orden de su llamada debe coincidir exactamente con el orden de la firma de la macro de destino.
Segundo, hay un tope de 30 argumentos, lo que en la práctica significa: si se está acercando a él,
pase una matriz o un Dictionary en lugar de una lista larga de argumentos.
Una sorpresa silenciosa: los objetos se pasan como valores, no como referencias vivas. Si pasa un
Range, el destino recibe su .Value, no el rango en sí. Cuando una macro necesita actuar sobre un
objeto real, ponga el nombre en la cadena y deje que el destino resuelva el objeto por sí mismo, en
lugar de intentar entregar el objeto a través de Application.Run.
Ejecutar una macro en otro libro abierto
Aquí es donde Application.Run se gana un uso habitual: llamar a una macro que reside en un libro
distinto —un complemento compartido, un libro de herramientas, una plantilla de informe—. Califique el
nombre con el libro:
Application.Run "'Monthly Tools.xlsm'!Module1.RefreshData"
Tres detalles deciden si esto funciona. El libro debe estar abierto: Application.Run no lo abrirá
por usted. Envuelva el nombre del libro entre comillas simples si contiene espacios
('Monthly Tools.xlsm'). Y la macro de destino debe ser Public (el valor predeterminado para un
Sub en un módulo estándar); una macro Private es invisible desde fuera de su propio módulo.
Equivóquese en cualquiera de los tres y acabará en el mismo error del que trata la siguiente sección.
La trampa: el nombre es una cadena, así que un error de escritura es un error en tiempo de ejecución
Este es el coste de la indirección, y la línea más importante de toda esta página. Cuando usted llama a
una macro directamente y la escribe mal, el compilador de VBA lo detiene antes de que nada se ejecute.
Cuando escribe mal la cadena en Application.Run, el compilador no tiene nada que comprobar —es solo
texto—, así que el error aflora únicamente cuando esa línea se ejecuta, como error en tiempo de
ejecución 1004, «Cannot run the 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
Como el compilador no puede ayudarle, tiene que hacerlo usted. Siempre que el nombre de la macro venga
de fuera de su código —una celda, un archivo, la entrada del usuario— envuelva la llamada en un control
On Error y trate «macro no encontrada» como un resultado normal, no como un
fallo. Una llamada gobernada por cadenas sin una protección de errores es un bug esperando al primer
error de escritura en una hoja de configuración.
Cuándo se gana Application.Run realmente su lugar: una tabla de despacho
Si conoce la macro en el momento de escribir el código, llámela directamente:
Application.Run "BuildReport" es más lento de leer y más fácil de romper que BuildReport. El método
rinde solo cuando el nombre es genuinamente dinámico. El ejemplo más claro es una tabla de despacho:
asigne un conjunto de nombres a un conjunto de acciones y ejecute luego el que la situación requiera.
Sub RunAction(actionName As String)
' Un Select Case entero se reduce a una sola linea:
' el Tag del boton, una celda o una fila de configuracion decide que macro se ejecuta.
Application.Run "Actions." & actionName ' "Actions.Export", "Actions.Refresh", ...
End Sub
Esa única línea sustituye a un Select Case creciente que, de otro modo,
tendría que editar cada vez que añade una acción. Es el patrón detrás de las arquitecturas de
complementos, de los botones de la cinta que llevan el nombre de su controlador en un Tag, y de las
macros cuyo comportamiento se gobierna desde una hoja de configuración. La prueba para saber si debe usar
Application.Run es sencilla: ¿es el nombre una constante? Si es así, llame directamente. Si no, esta
es la herramienta.
Application.Run frente a una llamada directa frente a CallByName
Tres maneras de invocar código, tres cometidos. Una llamada directa es para una macro que conoce por
su nombre al escribir el código: prefiérala siempre que pueda. Application.Run es para una macro
cuyo nombre es una cadena decidida en tiempo de ejecución, incluida una que esté en otro libro.
CallByName es la misma idea, pero dirigida a la propiedad o el método de
un objeto en lugar de a una macro independiente. Si se descubre construyendo una cadena para llegar a
un miembro de un objeto concreto (un control, una forma, una clase), ese es el cometido de CallByName, no
el de Run.
Cómo ayuda ExcelMaster
El fallo de esta página es silencioso por naturaleza: un nombre que hoy es correcto y deja de serlo en
cuanto alguien edita una hoja de configuración, y que aflora como error 1004 en lo profundo de una
ejecución. Proteger cada llamada gobernada por cadenas, poner entre comillas los nombres de los libros,
comprobar que un destino sea Public: es fácil equivocarse en alguno.
ExcelMaster le permite
describir el objetivo con palabras corrientes —«ejecuta la macro que aparece nombrada en esta celda y
avísame con claridad si no existe»— y escribe el código de Application.Run con la protección de
errores, el calificador de libro y el manejo del valor de retorno ya en su sitio. Usted se queda con el
libro y con el código, y se ahorra el 1004.
Preguntas frecuentes
¿Cómo ejecuto una macro por su nombre como cadena en VBA?
Use Application.Run "MacroName". Como instrucción, omite los paréntesis; para capturar el resultado de
una Function, escriba x = Application.Run("MyFunc", arg). Como el nombre es una cadena, el compilador
no puede comprobarlo, así que envuelva la llamada en un control On Error: un
error de escritura aparece como error en tiempo de ejecución 1004 en lugar de un error de compilación.
¿Cómo paso argumentos a una macro con Application.Run?
Enumérelos después del nombre, separados por comas: Application.Run "PostEntry", 2026, "March". Los
argumentos son solo posicionales —no puede usar la sintaxis named:=— y hay un límite de 30. Los objetos
se pasan como valores (un Range llega como su .Value), así que para algo más grande pase una matriz o
un Dictionary.
¿Cómo ejecuto una macro en otro libro?
Califique el nombre con el libro: Application.Run "'Tools.xlsm'!Module1.RefreshData". El otro libro ya
debe estar abierto, use comillas simples alrededor de su nombre si contiene espacios, y la macro de
destino debe ser Public. Application.Run no abre el libro por usted.
¿Por qué Application.Run da el error 1004, no se puede ejecutar la macro?
Casi siempre la cadena del nombre no se resuelve en una macro ejecutable: está mal escrita, el libro que
la contiene no está abierto, o la macro es Private. Como el nombre es texto, esto solo puede detectarse
en tiempo de ejecución. Revise la ortografía, confirme que el libro esté abierto y asegúrese de que el
destino sea Public.
¿Cuándo debo usar Application.Run en lugar de simplemente llamar a la macro?
Solo cuando el nombre no se conoce hasta el tiempo de ejecución: viene de una celda, una hoja de
configuración, una variable o un bucle, o la macro reside en otro libro. Si conoce el nombre de la macro
mientras escribe el código, llámela directamente: BuildReport es más claro y el compilador detectará
los errores de escritura. Para invocar un miembro de un objeto por su nombre, use
CallByName en su lugar.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación 27/09/2026.
Guías relacionadas: VBA CallByName · VBA Evaluate · VBA Sub · VBA Function · VBA On Error · VBA Select Case · VBA Dictionary
