Excelブック内の全シートに対する処理。「無条件データ処理」がもたらすリスクを回避するには。
みなさん、こんにちは。セルネッツ竹本です。
今回は、「For Each~Nextによる繰り返し処理」をテーマに、解説をしたいと思います。
◆実務でも頻度の高い「全シート処理」For~Nextステートメントは何故キケン?
まず、ブック内のシートには、可視化されないシート(表示できないシート)が潜んでいる可能性があります。
【1つ目】
これはVBAプログラムからしか表示することさえできない「xlSheetVeryHidden」を適用しているケースがあるためです。
↓通常、VBAからのシート表示 or 非表示は以下で記述します。
この方法で非表示したシートは、シートタブを右クリックで隠しシートも表示できます。
Worksheets(S_Idx).Visible = True ‘表示
Worksheets(S_Idx).Visible = False ‘非表示
↓但し、以下の方法で、シートを非表示した場合は、VBAから解除しないと見えません。
Worksheets(S_Idx).Visible = xlSheetVeryHidden ‘非表示
そのため、ユーザ自身がそれを認識できていないケースも多くあります。
↓【VBA入門】存在するシートなのに表示させない方法
https://www.cellnets.co.jp/dev_column/9271
【2つ目】
シート総数をとわず、とにかく「全て無条件で処理」あるだけ全部!
シート名もシート番号もノーチェックです。
For Each Obj_Ws In Worksheets
Obj_Ws.Range("A1").Value = "ABC"
Next Obj_Ws
これにより、想定し得ぬ予期せぬシートが存在していた場合に、意図しない結果を招くリスクがあるためです。
これを回避するためには、最低限の妥当性チェックを反映するだけでも、そのリスクを低減できます。
‘※※※※※※※※※※※※※※※※※※※※※※※※※※※
Sub M_全シートのデータを更新()
‘※※※※※※※※※※※※※※※※※※※※※※※※※※※
Dim S_CntSt総数 As Long
Dim S_Idx As Long
Dim S_St名 As String
S_CntSt総数 = Worksheets.Count
For S_Idx = 1 To S_CntSt総数
S_St名 = Worksheets(S_Idx).Name
If InStr(S_St名, "受注") > 0 Then
'ここで当該処理
Else
End If
Next S_Idx
End Sub
つまり、処理対象とするシート名にはルールがあるはず、という考え方です。
せめて、シート枚数を把握したうえで、[何枚目]の[何と言う名前のシート]で実行時エラーが発生しているかが把握できる設計だと、不具合の際の対応は、効率よく行えるでしょう。是非、習慣として身につけておきたいものです。
今回のテーマは、「For Each~Nextによる繰り返し処理」について、解説を行いました。
本記事が、Excel実務の効率化において、ご参考お役立てになれば幸いです。