文字列が等しいかどうかの判定


次のコードをご覧ください。

Sub Sample()
    Dim SheetName As String, i As Long
    SheetName = InputBox("シート名を入力してください")
    If SheetName = "" Then Exit Sub
    For i = 1 To Sheets.Count
        If SheetName = Sheets(i).Name Then
            MsgBox SheetName & " は存在します"
            Exit Sub
        End If
    Next i
    Sheets.Add(After:=ActiveSheet).Name = SheetName
End Sub

新しいワークシートを挿入するマクロです。挿入したシートには、ユーザーが入力した名前を付けます。実際に試してみましょう。

すでに存在する名前が指定された場合はメッセージを表示して処理を中止するようにしています。しかし、このマクロには重大なバグが隠れています。何だと思いますか。この先を読む前に、まずはじっくりとコードを読んでください。

では、バグの正体を明らかにしましょう。もう一度実行してみます。

新しいシート名として「SHEET3」を指定したらエラーになりました。このブックにはすでに「Sheet3」が存在しています。シート名は大文字と小文字を区別しないので、新しい「SHEET3」とすでに存在する「Sheet3」は同じ名前だと判定されてエラーになったのです。これは、ユーザーが入力した文字列と、既存のシート名を「If SheetName = Sheets(i).Name」と単純に比較しているのが原因です。このように、大文字と小文字を区別しないケースでは、あと一工夫が必要になります。

「SHEET3」と「Sheet3」を比べて"同じ"と判定するにはどうしたらいいでしょう。これには発想の柔軟さが必要です。そもそも、大文字と小文字が混在しているからいけないんです。どちらも大文字に変換してしまえば、大文字/小文字による差異はなくなります。文字列を大文字に変換するにはUCase関数を使います。

Sub Sample()
    Dim SheetName As String, i As Long
    SheetName = InputBox("シート名を入力してください")
    If SheetName = "" Then Exit Sub
    For i = 1 To Sheets.Count
        If UCase(SheetName) = UCase(Sheets(i).Name) Then
            MsgBox SheetName & " は存在します"
            Exit Sub
        End If
    Next i
    Sheets.Add(After:=ActiveSheet).Name = SheetName
End Sub

もちろん、どちらも小文字に変換してもいいです。文字列を小文字に変換するのはLCase関数を使います。