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

VBA の Function とは — 戻り値とユーザー定義関数(UDF)の作り方(Excel)

|

VBA の Function とは — 戻り値とユーザー定義関数(UDF)の作り方(Excel)

検証環境: Excel 365 v2509 · Excel 2021 · Excel 2019 · 最終確認 2026-06-07

要点Function値を返す プロシージャです。値は関数の 名前そのもの に代入して返します——VBA に Return キーワードはありません。そして値を返すからこそ、ワークシートのセルに自作の数式(UDF)として直接入力できます。

Function AddTax(price As Double, rate As Double) As Double
    AddTax = price * (1 + rate)     ' 名前に代入する ——これが戻り値
End Function
セルに:   =AddTax(A2, 0.2)         ' SUM や XLOOKUP の隣に並ぶ、あなた専用の数式

この 「セルの中で生きられる」 という一点こそ、Sub とは別に Function が存在する理由のすべてです。以下はそこから組み立てます。

メンタルモデル:Function は「報告して戻る Sub」

Sub は、作業をして去っていく作業員です。Function は、作業をしてから答えを教えてくれる作業員。 仕組みは同じ——名前つきのコードのかたまりに引数が入る——で、一点だけ違う。値が 出てくる のです。

この出力があるおかげで、Sub には決してできない場所、すなわち ワークシートのセル で Function を使えます。Excel のグリッドは式の結果を表示するためのものなので、値を返すもの——SUMXLOOKUP、あなたの AddTax——はセルに入れられます。Sub は何も返さず、Excel はセルに入れる物を持てません。=Greet() と入力すれば #NAME? が返ります。この絵を覚えておけば、Sub と Function の選択は自ずと決まります。

たった一つのルール:戻り値は名前に代入する(Return ではない)

Python・JavaScript・C# から来た人を必ず捕まえるバグです。

Function Discount(price As Double) As Double
    Discount = price * 0.9      ' ✅ VBA は関数名への代入で値を返す
End Function

Function Broken(price As Double) As Double
    Return price * 0.9          ' ❌ VBA はこう動かない ——黙って 0 を返す
End Function

Return は VBA にも存在しますが、古い GoSub の相方としてだけで、値は 返しませんReturn と書いても(あるいは名前への代入を丸ごと忘れても)、関数はエラーなくコンパイルされ、その型の既定値——0""Empty——を黙って返します。エラーは出ず、結果だけ間違う。UDF がいつも 0 を返すなら、ほぼ確実に名前への代入を忘れています。

名前へは何度代入しても構いません(関数内では普通の変数です)。関数が終わる時点で持っている値が返ります。

Function Grade(score As Long) As String
    Grade = "不合格"            ' 既定
    If score >= 50 Then Grade = "合格"
    If score >= 80 Then Grade = "優秀"
End Function

Sub と Function —— 一行で決める

長い比較表は忘れてください。選択は一つの問いに尽きます。

呼ぶ側が答えを必要とするか? はい → Function。いいえ → Sub

Sub Function
値を返す いいえ はい(名前に代入)
セルで使える いいえ はい(UDF になる)
マクロ一覧(Alt+F8)に出る Public かつ引数なしなら出る 出ない
典型的な仕事 何かを する(書式・出力・削除) 何かを 計算する(税率・ラベル・整形済み文字列)

見分けるコツ:Sub に結果をグローバル変数へ押し込ませて別のプロシージャに読ませているなら、本当は Function が欲しかったのです。グローバルでこっそり渡さず、値をきちんと返しましょう。

ワークシート関数(UDF)にする —— 決め手の機能

Function を 標準モジュール([挿入] → [標準モジュール]。シートや ThisWorkbook のモジュール ではない)に置くと、即座にグリッドと数式オートコンプリートで使えるようになります。

Function InitialsOf(fullName As String) As String
    Dim parts() As String
    parts = Split(Trim(fullName), " ")
    InitialsOf = Left(parts(0), 1) & Left(parts(UBound(parts)), 1)
End Function
=InitialsOf("Ada Lovelace")  →  "AL"

ここで VBA は、周囲の非プログラマーに対して真価を発揮します。ロジックを一度書けば、同僚はコードを見ずに、組み込み関数と同じように使えるのです。

新人 UDF が必ずつまずくルール:ワークシート関数は自分のセルにしか返せない

無数のフォーラム投稿を生む制約がこれです。Function が セルから 呼ばれると、Excel は保護モードで実行し、関数は 何も変更できません——他のセルへの書き込み、色の設定、シート名の変更、MsgBox のいずれも不可。できるのは計算して、呼んだセルの値を返すことだけです。

Function ColorMe(c As Range) As String
    c.Interior.Color = vbYellow   ' ❌ セルから呼ぶと何もしない
    ColorMe = "done"
End Function

これを書いて、文字は出るのに色は付かず、「VBA が壊れている」と結論する人がいます。壊れていません——UDF は設計上「純粋」 です。シートを 変更 したいなら、それは(ボタンやイベントで起動する)Sub の仕事で、UDF の仕事ではありません。この線を知るだけで何時間も節約できます——セルの数式 → 計算して返すだけ。ブックを変える → Sub。

省略可能・型つきの引数で UDF を「ネイティブ」に

二つの工夫で自作関数は使い心地が良くなります。

Function Net(gross As Double, Optional rate As Double = 0.1) As Double
    Net = gross / (1 + rate)       ' 呼ぶ側が省略すると rate は 0.1
End Function

Optional に既定値を付ければ =Net(A2)=Net(A2, 0.08) も両方動きます。戻り値の型を Variant のままにせず宣言する(As DoubleAs StringAs Boolean)と、関数は速くなり意図も明確になります。

主張:組み込み関数を作り直さない

VBA の Function は、Excel に まだない ロジックのためのものです。WorksheetFunction.SumIfTEXTJOINXLOOKUP で足りるならそれを呼びましょう——ネイティブ関数は速く、正しく再計算され、マクロ有効ブックも要りません。自作 Function は、本当に固有のルール——自社固有の税率区分、汚い文字列のパーサー、組み込みにない業務計算——に取っておきます。SUM を包むだけの UDF は負債、あなたの業務ルールを表す UDF は資産です。

よくある Function の誤り(と直し方)

症状 原因 直し方
関数がいつも 0 / 空を返す Return を使った、または名前に代入していない 結果を関数名に代入:MyFunc = result
セルが #NAME? 関数がシートモジュールにある/名前の綴り違い 標準 モジュール に移す。綴りを確認
UDF がセルの色を変えない セルから呼ぶ UDF はブックを変更できない 変更は Sub をボタン/イベントで
セルが #VALUE! 関数内の未処理エラー 入力を検証し、エラーでなく代替値を返す
UDF の結果が更新されない 関数が変更後の入力を見ていない 変更セルを引数に渡す、または Application.Volatile(控えめに)
呼び出しで「ステートメントの最後が必要です」 括弧/Call の混同(Sub と同じ) 戻り値を使う:x = MyFunc(a)

数式のロジックそのものが本題なら —— VBA は省こう

自作 Function は、再利用する一つの計算には最適です。けれど作業が「この 2 つのエクスポートを突き合わせ、一致しない行を印付けし、差額を月別に合計する」なら、手で書いて保守したくはありません。ExcelMaster Agent は、その一文を自然な日本語で受け取って結果を出します——デバッグする UDF も、配布するマクロ有効ファイルも不要。無料で試す →

関連記事

よくある質問

VBA の Function とは何ですか? Function は、作業をして呼んだコードに値を返す、名前のついたプロシージャです。Function 名前(引数) As 型 … End Function で定義し、結果を関数の名前そのものに代入して返します。

VBA の関数から値を返すには? 値を関数名に代入します。Function Total() As Double の中で Total = 42 と書きます。VBA にこのための Return 文はありません——Return は古い GoSub のもので、値を返しません。関数が終わる前に名前へ最後に代入した値が返ります。

VBA の関数が 0 や空を返すのはなぜ? 関数名に値を代入していない(または VBA で機能しない Return を使った)からです。関数は型の既定値——0""Empty——を返します。End Function の前に 関数名 = 結果 を加えてください。

Excel でユーザー定義関数(UDF)を作るには? Function を標準モジュール([挿入] → [標準モジュール])に置き、戻り値の型を付けて、結果を名前に代入します。あとはセルで =自作関数(...) と入力します。組み込み関数と同様に数式オートコンプリートに現れます。

UDF が他のセルや色を変えられないのはなぜ? Excel がセルから Function を呼ぶときは、値を返すことしかできない制限モードで実行されます——ブックの変更(セルへの書き込み、書式、MsgBox)はできません。シートを変えるには、UDF ではなくボタンやイベントで起動する Sub を使います。

Sub ではなく Function を使うのはどんなとき? 呼ぶ側が値を必要とするとき——計算・検索・整形済み文字列——や、セルから呼びたいときは Function を使います。プロシージャが何かを する だけ(書式・出力・削除)で何も返さないなら Sub を使います。