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

Excel VBA の Join — 配列を文字列に戻す、Split のちょうど逆操作

|

Excel VBA の Join — 配列を文字列に戻す、Split のちょうど逆操作

TL;DRJoin(sourceArray, delimiter)1 次元配列 を 1 つの文字列に畳み込み、各要素の あいだに delimiter を置きます。Split のちょうど逆操作です。Split は文字列を 配列に切り、Join は配列を貼り合わせて戻します。s = s & item & "," のループを置き換え、しかもその ループと違って 末尾に区切り文字を残しません。落とし穴:Join が取るのは 1 次元配列 であって、 Range でも 2 次元配列でもないので、Join(Range("A1:A10").Value, ",") は、先に列を 1 次元に平坦化 するまで失敗します。

Sub JoinDemo()
    Dim parts As Variant, line As String
    parts = Array("Jones", "Sarah", "Finance")

    line = Join(parts, ",")          ' 各要素のあいだをカンマで貼り合わせる
    Debug.Print line                  ' Jones,Sarah,Finance   <- 末尾にカンマなし

    Debug.Print Join(parts)           ' Jones Sarah Finance   <- 既定の区切り文字は空白
    Debug.Print Join(parts, "")       ' JonesSarahFinance     <- 空の区切り文字 = 連結
End Sub

構文です。区切り文字は任意で、既定はなしではなく空白である点に注意してください。

Join(sourceArray, [delimiter])
'    1 次元配列    既定は " "(空白 1 つ)であって "" ではない

この記事で学べること

  • 考え方の軸 — Join は Split を逆に回したもの
  • Join が連結ループを置き換える理由(そして末尾区切り文字のバグを消す)
  • 一番の罠:Join は 1 次元配列 を必要とするので、Range や 2 次元配列は失敗する
  • 区切り文字の既定は空白、そして各要素はテキストに変換される
  • ループを 1 行に変える Split-Filter-Join の往復

考え方の軸:Join は Split を逆回しにしたもの

Split と Join を対になった 1 組として握れば、どちらも扱いにくさが消えます。Split は、 構造が焼き込まれた 1 つの文字列 — CSV の 1 行、Last,First の氏名、区切り付きのログ行 — を取り、各 フィールドを配列にして返します。Join はその逆です。それらのフィールドを取り、あいだに好きな区切り文字を 挟んで 1 つの文字列に溶接し直します。Split が「連結を解く」なら、Join は「このリスト全体を一度に連結する」 です。

互いに逆操作なので、きれいに組み合わさります。行を切り分け、いくつかの断片を変え、Join で戻します。

Dim parts As Variant
parts = Split("Jones,Sarah,Finance", ",")
parts(2) = "Operations"                       ' 1 つのフィールドを編集
Debug.Print Join(parts, ",")                  ' Jones,Sarah,Operations

Join が連結ループに勝る理由

誰もが Join を知る前に文字列を組み立てるループを書き、そして誰もが同じバグを書きます。

' ⚠ 定番の末尾区切り文字バグを抱えたループ
Dim i As Long, s As String
For i = 0 To UBound(parts)
    s = s & parts(i) & ","          ' "Jones,Sarah,Finance," が残る — 末尾にカンマ
Next i
s = Left(s, Len(s) - 1)             ' それを切り落とす醜いハック

この末尾の区切り文字は、まれなエッジケースではありません — 毎回 です。だからこそ Left(s, Len(s) - 1) による切断がこれほど頻繁に見られるのです。Join には設計上そうした問題がありません。 区切り文字を要素の あいだ に置き、最後の要素の後には決して置かないからです。

s = Join(parts, ",")                ' Jones,Sarah,Finance — 一発で正しい

1 回の呼び出し、末尾の文字なし、Len - 1 の計算なし、空配列でも間違えようがありません(空配列の Join は単に "" になります)。

一番の罠:Join は Range ではなく 1 次元配列を必要とする

「Join が動かない」という報告のほとんどは、ここから来ます。Join が受け取るのは 1 次元配列だけ です。 2 次元のものを渡した瞬間に失敗します — そして複数セルの Range を読むと、まさにそれが返ってきます。

' ⚠ 失敗する — 複数セル範囲の .Value は 2 次元配列(10 行 x 1 列)
s = Join(Range("A1:A10").Value, ",")          ' 型の不一致 / エラー 13

Range("A1:A10").Value はリストではありません — 10 x 1 の 2 次元バリアント配列であり、Join は 2 つの 次元をどう扱えばよいのか分かりません。まず列を 1 次元に平坦化 しなければなりません。定番の平坦化は Application.Transpose で、単一列のサイズ 1 の次元を落とします。

Dim flat As Variant
flat = Application.Transpose(Range("A1:A10").Value)   ' 2 次元の列 -> 1 次元配列
s = Join(flat, ",")                                   ' これで Join は満足

これこそ Transpose がこのクラスターにいる理由です — セルから、Join と Filter が ともに必要とする 1 次元配列への架け橋なのです。(それ自身の上限に注意:Application.Transpose は 65,536 要素で頭打ちになるので、非常に背の高い列はループで平坦化しましょう。)

区切り文字の既定とテキスト変換

小さな驚きが 2 つ。1 つ目、区切り文字を省略すると、Join は空文字列ではなく 空白 1 つ を使います — Join(parts)"Jones Sarah Finance" になります。あいだに何も入れない素直な連結が欲しいときは、 明示的に "" を渡しましょう。

2 つ目、Join は 各要素をテキストに変換 します。数値・日付・ブール値は、システムの地域設定を使って 変換されます — Double はマシン次第で 1.5 にも 1,5 にもなり、日付はローカルの書式に従います。特定の 書式(不変の . 小数点、ISO 日付)が必要なら、ロケールに頼らず、Join する に各要素を FormatCStr で整形しましょう。オブジェクトや未初期化のバリアントである配列 要素は、変換されずにエラーを出します。

意見:もう二度とループで区切り文字列を組み立てない

For ループの中で配列要素を & で連結しているなら、あなたは後で Left(s, Len(s) - 1) でパッチを当てる ことになるバグを書いています。Join はまさにそのパターンを消すために存在します。ルールは単純です。 元がすでに配列なら、文字列は Join で組み立てる。元がセルにあるなら、まず 1 次元配列に平坦化してから Join する — ループはしないこと。

そして、この組をパイプラインとして頭に置いておきましょう。Split、Filter、Join は、口に出して言うであろう 文のように読める 1 つの正直な式に組み合わさります — 「この行を取り、2026 に言及するフィールドを残し、 カンマでつなぐ」。

result = Join(Filter(Split(line, ","), "2026"), ", ")

Split が解析し、Filter が部分集合を取り、Join が組み立て 直す — 3 つの組み込み関数、ループなし、off-by-one なし。

ExcelMaster の活用

つなぐことが本当の目的であることは、決してありません。目的は「これらのフィールドからメールの件名を 組み立てる」ことや、「レコードごとに区切り付きの 1 行をログに書く」ことです。範囲を平坦化し、小数が 生き残るよう各数値を整形し、区切り文字を選ぶ頃には、配管がアイデアより長くなっています。 ExcelMaster なら、出力を普通の言葉で — 「地域ごとに顧客名をセミコロン区切りの一覧にして」 — と説明するだけです。そして、セルを読み、予測どおりに 整形し、書き込む前にファイルをバックアップする Python を生成します。あなたは出力を説明するだけ。平坦化も、 数値の書式も、区切り文字も、それが処理します。

よくある質問

VBA の Join は何をしますか?

Join(sourceArray, delimiter) は 1 次元配列を取り、各要素のあいだに delimiter を置いた 1 つの文字列を 返します。Join(Array("a", "b", "c"), ",")"a,b,c" を返します。Split の逆操作であり、最後の要素の 後に区切り文字を決して残しません。

VBA の Join が範囲で型の不一致になるのはなぜですか?

Range("A1:A10").Value が 2 次元配列(行 × 列)であり、Join は 1 次元配列しか受け取らないからです。まず Application.Transpose(Range("A1:A10").Value) で列を平坦化すると、単一列の 2 次元配列が 1 次元配列に なります。それを Join に渡しましょう。

VBA の Join の既定の区切り文字は何ですか?

空白 1 つです。区切り文字なしの Join(parts) は、要素をつなげてしまうのではなく、空白で区切って返します。 要素のあいだに何も入れない素直な連結が欲しいときは、空文字列 Join(parts, "") を渡します。

VBA で末尾のカンマなしに配列を結合するには?

ループの代わりに Join を使います。Join(parts, ",") はカンマを要素の あいだ だけに置くので、切り 落とすべき末尾の区切り文字が決して生まれません。s = s & item & "," のループは必ず 1 つ残すので、人は それを Left(s, Len(s) - 1) で切り落とすことになります — Join はその必要をまるごと取り除きます。

VBA の Join は数値や日付を扱えますか?

はい。ただし地域設定を使って各要素をテキストに変換するので、小数や日付の書式はローカルのマシンに従います。 予測可能な結果のためには、ロケールに頼らず、結合の前に各要素を FormatCStr で整形しましょう。配列内の オブジェクトや未初期化のバリアントはエラーの原因になります。

検証環境

検証環境: Excel 365 (Windows 11), VBA 7.1 — 最終確認 2026-09-03.

関連ガイド: VBA Split · VBA Filter · VBA Transpose · VBA Format · VBA For Loop