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

Excel VBA の Str 関数 — 先頭スペースの罠と、なぜ CStr がほぼ常に正解なのか

|

Excel VBA の Str 関数 — 先頭スペースの罠と、なぜ CStr がほぼ常に正解なのか

TL;DRStr は数値をテキストに変換しますが、これは 2 つの罠を抱えた古い BASIC の関数です。1 つ目、Str(42)先頭にスペースが付いた " 42" を 返します(符号のための桁を予約するため)。2 つ目、Strロケールを無視します — カンマを小数点として期待するドイツ語環境でさえ、常に . を小数点として使います。 このため Str は、ロケールに依存しないファイルを書き出すには最適ですが、ユーザーが 目にするものには不適切です。「数値からテキスト」の既定は CStr(スペースなし、 ロケールを尊重)か Format(完全な制御)です。Str に手を伸ばすのは、固定の . 区切りを意図的に使いたいときだけ — そしてその場合でも、ほとんどのコードでは 使うべきではありません。

これは VBA の CStr、CDate、Val の姉妹記事です。あちらはテキストを 数値や日付変換することを扱っています。この記事は逆方向です。数値をテキスト 変換すること — そして特に、いかにも使えそうな Str 関数こそ、たいていは避けるべき 関数である理由についてです。

この記事で学べること

  • 先頭スペースの罠:なぜ Str(42)" 42" になるのか、そして何が壊れるのか
  • なぜ Str が地域設定を無視するのか — そしてそれが実際に役立つのはいつか
  • StrCStrFormat — どれをいつ使うか
  • Str/Val のペアと CStr/CDbl のペア

考え方の軸:Str は 2 つの地雷を抱えた「遺物」

Str を、数値が固定幅の桁で印字されていた、より古い BASIC の時代のツールだと 考えてください。Str はいまだにその流儀で振る舞います。マイナス符号のための場所を 空けておき、あなたがどの国にいるかを気にしません。どちらの挙動も 1985 年には理に かなっていましたが、2026 年には人々を驚かせます。

Sub TheTwoLandmines()
    Debug.Print "[" & Str(42) & "]"     ' -> "[ 42]"   先頭スペース!
    Debug.Print "[" & Str(-42) & "]"    ' -> "[-42]"   符号がその枠を埋める
    Debug.Print Str(3.14)               ' -> "3.14"   どんなロケールでも常にドット
End Sub

地雷 1:先頭スペース

Str は常に最初の 1 文字を符号のために予約します。正の数値はそこにスペースが 入り、負の数値は - が入ります。つまり Str(42) は 3 文字です。スペース、42。 これは密かに 3 つのことを壊します。

Sub LeadingSpaceBreaksThings()
    ' 1) 結合すると余分なスペースが入る
    Debug.Print "Total: " & Str(42)     ' -> "Total:  42"   (スペース 2 つ)

    ' 2) 比較が失敗する
    Debug.Print (Str(42) = "42")        ' -> False   (" 42" <> "42")

    ' 3) セルに書き込むと、スペース付きのテキストになる:
    '    数値に見えるが、ISNUMBER は False で、並べ替えが壊れる
    Range("A1").Value = Str(42)
End Sub

人々はこれを Trim(Str(n)) で「修正」します。確かに動きますが、これはコードの におい(code smell)です — 間違った関数を選んだのを取り繕っているのです。本当の 修正は、そもそもスペースを付けない関数を使うことです。

地雷 2:Str はロケールを無視する

Str は、Windows の地域設定に関係なく、常に . を小数点として出力します。ドイツ語 (小数点に , を使う)に設定されたマシンでも、Str(3.14) はやはり "3.14" です。

ここが、Str がその存在意義を発揮する唯一の場面です。CSV、SQL 文、JSON、その他 あらゆる機械可読フォーマットを書き出すとき、どこでも同じように解析されるよう、 固定の . 区切りが欲しいのです。Str はそれをタダで与えてくれます — ドイツ語 環境なら 3,14 を出力してファイルを壊してしまう CStr とは対照的に。

しかし人が読むものに対しては、ロケール無視はバグです。ドイツ語のユーザーは 3,14 を期待しますが、Str3.14 を見せてしまいます。

解決策:既定は CStr、制御が必要なら Format

Sub TheRightTools()
    ' CStr — 先頭スペースなし、ユーザーのロケールを尊重。これが既定。
    Debug.Print "[" & CStr(42) & "]"        ' -> "[42]"
    Debug.Print CStr(3.14)                  ' -> ドイツ語環境では "3,14"

    ' Format — 桁数、パディング、桁区切りを完全に制御
    Debug.Print Format(42, "0")             ' -> "42"
    Debug.Print Format(1234.5, "#,##0.00")  ' -> "1,234.50" (またはロケール相当)
    Debug.Print Format(7, "000")            ' -> "007"
End Sub

頭に入れておける、1 つの表にまとめた判断基準です。

  • CStr — 一般用途の数値 → テキスト。スペースなし、ロケール対応。これが既定。
  • Format — パディング、固定小数桁、桁区切りが必要なとき。
  • Str — ファイルやプロトコル用にロケール非依存の . が特に必要で、かつ先頭 スペースを受け入れる(または Trim する)ときだけ。

率直に言えば、判断はこうです。2026 年において、新しいコードにある裸の Str() は、 ほぼ常にバグか、コメントのないファイル書き込みの特殊ケースのどちらかです。 「この数値をテキストとして欲しい」という意味なら CStr と書きます。「この数値を 整形したい」という意味なら Format と書きます。Str はロケール非依存の出力という 狭いケースのためにとっておき、その隣には理由を説明するコメントを添えましょう。

Str/Val のペアと CStr/CDbl のペア

これらの関数は、ロケール対応か否かで対になっています — それらを混ぜることが、 往復変換が密かにデータを壊す原因です。

  • StrVal — どちらもロケール無視(常に .)。Val("3.14") はどの マシンでも 3.14 です。Val は最初の非数値文字で止まる点にも注意。固定フォーマット のファイル I/O にはこのペアを使います。
  • CStrCDbl — どちらもロケール対応CDbl は地域設定のカンマを尊重し、 CStr はそれを出力します。ユーザーが目にする値の往復にはこのペアを使います。

避けるべきバグは、ペアをまたぐことです。Str(ドット)で書き込んで、カンマ ロケールのマシンで CDbl で読み戻すと、数値が変わってしまいます。各往復変換は 1 つのペアの中で完結させましょう。

ExcelMaster の活用

数値からテキストへの VBA は、たいていエクスポートやラベルを組み立てるために 存在します — 値札、CSV のフィールド、ゼロ埋めした請求書番号などです。 ExcelMaster は、それを説明から生成します — 「これらの金額を小数 2 桁の テキストと、先頭ゼロ付きの ID としてエクスポートして」といった具合に。しかも StrCStrFormat のどれを選ぶか悩んだり、先頭スペースを痛い目を見ながら 発見したりすることなく、ロケールもパディングも正しく処理します。

これからもマクロの中で変換をそのまま書くことはあるでしょう。しかし「この整形済み エクスポートを作る」作業なら、フォーマットを言葉で説明する方が、変換関数を手作業で 選ぶより優れています。

よくある質問

VBA の Str と CStr の違いは何ですか?

Str は正の数値の前に先頭スペースを付け、ロケールに関係なく常に . を小数点として 使います。CStr はスペースを付けず、ユーザーの地域設定を尊重します。一般的な 「数値からテキスト」への変換には CStr を使い、Str はファイルやプロトコル用に ロケール非依存の . が必要なときだけ使いましょう。

VBA の Str はなぜ数値の前にスペースを付けるのですか?

Str は最初の 1 文字を符号のために予約します — 正の数値にはスペース、負の数値には - です。これは固定幅の数値印字の名残です。取り除くには、スペースを一切付けない CStr を使うか、Trim(Str(n)) で包みます。ただし、より整った修正は CStr です。

VBA の Str は地域の小数点記号を尊重しますか?

いいえ。Str は、小数点にカンマを使う設定(ドイツ語、フランス語など)のマシンでも 常に . を出力します。これはどこでも同じように解析されるべき CSV/SQL を書くには 役立ちますが、ユーザーに見せる値には不適切です — そちらには CStrFormat を 使いましょう。

VBA で数値を文字列に変換するにはどうすればいいですか?

既定では CStr(number) を使います — 先頭スペースなしでロケール対応です。特定の 小数桁、パディング、桁区切りが必要なときは Format(number, "0.00") を使います。 Str(number) はロケール非依存のファイル出力専用にとっておきましょう。

検証環境

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

関連ガイド: VBA CStr · VBA Format · VBA Concatenate · VBA UCase & LCase · VBA Trim