以前とある業務で、引き継ぎ相手に Web送信用のCSVファイルを作らせて、自作ファイルと比較しようと思った時のこと。チェックしようとして気付いたのだが、何故か引き継ぎ相手が作ったファイルは私のものとは行の並びが違っていた。送信するデータの順番自体はどっちでも良かったので、純粋に中身に問題がないかだけ確かめようと考えた。その時は急いでいたので、2つのテキストデータをシートに2列並べて、COUNTIF関数でチェックした。結果間違いはなく送信も完了したのだが、これってクエリでチェックできるんじゃないかなと後で考えた。
2つのファイルは「A.csv」「B.csv」として、指定フォルダに保存しているものとする。
まずはフォルダパスを指定して、その階層のファイルテーブルを呼び出し、CSVファイルだけを抽出する。
let
フォルダパス = "C:\……\……\",
ソース = Folder.Files(フォルダパス),
次にそれぞれの CSVファイルをリスト形式で呼び出す。
リストA = Lines.FromBinary(
ソース{[Name="A.csv"]}[Content], null, null, 932
),
リストB = Lines.FromBinary(
ソース{[Name="B.csv"]}[Content], null, null, 932
),
ひとまずここまで。
次にリスト同士を比較して「リストB」から「リストA」と一致するものを削除。おわったら「,」記号で分割して(今回のファイルは列数「6」を指定)テーブルに変換する。
リスト比較 = List.RemoveItems(リストB, リストA),
不一致テーブル = Table.FromRows(
List.Transform(
リスト比較,
each Splitter.SplitTextByDelimiter(",")(_)
), 6
),
同じく、除外する前の「リストA」をそのままテーブルに変換。
テーブルA = Table.FromRows(
List.Transform(
リストA,
each Splitter.SplitTextByDelimiter(",")(_)
), 6
),
2つのテーブルをマージし、不一致の箇所をリスト化して抽出する。
クエリのマージ = Table.NestedJoin(
不一致テーブル, {"Column6"},
テーブルA, {"Column6"},
"テーブルA"
),
不一致項目列の作成 = Table.AddColumn(クエリのマージ, "不一致項目", each [
リストA = Table.ToRows([テーブルA]){0},
リストB = List.FirstN(Record.FieldValues(_), 6),
リスト結合 = List.Zip({リストA, リストB}),
比較リスト = List.Transform(リスト結合, each Number.From(_{0}=_{1})),
見出しリスト = List.Transform(
{1..List.Count(比較リスト)},
each Number.ToText(_, "Column0")
),
不一致抽出 = List.Select(
List.Zip({比較リスト, 見出しリスト}),
each _{0}=0
),
不一致項目 = Text.Combine(
List.Transform(不一致抽出, each _{1}), ", "
)
][不一致項目]),
あとはマージ列を削除。
テーブル列の削除 = Table.RemoveColumns(不一致項目列の作成,{"テーブルA"})
in
テーブル列の削除
これを読み込めばおしまい。
ついでに見やすいように条件付き書式を入れておいた。
テーブルの範囲を選択して
[ホーム]→[条件付き書式]→[新しいルール]
[数式を使用して、書式設定するセルを決定]を選択
「次の数式を満たす場合に値を書式設定」下の空欄に「=A$1=$G2」と入れる
[書式]で塗りつぶしを設定して[OK]→[OK]
以上。
一応名誉のために書いておくと、引き継ぎ相手の作ったファイルはこんな間違いはなく、中味は正しかった。