はじめに

VBAでコードを実行したときによく見る「実行時エラー ‘1004’」。
これはどういう時に起きるエラーなのか?
コードを書いている人誰しもが遭遇する可能性があるエラーです。
かくいう私もコードが完成し実行後、エラー1004が出現しプログラムが止まることがあります。
しかしこのエラーは特定の不具合に対して出るエラーではなく、Excel側の実行エラー全般のエラーよくオブジェクトの操作に失敗したときに広く出るものです。
・Worksheet
・Range / Cells
・Copy / Paste
・SaveAs
・Sort / AutoFilter
そんなエラーたちを一覧化と実際のコードも記載してわかりやすくしています。
コツ
エラー全般とはいえ、なにがいけないのか記載があるためそれを見ましょう。
そこを確認することでよりなにが原因かわかります。

出現原因
存在しない範囲を指定

' ✕
Sub Sample1004()
Range("A0").Value = 1
End Subセル”A0″は存在しないためエラー
存在するセルを指定しましょう。
' 〇
Sub Sample1004()
Range("A1").Value = 1
End SubCells / Range の参照先が曖昧

' ✕
Sub Sample1004()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
ThisWorkbook.Worksheets("Sheet2").Activate
ws.Range(Cells(1, 1), Cells(2, 2)).Value = 1
End Sub条件:sheet1 , sheet2 が存在すること
Sheet1 をアクティブにしない
↓
Cells が ActiveSheet(Sheet2) を指す
↓
ws.Range(…) は Sheet1 上の Rangeとなっているため
↓
異なるシートの Cells を渡すので 1004 が出る
' 〇
Sub Sample1004()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
ws.Range(ws.Cells(1, 1), ws.Cells(2, 2)).Value = 1
End Subコピー・貼り付け先が不正

' ✕
Sub Sample1004()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
ThisWorkbook.Worksheets("Sheet2").Activate
ws.Range(Cells(1, 1), Cells(10, 1)).Copy
End Sub条件:sheet1 , sheet2 が存在すること
Cells / Range の参照先が曖昧で紹介した例と似ているため、説明は割愛。
“Excelが解釈できない参照”のときに出ます。
' 〇
Sub Sample1004()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
ws.Range(ws.Cells(1, 1), ws.Cells(10, 1)).Copy
End Sub保護されているシートへのアクセス

' ✕
Sub Sample1004()
' シートを保護
Worksheets("Sheet1").Protect Password:="1234"
' 保護されたまま書き込み
Worksheets("Sheet1").Range("A1").Value = "test"
End Subsheet1を保護したあと、書き込みをすると出現します。
このエラー1004メッセージはきちんと原因の記載があるため、わかりやすいですね。
' 〇
Sub Sample1004()
' シートを解除
ws.Unprotect Password:="1234"
' 保護されたまま書き込み
Worksheets("Sheet1").Range("A1").Value = "test"
' シートを保護
Worksheets("Sheet1").Protect Password:="1234"
End Sub
ちなみにコード上で保護をしていますが、コード上で保護をせず手動で保護した場合も同様です。
フィルタやソート対象が不正

' ✕
Sub Sample1004()
' 1列しかない範囲
Worksheets("Sheet1").Range("A1").AutoFilter Field:=2
End Sub範囲が1列のみなのに2列目を指定することでエラーを出す。
存在しない列を指定しているためです。
' 〇
Sub Sample1004()
Worksheets("Sheet1").Range("A1").CurrentRegion.AutoFilter Field:=2
End SubA1を含む「データのかたまり(表全体)」を自動取得
ファイル保存時のパスや名前が不正

' ✕
Sub Sample1004()
ActiveWorkbook.SaveAs "C:\test\aaa?.xlsx"
End Subファイル名に?があるのが原因です。
以下の文字列がないか確認しましょう。
\ / : * ? ” < > |
' 〇他にも、存在しないフォルダを指定することでエラーが起きます。
' ✕
ActiveWorkbook.SaveAs "C:\存在しないフォルダ\test.xlsx"結合セルや merged cell が絡む

' ✕
Sub Sample1004()
With Worksheets("Sheet1")
' 空白なしデータを作る
.Range("A1:A10").Value = "data"
' 空白セルを取得しようとする
.Range("A1:A10").SpecialCells(xlCellTypeBlanks).Select
End With
End SubSpecialCells(xlCellTypeBlanks)は該当するセルが1つもないとエラーになる仕様です。
今回、A1:A10の中に文字列”data”が埋まっているため空白は0件でのため出現します。
On Error Resume Nextでエラーが起きても無視する方法
' 〇
Sub Sample1004()
With Worksheets("Sheet1")
.Range("A1:A10").Value = "data"
On Error Resume Next
.Range("A1:A10").SpecialCells(xlCellTypeBlanks).Select
On Error GoTo 0
End With
End SubチェックしメッセージBOXの表示
' 〇
Sub Sample1004()
Dim ws As Worksheet
Dim rng As Range
Set ws = Worksheets("Sheet1")
ws.Range("A1:A10").Value = "data"
On Error Resume Next
Set rng = ws.Range("A1:A10").SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If Not rng Is Nothing Then
rng.Select
Else
MsgBox "空白セルはありません"
End If
End Sub特定の種類のセルだけを取得する機能
まとめ
どうでしたか、原因のエラーは見つかりましたでしょうか?
Runtime Error 1004 = Excel操作に失敗したときの代表的なエラーです。
特に見るべきは、
- シート名は正しいか
- Range/Cells の指定は正しいか
- ActiveSheet 依存になっていないか
- 保護されていないか
- 保存先やコピー先は有効か
これらを確認するだけでエラーの解消ができます。
