エラー1004はVBAで最も頻繁に遭遇するエラーのひとつで、原因が多岐にわたるため初心者が特に悩みやすいポイントです。
この記事では、実行時エラー1004の8つの主な原因と、それぞれの具体的な解決方法をコード付きで徹底解説します。
✅ シート名・ファイルパスの間違い
✅ 範囲指定のミス
✅ ブック保護・読み取り専用の影響
✅ すぐに使える実務テンプレート
初心者でもわかりやすく、実務ですぐ使えるコードサンプルを豊富に用意しています。
- 📌 実行時エラー1004とは?
- 🔍 実行時エラー1004の8つの原因と解決方法
- 🛠️ 実務で使える!エラー1004対策テンプレート
- 💡 エラー1004を防ぐ5つのベストプラクティス
- ❓ よくある質問(FAQ)
- 📚 関連記事
- ✅ まとめ
📌 実行時エラー1004とは?
エラー1004の正式名称
実行時エラー1004の正式なメッセージは以下のいずれかです。
- 「アプリケーション定義またはオブジェクト定義のエラーです。」
- 「’〇〇’メソッドは失敗しました。」
- 「RangeクラスのSelectメソッドが失敗しました。」
このエラーはExcel VBAがオブジェクト操作に失敗したときに発生します。
エラー1004が発生する主な場面
- シートやブックを開こうとしたとき
- セルや範囲を選択・コピーしようとしたとき
- ファイル保存・削除を実行しようとしたとき
- グラフや図形を操作しようとしたとき
実行時エラー9(インデックスが有効範囲にありません)と並んで、VBA初心者が最初に遭遇する壁です。

🔍 実行時エラー1004の8つの原因と解決方法
以下、原因別に具体的な解決コードを紹介します。
原因1️⃣ シート名が間違っている
❌ エラーが出るコード例
Sub シート名ミス()
Worksheets("売上データ").Activate
' 実際のシート名が「売上」の場合、エラー1004が発生
End Sub
✅ 正しいコード例
Sub シート名を確認()
On Error GoTo ErrorHandler
' シート名を正確に指定
Worksheets("売上").Activate
Exit Sub
ErrorHandler:
MsgBox "指定したシート名が見つかりません。" & vbCrLf & _
"シート名を確認してください。", vbCritical
End Sub
💡 対処ポイント
- シート名は半角・全角スペースまで完全一致させる
Worksheets.Countでシート一覧を確認するコードを書く- 名前をハードコーディングせず、変数や定数で管理する
原因2️⃣ 存在しないファイルパスを指定している
❌ エラーが出るコード例
Sub ファイルが存在しない()
Workbooks.Open "C:\作業フォルダ\データ.xlsx"
' ファイルが存在しない場合、エラー1004が発生
End Sub
✅ 正しいコード例(Dir関数で事前チェック)
Sub ファイル存在チェック()
Dim filePath As String
filePath = "C:\作業フォルダ\データ.xlsx"
' Dir関数でファイルの存在を確認
If Dir(filePath) = "" Then
MsgBox "ファイルが見つかりません。" & vbCrLf & filePath, vbExclamation
Exit Sub
End If
' ファイルを開く
Workbooks.Open filePath
MsgBox "ファイルを開きました。", vbInformation
End Sub
💡 対処ポイント
Dir()関数で事前にファイルの存在を確認- フルパスではなく
ThisWorkbook.Pathで相対パス指定も検討 - ファイル名に全角スペースや特殊文字が含まれていないか確認
原因3️⃣ 範囲指定が無効(範囲外を指定している)
❌ エラーが出るコード例
Sub 範囲指定ミス()
Range("A1:Z1048577").Select
' Excelの最大行を超えた指定でエラー1004
End Sub
✅ 正しいコード例
Sub 安全な範囲指定()
Dim lastRow As Long
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
' 最終行を取得
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
' 最終行までの範囲を指定
ws.Range("A1:A" & lastRow).Select
End Sub
💡 対処ポイント
- 固定値で範囲を指定せず、
Cells().End(xlUp).Rowで最終行を動的取得 - Excel 2016以降は最大1,048,576行、16,384列(XFD列)
- 範囲指定前に
UsedRangeで実際のデータ範囲を確認
原因4️⃣ ブックやシートが保護されている
❌ エラーが出るコード例
Sub 保護シートに書き込み()
Worksheets("売上").Range("A1").Value = "更新"
' シートが保護されている場合、エラー1004
End Sub
✅ 正しいコード例(保護解除→処理→再保護)
Sub 保護シートへ安全に書き込み()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("売上")
On Error GoTo ErrorHandler
' シート保護を解除
ws.Unprotect Password:="yourpassword"
' データ書き込み
ws.Range("A1").Value = "更新完了"
' シート保護を再設定
ws.Protect Password:="yourpassword"
Exit Sub
ErrorHandler:
MsgBox "エラーが発生しました。" & vbCrLf & Err.Description, vbCritical
' エラー時も保護を戻す
ws.Protect Password:="yourpassword"
End Sub
💡 対処ポイント
- 処理前に
Unprotect、処理後にProtectを必ず実行 On Errorでエラー時も保護を戻す処理を入れる- パスワードは変数で管理し、ハードコーディングを避ける
原因5️⃣ 別のブックが開かれていない状態で操作しようとしている
❌ エラーが出るコード例
Sub 開いていないブックを操作()
Workbooks("データ.xlsx").Worksheets("Sheet1").Range("A1").Value = "テスト"
' ブックが開いていない場合、エラー1004
End Sub
✅ 正しいコード例(ブック存在チェック付き)
Sub ブック存在確認付き操作()
Dim wb As Workbook
Dim bookName As String
bookName = "データ.xlsx"
' ブックが開いているか確認
On Error Resume Next
Set wb = Workbooks(bookName)
On Error GoTo 0
If wb Is Nothing Then
MsgBox bookName & " が開かれていません。", vbExclamation
Exit Sub
End If
' 処理を実行
wb.Worksheets("Sheet1").Range("A1").Value = "テスト"
MsgBox "データを書き込みました。", vbInformation
End Sub
💡 対処ポイント
On Error Resume Nextで一時的にエラーを無視してブック存在チェックIs Nothingで判定後、処理を分岐- ブック名だけでなくフルパスで開く処理も併用すると安全
原因6️⃣ ファイルが読み取り専用で開かれている
❌ エラーが出るコード例
Sub 読み取り専用ファイルに保存()
ThisWorkbook.Save
' 読み取り専用の場合、エラー1004
End Sub
✅ 正しいコード例(読み取り専用チェック)
Sub 読み取り専用チェック付き保存()
If ThisWorkbook.ReadOnly Then
MsgBox "このファイルは読み取り専用です。" & vbCrLf & _
"名前を付けて保存してください。", vbExclamation
Exit Sub
End If
ThisWorkbook.Save
MsgBox "保存しました。", vbInformation
End Sub
💡 対処ポイント
Workbook.ReadOnlyプロパティで事前チェック- 読み取り専用の場合は
SaveAsで別名保存を促す - ネットワークドライブの権限設定も確認
原因7️⃣ 同じ名前のシートが既に存在する
❌ エラーが出るコード例
Sub シート名重複()
Worksheets.Add.Name = "売上"
' 既に「売上」シートが存在する場合、エラー1004
End Sub
✅ 正しいコード例(重複チェック付き)
Sub シート名重複チェック付き追加()
Dim ws As Worksheet
Dim newSheetName As String
newSheetName = "売上"
' シート名の重複をチェック
On Error Resume Next
Set ws = Worksheets(newSheetName)
On Error GoTo 0
If Not ws Is Nothing Then
MsgBox "シート名「" & newSheetName & "」は既に存在します。", vbExclamation
Exit Sub
End If
' シートを追加
Worksheets.Add.Name = newSheetName
MsgBox "シート「" & newSheetName & "」を追加しました。", vbInformation
End Sub
💡 対処ポイント
On Error Resume Nextでシート存在チェック- 重複時は連番を付ける処理(「売上_1」など)も検討
- シート削除前に確認ダイアログを表示すると安全
原因8️⃣ 別のシートがアクティブな状態で範囲選択している
❌ エラーが出るコード例
Sub 別シートの範囲選択()
Worksheets("売上").Range("A1").Select
' 現在アクティブなシートが「売上」でない場合、エラー1004
End Sub
✅ 正しいコード例(シートをアクティブにしてから操作)
Sub 安全な別シート範囲選択()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("売上")
' シートをアクティブにする
ws.Activate
' 範囲を選択
ws.Range("A1").Select
End Sub
💡 もっと良い方法(Selectを使わない)
Sub Select不要の処理()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("売上")
' Selectせずに直接値を代入
ws.Range("A1").Value = "更新"
ws.Range("A1").Interior.Color = RGB(255, 255, 0)
End Sub
💡 対処ポイント
- Select/Activateはできるだけ使わない(実行速度も遅い)
- ワークシート変数(
Worksheet型)で直接操作する - どうしてもSelectが必要な場合は事前に
Activate
🛠️ 実務で使える!エラー1004対策テンプレート
汎用エラーハンドリング付きテンプレート
Sub 汎用エラー1004対策テンプレート()
Dim ws As Worksheet
Dim filePath As String
Dim lastRow As Long
On Error GoTo ErrorHandler
' ========== 処理1: ファイルパスの存在確認 ==========
filePath = "C:\作業フォルダ\データ.xlsx"
If Dir(filePath) = "" Then
MsgBox "ファイルが見つかりません: " & filePath, vbCritical
Exit Sub
End If
' ========== 処理2: シートの存在確認 ==========
On Error Resume Next
Set ws = ThisWorkbook.Worksheets("売上")
On Error GoTo ErrorHandler
If ws Is Nothing Then
MsgBox "シート「売上」が見つかりません。", vbCritical
Exit Sub
End If
' ========== 処理3: 保護解除(必要な場合) ==========
If ws.ProtectContents Then
ws.Unprotect Password:="yourpassword"
End If
' ========== 処理4: 最終行を取得して安全に範囲指定 ==========
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
' ========== 処理5: データ処理(Selectを使わない) ==========
ws.Range("A1:A" & lastRow).Interior.Color = RGB(255, 255, 0)
' ========== 処理6: 保護を戻す ==========
If ws.ProtectContents = False Then
ws.Protect Password:="yourpassword"
End If
MsgBox "処理が完了しました。", vbInformation
Exit Sub
ErrorHandler:
MsgBox "エラーが発生しました。" & vbCrLf & _
"エラー番号: " & Err.Number & vbCrLf & _
"エラー内容: " & Err.Description, vbCritical
' エラー時も保護を戻す
On Error Resume Next
If Not ws Is Nothing Then
ws.Protect Password:="yourpassword"
End If
End Sub
💡 エラー1004を防ぐ5つのベストプラクティス
| 項目 | ベストプラクティス | 理由 |
|---|---|---|
| 1️⃣ シート名・ファイル名 | 変数や定数で一元管理 | タイプミスを防ぎ、変更時の修正が1箇所で済む |
| 2️⃣ 範囲指定 | 固定値を避け、動的に取得 | データ量の変化に対応でき、範囲外エラーを防げる |
| 3️⃣ ファイル操作 | Dir()で事前存在確認 | 存在しないファイルへのアクセスを未然に防ぐ |
| 4️⃣ Select/Activate | できるだけ使わない | 実行速度が速く、エラー1004の発生率が下がる |
| 5️⃣ エラーハンドリング | On Error GoToを必ず設定 | 予期せぬエラーでも安全に処理を終了できる |
❓ よくある質問(FAQ)
Q1. エラー1004とエラー9の違いは?
A. エラー9はインデックス(番号や名前)が範囲外の場合に発生します(例: 存在しないシート番号を指定)。エラー1004はオブジェクト操作全般の失敗で、原因が多岐にわたります。
詳しくは実行時エラー9の記事も参照してください。
Q2. On Error Resume Nextを使うと問題ない?
A. On Error Resume Nextはエラーを無視して次の行に進むため、本来のエラー原因を見逃す危険があります。基本的にはOn Error GoToで適切にエラー処理を行うのがベストです。
詳しくはOn Errorの基本記事をご覧ください。
Q3. エラー1004が発生したときのデバッグ方法は?
A. 以下の手順でデバッグします。
- F8キー(ステップ実行)で1行ずつ実行し、どの行でエラーが出るか特定
- イミディエイトウィンドウ(Ctrl+G)で変数の中身を確認
- ブレークポイント(F9)を設定して一時停止→変数をチェック
Q4. ファイルパスにスペースが含まれているとエラーになる?
A. 全角スペースや特殊文字が含まれていると、VBAが正しく認識できずエラー1004が発生する場合があります。ファイル名・フォルダ名は半角英数字と記号(ハイフン、アンダースコア)のみにするのが安全です。
Q5. Selectを使わないコードの書き方を教えて!
A. 以下のようにワークシート変数で直接操作します。
' ❌ Selectを使うコード
Worksheets("売上").Range("A1").Select
Selection.Value = "更新"
' ✅ Selectを使わないコード
Dim ws As Worksheet
Set ws = Worksheets("売上")
ws.Range("A1").Value = "更新"
Selectを使わない方が実行速度が速く、エラーも減ります。
📚 関連記事
- 【ExcelVBA・マクロ】実行時エラー9「インデックスが有効範囲にありません」の原因と対処法
- 【ExcelVBA】On Errorの基本|エラーで止まらない”安全な処理”の書き方
- いがぴブログ – ExcelVBAの勉強記録
✅ まとめ
実行時エラー1004は、VBAで最も頻繁に遭遇するエラーのひとつですが、原因を正しく理解すれば必ず解決できます。
この記事で紹介した8つの原因と対処法を押さえておけば、ほとんどのエラー1004に対応できます。
特に重要なポイント:
- ✅ シート名・ファイルパスは変数で一元管理
- ✅ Dir()でファイル存在を事前確認
- ✅ 範囲指定は動的に取得(固定値を避ける)
- ✅ Select/Activateを使わず直接操作
- ✅ On Error GoToで安全なエラーハンドリング
実務では、この記事の「汎用エラー1004対策テンプレート」をコピーして、自分のコードに組み込んで使ってください。
エラー1004で困ったときは、ぜひこの記事を見返してください!
💬 質問・感想はコメント欄へ!
「この方法で解決できた!」「こんなケースはどうすればいい?」など、お気軽にコメントください。

コメント