ゴールのイメージをそろえる
今回のテーマは「Power Query で “エラー行だけをきれいに別テーブルに分離する” 実務テンプレです。
ここまでやってきた
必須項目未入力チェック
数値範囲チェック
桁数チェック
マスタ未存在データ検出
などで見つかった「おかしな行」を、
本体テーブル(正常データ)
エラーテーブル(要確認データ)
にきちんと分けておく——これが、前処理の“締め”になります。
今日はその「分け方」を、初心者でも真似しやすい形でテンプレ化します。
まず「エラー行」と「正常行」をどう持つかを決める
フラグ方式で考えるのが一番シンプル
前処理の途中で、こんな列を作ってきましたよね。
必須項目NG(true/false)
数値範囲NG(true/false)
桁数NG(true/false)
マスタ未存在(true/false)
この「NG フラグ」をうまく使うと、
「エラー行だけのテーブル」と「正常行だけのテーブル」を簡単に作れます。
イメージはこうです。
元テーブルに「エラーかどうか」のフラグ列を追加する
フラグ = true の行だけを抽出 → エラーテーブル
フラグ = false の行だけを抽出 → 正常テーブル
この“二分割”を、Power Query の Table.SelectRows でやっていきます。
例題:必須項目+数値範囲のエラーをまとめてフラグ化する
まずは「エラーかどうか」を1列にまとめる
次のようなテーブルを想像してください。
| 受注番号 | 受注日 | 顧客コード | 金額 |
|---|---|---|---|
| 1001 | 2024/01/05 | C001 | 1200 |
| 1002 | C002 | 800 | |
| 1003 | 2024/01/10 | 500 | |
| 1004 | 2024/01/15 | C004 | -100 |
| 1005 | 2024/01/20 | C005 | 200000 |
ルールをこう決めます。
受注日:必須(空欄・NULL は NG)
顧客コード:必須
金額:0〜100000 の範囲内
この3つのチェックをまとめて「エラー行フラグ」にしてみます。
let
Source = ・・・前のステップ・・・,
AddedErrorFlag =
Table.AddColumn(
Source,
"エラー行",
each
let
// 受注日 必須チェック
vDate = [受注日],
tDate =
if vDate = null then
""
else
Text.Trim(Text.From(vDate)),
isDateEmpty = tDate = "",
// 顧客コード 必須チェック
vCust = [顧客コード],
tCust =
if vCust = null then
""
else
Text.Trim(Text.From(vCust)),
isCustEmpty = tCust = "",
// 金額 数値範囲チェック(0〜100000)
vAmt = [金額],
isAmtNull = vAmt = null,
isAmtOutOfRange =
not isAmtNull
and (vAmt < 0 or vAmt > 100000),
// どれか一つでも NG なら「エラー行」
isError =
isDateEmpty
or isCustEmpty
or isAmtNull
or isAmtOutOfRange
in
isError,
type logical
)
in
AddedErrorFlag
Power Queryここで大事なのは、「エラーの定義を1か所にまとめている」ことです。
この「エラー行」列が true なら、その行は何かしらのルールに違反している、という意味になります。
ステップ1:エラー行だけを別テーブルに分離する
フラグ = true の行だけを抽出する
さっき作った「エラー行」列を使って、エラー行だけのテーブルを作ります。
let
Source = AddedErrorFlag, // さっきのステップ
ErrorTable =
Table.SelectRows(
Source,
each [エラー行] = true
)
in
ErrorTable
Power Queryこの ErrorTable には、次のような行が入ります。
受注日が空欄の行
顧客コードが空欄の行
金額が NULL の行
金額が 0〜100000 の範囲外の行
つまり、「本番集計に混ぜたくない行の一覧」です。
これを「エラーログ」として別シートに出したり、担当者に渡したりできます。
ステップ2:正常行だけを本体テーブルとして残す
フラグ = false の行だけを抽出する
同じフラグを使って、今度は「正常行だけ」のテーブルを作ります。
let
Source = AddedErrorFlag, // さっきのステップ
ValidTable =
Table.SelectRows(
Source,
each [エラー行] = false
)
in
ValidTable
Power Queryこの ValidTable が、「本番の集計・分析に使うテーブル」です。
エラー行はすべて除外されているので、
「変な値のせいで集計結果が壊れる」リスクをかなり減らせます。
ステップ3:クエリを2本に分ける設計にしておく
「元クエリ+エラークエリ+正常クエリ」という構成
実務で運用しやすい形は、だいたいこうです。
クエリA:元データの取り込み+前処理+エラーフラグ追加(エラー行列)
クエリB:クエリAを参照して、エラー行だけ抽出(エラーテーブル)
クエリC:クエリAを参照して、正常行だけ抽出(本体テーブル)
Power Query 的には、B と C は A を「参照」して作るイメージです。
M コードで書くと、B と C の先頭はこうなります。
let
Source = クエリA, // 参照
...
in
...
Power Queryこうしておくと、
エラーの定義を変えたいときは、クエリAの「エラー行」列だけ直せばよい
クエリB(エラー)とクエリC(正常)は、その変更を自動で引き継ぐ
という構造になります。
「エラーの定義が散らばらない」というのが、めちゃくちゃ大事なポイントです。
応用:エラーの種類を分けて持ちたい場合
「どのルールに引っかかったか」も残しておく
もう一歩踏み込むと、「どのチェックに引っかかったか」も残しておくと便利です。
例えば、こんな列を追加します。
受注日必須NG
顧客コード必須NG
金額_範囲NG
それぞれ true/false で持っておき、
「エラー行」はそれらの OR で作る、という形です。
let
Source = ・・・前のステップ・・・,
AddedFlags =
Table.AddColumn(
Source,
"受注日_必須NG",
each
let
v = [受注日],
t =
if v = null then
""
else
Text.Trim(Text.From(v))
in
t = "",
type logical
),
AddedFlags2 =
Table.AddColumn(
AddedFlags,
"顧客コード_必須NG",
each
let
v = [顧客コード],
t =
if v = null then
""
else
Text.Trim(Text.From(v))
in
t = "",
type logical
),
AddedFlags3 =
Table.AddColumn(
AddedFlags2,
"金額_範囲NG",
each
let
v = [金額]
in
v = null or v < 0 or v > 100000,
type logical
),
AddedErrorFlag =
Table.AddColumn(
AddedFlags3,
"エラー行",
each
[受注日_必須NG]
or [顧客コード_必須NG]
or [金額_範囲NG],
type logical
)
in
AddedErrorFlag
Power Queryこうしておくと、エラーテーブル側で
「どのルールに引っかかったのか」を列単位で確認できます。
担当者に渡すときも、「ここが空欄です」「ここが範囲外です」と説明しやすくなります。
重要ポイントの深掘り
「エラーを消す」のではなく「分ける」という発想
前処理で一番やってはいけないのは、
「エラー行を何も記録せずに消してしまう」ことです。
確かに、Table.SelectRows で正常行だけ残せば、
見た目はきれいなテーブルになります。
でも、「どれだけエラーがあったのか」「どんなエラーが多いのか」が分からなくなります。
これは、品質管理の観点ではかなり危険です。
だからこそ、
元データ
正常テーブル
エラーテーブル
という3層構造にして、
「エラーは消さずに、別テーブルとしてちゃんと残す」という設計が大事になります。
エラー行の扱いは“業務側と決める”
技術的には、「エラー行を分離する」ところまでが Power Query の仕事です。
その先——
エラー行を修正して再取り込みするのか
エラー行を除外したまま集計するのか
エラー行を別のフローで補完するのか
は、業務ルールの話になります。
だからこそ、「エラー行をきれいに分離して渡せる」ことが、
データ担当としての大きな武器になります。
実務テンプレとしてのまとめ
「エラー行を別テーブル分離」の本質は、次の2ステップです。
エラーの条件(必須NG・範囲NG・マスタ未存在など)を logical 列(エラー行フラグ)として1か所にまとめる。
そのフラグを使って、Table.SelectRows で「エラー行テーブル」と「正常行テーブル」に二分割する。
そして、実務で効かせるためには、
元クエリ(フラグまで)
エラークエリ(エラー行だけ)
正常クエリ(正常行だけ)
という構成にして、「エラーの定義を1か所に集約する」ことがとても重要です。
ここまであなたが積み上げてきた
必須項目チェック
桁数チェック
数値範囲チェック
マスタ未存在検出
などのテンプレと、この「エラー行分離」を組み合わせると、
“壊れた行を本番集計に混ぜない”ための前処理ラインが、かなりプロっぽいレベルになります。
