【実行時エラー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