実行時エラー1004「Range クラスの Select メソッドが失敗しました」の原因と直し方
Select や Activate で実行時エラー1004が出る原因(アクティブでないシートのセルを選んでいる・非表示のシート)と、Select を使わずに書き直す方法を、コード例で解説します。
どんなエラーか
ws.Range("A1").Select のように、セルを選択する行で止まるエラーです。メッセージは「Range クラスの Select メソッドが失敗しました」や「Worksheet クラスの Select メソッドが失敗しました」と表示されます。
マクロの記録で作ったコードは Select と Selection を多く使うため、シートを指定する書き方に直したときに、このエラーが出やすくなります。
よくある原因1:アクティブでないシートのセルを選んでいる
セルを選択できるのは、今画面に表示されている(アクティブな)シートだけです。別のシートのセルを Select すると、エラーになります。どうしても選択したい場合は、先にそのシートをアクティブにするか、Application.Goto を使います。
' エラーになる例(Sheet1 が表示されているときに Sheet2 のセルを選ぶ)
Worksheets("Sheet2").Range("A1").Select
' 正しい例1:先にシートをアクティブにする
Worksheets("Sheet2").Activate
Worksheets("Sheet2").Range("A1").Select
' 正しい例2:Application.Goto はシートの切り替えと選択を一度に行う
Application.Goto Worksheets("Sheet2").Range("A1")よくある原因2:シートが非表示、またはブックがアクティブでない
非表示のシートは、アクティブにすることも、セルを選択することもできません。また、別のブックのシートを選ぶ場合は、先にそのブックをアクティブにする必要があります。
非表示のシートにデータを書き込む処理であれば、そもそも選択は必要ありません。次の項目のように、Select を使わない書き方に直すのがおすすめです。
根本的な対処:Select を使わない書き方に直す
VBA では、セルを選択しなくても、シートとセルを指定すれば値の読み書きやコピーができます。Select をなくすと、このエラーが出なくなるだけでなく、画面のちらつきが減り、処理も速くなります。
直し方は、「Select した行」と「Selection を使う行」を1行にまとめることです。
' マクロの記録で作られるコード
Sheets("集計").Select
Range("B2").Select
Selection.Value = "合計"
Range("A1:D10").Select
Selection.Copy
' Select を使わない書き方
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("集計")
ws.Range("B2").Value = "合計"
ws.Range("A1:D10").Copy選択が必要な場面と注意点
処理の最後に、利用者に見てほしいセルを表示したい場合など、選択が必要な場面もあります。その場合は、処理の途中ではなく最後に1回だけ Application.Goto を使うと、エラーを避けつつ目的を果たせます。
- Application.ScreenUpdating = False の間でも Select は使えるが、処理が遅くなるため避ける
- Goto の引数 Scroll:=True を付けると、そのセルが画面の左上に来るようにスクロールする
- グラフシートなど、ワークシート以外のシートには Range がないため、別のエラーになる
※マクロの記録で作ったコードを本番で使う前に、Select と Selection を減らしておくと、このエラーの多くを防げます。