🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

Excel VBA の UCase と LCase — 大文字小文字を無視した比較と StrConv のタイトルケースの罠

|

Excel VBA の UCase と LCase — 大文字小文字を無視した比較と StrConv のタイトルケースの罠

TL;DRUCaseLCase はテキストをすべて大文字、またはすべて小文字に 変換します。よくある間違いは、これらをデータのクリーニングのための関数だと 思い込むことです。これらの用途は 2 つだけ。比較(VBA の = は大文字小文字を 区別するので、"Yes" = "yes"False — 比較する前に両辺を UCase で 揃えます)と、表示です。これらは情報を失う不可逆な変換なので、保存済みの データを上書きしては絶対にいけません。そしてタイトルケースには組み込みの PCase がないため、StrConv(s, vbProperCase) を使いますが、これは普通の名前には 効いても McDonaldO'BrieniPhone を台無しにします。

大文字小文字の変換は VBA で最も単純な操作に思えますし、UCase/LCase 自体は 確かに単純です。バグが生まれるのは、人々がなぜそれらに手を伸ばすか、その理由の 方です。比較のツールとして使えば、これらは欠かせません。保存のツールとして使えば、 密かに情報を破壊します。

この記事で学べること

  • VBA で "Yes" = "yes" がなぜ False なのか — そして大文字小文字を無視して 比較する正しい方法
  • 大文字小文字を無視したマッチングの 3 つの方法(とどれを選ぶべきか)
  • UCase の出力で元データを上書きしてはいけない理由
  • タイトルケースのための StrConv — そしてそれに付きまとう固有名詞の罠

考え方の軸:大文字小文字は「比較」と「表示」のためであり、「保存」のためではない

UCase/LCase を、ページに加える編集ではなく、それを通して見るレンズの組だと 考えてください。2 つの文字列が大文字小文字を問わず一致するか知りたいときは、同じ レンズを通して両方を見て(両方を UCase して)、見えたものを比較します — 下に あるページ自体は手つかずです。レンズを編集として扱った瞬間 — UCase(name)name に書き戻した瞬間 — 元の大文字小文字は永遠に失われます。

Sub TheLensIdea()
    Dim stored As String
    stored = "McDonald"               ' 本物のデータ — これは残す

    ' レンズを通して比較し、データは変えない
    If UCase(stored) = UCase("mcdonald") Then
        Debug.Print "match"           ' これは表示される
    End If

    Debug.Print stored                ' いまだに "McDonald" — 手つかず
End Sub

大文字小文字バグの第 1 位を捕まえるルール:VBA の = は大文字小文字を区別する

これは「If が一度も実行されない」という質問の大半に潜む失敗パターンです。VBA は 既定で文字列を1 バイトずつ比較するため、大文字小文字が結果を左右します。

Sub CaseSensitiveByDefault()
    Dim answer As String
    answer = "YES"                    ' ユーザーが実際に入力したもの

    If answer = "yes" Then            ' FALSE — "YES" <> "yes"
        Debug.Print "confirmed"       ' 実行されない
    End If

    ' 修正:両辺を同じレンズを通して揃える
    If UCase(answer) = "YES" Then     ' TRUE
        Debug.Print "confirmed"       ' 実行される
    End If
End Sub

比較を大文字小文字に依存しないようにする方法は 3 つあり、その選択は本物の判断を 要します。

  1. 両辺を UCase/LCaseUCase(a) = UCase(b)。明示的で、局所的で、次に読む 人にも一目瞭然。単発の比較ではこれが最良の既定です。
  2. StrComp(a, b, vbTextCompare) — 大文字小文字を無視して等しいとき 0 を返します。 ほかには何も要らず、純粋に比較だけしたいときに最もすっきりします。
  3. モジュール先頭の Option Compare Text — そのモジュール内のすべての =LikeInStr を大文字小文字に依存しなくします。強力ですが見えません。1 行だけ 読んだ人には、比較規則が変わったことが分かりません。控えめに、そしてモジュール 全体が本当にその挙動を望むときだけ使いましょう。

私のルール:単発の比較には明示的な UCase を選ぶ。Option Compare Text を使うのは モジュール全体が本当に大文字小文字に依存しない場合だけにして、目立つコメントを 付ける。

Dictionary のキーも大文字小文字を区別する

同じ罠が Scripting.Dictionary にも噛みつきます。既定では d("USA")d("usa")2 つの別々のキーです — 思いがけず重複した項目が できてしまいます。生成直後に d.CompareMode = vbTextCompare を設定するか、保存・ 参照する前にすべてのキーを UCase するか、どちらかにしましょう。1 つに決めて、 一貫させることが大切です。

タイトルケース:PCase は存在しないので StrConv を使う

VBA には UCaseLCase はありますが、組み込みのプロパーケース関数は ありません。そのためのツールが、vbProperCase フラグを付けた StrConv です。

Debug.Print StrConv("john smith", vbProperCase)   ' -> "John Smith"

これは普通の小文字の入力に対しては見事に機能します。しかし StrConv が知っている ルールは 1 つだけ — 各単語の最初の文字を大文字にし、残りを小文字にする — そしてそのルールは、現実の名前の多くに対して間違っています。

Debug.Print StrConv("McDonald", vbProperCase)  ' -> "Mcdonald"   (間違い)
Debug.Print StrConv("O'BRIEN", vbProperCase)   ' -> "O'brien"    (間違い)
Debug.Print StrConv("iPhone", vbProperCase)    ' -> "Iphone"     (間違い)
Debug.Print StrConv("ACME III", vbProperCase)  ' -> "Acme Iii"   (間違い)

判断の目安:StrConv(..., vbProperCase) は、入力がすべて大文字かすべて小文字で ある自由記述の名前や住所に対する「そこそこ使える」クリーナーです。これはブランド名 や固有名詞のフォーマッタではありません。特定の名前で正確さが重要なら、例外 リストを持っておいて StrConv の後で修正するか、そもそも自動タイトルケース化を しないことです。

StrConv は大文字小文字の変換だけにとどまらず、はるかに多くのことをこなします。 だからこそ、この機能の置き場所としてふさわしいのです — 半角と全角の変換 (vbWide/vbNarrow)や、東アジア言語のひらがなとカタカナの変換 (vbHiragana/vbKatakana)、さらにバイト/Unicode の変換も行います。こうした ニーズにぶつかったとき、このフラグ一覧が存在すると知っておく価値があります。

ExcelMaster の活用

大文字小文字を扱う VBA の多くは、クリーニング処理の一部です。列を標準化して、 マッチングや検索が取りこぼさないようにするためのものです。ExcelMaster は、 それを説明から行います — 「この 2 つの顧客リストを大文字小文字と空白を無視して 突き合わせて」といった具合に。しかもシート上の表示値を破壊することなく、比較のため だけに正規化します。意図(大文字小文字を無視したマッチング、表示用のタイトル ケース)を伝えれば、元のデータはそのまま保たれます。

これからもマクロの中で UCase/LCase をそのまま書くことはあるでしょう。しかし 「これらの列をクリーニングして突き合わせる」作業なら、ルールを述べる方が、すべての キーを手作業で正規化するより優れています。

よくある質問

VBA でテキストを大文字や小文字に変換するにはどうすればいいですか?

すべて大文字にするには UCase(text)、すべて小文字にするには LCase(text) を 使います。これらは新しい文字列を返し、元の文字列は変更しません。残したいなら、 結果をどこかに代入してください。

VBA で大文字小文字を無視した比較をするにはどうすればいいですか?

両辺を同じ関数で揃えます — UCase(a) = UCase(b) — か、大文字小文字を無視して 等しいとき 0 を返す StrComp(a, b, vbTextCompare) を使います。モジュール全体なら、 Option Compare Text であらゆる比較が大文字小文字に依存しなくなります。

VBA で各単語の先頭文字を大文字にするにはどうすればいいですか?

StrConv(text, vbProperCase) を使います。ただし、それ以外をすべて小文字にする点に 注意してください。そのため McDonaldMcdonald に、iPhoneIphone に なります。途中に大文字を含む名前は、後から例外リストで修正しましょう。

StrConv が McDonald のような名前を台無しにするのはなぜですか?

vbProperCase は 1 つの硬直したルールに従います。各単語の最初の文字を大文字にし、 残りを小文字にする、というものです。固有名詞の知識を持たないため、途中に大文字を 含む名前(McDonaldMacLeodiPhone)やアポストロフィを含む名前(O'Brien)は すべて間違った結果になります。名前に対する権威ではなく、ベストエフォートの クリーナーとして扱いましょう。

検証環境

検証環境: Excel 365(Windows 11)、VBA 7.1 — 最終確認 2026-06-14。

関連ガイド: VBA Concatenate · VBA Str · VBA Replace · VBA Dictionary · VBA For Loop