TL;DR —
Application.Run "MacroName", arg1, arg2は、名前を 文字列 で指定したマクロを実行します。 つまり どの マクロを走らせるかを、コードを書くときではなく、実行しているまさにその時に決められます。かっこなし のステートメントとして使うか、x = Application.Run("MyFunc", 5)のようにFunctionの戻り値を受け取ります。 落とし穴は、名前がただの文字列であることです。打ち間違えても、コンパイル時に赤い波線が出るのではなく、実行時 エラー 1004 になります。マクロ名が実行時までわからないとき — ディスパッチテーブル、セルの中の名前、プラグイン — に手を伸ばしましょう。すでにマクロがわかっているなら、そのまま直接呼び出せば十分です。
Sub RunByName()
' マクロ名を実行時に決めてから実行する
Dim macroName As String
macroName = Range("Config!B2").Value ' 例: "BuildMonthlyReport"
Application.Run macroName, Date, "Finance" ' 引数を位置で渡す
End Sub
たいていの場合、マクロは当たり前のやり方で呼び出します。名前 BuildReport を打ち込めば、それが実行されます。これ
が成り立つのは、コードを書く時点で名前がわかっている からにほかなりません。Application.Run は、そうではない場合
のための道具です — 名前がセルや設定シート、あるいは変数の中にあって、マクロがすでに動き出すまでそれがわからない、と
いうときです。これは同じ考え方を共有する三つの道具の一つ目なので、その考え方を先にはっきりさせておく価値がありま
す。Application.Run、CallByName、Evaluate は、どれも文字
列を、実行時に実行されるアクションへと変えます。 Run は文字列で名前を指定した マクロ を実行し、CallByName は文字
列で名前を指定したオブジェクトの メンバー を呼び出し、Evaluate はテキストとして持っている Excel の 式 を計算しま
す。力の源は間接呼び出しであり、その代償としてコンパイラの助けを手放すことになります。だから打ち間違いは、波線では
なく実行時エラーになるのです。三つすべてを貫く鉄則は、自分で組み立てるか確かめたのではない文字列を、決してこれらに
渡さないことです。
この記事で学べること
Application.Run、CallByName、Evaluateを結びつける考え方- ステートメント形式と、
Functionの戻り値を受け取る形式の違い - 引数を位置で渡す方法 — 最大 30 個まで、そしてオブジェクトが値として届く理由
- 別の開いているブックにあるマクロを呼び出す方法
- 打ち間違えた名前がコンパイル時ではなく実行時に失敗する理由と、その防ぎ方
Application.Runが本当に正当化される唯一の場面:ディスパッチテーブル
考え方の軸:名前でマクロを探す電話交換台
電話交換手を思い浮かべてください。直接呼び出しの BuildReport は、一つのオフィスにまっすぐつながった専用回線で
す — 速いけれど、永遠に固定されています。Application.Run は交換手です。名前を口に出して伝えると、今この瞬間に
その名前が指す相手へつないでくれます。名前はどこから来てもかまいません — セル、設定シート、リストを回すループ — なぜ
なら、接続はコードを書くときにはんだ付けされるのではなく、実行時に作られるからです。
BuildReport ' 直接呼び出し: 名前は記述時に固定される
Application.Run "BuildReport" ' 間接呼び出し: 名前は実行時に解決される
この二行は、今日のところは同じことをします。違いが表に出るのは、名前が定数でないときだけです。Application.Run someVariable
と書いた瞬間、あなたは間接呼び出しを手に入れ — そして someVariable が本物のマクロ名を保持していることを保証する責
任を引き受けたのです。このトレードオフこそが、この記事のすべてです。
構文:ステートメント形式と戻り値を受け取る形式
MsgBox と同じように、Application.Run には二つの形があり、どちらになるかはかっこが決めま
す。ステートメント として使うなら、かっこを外します。
Application.Run "FormatSheet", ActiveSheet.Name ' Sub を実行し、結果は無視する
Function が返すものを受け取る には、呼び出し全体をかっこで包んで代入します。
Dim total As Double
total = Application.Run("SumColumn", "B") ' Function の戻り値を受け取る
この規則は、MsgBox で人がつまずくのと同じものです。かっこは これは値がほしい式です という意味なのです。
Sub にはステートメント形式を、結果が必要な Function には関数形式を
使いましょう。
引数を渡す — 位置で、最大 30 個まで、値として
引数は名前のあとに、カンマで区切って渡します。覚えておく価値のある厳しい制限が二つあります。
Application.Run "PostEntry", 2026, "March", 4820.5 ' 引数は名前ではなく位置で渡る
まず、引数は 位置指定のみ です — ここでは named:= の引数は使えません。ですから呼び出しの順序は、対象マクロのシグ
ネチャの順序と正確に一致していなければなりません。次に、30 個 という上限があります。これは実際には、その数に近づ
いているなら、長い引数リストではなく配列か Dictionary を渡しなさい、ということを意味しま
す。
ひとつ、静かな驚きがあります。オブジェクトは、生きた参照としてではなく 値として 渡されます。Range を渡すと、対
象が受け取るのは範囲そのものではなく、その .Value です。マクロが本物のオブジェクトを操作する必要があるときは、
Application.Run 越しにオブジェクトを手渡そうとするのではなく、名前を文字列に入れて、対象自身にオブジェクトを解決さ
せましょう。
別の開いているブックにあるマクロを実行する
ここが、Application.Run が日常的に使われる価値を得る場面です。別の ブックにあるマクロ — 共有アドイン、ツール用ブ
ック、レポートのテンプレート — を呼び出すときです。名前をブックで修飾します。
Application.Run "'Monthly Tools.xlsm'!Module1.RefreshData"
これが動くかどうかは、三つの細部で決まります。ブックは 開いていなければなりません — Application.Run があなたの
代わりに開いてくれることはありません。名前にスペースが含まれるなら、ブック名を シングルクォート で包みます
('Monthly Tools.xlsm')。そして対象のマクロは Public でなければなりません(標準モジュールの Sub は既定で
Public です)。Private のマクロは、自分のモジュールの外からは見えません。三つのどれか一つでも間違えると、次のセク
ションで扱うのと同じエラーにたどり着きます。
落とし穴:名前は文字列なので、打ち間違いは実行時エラーになる
これが間接呼び出しの代償であり、このページで最も重要な一行です。マクロを直接呼び出して名前を綴り間違えると、VBA コン
パイラは何かが動き出す前にあなたを止めてくれます。ところが Application.Run の中の文字列を綴り間違えると、コンパイラ
には確かめるものが何もありません — それはただのテキストだからです — ですから間違いは、その行が実行されて初めて 実行
時エラー 1004「マクロを実行できません」 として表に出ます。
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
コンパイラが助けてくれない以上、あなた が助けるしかありません。マクロ名がコードの外から来るときはいつでも — セル、
ファイル、ユーザー入力 — 呼び出しを On Error の処理で包み、「マクロが見つからない」ことを、
クラッシュではなく普通の結果として扱いましょう。エラーガードのない文字列駆動の呼び出しは、設定シートで最初の打ち間違
いが起きるのを待っているバグです。
Application.Run が本当に活きる場面:ディスパッチテーブル
記述時にマクロがわかっているなら、直接呼び出しましょう — Application.Run "BuildReport" は BuildReport より読むの
に手間がかかり、壊れやすくなります。このメソッドが報われるのは、名前が本当に動的なときだけです。もっともきれいな例が
ディスパッチテーブル です。名前の集合をアクションの集合に対応づけておき、状況が求めるものを実行するのです。
Sub RunAction(actionName As String)
' Select Case 全体が一行に畳み込まれる:
' ボタンの Tag、セル、設定行が、どのマクロを実行するかを決める。
Application.Run "Actions." & actionName ' "Actions.Export", "Actions.Refresh", ...
End Sub
このたった一行が、アクションを追加するたびに編集しなければならない、増え続ける Select Case
を置き換えます。これは、プラグインのアーキテクチャ、ハンドラー名を Tag に持たせたリボンのボタン、そして設定シートに
振る舞いを委ねたマクロの背後にあるパターンです。Application.Run を使うべきかどうかのテストは単純です。名前は定数
か? イエスなら直接呼び出します。ノーなら、これがその道具です。
Application.Run と直接呼び出しと CallByName
コードを呼び出す三つの方法、それぞれに役割があります。直接呼び出し は、記述時に名前がわかっているマクロのための
ものです — できるときは常にこれを選びましょう。Application.Run は、実行時に文字列で決まる名前を持つ マクロ の
ためのもので、別のブックにあるマクロも含みます。CallByName は同じ考え方を、単独のマク
ロではなく オブジェクト のプロパティやメソッドに向けたものです。特定のオブジェクト(コントロール、シェイプ、クラ
ス)のメンバーに到達するために文字列を組み立てている自分に気づいたら、それは Run ではなく CallByName の仕事です。
ExcelMaster の活用
このページの失敗は、本質的に静かなものです。今日は正しくても、誰かが設定シートを編集した瞬間に間違いになる名前が、実
行の奥深くでエラー 1004 として表に出ます。文字列駆動の呼び出しすべてをガードし、ブック名をクォートで囲み、対象が
Public かどうかを確かめる — そのどれか一つを間違えるのは、たやすいことです。
ExcelMaster には、目的を普通の言葉で伝え
られます — 「このセルに名前が書かれたマクロを実行して、もし存在しなければはっきり教えて」 — すると、エラーガードとブ
ックの修飾子、そして戻り値の処理までそろえた Application.Run のコードを書いてくれます。ブックとコードはあなたの手元
に残り、1004 も避けられます。
よくある質問
VBA でマクロを名前(文字列)で実行するには?
Application.Run "MacroName" を使います。ステートメントとして使うときはかっこを省き、Function の結果を受け取るには
x = Application.Run("MyFunc", arg) と書きます。名前は文字列なのでコンパイラには確かめようがありません。ですから呼び
出しを On Error の処理で包みましょう — 打ち間違いは、コンパイルエラーではなく実行時エラー
1004 として現れます。
Application.Run でマクロに引数を渡すには?
名前のあとに、カンマで区切って並べます:Application.Run "PostEntry", 2026, "March"。引数は位置指定のみで — named:=
の構文は使えません — 上限は 30 個です。オブジェクトは値として渡されます(Range はその .Value として届きます)。で
すから、それより大きいものは配列か Dictionary を渡しましょう。
別のブックにあるマクロを実行するには?
名前をブックで修飾します:Application.Run "'Tools.xlsm'!Module1.RefreshData"。相手のブックはあらかじめ 開いて い
なければならず、名前にスペースが含まれるならシングルクォートで囲み、対象のマクロは Public でなければなりません。
Application.Run があなたの代わりにブックを開くことはありません。
Application.Run でエラー 1004(マクロを実行できません)が出るのはなぜですか?
ほとんどの場合、名前の文字列が実行可能なマクロに解決されていません。綴りが間違っているか、それを収めたブックが開いて
いないか、マクロが Private かのいずれかです。名前はテキストなので、これは実行時にしか捕まえられません。綴りを確か
め、ブックが開いていることを確認し、対象が Public であることを確かめましょう。
マクロを直接呼び出すのではなく Application.Run を使うべきなのはいつですか?
名前が実行時までわからないときだけです — セル、設定シート、変数、ループから来る場合や、マクロが別のブックにある場合で
す。コードを書く時点でマクロ名がわかっているなら、直接呼び出しましょう:BuildReport のほうが分かりやすく、コンパイ
ラが打ち間違いを捕まえてくれます。オブジェクトの メンバー を名前で呼び出すには、代わりに
CallByName を使います。
検証環境
検証環境: Excel 365 (Windows 11)、VBA 7.1 — 最終確認 2026-09-27。
関連ガイド: VBA CallByName · VBA Evaluate · VBA Sub · VBA Function · VBA On Error · VBA Select Case · VBA Dictionary
