VBA自作関数の例外は間違えたまま動かさないために使う

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で一番避けたいのは、失敗しているのに成功したかのように後続処理へ進むことです。

たとえば、次のような業務処理を考えます。

  1. AAA シートをコピーする

  2. 元の AAA シートを削除する

もし1番目のコピーに失敗しているのに、2番目の削除だけが動くと、データを失う可能性があります。

この場合、コピーに失敗した時点で止まるべきです。止まることは問題ではありません。失敗を無視して進むことが問題です。

戻り値で失敗を表す難しさ

関数の失敗を戻り値で表す方法もあります。

Function TryGetValue(ByVal key As String) As Variant
    If key = "" Then
        TryGetValue = CVErr(xlErrValue)
        Exit Function
    End If
    TryGetValue = "value"
End Function

CVErr を使えば、通常の値と違うエラー値を返すことはできます。

しかし、この方法には弱点があります。呼び出し元が毎回チェックしなければならないことです。

Dim v As Variant
v = 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 String
value = 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