Power BIで文字列を結合したいのに、Text.Combineの書き方が分からず手が止まることは多いです。Text.CombineはDAXではなくPower Query(M言語)の関数で、列同士の結合や区切りの挿入、nullの自動無視までまとめて解決できます。本記事では基本構文から実務で使える応用例、つまずきやすい型変換のコツまで解説します。
Text.Combineは「Power Query(M言語)」の文字列連結関数
最初に結論です。Power BIでよく聞く「式」には大きく分けて次の2種類があり、Text.CombineはDAXではなくPower Query(M言語)の関数です。
| どこで使う? | 言語 | 代表例 | 得意なこと |
|---|---|---|---|
| Power Query エディター(変換/整形) | M言語 | Text.Combine / Table.AddColumn | 取り込み時にデータを加工して列を作る |
| レポート画面(計算列/メジャー) | DAX | & / CONCATENATEX | 集計やフィルター状況に応じて計算する |
「Power Queryで列を作りたいのに、DAXの書き方を探してしまう」ことが、Text.Combineの入力例が見つからない原因になりがちです。Power Query エディターのカスタム列や詳細エディターに、M言語として記述します。
基本構文(これだけ覚えればOK)
Text.Combineは、文字列のリスト(list)を受け取り、必要なら区切り文字を挟んで1つのテキストにします。さらに重要な特徴として、リスト内のnull(空値)は自動で無視されます(公式ドキュメント参照)。
Text.Combine(texts as list, optional separator as nullable text) as text
- texts:連結したい要素を
{ ... }でまとめたリスト - separator:要素の間に入れる区切り(省略可)
覚え方:「カンマでつなぐ」ではなく「リストを作ってText.Combineに渡す」と覚えると迷いません。M言語の多くの関数は、テーブル/リスト/レコードを材料にします。
どこに入力する?Power Queryでの書き場所(手順)
「式をどこに書くか」でつまずく人が非常に多いので、入力場所も整理します。
- Power BI Desktopで対象のデータを開く
- リボンのデータの変換をクリックしてPower Query エディターを開く
- 列の追加タブ → カスタム列
- 数式欄にM言語で入力(Text.Combineをここに書く)
慣れてきたら、詳細エディターでステップ全体を編集するのもおすすめです。Power Queryは「ステップ」が積み重なるので、式を1つの行だけで解こうとして苦しくなるより、段階的に整形してから結合すると読みやすくなります。
最短で動くText.Combineの入力例
まずは公式の最小例です。リストを作り、必要なら区切り文字を渡します。
| 式(M) | 結果 | ポイント |
|---|---|---|
Text.Combine({"Seattle", "WA"}) | SeattleWA | 区切りを省略するとそのまま連結 |
Text.Combine({"Seattle", "WA"}, ", ") | Seattle, WA | 区切りは第2引数 |
Text.Combine({"Seattle", null, "WA"}, ", ") | Seattle, WA | nullは無視される |
実務で一番多い:列を使って「フルネーム列」を作る
Power QueryでText.Combineが一番活躍するのは、複数列を結合して新しい列を作るケースです。例えば「名」「ミドルイニシャル」「姓」からフルネームを作る場合は、カスタム列で次のように書きます。
Table.AddColumn(Source, "Full Name",
each Text.Combine({[First Name], [Middle Initial], [Last Name]}, " ")
)
ミドルイニシャルがnullでも、Text.Combineが無視してくれるため、余計なnull文字が入ったり、エラーで止まったりしにくいのがメリットです。
Text.Combineが便利な理由:&(連結演算子)との違い
M言語にもテキストをつなぐ演算子&があります。では、なぜText.Combineが必要なのでしょうか。違いを押さえると「どっちを使うべき?」が一瞬で判断できます。
| やりたいこと | おすすめ | 理由 |
|---|---|---|
| 2つの文字列を単純に結合 | & | 短く書ける |
| 複数項目をまとめて結合 | Text.Combine | リストで見通しが良い |
| nullを混ぜても自然に結合 | Text.Combine | nullを無視する |
注意:M言語の
&は、片方がnullだと結果もnullになってしまい、意図せず値が消えることがあります。列にnullが混ざる可能性があるなら、Text.Combineのほうが安全です。
nullは無視されるが、空文字(””)は残る
Text.Combineは便利ですが、もう1つの落とし穴があります。null(空値)は無視されますが、空文字(””)は「値として存在する」扱いです。つまり、空文字が混ざると区切り文字だけが残り、見た目が不自然になることがあります。
| リストの中身 | 区切り | 結果 | 見た目の問題 |
|---|---|---|---|
{"A", null, "B"} | ", " | A, B | 問題なし(nullは無視) |
{"A", "", "B"} | ", " | A, , B | 区切りが余計に出る |
この場合は、結合前に「空文字も除外」するのがコツです。次のようにList.Selectでフィルタすると、nullと空文字を両方避けられます。
Text.Combine(
List.Select({[A], [B], [C]}, each _ <> null and _ <> ""),
" / "
)
「入力元によっては空文字が入る」「手入力データで空白が多い」など、データ品質が揺らぐ環境ほど、この一手間が効きます。
型が違う列を混ぜるときはText.Fromで安全に
Power Queryでは、数値や日付をそのままText.Combineに入れると、型不一致でエラーになることがあります。そこで、Text.Fromで文字列化してからリストに入れるのが鉄板です。
Microsoft Learn: Power Query M formula language reference
| 元の型 | よくある列 | おすすめの文字列化 | 例 |
|---|---|---|---|
| 数値 | ID、郵便番号、金額 | Text.From(必要なら桁や小数も調整) | Text.From([CustomerID]) |
| 日付 | 受注日、請求日 | Date.ToTextで書式を固定 | Date.ToText([OrderDate], "yyyy-MM-dd") |
| 日時 | 更新日時、ログ時刻 | DateTime.ToTextで書式を固定 | DateTime.ToText([UpdatedAt], "yyyy-MM-dd HH:mm:ss") |
例えば「顧客ID-日付」のキー列を作るなら、次のように書けます。
Table.AddColumn(Source, "Key",
each Text.Combine(
{
Text.From([CustomerID]),
Date.ToText([OrderDate], "yyyy-MM-dd")
},
"-"
),
type text
)
実務メモ:日付は環境やロケールによって表示が変わることがあります。キーやファイル名に使う場合は、
Date.ToTextの書式を明示して「常に同じ形」に固定しておくとトラブルが減ります。
よく使うレシピ集(コピペで使える)
住所を1列にまとめる(都道府県・市区町村・番地)
住所の結合は、区切りを入れないケース(連結)と、スペースや記号を入れるケース(整形)に分かれます。日本の住所なら、まずは単純に連結してOKなことが多いです。
Table.AddColumn(Source, "住所",
each Text.Combine({[都道府県], [市区町村], [番地]}, ""),
type text
)
ただし、番地が欠けて空文字が入ることがあるなら、前述のList.Selectで空文字も除外すると見た目が整います。
部署名+氏名+括弧つき電話番号(括弧やハイフンを混ぜる)
区切り文字は「要素間に同じものを挟む」用途が得意です。括弧などの装飾を混ぜたいときは、リスト側に文字列として含めると分かりやすくなります。
Table.AddColumn(Source, "表示名",
each Text.Combine(
{
[部署],
[氏名],
"(",
Text.From([内線]),
")"
},
" "
),
type text
)
この例は区切りに半角スペースを入れているため、「(」「)」の前後にもスペースが入りやすいです。見た目をきっちりさせたい場合は、次のように「区切りなし+必要なところだけスペース」を入れる方が確実です。
Table.AddColumn(Source, "表示名",
each
Text.Combine({[部署], " ", [氏名], " (", Text.From([内線]), ")"}, ""),
type text
)
URLやファイルパスを組み立てる(スラッシュの重複に注意)
URLやパスは「/」の重複が起きがちです。安全策として、各パーツの前後を整形してから結合します。
Table.AddColumn(Source, "URL",
each
let
base = Text.TrimEnd([BaseUrl], "/"),
path = Text.TrimStart([Path], "/")
in
Text.Combine({base, path}, "/"),
type text
)
この書き方なら、BaseUrlが「https://example.com/」でも「https://example.com」でも同じ結果になります。
複数列をまとめて連結(列数が多い/可変のとき)
列が3つ程度なら{[A],[B],[C]}で十分ですが、列数が多い場合や将来増える場合は、列名リストを使うとメンテしやすくなります。
let
cols = {"Col1", "Col2", "Col3", "Col4"},
Add = Table.AddColumn(Source, "結合",
(r) =>
Text.Combine(
List.Select(
List.Transform(cols, (c) => try Text.From(Record.Field(r, c)) otherwise null),
each _ <> null and _ <> ""
),
"|"
),
type text
)
in
Add
Record.Field(r, c)で「列名から値を取り出す」try ... otherwise nullで変換エラーを吸収(実データに強い)- 最後に
List.Selectでnull/空文字を落としてから結合
行をまたいで結合(顧客ごとの商品一覧を1セルにまとめる)
「同じ顧客の購入商品をカンマ区切りで一覧化したい」など、ExcelのTEXTJOIN的な要件もよくあります。Power QueryならTable.Groupでグループ化し、グループ内の列がリストになることを利用します。
let
g = Table.Group(
Source,
{"CustomerID"},
{
{"Products",
(t) => Text.Combine(List.Sort(List.Distinct(t[ProductName])), ", "),
type text
}
}
)
in
g
ポイントは次の通りです。
t[ProductName]はグループ内のProductName列が「リスト」として取り出されるList.Distinctで重複を排除し、List.Sortで順序を安定させる- 最後に
Text.Combine(..., ", ")で結合
Text.Combineでよく起きるエラーと対処法
「書き方は合っているはずなのに動かない」場合、原因の多くは型か参照ミスです。代表的な症状と対処をまとめます。
| 症状(例) | よくある原因 | 対処 |
|---|---|---|
| 数値/日付の列を入れたらエラー | Text.Combineは基本的にテキスト前提 | Text.FromやDate.ToTextで文字列化してから結合 |
| 区切りが余計に連続して見える | 空文字(””)が混ざっている | List.Selectで空文字も除外 |
| 列名が見つからない | 列名のスペル/大文字小文字/スペース違い | 実際の列名を確認し、[列名]を正確に指定 |
| 式は動くが結果がnullになる | &で連結していてnullが混入 | nullがあり得るならText.Combineへ変更 |
DAXのCONCATENATEXと混同しないための判断基準
同じ「文字列結合」でも、Power Query(M)とDAXは役割が違います。検索するとDAXの例が大量に出てきますが、やりたいことが「取り込み時の整形」ならPower Query、やりたいことが「集計結果としての結合」ならDAXです。
| やりたいこと | 使う場所 | 使う関数 | 例 |
|---|---|---|---|
| 名+姓でフルネーム列を作って保存したい | Power Query | Text.Combine | 取り込み時に列を追加 |
| フィルターされた行だけを結合して表示したい | DAX | CONCATENATEX | レポート上で集計結果を文字列化 |
迷ったら、「Power Query エディターを開いて作業しているか?」で判断すると間違いません。開いているならM言語、開いていないならDAXの可能性が高いです。
実務で使えるテンプレ(この形から始めると早い)
最後に、現場で使いやすい「安全寄り」のテンプレを載せます。nullだけでなく空文字も除外し、数値や日付の混在にも強くしています。
Table.AddColumn(Source, "結合列",
(r) =>
Text.Combine(
List.Select(
{
try Text.From(r[ColA]) otherwise null,
try Text.From(r[ColB]) otherwise null,
try Date.ToText(r[ColC], "yyyy-MM-dd") otherwise null
},
each _ <> null and _ <> ""
),
" "
),
type text
)
このテンプレをベースに、「区切りを変える」「括弧や記号を足す」「結合する列を増やす」だけで、ほとんどの要件に対応できます。

コメント