マクロを作るとき、その動作をイメージします。そのとき、無意識のうちに、人が手動で操作するときの動作を考えて「これって、すごく時間がかかるのでは」と誤解することが多いです。もちろん、人が手動でやれば膨大な時間を要する作業でも、VBAでやれば一瞬ということもあります。たとえば、ワークシートの中から、特定のセルを探し出すという動作は、手動で1セルずつ見ていったら大変です。でも、Excelの検索機能を使えば一瞬で終わります。今回は、先日のセミナー中に受講生から質問された話です。
膨大なワークシートから、特定のシートを探し出すにはどうしたらいいでしょう?
膨大なというのが、どれくらいか分かりませんが、ここでは1,000枚のワークシートから、任意のシートを探し出してみましょう。

この画像だけでは証拠になりませんが、シートが1,000枚あります。
質問された方は、セルの検索みたいな機能がないかと期待されたのだと思います。そんなものは、ありません。じゃ、どうするかといえば、簡単です。シートの名前を1枚ずつチェックしていけばいいんです。私がそう答えると「ええ?1,000枚もチェックしたら、さぞ時間がかかるのでは」と言いたげな表情をされていました。じゃ、やってみましょう。
Sub Sample1()
Dim i As Long
For i = 1 To Sheets.Count
If Sheets(i).Name = "Sheet1000" Then
Sheets(i).Range("A1") = Now
End If
Next i
End Sub

パソコンの性能にもよりますが、こんなもんです。表示されている数値は、GetTickCountを使って計測した、ミリ秒単位の所要時間です。ああ、ちなみに、上記のコードで見つかる"Sheet1000"は、右端にある1,000枚目のシートです。
「VBA高速化テクニック」にも書きましたが、繰り返しの命令は、For NextよりもFor Eachの方が、ほんの少し速いです。これ、For Eachでやってみましょう。
Sub Sample2()
Dim ws As Worksheet
For Each ws In Sheets
If ws.Name = "Sheet1000" Then
ws.Range("A1") = Now
End If
Next ws
End Sub

あるいは、ただ存在の確認をしたいだけでしたら、1枚ずつチェックしないでも、エラーを利用する方法もあります。たとえば、もし[Sheet1000]というシートが存在していたら、Sheets("Sheet1000").Nameを取得できます。もし存在していなかったら、Sheets("Sheet1000").Nameを取得しようとするとエラーになります。だから、試してに取得してみて、エラーになるかどうかで判定すればいいんです。
Sub Sample3()
Dim A As String
On Error Resume Next
A = Sheets("Sheet1000").Name
If Err.Number > 0 Then
MsgBox "存在しません"
Else
MsgBox "存在します"
End If
End Sub
これも所要時間を計測したのですが、何回やっても0秒でした。