シートを検索する


マクロを作るとき、その動作をイメージします。そのとき、無意識のうちに、人が手動で操作するときの動作を考えて「これって、すごく時間がかかるのでは」と誤解することが多いです。もちろん、人が手動でやれば膨大な時間を要する作業でも、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秒でした。