TL;DR —
Join(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 する 前 に各要素を
Format か CStr で整形しましょう。オブジェクトや未初期化のバリアントである配列
要素は、変換されずにエラーを出します。
意見:もう二度とループで区切り文字列を組み立てない
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 は数値や日付を扱えますか?
はい。ただし地域設定を使って各要素をテキストに変換するので、小数や日付の書式はローカルのマシンに従います。
予測可能な結果のためには、ロケールに頼らず、結合の前に各要素を Format か CStr で整形しましょう。配列内の
オブジェクトや未初期化のバリアントはエラーの原因になります。
検証環境
検証環境: Excel 365 (Windows 11), VBA 7.1 — 最終確認 2026-09-03.
関連ガイド: VBA Split · VBA Filter · VBA Transpose · VBA Format · VBA For Loop
