はじめに
職場で事務作業用のマクロを作っていたところ、「修飾子が不正です」というコンパイルエラーが突然発生しました。
以前に投稿した【ExcelVBA】「定数式が必要です」でコンパイルできないと同じく、最初は原因が全く分からなかったので、備忘録としてこの記事を書くことにしました。
実際のコードのイメージ
- 以下のようなコードを作ると、Module1の5行目の
Test.GetMessage()
でコンパイルエラーとなり、「修飾子が不正です」というエラーメッセージが表示されます。 - VBEditor上で以下のコードをよく見ると、
Test.GetMessage()
が自動的にtest.GetMessage()
に変換されていました。
Test
Option Explicit
Public Function GetMessage() As String
GetMessage = "テストです"
End Function
Module1
Option Explicit
Sub Main()
Dim test As String
test = Test.GetMessage() ' ★この行でコンパイルエラーが起きる
MsgBox Test
End Sub
問題の原因
- コンパイラ側で、Module1内の変数
test
と、呼び出している関数のモジュール名Test
が識別できなくなっていたことが原因でした。 - 他の言語では大文字と小文字を区別してくれるものが多いですが、VBAは大文字と小文字を区別せずに識別しているようです。
- 変数名と標準モジュール名だけでなく、変数名とクラス名の場合も同様の理由でエラーが発生するようです。
解決策
- モジュール名、もしくは変数名のどちらかを変える(リネームする)ことで問題を回避できます。
- 例えば、以下のようにModule1中の変数
test
をtestMsg
に変えるだけでコンパイルエラーを回避できます。
- 関数を呼び出す際に、関数の書かれている標準モジュール名を削除した場合も、この問題を回避することができます。
- この方法の場合、
GetMessage
という名前の関数が同一標準モジュール内にあると、同一標準モジュール内のGetMessage
が呼び出されてしまう欠点があります。
Module1
' 解決策1(変数名をtest→testMsgに変更)
Option Explicit
Sub Main()
Dim testMsg As String
testMsg = Test.GetMessage()
MsgBox testMsg
End Sub
Module1
' 解決策2(関数を呼び出す際に、標準モジュール名を割愛)
Option Explicit
Sub Main()
Dim test As String
test = GetMessage()
MsgBox test
End Sub