VBA自作関数の例外は間違えたまま動かさないために使う
Copyright © 2026 LWP 山中 一弘
本資料は、出典を明記いただければ、商用・非商用を問わず、ご自由に複製・改変・再配布していただけます。なお、著作権表示は改変せず、そのまま記載してご利用くださいますようお願いいたします。
記事要約
VBAの自作関数では、「失敗したときにどうするか」を先に決めておく必要があります。
業務マクロで一番危ないのは、途中で失敗しているのに後続処理が動き続けることです。止まること自体は悪ではありません。むしろ、間違えたまま処理を進める方が危険です。
この記事では、VBAの自作関数で例外をどう使うべきかを、「間違えたまま動かさない」という観点で整理します。
本記事の対象とゴール
VBAで自作関数や業務マクロを作っている人
関数の戻り値でエラーを返す設計に限界を感じている人
ノンプロ向けのVBAでも、最低限の安全性を持たせたい人
先に結論
自作関数は、処理を続けられない状態になったら例外として止めてよいです。
業務マクロでは、すべての失敗を戻り値で表現し、呼び出し元で毎回確認する設計は重くなりがちです。
処理の前提が崩れたら、Err.Raise で止める。最上位で必要ならまとめて捕まえる。ノンプロ向けの小さな業務アプリなら、止まって原因を直す方が安全な場合が多くあります。
<!-- LWP_REWRITE_EXPANSION_記事103 -->
1. 例外は異常終了のためだけではない
VBAで例外というと、実行時エラーで処理が止まるものと考えがちです。しかし自作関数では、例外を「間違った前提で処理を続けないための合図」として使えます。
たとえば、必ず1件だけ見つかるはずの検索で0件または複数件が返った場合、そのまま空文字や先頭行を返すと、後続処理が間違った値を正しいものとして扱ってしまいます。この場合は、関数の中で異常を検出し、呼び出し元へ明示的に知らせた方が安全です。
2. 戻り値で表すか例外で止めるか
すべてを例外にすればよいわけではありません。未入力、該当なし、キャンセルのように業務上あり得る状態は、戻り値や結果オブジェクトで表す方が自然です。一方で、設計上あり得ない状態、データ破損、前提条件違反は、例外として止める候補になります。
判断基準は単純です。その状態が通常の分岐として扱うべきものなら戻り値で返します。その状態で処理を続けるとデータを壊すなら例外で止めます。
3. 呼び出し元へ責任を戻す
自作関数の中で異常を握りつぶすと、呼び出し元は何が起きたか分からなくなります。On Error Resume Next で進める場合でも、直後にエラー番号を確認し、何を許容し、何を許容しないかを明示する必要があります。
例外を使う目的は、派手に止めることではありません。間違った状態を見逃さず、呼び出し元が正しい判断をできるようにすることです。
間違えたまま動くことが一番危ない
関数やSubで一番避けたいのは、失敗しているのに成功したかのように後続処理へ進むことです。
たとえば、次のような業務処理を考えます。
AAA シートをコピーする
元の AAA シートを削除する
もし1番目のコピーに失敗しているのに、2番目の削除だけが動くと、データを失う可能性があります。
この場合、コピーに失敗した時点で止まるべきです。止まることは問題ではありません。失敗を無視して進むことが問題です。
戻り値で失敗を表す難しさ
関数の失敗を戻り値で表す方法もあります。
Function TryGetValue(ByVal key As String) As Variant If key = "" Then TryGetValue = CVErr(xlErrValue) Exit Function End If TryGetValue = "value"End FunctionCVErr を使えば、通常の値と違うエラー値を返すことはできます。
しかし、この方法には弱点があります。呼び出し元が毎回チェックしなければならないことです。
Dim v As Variantv = TryGetValue(key)If IsError(v) Then ' エラー処理Else ' 通常処理End Ifこのチェックを書き忘れると、結局「間違えたまま動く」状態になります。
例外で止める設計
処理を続けられないなら、例外を発生させる設計にします。
Function GetValueOrRaise(ByVal key As String) As String If key = "" Then Err.Raise vbObjectError + 1000, , "keyが空です。" End If GetValueOrRaise = "value"End Functionこの関数は、失敗時に戻り値を返しません。処理を止めます。
呼び出し元は、成功している前提で処理を書けます。
Dim value As Stringvalue = GetValueOrRaise(key)' ここへ来た時点で、valueは取得できている。この形にすると、正常系のコードが読みやすくなります。
ノンプロアプリでは止めてよい場面が多い
大規模な業務システムでは、例外をどこで捕まえ、ログをどう残し、リカバリするかを設計します。
しかし、Excel VBAで作る小さな業務アプリでは、すべての失敗を細かく復旧するより、止めて原因を見つける方が現実的な場合があります。
特に、ファイルがない、シートがない、列がない、前提データが壊れている、といった状況では、処理を続けても正しい結果にはなりません。
このような場合は、失敗を隠さず止める方が安全です。
組み込み関数の挙動から学ぶ
VBAの組み込み処理も、前提を外れると実行時エラーを出します。
たとえば、配列の範囲外を参照すればエラーになります。これは、範囲外アクセスを無理に値として返さず、間違いとして止めてくれているということです。
自作関数でも同じ考え方を使えます。
関数が処理できる前提を満たしていないなら、戻り値で曖昧に伝えるのではなく、例外として止める。
これにより、関数の「間違えていなさ」を上げられます。
まとめ
VBA自作関数の例外は、特別な上級技術ではありません。
間違えたまま動かさないための安全装置です。
戻り値で失敗を返す方法は便利ですが、呼び出し元のチェック漏れに弱くなります。処理を続けられない失敗なら、Err.Raise で止める方が安全です。
ノンプロ向けの業務マクロでも、例外を恐れる必要はありません。むしろ、前提が壊れたときに確実に止まる関数の方が、業務を壊しにくい関数です。
出典メモ- 元Posfie URL: https://posfie.com/@hoehoe1234/p/RrGmi7a
元Posfieタイトル: 2022-02-05 VBA 自作関数における例外の使い方
投稿者: hoehoe1234
投稿数: 14
画像確認: 画像なし
取得・確認日: 2026-06-11
