【VBA入門】危険!For Each~Nextステートメントによる全シート操作に潜むリスクを解説

Excelブック内の全シートに対する処理。「無条件」処理がもたらすリスクを回避するには。


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実務の効率化において、ご参考お役立てになれば幸いです。


全国対応!お気軽にお問い合わせください