VBAで『オブジェクトが必要です』エラーになる原因とは?複数シート共通処理を作る正しい書き方を解説

Visual Basic

Excel VBAで同じ処理を複数シートに使い回したい場合、標準モジュールに処理を書いて各シートからCallする構成は非常によく使われます。しかし、その際に「オブジェクトが必要です」というエラーが発生して困るケースがあります。

特にWorksheet_Changeイベントをモジュールへ移そうとした時に発生しやすく、VBA初心者がつまずきやすいポイントでもあります。

この記事では、なぜ「オブジェクトが必要です」エラーになるのか、そして複数シート共通化する正しいVBAの書き方をわかりやすく解説します。

『オブジェクトが必要です』が出る原因

今回のコードでは、以下の部分でエラーが発生しています。

If Target.Address <> "$B$2" Then Exit Sub

これは、標準モジュール側では「Target」が存在しないためです。

TargetはWorksheet_Changeイベント専用の引数であり、シートイベント内でのみ自動的に渡されます。

つまり、標準モジュールへそのまま移動するとTargetが未定義になるため、オブジェクトエラーになります。

複数シート対応する正しい考え方

VBAで複数シート共通処理を作る場合は、以下のように役割を分けるのが基本です。

場所 役割
各シート イベント受け取り
標準モジュール 実際の処理

つまり、Worksheet_Changeで受け取ったTargetを、標準モジュールへ引数として渡します。

正しいコード例

まず、標準モジュールに以下を書きます。

Public Sub ChangeDateFormat(Target As Range)

    If Target.Address <> "$B$2" Then Exit Sub

    Call setCalendarDateForCell(Target)

    Dim num As Long

    num = CLng(Format(Target.Value, "yyyymmdd"))

    Target.Value = num
    Target.NumberFormatLocal = "G/標準"

End Sub

次に、各シートモジュール側には以下を書きます。

Private Sub Worksheet_Change(ByVal Target As Range)

    Call ChangeDateFormat(Target)

End Sub

この形にすると、複数シートで同じ処理を簡単に再利用できます。

Range(“B2”)を直接書かない方がよい理由

元コードでは以下のように固定セル指定されていました。

Range("B2").Value = num

これでも動作することはありますが、複数シートで使う場合はTargetを使う方が安全です。

理由は、アクティブシートが変わった際に意図しないシートのB2を操作する危険があるためです。

特にイベント処理では、どのシートから呼ばれたかを明確にすることが重要です。

複数セル変更時にも注意

Worksheet_Changeは、複数セル貼り付けでも発火します。

そのため、以下のようなチェックを追加するとさらに安全です。

If Target.Count > 1 Then Exit Sub

これを入れておくと、複数セル操作時の誤動作を防げます。

イベントループにも注意する

VBAでセル値を書き換えると、再びWorksheet_Changeが発火する場合があります。

そのため、本格的な処理では以下を使うケースもあります。

Application.EnableEvents = False

処理終了後には必ずTrueへ戻します。

Application.EnableEvents = True

これを忘れるとExcel全体のイベントが止まるため注意が必要です。

共通化すると保守がかなり楽になる

今回のように標準モジュールへ処理をまとめると、修正箇所が1つで済みます。

例えば10シートで同じ処理をしていても、標準モジュールを直すだけで全シートへ反映できます。

これは実務VBAでも非常によく使われる設計方法です。

まとめ

VBAで「オブジェクトが必要です」エラーになる原因は、Worksheet_Change専用のTargetを標準モジュール内で直接使っていたためです。

複数シート共通化する場合は、シートイベントで受け取ったTargetを引数として標準モジュールへ渡す構成にすると綺麗に動作します。

また、Targetを使うことでシート依存の不具合も防げるため、実務でも非常に重要な考え方になります。

コメント

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