VBAで「定数、固定長文字列、配列、ユーザー定義型文字列、およびDeclareステートメントは、オブジェクトモジュールのパブリックメンバとしては使用できません。」というエラーの原因と対処のまとめ
VBAで「定数、固定長文字列、配列、ユーザー定義型文字列、およびDeclareステートメントは、オブジェクトモジュールのパブリックメンバとしては使用できません。」というエラーの原因と対処方法についてまとめましたので、本エントリーで紹介します。
1.エラーが発生したケース
「Excel VBAで文字入力後の左矢印キーでセルを移動させないマクロ」で紹介したコード(下記)の動作確認時、当初は図に示す「Misosoft Excel Object」→「Sheet1」に追加していました。
追加したコードは下記です。
Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Function Check_input_key(key As Integer)
If GetAsyncKeyState(key) <> 0 Then
Check_input_key = 1
Else
Check_input_key = 0
End If
End Function
Private Sub Worksheet_Change(ByVal Target As Range)
Dim result As Integer
result = Check_input_key(37)
If result = 1 Then
Range(Target.Address).Activate
SendKeys "{F2}"
End If
End Sub
追加後、「Sheet1」シート上の任意のセルに文字を入力して左矢印キーを押下したところ、「定数、固定長文字列、配列、ユーザー定義型文字列、およびDeclareステートメントは、オブジェクトモジュールのパブリックメンバとしては使用できません。」というエラーが発生しました。
2.原因
原因はダイアログに記されているとおり、Declare文をワークシートに記述したためです。
3.対処
VBEの「挿入」→「標準モジュール」を選択して標準モジュールを追加し、Declare文を標準モジュールに移動することでこのエラーは解消しました。
なお、GetAsyncKeyState()を利用する関数(上記のサンプルであればCheck_input_key())は標準モジュールに移動しなくても動作します。
次に、このエラーが発生する原因などについて言及したいと思います。
4.オブジェクトモジュールとは?
エラーメッセージに含まれる「オブジェクトモジュール」とは、標準モジュール以外のモジュール、
- Misosoft Excel Object
- クラスモジュール
を指すものと思われます(図の赤枠部分)。
つまり、赤枠で示したモジュールではエラーメッセージに表示された条件のパブリックメンバが定義できないということになります(すべてのパブリックメンバが定義できないという意味ではありません)。
5.パブリックメンバとは?
「パブリックメンバ」とは「Public」で宣言された変数を指します。
Public foo As Integer
Publicで宣言された変数は、プロジェクト内にあるすべてのモジュールから参照することができます。
これとは逆に「プライベートメンバ」というものがあり、これは「Private」で宣言された変数を指します。
Private bar As Integer
Private宣言した変数は、宣言したモジュール内からのみ参照できます。「Private」は「Dim」と同じ意味です。
Dim bar As Integer
なお、ユーザ定義型はデフォルトでPublicとなります。
たとえば、次のユーザ定義型、
Type Sample
a As String
b As Integer
End Type
は、
Public Type Sample
a As String
b As Integer
End Type
と同じ意味になります。
6.エラーが発生するすべてのケース
エラーメッセージに記載されている、
- 定数
- 固定長文字列
- 配列
- ユーザー定義型
- Declareステートメント
での具体的なエラー発生ケースを確認してみました。
ワークシートやクラスモジュールなどのオブジェクトモジュールに次の内容を記述するとエラーが発生します。
定数
Public Const foo = "bar"
固定長文字列
Public foo As String * 20
配列
Public foo() As Integer
ユーザ定義型
Type Sample
a As String
b As Integer
End Type
Declareステートメント
Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
定数・固定長文字列はVBE編集時に、配列・ユーザ定義型・Declareステートメントは実行時にこのエラーメッセージが表示されます。
なお、ユーザ定義型で試したところ、「オブジェクトモジュール内では、パブリックユーザー定義型は定義できません」というエラーになり、同様のエラーメッセージになりませんでした。
7.すべてのケースの対処方法
対処方法は、6項のコードを標準モジュールに記述するか、Publicである必要がなければPrivate宣言すればOKです。
特にユーザ定義型はデフォルトでPublicとなるので、オブジェクトモジュールで利用したい場合はPrivate宣言すればよいでしょう。
Private Type Sample
a As String
b As Integer
End Type