【Excel VBA】全シートに同じ処理を繰り返す方法|For Eachで一括処理

【VBA】複数シートに同じ処理を一括実行する方法の解説用アイキャッチ画像 VBA

ブック内の全シートに同じ書式設定や集計処理を行う場合、1シートずつ手作業で対応すると時間がかかります。

この記事では、For Eachを使って全シートに同じ処理を繰り返すVBAコードを解説します。特定シートを除外する方法や、処理対象を間違えないための考え方も確認できます。

  1. この記事でできること
  2. 完成イメージ(Before / After)
  3. どんな場面で使う?
  4. 今回の検証条件と一括処理の結果
  5. 実行前の準備
    1. バックアップを取る
  6. For Each・番号ループ・シート名指定の判断基準
  7. コード(最小版)– 全シートに同じ処理を一括実行
    1. 書き換えポイント
    2. コードの流れ
  8. コード(実務版)– シート名で対象を絞り、特定シートをスキップ
    1. 書き換えポイント
    2. コードの流れ
  9. 実務で起きやすい全シート処理の失敗例
    1. 失敗例1: ws. を付け忘れてアクティブシートだけ処理する
    2. 失敗例2: 設定シートや集計シートまで上書きする
    3. 失敗例3: 非表示シートまで処理して気づかない
  10. よくある落とし穴5選
    1. 1. ws. を付け忘れてアクティブシートだけ処理される
    2. 2. 目次シートや集計シートまで処理してしまった
    3. 3. 非表示シートも処理されてしまう
    4. 4. シート名の全角・半角やスペースが一致しない
    5. 5. ループ中にシートを追加/削除するとエラーになる
    6. VBAで複数シート処理中に特定シートだけエラーになるときの対処法
    7. VBAのFor Eachループで処理順がバラバラになるときの対処法
  11. 全シート処理で最初に決める除外ルール
    1. 除外シートを先に判定する例
  12. FAQ
    1. Q1: 特定のシートだけを処理したい(全シートではなく)
    2. Q2: 処理の進捗をリアルタイムで確認したい
    3. Q3: 全シートに色分けを一括適用したい
    4. Q4: 全シートのデータを1つのシートに集約したい
    5. Q5: ボタン1つで全シート処理を実行したい
  13. まとめ
    1. 関連記事
  14. 次にやりたくなること
  15. 次に読みたい関連記事

この記事でできること

12枚のシートに同じ操作を手作業で繰り返す。 1月シートを開いて書式変更、2月シートを開いて同じ操作、3月シートを開いて…。12回繰り返して30分。しかも1シートだけ漏れて月次報告で手戻り。毎月やるのに、毎月ヒヤヒヤしている――そんな経験はないだろうか。

この記事のVBAを使えば、全シート(または指定シート)に同じ処理を一括で適用できる。 12シート分の作業が数秒で完了し、漏れもゼロになる。

For Eachループの使い方はシンプル。コピペして実行するだけで、今日から繰り返し地獄を卒業できる。

  • VBAで1つのExcel内の全シートに同じ処理を一括実行できる
  • 特定のシート(目次・集計など)をスキップして処理できる
  • シート数が増えても、コードを変えずにそのまま動く

12枚の月別シートに同じ書式変更を手作業で繰り返していた。1枚忘れて上司に指摘されたことも。VBAで一括処理にしてからは、1クリックで全シート完了。あのヒヤヒヤがなくなった。

完成イメージ(Before / After)

複数シートの同じ処理を一括実行のBefore After図解
複数シートの同じ処理を一括実行で、手作業からVBA自動化へ変わる流れを整理します。
複数シートの同じ処理を一括実行の処理フロー図解
複数シートの同じ処理を一括実行の処理フローを4ステップで確認できます。
複数シートの同じ処理を一括実行の実務チェックリスト
複数シートの同じ処理を一括実行を本番で使う前に確認したいポイントです。

Before(手動で繰り返し):

  1. 「1月」シートを開いてヘッダー行を挿入
  2. 「2月」シートを開いて同じ操作
  3. 「3月」シートを開いて同じ操作
  4. …(12回繰り返し)
  5. 1シートだけ漏れて、あとから手戻り

After(VBAで一括処理):

  1. マクロを実行
  2. 全シート(または指定シート)に同じ処理が一括で適用される
  3. 処理完了のメッセージが表示される

12ヶ月分のシートに毎月同じ操作を手動で繰り返していた。1シートでも漏れると月次報告で手戻りになる。毎月やるのに30分以上かかっていたし、1シートだけ漏れて上司に指摘されたこともある。VBAのFor Eachループを使って一括処理するようにしてからは、12シート分の作業が数秒で終わるようになった。この記事で、同じ繰り返し地獄から抜け出してほしい。

同じ操作を12回繰り返すのは、人間がやる仕事じゃない。VBAのループに任せよう。

なお、「複数のファイルを1つに統合する」のとは別のテーマ。ファイル統合は/005を参照。

どんな場面で使う?

  • 月別12シートにヘッダー行を挿入・書式変更を一括で適用したい
  • 全シートのA1セルに同じ文言(「社外秘」など)を一括追記したい
  • 部署別シートの集計列を全シートまとめて更新したい
  • 特定のシート(目次・集計)だけスキップして、データシートだけ処理したい

今回の検証条件と一括処理の結果

この記事では、入力シート3枚、集計シート1枚、設定シート1枚のブックを想定し、全シート処理と除外シートありの処理を分けて確認しています。

確認したこと 結果 記事内での判断
全シートに同じ書式を適用For Eachでまとめて処理できる最小版で紹介
集計シートを除外シート名で先に判定すると安全実務版で紹介
非表示シートがある見えていないシートも処理対象になる必要なら Visible を確認する
処理中にシートを追加/削除ループが不安定になりやすいループ中の構成変更は避ける

Beforeは、各シートを開いて同じ操作を繰り返している状態です。Afterは、対象シートと除外シートを決めて、同じ処理を一括実行できる状態です。

実行前の準備

バックアップを取る

全シートに一括で変更を加えるため、意図しないシートにも影響する可能性がある。必ずファイルのコピーを別フォルダに保存してから実行する。

For Each・番号ループ・シート名指定の判断基準

全シート処理では、ただ回すより「どのシートを処理しないか」を先に決める方が大事です。対象外のシートまで処理すると、集計表や設定表を壊す原因になります。

状況 向いている書き方 理由
全シートに同じ処理をするFor Each ws In Worksheets読みやすく、シート数が変わっても対応できる
先頭から順番に番号で扱いたいFor i = 1 To Worksheets.Count処理順を番号で確認しやすい
決まった数枚だけ処理したいシート名の配列処理対象を明示できる
集計・設定・目次を除外したい除外判定を先に書く誤処理を防ぎやすい

自分なら、最初はFor Eachで書き、実務では除外シート名を配列や関数にまとめます。全シート処理は便利な分、対象外を壊さない設計が品質になります。

コード(最小版)– 全シートに同じ処理を一括実行


'============================================================
' ■ 全シートに同じ処理を一括実行(最小版)
'   → For Each で全シートをループし、A1セルに値を書き込む
'   ※ ThisWorkbook = このマクロが入っているブック
'     (ActiveWorkbook とは異なる。通常は ThisWorkbook を使う)
'============================================================
Sub ProcessAllSheets()

    Dim ws As Worksheet
    Dim count As Long
    count = 0

    For Each ws In ThisWorkbook.Worksheets

        '--- ★ここに各シートで実行したい処理を書く ---
        ws.Range("A1").Value = "更新日: " & Format(Date, "yyyy/mm/dd")
        ws.Range("A1").Font.Bold = True

        count = count + 1
    Next ws

    MsgBox count & " シートの処理が完了しました。", vbInformation

End Sub

書き換えポイント

変数・箇所 説明 初期値
'--- ★ここに〜 各シートで実行したい処理をここに書く A1に更新日を書き込み(デモ用)

コードの流れ

  1. For Each ws In ThisWorkbook.Worksheets で全シートを1枚ずつ取得
  2. ws.Range("A1") のように ws.を付けて 各シートのセルを操作
  3. 処理したシート数をカウントし、完了メッセージを表示

重要: セルを操作するときは必ず ws.Range("A1") のように シート変数を付けるRange("A1") だけだと、ループ中ずっとアクティブシートのA1を操作してしまう。これが最大の落とし穴。

コード(実務版)– シート名で対象を絞り、特定シートをスキップ

実務では「目次」「集計」「マスタ」のようなシートは処理対象から外したい。また、非表示シートも除外したほうが安全。

この仕組みを入れてからは、「目次シートまで書き換えてしまった…」という事故がなくなった。スキップ対象を配列で管理するだけで、安心感がまったく違う。色分けマクロ(/006)も全シートに一括適用できるので、月次報告書の見た目統一が一気に終わる。


'============================================================
' ■ 特定シートをスキップして一括処理(実務版)
'   → スキップ対象を配列で定義。非表示シートも除外
'   → 処理内容: ヘッダー行の挿入+書式設定(カスタマイズ可能)
'============================================================
Sub ProcessSheetsWithSkip()

    '--- ★書き換えポイント1: スキップするシート名 ---
    Dim skipSheets As Variant
    skipSheets = Array("目次", "集計", "マスタ")
    '--- ★ここまで ---

    Dim ws As Worksheet
    Dim count As Long
    count = 0

    For Each ws In ThisWorkbook.Worksheets

        '--- 非表示シートをスキップ
        If ws.Visible <> xlSheetVisible Then GoTo NextSheet

        '--- スキップ対象のシートをスキップ
        '    ※ GoTo NextSheet は VBA でスキップ処理を書く定番パターン。
        '      ネストが深くならず可読性が高い
        If IsInArray(ws.Name, skipSheets) Then GoTo NextSheet

        '--- ★書き換えポイント2: 各シートで実行したい処理 ---

        '--- 例1: 1行目にヘッダーを挿入
        ws.Rows(1).Insert
        ws.Range("A1").Value = "月次報告書"
        ws.Range("B1").Value = "更新日: " & Format(Date, "yyyy/mm/dd")

        '--- 例2: ヘッダー行の書式設定
        With ws.Range("A1:E1")
            .Font.Bold = True
            .Font.Size = 12
            .Interior.Color = RGB(0, 112, 192)
            .Font.Color = RGB(255, 255, 255)
        End With

        '--- ★ここまで ---

        count = count + 1

NextSheet:
    Next ws

    MsgBox count & " シートの処理が完了しました。" & vbCrLf & _
           "(スキップ対象・非表示シートは除外)", vbInformation

End Sub

'============================================================
' ■ 補助関数: 値が配列に含まれるかチェック
'============================================================
Private Function IsInArray(val As String, arr As Variant) As Boolean
    Dim i As Long
    For i = LBound(arr) To UBound(arr)
        If arr(i) = val Then
            IsInArray = True
            Exit Function
        End If
    Next i
    IsInArray = False
End Function

書き換えポイント

変数・箇所 説明 初期値
skipSheets スキップするシート名の配列。追加・削除は Array(...) 内を変更するだけ Array("目次", "集計", "マスタ")
'--- ★書き換えポイント2 各シートで実行したい処理 ヘッダー挿入+書式設定(デモ用)

コードの流れ

  1. スキップ対象の定義: Array("目次", "集計", "マスタ") でスキップするシート名を配列で指定
  2. 非表示チェック: ws.Visible <> xlSheetVisible なら処理をスキップ
  3. シート名チェック: IsInArray 関数でスキップ対象に含まれるか確認
  4. 処理の実行: 対象シートにヘッダー挿入+書式設定
  5. 完了メッセージ: 処理したシート数を表示

全シートにヘッダーを挿入した後、ボタン(/013)を設置すれば、次回からはワンクリックで一括処理できる。

実務で起きやすい全シート処理の失敗例

失敗例1: ws. を付け忘れてアクティブシートだけ処理する

ループ内では CellsRange を単独で書かず、ws.Cells のように対象シートを明示します。ここを省くと、見ているシートだけが変わることがあります。

失敗例2: 設定シートや集計シートまで上書きする

全シート処理では、処理しないシートを先に決めます。シート名に「集計」「設定」「目次」が含まれる場合は除外する、などのルールを用意します。

失敗例3: 非表示シートまで処理して気づかない

非表示シートも Worksheets には含まれます。表示中のシートだけ処理したい場合は、ws.Visible = xlSheetVisible を確認します。

よくある落とし穴5選

1. ws. を付け忘れてアクティブシートだけ処理される

原因: Range("A1").Value = "test" と書くと、ループ中ずっとアクティブシートのA1を操作する。

自分も最初、ws. を付け忘れて12シート分の処理が全部アクティブシートの1枚に上書きされた。「12シート処理完了」と出たのにアクティブシートしか変わっていなくて、しばらく原因が分からなかった。

対策: 必ず ws.Range("A1") のようにシート変数を付ける。ws.Cells, ws.Rows も同様。

2. 目次シートや集計シートまで処理してしまった

自分もこれで痛い目にあった。For Eachで全シートにヘッダー挿入を実行したら、「目次」シートにもヘッダーが入ってしまい、目次のリンクが全部ずれた。戻すのに1時間かかった。目次シートまでぶっ壊すとは思わなかった。

対策: 実務版のように skipSheets 配列でスキップ対象を事前に定義する。

3. 非表示シートも処理されてしまう

原因: For Each ws In Worksheets は非表示シートも含む。非表示にしていたマスタシートが書き換えられる可能性がある。

対策: ws.Visible <> xlSheetVisible でスキップする。実務版コードには組み込み済み。

4. シート名の全角・半角やスペースが一致しない

原因: If ws.Name = "目次" と書いたが、実際のシート名が「目次 」(末尾に半角スペースあり)だった。

対策: If Trim(ws.Name) = "目次" のように Trim(文字列の前後のスペースを除去する関数)でスペースを除去してから比較する。

5. ループ中にシートを追加/削除するとエラーになる

原因: For Each ループの途中でシートのコレクションを変更すると、VBAが混乱してエラーが出る。

対策: ループ中はシートの追加・削除をしない。必要なら、ループ前にシート名を配列に格納し、配列でループする。

VBAで複数シート処理中に特定シートだけエラーになるときの対処法

「一部のシートだけ処理されない」という場合、原因はシート名にスペースや特殊文字が含まれているか、グラフシートが混在していることだ。If ws.Type = xlWorksheet Then で通常のワークシートだけを対象に絞れば、グラフシートでのエラーを回避できる。

VBAのFor Eachループで処理順がバラバラになるときの対処法

「シートの処理順が想定と違う」という場合、原因はFor Eachがシートのインデックス順で処理するため、シートの並び順が変わると処理順も変わることだ。処理順を固定したい場合は、シート名を配列に格納して For i = 1 To UBound(arr) のインデックスループに切り替えれば解決する。

全シート処理で最初に決める除外ルール

全シートに同じ処理をかけるマクロは、作業時間を大きく減らせます。ただし、何も考えずに全シートを対象にすると、目次シート、集計シート、設定シート、非表示シートまで処理してしまうことがあります。実務では、ループを書く前に「処理するシート」と「処理しないシート」を決めておくのが安全です。

特に、部署内で使うブックはあとからシートが増えます。最初は3シートだけだったブックに、確認用、貼り付け用、バックアップ用のシートが追加されることもあります。シートが増えても壊れにくくするには、名前で除外する、接頭辞で対象を絞る、非表示シートは飛ばす、というルールを明示します。

  • 集計、設定、目次、マスタなどのシートは除外する
  • 非表示シートは処理対象に含めるか事前に決める
  • 処理対象シートの名前に共通ルールを付ける
  • ActiveSheetに頼らず、必ず ws. を付けて処理する
  • 処理前に対象シート名をログやメッセージで確認できるようにする

除外シートを先に判定する例

For Each ws In ThisWorkbook.Worksheets
    If ws.Name <> "集計" And ws.Name <> "設定" Then
        If ws.Visible = xlSheetVisible Then
            ws.Range("A1").Value = "処理済み"
        End If
    End If
Next ws

この例では、集計シートと設定シートを除外し、表示されているシートだけを処理しています。全シート処理は強力な分、間違えると一気に広がります。最初は対象シート名を確認するだけのテストにして、問題ないことを見てから実処理へ進むと安心です。

FAQ

Q1: 特定のシートだけを処理したい(全シートではなく)

スキップではなく対象シートを指定したい場合は、対象シート名を配列に入れて一致チェックする:


Dim targetSheets As Variant
targetSheets = Array("1月", "2月", "3月")

For Each ws In ThisWorkbook.Worksheets
    If IsInArray(ws.Name, targetSheets) Then
        ' 対象シートの処理
        ws.Range("A1").Value = "処理済み"
    End If
Next ws

Q2: 処理の進捗をリアルタイムで確認したい

ステータスバーに進捗を表示する:


Dim total As Long
total = ThisWorkbook.Worksheets.Count

For Each ws In ThisWorkbook.Worksheets
    count = count + 1
    Application.StatusBar = "処理中... " & count & " / " & total & " シート"
    ' --- 処理 ---
Next ws

Application.StatusBar = False  ' ステータスバーを元に戻す

Q3: 全シートに色分けを一括適用したい

ループ内で色分け処理を呼び出す。色分けの方法は/006を参照。


For Each ws In ThisWorkbook.Worksheets
    Call ColorByValue(ws)  ' 各シートを引数で渡す
Next ws

Q4: 全シートのデータを1つのシートに集約したい

これは「複数シートの一括処理」とは別のテーマ。複数Excelファイルを1つに統合する方法は/005を参照。1ファイル内のシート統合もループで可能だが、処理内容が複雑になるためカスタマイズの範囲。

Q5: ボタン1つで全シート処理を実行したい

/013で、ProcessSheetsWithSkip をボタンに割り当てる。シート上に「全シート一括処理」ボタンを置けば、同僚にも簡単に使ってもらえる。

まとめ

  • For Each ws In ThisWorkbook.Worksheets で全シートをループできる
  • ws.Range("A1") のようにシート変数を付けないと、アクティブシートだけ処理される(最大の落とし穴)
  • スキップ対象は配列で管理し、非表示シートも除外すると安全
  • シート数が増えてもコードの変更は不要。ループが自動で全シートを処理する

関連記事

  • /005 — 複数Excelファイルを1つに統合する方法。複数ファイルの統合はこちら。1ファイル内の複数シート処理は本記事
  • /006 — セルの値に応じて行を自動色分けする方法。全シートに色分けを一括適用する応用
  • /013 — マクロをボタン1つで実行する方法。一括処理マクロをボタンに割り当て
  • /043 — シートを別ブックにコピー・移動する方法。シート単位でファイルを分割したい場合に
  • /069 — シート名の取得・一括変更・存在チェックする方法。シート名を動的に扱いたい場合に

次にやりたくなること

  • /043 — シートを別ブックにコピー。月別シートを個別のExcelファイルに分割して配布したい場合に。一括処理でデータを整えた後、シートごとにファイルを分けるワークフローが作れる
  • /069 — シート名の取得・変更。シート名を動的に取得して処理に使ったり、一括でリネームしたりできる。シート一括処理と組み合わせると、より柔軟な自動化が可能になる
  • /006 — 行の自動色分け。全シートにステータス別の色分けを一括適用したい場合に
  • /023セルの書式を一括変更。全シートのフォントや罫線を一括で統一したい場合に
  • /032 — 最終行・最終列の取得。シートごとにデータ範囲が異なるときに正確に処理範囲を取得したい場合に

次に読みたい関連記事

コメント

タイトルとURLをコピーしました