VBAで「定数、固定長文字列、配列、ユーザー定義型文字列、およびDeclareステートメントは、オブジェクトモジュールのパブリックメンバとしては使用できません。」というエラーの原因と対処のまとめ

VBAで「定数、固定長文字列、配列、ユーザー定義型文字列、およびDeclareステートメントは、オブジェクトモジュールのパブリックメンバとしては使用できません。」というエラーの原因と対処のまとめ

Posted at July 31,2014 2:22 AM
Tag:[Excel, VBA]

VBAで「定数、固定長文字列、配列、ユーザー定義型文字列、およびDeclareステートメントは、オブジェクトモジュールのパブリックメンバとしては使用できません。」というエラーの原因と対処方法についてまとめましたので、本エントリーで紹介します。

1.エラーが発生したケース

Excel VBAで文字入力後の左矢印キーでセルを移動させないマクロ」で紹介したコード(下記)の動作確認時、当初は図に示す「Misosoft Excel Object」→「Sheet1」に追加していました。

VBE

追加したコードは下記です。

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ステートメントは、オブジェクトモジュールのパブリックメンバとしては使用できません。」というエラーが発生しました。

定数、固定長文字列、配列、ユーザー定義型文字列、およびDeclareステートメントは、オブジェクトモジュールのパブリックメンバとしては使用できません。

2.原因

原因はダイアログに記されているとおり、Declare文をワークシートに記述したためです。

3.対処

VBEの「挿入」→「標準モジュール」を選択して標準モジュールを追加し、Declare文を標準モジュールに移動することでこのエラーは解消しました。

VBE

なお、GetAsyncKeyState()を利用する関数(上記のサンプルであればCheck_input_key())は標準モジュールに移動しなくても動作します。

次に、このエラーが発生する原因などについて言及したいと思います。

4.オブジェクトモジュールとは?

エラーメッセージに含まれる「オブジェクトモジュール」とは、標準モジュール以外のモジュール、

  • Misosoft Excel Object
  • クラスモジュール

を指すものと思われます(図の赤枠部分)。

VBE

つまり、赤枠で示したモジュールではエラーメッセージに表示された条件のパブリックメンバが定義できないということになります(すべてのパブリックメンバが定義できないという意味ではありません)。

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
関連記事
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)