【実行時エラー1004】アプリケーション定義またはオブジェクト定義のエラーです。

エラー表示

このエラーが発生すると、マクロ起動時(コンパイル時)に次のエラーが表示されます。
実行時エラー '1004'

アプリケーション定義またはオブジェクト定義のエラーです。

エラーの発生理由について

本エラーの原因はいくつか想定できます。
順を追ってみていきましょう。

【原因1】Rangeを用いた範囲指定で、シートの指定漏れ

エラーの原因について

セルの範囲の指定方法を誤った時です。
下記サンプルでは、Range内にCellsを入れて範囲を指定しています。Rangeでシートを指定していますが、Cellsにシートの指定をしていないことです。(Range, Cells共にシートを指定する必要があります)
主にブックをまたいだ操作で本エラーが発生します。

' 本エラーが発生するサンプル
Sub TestFunc1_Err1()
    Dim wb As Workbook
    Set wb = Workbooks.Add
    ' Rangeはシートを指定しているが、Cellsでシートを指定していない
    wb.Sheets(1).Range(Cells(1, 1), Cells(2, 2)).Copy
End Sub
解決法

本ケースでは、Rangeとそのカッコ内のCellsで異なるシート指定したことが原因でした(シートを指定していないCellsはアクティブシートを指定したことになります)。RangeとCellsでシートを統一するため、必要があるため、Cellsにも"ws."をつけてシートを指定するか、Rangeの「ws.」を外しましょう。

' 修正例
Sub TestFunc1_OK()
    Dim wb As Workbook
    Set wb = Workbooks.Add
    ' Range内のCellsにシートを指定した
    wb.Sheets(1).Range(wb.Sheets(1).Cells(1, 1), _
                        wb.Sheets(1).Cells(2, 2)).Copy
End Sub
予防策

範囲を指定する場合は、必ずシートを指定しましょう。

余談ですが、Withを使用していると、ドットをつけ忘れた場合に気づきにくいというデメリットがありますので注意が必要です。

Sub TestFunc1_Err2()
    Dim wb As Workbook
    Set wb = Workbooks.Add
    With wb.Sheets(1)
        ' 2つめのCellsに"."をつけ忘れた
        .Range(.Cells(1, 1), Cells(2, 2)).Copy
    End With
End Sub

補足

このケースでは、主に他のブックと連携時に発生します。マクロが記載されているブック内で完結する場合は、本エラーが発生しないものの論理エラーになる可能性があります。
そのため、範囲を指定する場合は必ずシートを指定しましょう。

【原因2】Cellsの指定ミス

Cellsを用いてありえないセルを指定してしまった時です。次のサンプルでは、xに値を代入せず、xが0の状態で(数値型の変数の初期値は0)、セルを指定した結果、エラーが発生しています。

' エラーが発生するサンプル
Sub TestFunc2_Err()
    Dim x as Long
    ' x が 0 のため、Cells(0,1)となりエラーとなる
    MsgBox ActiveSheet.Cells(x, 1) ' ←ここでエラー
End Sub
解決法

本ケースは、Cells(0, 1)を指定したことが原因でした(値を入れていない整数型の初期値は0です)。正しくセルを指定するよう変数に値を代入しましょう。

Sub TestFunc2_OK()
    Dim x as Long
    x = 1
    MsgBox ActiveSheet.Cells(x, 1)
End Sub
予防策

必ず変数の初期設定を行うようにしましょう。
変化球になりますが、vbaでは変数の初期化(変数の作成時に任意の値をプログラマが設定すること)が出来ませんが、半角コロン(:)を入力すると同じ行に2ステップ以上記載できます。ただし、可読性が下がるため、多用は厳禁です。

' 修正例②
Sub TestFunc2_OK2()
    Dim x As Long: x = 1 ' :を入力すると同行に2ステップ以上記載できる
    MsgBox ActiveSheet.Cells(x, 1) 
End Sub

【原因3】アクティブでないシートのセルを Select した

アクティブでないシートを選択してしまった時です。次のサンプルでは、アクティブでないシートを選択してしまった場合のサンプルです。

' Sheet1がアクティブになっているとします。
Sub TestFunc3_Err()
    ' アクティブでないシートのセルをSelectするとエラーが発生します
    Worksheets("Sheet2").Range("A2:A3").Select
    Selection.Copy
End Sub
解決法

ケース3ではアクティブになっていないシートを選択したことが原因でした。そのため、シートを一度アクティブにしてから、選択すれば解消します。

' 修正例
Sub TestFunc3_OK()
    ' 選択する範囲があるシートをアクティブにします。
    Worksheets("Sheet2").Activate
    Worksheets("Sheet2").Range("A2:A3").Select
    Selection.Copy
End Sub
予防策

可能であれば、Selectを使用せずに直接セル(範囲)を指定した処理を行うことを考慮しましょう(Range("A1").Selectでなく、Range("A1").Copyとする等)。

' 修正例②
Sub TestFunc3_OK2()
    ' Sheet2のセルA2~A3をコピーします
    Worksheets("Sheet2").Range("A2:A3").Copy
End Sub

補足

範囲選択後にアクティブなシートを元に戻したい場合は、アクティブ変更前のシート名を変数名に格納して、再びアクティブなシートを変更しましょう。

Sub TestFunc3_2()
    Dim sName As String
    sName = ActiveSheet.Name
    'アクティブなシートを変更する
    Worksheets("Sheet2").Activate

    'シート選択後、何らかの処理を行う
    
    'アクティブなシートを元に戻す
    Worksheets(sName).Activate
End Sub

関連リンク

ページの先頭へ