和風スパゲティのレシピ

日本語でコーディングするExcelVBA

偶数シートなど飛び飛びのシートをループする

偶数番のシートや、3つおきのシートなど、
規則性がある飛び飛びのシートをループ処理するコードを紹介します。



飛び飛びのシート

こんなブックで、「データシートだけ」をループ処理する方法ですね。
 

Forステートメントの「Step」を使う

最も基本の書き方がこちらです。

Dim シート番号 As Long
For シート番号 = 2 To 6 Step 2

    Worksheets(シート番号).Cells(1, 1) = 1

Next

For~Nextステートメントでループ処理を書くとき、
Stepを指定することで、1週ごとにカウンタ変数をいくつ増やすかを設定することができます。

サンプルは2から6までを2ずつ増やしながらループしますので、
2、4、6番目のシートを処理することができます。


Stepは書き方が単純でしかも万能なので、
しっかり身に着けておきましょう。


例えばStepにはマイナスも指定できるため、

Dim シート番号 As Long
For シート番号 = 6 To 2 Step -2

    Worksheets(シート番号).Cells(1, 1) = 1

Next

とすれば、6、4、2と、
年度が古い順番にデータシートをループ処理することもできます。

シートのインデックス番号を偶奇判定する

上記のStepさえ覚えればいらない方法ですが、

Dim シート番号 As Long
For シート番号 = 2 To 6
    If WorksheetFunction.IsEven(シート番号) Then

        Worksheets(シート番号).Cells(1, 1) = 1

    End If
Next

と、For文ではすべてのシートをループして、直後のIf文でシート番号を偶奇判定する方法もあります。

こちらも知識として知っておいて損はないですね。


偶奇判定はWorksheetFunctionのIsEvenとIsOddで行うと読みやすい気がしますが、
余りを求めるMod演算子を用いて

If シート番号 Mod 2 = 0 Then

と書くこともできます。

3つ飛び、4つ飛びなどをやりたい場合は、Mod演算子を使って下さい。

シート名で判定する

シート名に規則性がある場合は、それで判定することもできます。

Dim シート番号 As Long
For シート番号 = 1 To Worksheets.Count
    If Left(Worksheets(シート番号).Name, 3) = "データ" Then

        Worksheets(シート番号).Cells(1, 1) = 1

    End If
Next

Left関数でシート名の前方3文字を判定することで、
「データ○○」というシートだけを処理するコードです。


「たぶん規則的なんだけど、本当にちゃんと並んでるか怪しいブック」では、
シート名で判定したほうが安全ということもあるかもしれません。


例えば怪しいブック対策としては、

Dim シート番号 As Long
For シート番号 = 1 To Worksheets.Count
    If Left(Worksheets(シート番号).Name, 3) = "データ" _
    And Instr(Worksheets(シート番号).Name, "(") = 0 Then

        Worksheets(シート番号).Cells(1, 1) = 1

    End If
Next

このようにInstr関数で「(」を含まないシートを条件とすることで、
「データ2021 (1)」のようなコピーシートをはじくこともできます。


このシート名判定も、Stepとは違う観点で万能ですので、覚えておきましょう。

おまけ:変数名「シート番号」について

For文による「シートインデックス番号を用いたループ処理」で、

Dim i As Long
For i = 2 To 5
    Worksheets(i).Range("A1") = 1
Next

と、変数名に「i」を使っているコードをよく見かけますが、
これはなるべくやめた方が良いです。


理由は単純で、

' 2~5番目のシートの、A1~A4セルを処理	
Dim i As Long	
For i = 2 To 5	
    For i = 1 To 4	
        Worksheets(i).Cells(i, 1) = 1 ' ←これはダメ。シートもセルもiを使おうとしてダブってる	
    Next	
Next	

と、あとあと「同じ名前の変数は1個まで」という決まりに困ることになるからです。


ワークシートは「何かの親オブジェクト」として登場することが多く、
 「シートを○○するマクロ」
ではなく、
 「シート内の△△を○○するマクロ」
を作ることが多いです。

△△は当然セルが多いですね。


この時、親側で一番使いやすい「i」を使ってしまうと、
もっとたくさん処理を書かなければいけないセルなどに「i」が使えない
のです。


一番ありがちなやらかしとしては、
今まで作ったコード同士をコピペ合体できない><
なんて事態を往々にして招きます。


そんでもって、シートをi、行番号をj、列番号をkみたいに、
今まで書いたコードの「置換ができない1文字カウンタ」を、
ひとつひとつ手で書き換えてツギハギ対応していくと、
たぶんいつか崩壊します(笑)
 
 

For シート番号 = 2 To 5	
    For R = 1 To 4	
        For C = 2 To 3	
            Worksheets(シート番号).Cells(R, C) = 1	
        Next	
    Next	
Next

このように、シート番号に限らず、行や列なども分かりやすい変数名にしておけば、
変数の取り違えも減らせますし、コピペ合体もとても楽になります。

カウンタ変数は、何のカウンタかわかるように命名しましょう。


ということで、本サイトでは「そのままコピペで動くコード」にしたいため、
「シート番号」という変数名にしています。


今回のコードたちも、ForからNextまでの間に皆さんが書いた「セルをいじるコード」をコピペ挿入しても、問題なく動きます。

シートの指定はもちろん書き換える必要がありますが、
Worksheetを変数にSetしてもいいし、「シート番号」は置換に超強いので楽勝です。


シート番号という名前がまどろっこしければ、
自分で作る際は「s」とかでもいいです。

とにかく「i」はやめておきましょう(´∀`;)


よろしければこちらの記事もどうぞ

www.limecode.jp