概要
Excel VBAを習得する過程で、誰もが最初に直面する大きな壁が「複数のシートに対する一括処理」です。特定のシートだけではなく、ブック内のすべてのシートに対して同じフォーマットを適用したり、特定のデータを抽出したりする作業は、業務自動化の基本中の基本です。しかし、この「全シート走査」を疎かにすると、コードが冗長化し、メンテナンスが困難なプログラムになりがちです。本記事では、VBA初級者から中級者へステップアップするために不可欠な、Worksheetsコレクションを巡回する二つの主要手法を徹底解説します。
詳細解説
VBAにおいて、ブック内の全シートを操作する手法には大きく分けて「インデックス番号による走査(For~Next)」と「オブジェクトの列挙(For Each~Next)」の二つが存在します。
まず、一つ目の「For i = 1 To Worksheets.Count」という手法は、シートのインデックス番号を利用する方法です。Worksheets.Countプロパティは、ブック内に存在するシートの総数を返します。この数値をループの終了条件に設定することで、1番目のシートから最後のシートまで順番に処理を実行します。この手法の最大の利点は、現在の処理対象が「何番目のシートか」という情報を数値として保持できる点にあります。
次に、二つ目の「For Each ws In Worksheets」という手法です。これはオブジェクト指向的なアプローチであり、コレクション内の要素を一つずつ変数(この場合はws)に代入しながらループを回します。コードが非常に直感的であり、シートの名前やインデックスを意識する必要がないため、現代のVBA開発において最も推奨される手法です。
なぜこの二つの手法を理解する必要があるのか。それは、Excelという環境が常に「シートの追加・削除」という動的な変化を伴うからです。ハードコーディングで特定のシート名を指定し続けると、シート名が変更された瞬間にプログラムはエラーを吐き出します。ループ処理をマスターすることは、堅牢で柔軟なプログラムを作るための第一歩なのです。
サンプルコード
以下に、それぞれの手法を用いた実践的なコードを提示します。これらは全シートのA1セルに現在のシート名を書き込むというシンプルな例ですが、応用範囲は無限大です。
'手法1:インデックス番号による走査(For~Next)
Sub LoopByCount()
Dim i As Long
' Worksheets.Countでシートの総数を取得
For i = 1 To Worksheets.Count
' インデックス番号でシートを指定
With Worksheets(i)
.Range("A1").Value = "このシートは" & .Name & "です"
End With
Next i
End Sub
'手法2:オブジェクトの列挙(For Each~Next)★推奨
Sub LoopByObject()
Dim ws As Worksheet
' 各シートオブジェクトをws変数に格納しながらループ
For Each ws In ThisWorkbook.Worksheets
' シートの状態を確認(非表示シートを除外する等の制御が可能)
If ws.Visible = xlSheetVisible Then
ws.Range("A1").Value = "このシートは" & ws.Name & "です"
End If
Next ws
End Sub
実務アドバイス
実務でこれらのコードを使用する際、必ず考慮すべき点が「例外処理」です。例えば、ブックの中には「集計用シート」や「設定用シート」など、処理対象から除外したいシートが混在していることが多々あります。
For Eachループ内で「If ws.Name <> “設定” Then」のように条件分岐を加えるのは初歩ですが、さらに高度な手法として「シートのCodeName(オブジェクト名)を利用する」というテクニックがあります。シート名がユーザーによって変更されても、VBAエディタ上で設定するプロパティであるCodeNameは変化しません。
また、ループ処理中のパフォーマンスについても言及しておきます。画面更新(ScreenUpdating)を停止させることは基本ですが、全シートを巡回する際は、処理の途中で「警告ダイアログ」が表示されないよう、DisplayAlertsプロパティをFalseに設定することも忘れないでください。特にシートの削除を伴う全シートループを行う場合、この設定が漏れていると、何百回とクリックを求められる悲劇的な事態に陥ります。
さらに、大きなブックを扱う際は、ループの進行状況をステータスバー(Application.StatusBar)に表示させる工夫もプロの技術です。「何%完了したか」を視覚化することで、ユーザーの不安を解消し、フリーズと誤認されるリスクを減らすことができます。
まとめ
全シートを走査するスキルは、VBAにおける「自動化の骨格」です。インデックスを利用するForループは数値管理が必要な場合に、そしてFor Eachループはオブジェクトを直接扱うモダンな記述として、状況に応じて使い分けることが重要です。
特にFor Eachループは、コードの可読性が高く、バグを未然に防ぐためにも優先的に採用すべきです。今回紹介したコードをベースに、皆さんの業務環境に合わせて「特定の文字列を含むシートだけを処理する」「特定のセルが空白ならスキップする」といった条件分岐を組み込んでみてください。
VBAは、単にコードを書く技術ではなく、業務の「構造」をプログラムに落とし込む設計の技術です。シートという単位を自動化の最小単位として捉え、ループ処理を完全に手足のように操れるようになれば、あなたの業務効率は劇的に改善されます。今日から、手動で行っている全シートへの繰り返し作業を、すべてVBAのループ処理に任せてしまいましょう。それが、ベテランエンジニアへの最短ルートです。
