備考欄や住所欄に改行を含むCSVをPower Queryで取り込むと、1件のデータが複数の行に分かれてしまうことがあります。次のような症状が出ていたら、この記事の確認順で直せる可能性があります。
- 1件のはずのデータが2行以上に分かれている
- 分かれた後半の行では、1列目に文章の続きが入り、残りの列がnullになっている
- 「変更された型」のステップで、日付や数値の列にエラーが出る(文章の続きが入り込んでいるため)
- 読み込んだ行数が、出力元のシステムで表示された件数より多い
こうした症状のおもな原因は、CSVを読むCsv.Document関数の設定にあります。特にQuoteStyle・区切り文字・列数の3つを確認します。
まずソースステップの式を表示する
Power Queryエディターの「適用したステップ」で「ソース」を選ぶと、数式バーに次のような式が表示されます。数式バーが見えないときは、「表示」タブで「数式バー」にチェックを入れます。
= Csv.Document(File.Contents("C:\Data\受注.csv"),[Delimiter=",", Columns=8, Encoding=65001, QuoteStyle=QuoteStyle.None])
[ ]の中が読み込みの設定です。
| 引数 | 意味 | 行や列のずれとの関係 |
|---|---|---|
Delimiter |
区切り文字 | 実際と違うと、全体が1列にまとまったり列がずれたりする |
Columns |
列数 | 実際より少ないと右側の列が捨てられ、多いと空の列が増える |
Encoding |
文字コード(65001はUTF-8、932はShift_JIS) | 行のずれとは別の問題だが、同じ式の中で指定する |
QuoteStyle |
引用符で囲まれた値の中の改行をどう扱うか | QuoteStyle.Noneだと、引用符の中の改行でも行が終わる |
QuoteStyleのCsvとNoneの違い
QuoteStyle.Csv:ダブルクォートで囲まれた値の中にある改行を、値の一部として扱います。QuoteStyle.None:引用符の中かどうかに関係なく、改行をすべて行の終わりとして扱います。
Microsoftの関数リファレンスでは、Csv.DocumentでQuoteStyleを省略したときの既定はQuoteStyle.Noneと説明されています。式にQuoteStyleがなくても、セル内改行で行が分かれることがあるということです。
たとえば次のCSVがあるとします。
受注番号,顧客名,備考
1001,山田商店,"午前中配達
不在時は再配達"
1002,佐藤工業,
QuoteStyle.Csvなら、受注番号1001の備考は「午前中配達(改行)不在時は再配達」という1つの値になり、データは2件です。QuoteStyle.Noneだと備考は途中で切れて、次の行の1列目に「不在時は再配達」という続きが入ります。その結果、データが3件に増えてしまいます。
直し方1:QuoteStyleをCsvに変える
- 「適用したステップ」で「ソース」を選ぶ
- 数式バーの
QuoteStyle=QuoteStyle.NoneをQuoteStyle=QuoteStyle.Csvに書き換え、Enterを押す - 式に
QuoteStyleがなければ、[ ]の中の最後に, QuoteStyle=QuoteStyle.Csvを書き足す
書き足したあとの例です。
= Csv.Document(File.Contents("C:\Data\受注.csv"),[Delimiter=",", Columns=8, Encoding=65001, QuoteStyle=QuoteStyle.Csv])
画面で設定することもできます。「ソース」ステップの右にある歯車アイコンを押すと、バージョンによっては、引用符の中の改行をどう扱うかを選ぶ項目が出てきます。項目が見当たらないときは、数式バーで直接書き換えてください。
フォルダーから複数のCSVを結合して作ったクエリでは、同じ式がヘルパークエリ(「サンプル ファイルの変換」など)の「ソース」ステップにあります。結合したあとのクエリではなく、そちらを直します。
書き換えたら、「ソース」のあとの「昇格されたヘッダー」「変更された型」などのステップを順にクリックしていき、エラーが消えたか確認します。
直し方2:Columnsの数を見直す
Columns=8のような列数は、最初に取り込んだときのファイルから自動で入る固定値です。
- 実際の列数より少ないと、右側の列はエラーにならずに捨てられます
- 実際の列数より多いと、中身が空の
Column9のような列ができます
メモ帳でCSVの1行目(見出し)を開き、区切り文字で区切られた列の数を数えて、Columnsと一致しているか確かめます。出力元の都合で列が増えることがある場合は、Columns=8, の部分を消して引数ごと省くと、ファイルの内容から列数が決まります。ただし列の数が変わると、そのあとの列名の変更や型の変更のステップでエラーが出ることがあります。
直し方3:区切り文字を確認する
メモ帳でCSVを開き、値が何で区切られているかを見ます。
| ファイルの区切り | Delimiterの書き方 |
|---|---|
| カンマ | Delimiter="," |
| タブ | Delimiter="#(tab)" |
| セミコロン | Delimiter=";" |
タブ区切りのファイルを","で読むと全体が1列にまとまり、値の中にカンマがあるとそこで列が分かれてしまいます。拡張子が.csvでも中身はタブ区切り、というファイルもあるので、拡張子だけで判断しないようにします。
QuoteStyleをCsvにしても直らないとき
次のようにファイルの中身が崩れている場合は、Power Queryの設定だけでは直せません。
- 閉じていない引用符がある:
QuoteStyle.Csvでは、次の引用符が出てくるまでの複数行が1つのセルに入り込みます。その結果、件数が逆に減ります。 - カンマを含む値が引用符で囲まれていない:どの設定でも、その行だけ列がずれます。
こうしたときは、出力元のシステムやツールの出力設定を見直してもらうのが確実です。崩れている行を見つけるには、「列の追加」→「インデックス列」で行番号を付けます。そのうえで、キー列(受注番号など)がnullの行や、本来は空にならない最後の列がnullの行をフィルターで絞り込みます。
直したあとに件数を照合する
セル内改行があるCSVでは、メモ帳で見た行数はデータの件数より多くなります。そのため、照合には次の方法を使います。
- 出力元の件数と比べる:システムの出力画面や処理ログに出る件数と、「クエリと接続」に表示される読み込み行数を比べます。エディター内で確かめるなら、「変換」→「行数のカウント」を一時的に追加し、確認したらそのステップを削除します。
- キー列にnullがないか見る:受注番号などのキー列をフィルターで「null」だけに絞り、0件になることを確かめます。分かれた行が残っていると、ここに出てきます。
- キー列の個別の件数を見る:「表示」タブで「列の分布」をオンにすると、列ごとに個別の値の数が表示されます。既定では上位1000行だけが対象なので、画面下のステータスバーの表示をクリックし、データセット全体を対象にする設定に切り替えます。キーが重複しないデータなら、個別の値の数と行数が一致するはずです。
- 改行を含む1件を開いて見る:元のCSVで改行が入っていたデータを1件選び、改行の前後の文章が同じセルに入っているか確かめます。シートに読み込んだあとは、そのセルに「折り返して全体を表示」を設定すると改行が見えます。
照合結果は、たとえば次のように記録しておくと、翌月以降も比べやすくなります(数値は記入例です)。
| 項目 | 修正前 | 修正後 |
|---|---|---|
| 出力元が表示した件数 | 500 | 500 |
| 読み込まれた行数 | 523 | 500 |
| 受注番号がnullの行 | 23 | 0 |
改行をデータから取り除きたいとき
取り込み先が改行を含む値を受け付けないときは、正しく1件ずつ読み込めたことを確かめてから、改行を空白などに置き換えます。「変換」→「値の置換」の詳細設定オプションで特殊文字を使う設定にすると、改行を指定できます。式で書く場合は、たとえば次のようになります(変更された型は直前のステップ名、備考は対象の列名です)。
= Table.ReplaceValue(変更された型, "#(cr)#(lf)", " ", Replacer.ReplaceText, {"備考"})
改行はCRとLFの組み合わせのこともあれば、LFだけのこともあります。#(cr)#(lf)を置き換えたあと、#(lf)だけを置き換えるステップも追加すると取りこぼしを防げます。改行を残してよい場合は、このステップは不要です。
まとめ
セル内改行で行が分かれるときは、まず「ソース」ステップのQuoteStyleを確認し、QuoteStyle.Csvにします。あわせてColumnsの数とDelimiterがファイルの実態と合っているかも見ます。直したあとはメモ帳の行数ではなく、出力元の件数・キー列のnull・改行を含む1件の中身で照合します。それでも合わない場合は、ファイル側の引用符の崩れを疑います。
