Excel VBAのユーザー定義関数(UDF)が #NAME? になる意外な原因とは?

サーバー
スポンサーリンク

今回は、ユーザー関数でハマった実体験の話です。

ある日、こんな状況に陥りました:

  • ユーザー定義関数を作ったのに、シート上で #NAME?
  • VBAでは正常に動いている(デバッグも通る)
  • セキュリティ設定もマクロ有効
  • OneDrive上のファイル?ネットワーク?原因を探るもわからない

「なんでだ……?本当に関数がないのか?」

混乱しながら、あれこれ検証していく中で、まさかの原因にたどり着きました。その原因とは・・・


試した関数:test()

最小限の関数で検証を開始しました。

Function test() As String
    test = "Hello from test!"
End Function

標準モジュールにこのコードを作って、シート上で =test() を入力。

結果は…… #NAME?

「あれ?ユーザー関数の戻り型が Variant じゃないとダメだったっけ?」「VBAエディタで確かに存在してるのに……」

セキュリティ設定を見直し、配列関数でも試し、別ファイルでも試し、果てはローカルにコピーしても解決せず。

実は予約語とか?なども含めて調べてもみました。


原因:関数名とモジュール名が一致していた

最終的に気づいたのは、モジュール名が test になっていたこと。

このように、関数名とモジュール名が同じであると、Excelの名前解決の仕組みで衝突が発生し、シート上からは関数が認識されなくなります。

正常に動作する別パターン(ヒントはここにあった)

  • モジュール名:test
  • 関数定義:
Function test2() As String
    test2 = "Hello from test!"
End Function

この状態ならば、シート上で =test2() を入力することで Hello from test! になります。


解決策:モジュール名を変更する

モジュール名を ModTestMyTestFunctions など、関数名と異なるものにすれば、即座に #NAME? は解消します。

修正後:

  • モジュール名:ModTest
  • 関数定義:
Function test() As String
    test = "OK"
End Function

→ シートで =test() と入力すると正常に表示されますね。


なぜこのようなことが起きるのか?

Excelは、シート上の関数名を解決するときに、VBAプロジェクト内のすべての名前空間(関数、変数、モジュール名)を対象にする挙動があるようです。

そのため、関数名と同じモジュール名があると、関数ではなくモジュールを参照しようとして失敗#NAME? エラーになるという、非常に分かりにくい状態に陥ります。


まとめ

Excel VBAで #NAME? が出る原因は、セキュリティ設定や戻り値の型など複数考えられますが、「モジュール名との衝突」も確実に押さえておくべきチェックポイントです。

特に短い関数名(test, Eigなど)を使う場合は、名前の衝突が起こりやすいため注意が必要です。

関数が見えるのに動かない――そんなときは、一度モジュール名を見直してみてください。

✅ 関数が動かないときのチェックリスト

  • 関数の戻り型と、実際に返している値の型が一致しているか?
  • 標準モジュールに書いているか?
  • セキュリティセンターでマクロは有効か?
  • ファイル形式は .xlsm か?
  • 関数名とモジュール名が衝突していないか? ← 今回の主題!

コメント

タイトルとURLをコピーしました