指定した名前のシートがあるか調べる
ブック内のある名前のシートが存在するが調べたい時があります。
このような処理は、ブック全体のシートを走査して該当のシート名があるかをTrue・Falseで返すようにすれば良いでしょう。
汎用的に使えるようプロシージャにまとめました。後から改造するときに役立つ方法も指南しますので参考にしてみてください。
サンプルコード
'sheetNameというシート名があるかを返す
Public Function isExistsSheet(sheetName As String) As Boolean
Dim b As Boolean
Dim ws As Variant
b = False
For Each ws In Sheets
If ws.Name = sheetName Then
b = True
Exit For
End If
Next
isExistsSheet = b
End Function
コード解説
プログラムとしては、Sheetsというブック内のシートのコレクションを For Each In で1つづつ取り出して、その名前が引数の文字列と同じかを比較しているだけです。
個人的には2つの工夫点があります。
一つは、プロシージャ名の命名の仕方です。私の場合はそのプロシージャがTrue・Falseを返すような場合は、Is で始まるような名前にしています。
今回は、isExistsSheet としています。これだと、使用する際にどんな値が返ってくるのかイメージしやすくなります。
もう一つは、Boolean型の変数を用意する点です。
冒頭でBoolean型の変数を宣言した後、すかさず False で初期化します。
そうしてから True となるような条件式を書いていき、そこでBoolean型の変数にTrueを代入するようにします。
今回の場合、Trueと判断してすぐに Exit Function としても良いのですが、敢えて Exit For としてFor文を抜けるようにしています。
理由は、Functionでは、プロシージャ名=値 という形で終わるためIf文の中や、最後で何度もこの形で書かなければならない場合、プロシージャ名を変更したときにエラーの原因となりやすいからです。
プロシージャ名=値 という形はなるべく少なく、最後に書くようにした方が後々改造や変更をするときに便利です。
最後に上記のプログラムをテストするためのコードを書きます。
Sub testCode()
Debug.Print isExistsSheet("Sheet1")
End Sub
こうして一旦小さなプログラムでテストすることでデバッグ作業を最小限にすることができます。
特に値を返すFunctionなどは、Subの内部から実行しないと動作確認ができませんのでテストコードは必須となります。
サンプルコード(別ブックを探す)
今度は、別ブック内に指定するシート名があるか判断するプログラムを書いてみます。
'指定したブックの Sheets に指定した名前のシートが存在するか判定する
Public Function isExistsBookInSheet(bookName As String, sheetName As String) As Boolean
Dim b As Boolean
Dim ws As Variant
Dim wb As Variant
b = False
For Each wb In Workbooks
If wb.Name = bookName Then
Exit For
End If
Next
If IsEmpty(wb) Then
MsgBox bookName & "ブックがありません。"
GoTo LABEL
End If
For Each ws In wb.Sheets
If ws.Name = sheetName Then
b = True
Exit For
End If
Next
LABEL:
isExistsBookInSheet = b
End Function
コード解説
今回のコードでは、引数を増やしてブック名を指定するようにしています。
見に行くブックは開いていなければいけません。
最初に Workbooksコレクションを巡り、開いているブック名を調べます。
もし無かった場合は、For Each を抜けた後、wb は Empty となっていますので、これを拾います。
そのあとはメッセージを出して GoTo LABEL で最後まで飛ばします。
ブック名がヒットした場合は、wb に値(オブジェクト)が入ったままなのでこれをそのまま使用します。
後は前と同じで、シートのコレクションを巡って指定のシート名を探します。
今回のように改造しても、プロシージャ名=値 という形は最後だけなので、プロシージャ名の書き換えは1カ所だけでOKです。
返り値のBooleanの管理もやりやすいと思います。
最後にテストコードです。
Sub testCode2()
If isExistsBookInSheet("作業記録.xlsx", "2211") Then
MsgBox "見つかりました。"
Else
MsgBox "見つかりませんでした。"
End If
End Sub
余談:プログラミングの流儀
今回はFunctionでBooleanを返す場合のプログラムの書き方を解説させていただきました。
プログラムの書き方は、一通りという事はなくいくつかの表現方法があります。
優劣はあるのかもしれませんが、自分の書きやすい読みやすいコードに落ち着いてきます。たまに人のコードを見ると違和感を覚える事がありますが、その人が別の言語に触れているとその癖が出るのかもしれません。
例えば私などはC言語風の書き方になりがちです。変数の宣言は上にまとめて書くとか、For文やIf文の字下げなどは、VBAをやる前から癖がついていました。
また、RangeよりもCellsを使う事がほとんどでRangeの使用意義に疑問すらありました。
現在では、Rangeは絶対的ば場面で、Cellsは相対的な場面で使用するようになり、変数の宣言も必要になった時点で書くような手法に落ち着きました。
書き方についてはある程度、良い悪いはあると思いますが、個人々の流儀というのはどうしてもあります。あまり固執せずに柔軟な姿勢で、良いと思う事は吸収しようという気持ちでいるのがよろしいかと思います。