ゴールのイメージをそろえる
今回のテーマは「2024/10/01 や 2024-10-01 のような“日付っぽい文字列”を、Power Query で ちゃんと日付型(type date)に変換する実務テンプレ」です。
見た目は日付なのに、実は text のままで、
並べ替えが文字順になる・期間集計ができない・他テーブルの日付と JOIN できない——こういう“日付あるある事故”を防ぐのが目的です。
キーワードは「文字列のパターンをそろえる」「ロケール(日付の読み方)を意識する」「エラーを出さないように変換する」です。
まず「なぜ日付になってくれないのか」を理解する
Power Query が日付として認識できるかどうかは“書式次第”
Power Query は、2024-10-01 や 2024/10/01 のような、
「その環境のロケールで“日付として読める形”」なら、自動で date 型に変換できます。
逆に、次のようなパターンは、そのままだと失敗しがちです。
2024.10.01(ドット区切り)2024年10月1日(日本語入り)20241001(区切りなし8桁)01/10/2024(日付と月の順番がロケールと違う)
なので、やるべきことはこうです。
文字列を「Power Query が読める日付書式」にそろえる。
そのうえで、date 型に変換する(または Date.FromText を使う)。
この2ステップをテンプレ化しておけば、ほとんどの“日付文字列”は怖くなくなります。
例題の前提データをイメージする
次のようなテーブルを想像してください。
| 受注番号 | 受注日 | 納品予定日 |
|---|---|---|
| 1001 | “2024/10/01” | “2024-10-05” |
| 1002 | “2024年10月2日” | “2024/10/10” |
| 1003 | “20241003” | “” |
| 1004 | null | “2024.10.15” |
ポイントはこうです。
受注日・納品予定日が、どちらも text として入っている。
書式がバラバラ(スラッシュ、ハイフン、日本語、8桁、ドット)。
空文字や NULL も混ざっている。
このままでは、期間フィルタ・月別集計・日付差分(納期遅延日数など)がまともに計算できません。
ここに「日付文字列を日付型に変換」テンプレをかけていきます。
一番シンプルな型:すでに「YYYY/MM/DD」ならそのまま型変換
受注日がきれいな 2024/10/01 形式の場合
まずは、書式がすでに「YYYY/MM/DD」でそろっている、いちばんラクなパターンです。
let
Source = ・・・前のステップ・・・,
ChangedType =
Table.TransformColumnTypes(
Source,
{{"受注日", type date}}
)
in
ChangedType
Power Queryこれだけで、"2024/10/01" は #date(2024, 10, 1) という date 型になります。
日本語環境(ロケールが日本)なら、YYYY/MM/DD や YYYY-MM-DD は素直に読んでくれます。
「まずは型変換だけ試してみて、ダメなら前処理を足す」という順番で考えると、シンプルに進められます。
パターン1:YYYY年MM月DD日 を日付型に変換する
日本語入りの日付文字列をどう扱うか
"2024年10月2日" のような文字列は、そのまま type date に変換しようとすると、たいていエラーになります。
なので、いったん「数字と区切りだけの形」に変換してから、日付型にします。
例えば、"2024年10月2日" を "2024/10/2" に変えてから date にする、というイメージです。
受注日列に対しての変換テンプレ
let
Source = ・・・前のステップ・・・,
// 1) 日本語を取り除き、スラッシュ区切りにそろえる
Normalized =
Table.TransformColumns(
Source,
{
{
"受注日",
each
if _ = null then
null
else
let
t = Text.From(_),
noYear = Text.Replace(t, "年", "/"),
noMonth = Text.Replace(noYear, "月", "/"),
noDay = Text.Replace(noMonth, "日", "")
in
noDay,
type nullable text
}
}
),
// 2) 日付型に変換
ChangedType =
Table.TransformColumnTypes(
Normalized,
{{"受注日", type date}}
)
in
ChangedType
Power Queryここでやっていることを言葉で整理します。
"2024年10月2日" → "2024/10/2/" → "2024/10/2/" → "2024/10/2" のように、
「年」「月」「日」をスラッシュや空文字に置き換えて、YYYY/MM/DD 形式に寄せている。
そのうえで type date に変換している。
これで、日本語入りの日付文字列も、きれいに date 型にできます。
パターン2:YYYYMMDD(8桁)を日付型に変換する
区切りなし8桁の日付文字列
"20241003" のような「区切りなし8桁」は、
そのままでは日付として認識されませんが、YYYY/MM/DD に変形してしまえば、あとは同じです。
8桁日付を YYYY/MM/DD に変換するテンプレ
let
Source = ・・・前のステップ・・・,
// 1) 8桁文字列を YYYY/MM/DD に整形
Normalized =
Table.TransformColumns(
Source,
{
{
"受注日",
each
if _ = null or _ = "" then
null
else
let
t = Text.From(_),
y = Text.Start(t, 4),
m = Text.Middle(t, 4, 2),
d = Text.End(t, 2),
result = y & "/" & m & "/" & d
in
result,
type nullable text
}
}
),
// 2) 日付型に変換
ChangedType =
Table.TransformColumnTypes(
Normalized,
{{"受注日", type date}}
)
in
ChangedType
Power Query"20241003" → "2024"(年)+ "10"(月)+ "03"(日) → "2024/10/03"
という形にしてから、date 型に変換しています。
空文字や NULL はそのまま NULL にしているので、変換エラーも出ません。
パターン3:ドット区切り YYYY.MM.DD を日付型に変換する
"2024.10.15" のようなパターン
"2024.10.15" は、そのままだとロケールによっては日付として認識されません。
これも、「ドットをスラッシュに変える」だけで、かなり素直に変換できるようになります。
let
Source = ・・・前のステップ・・・,
Normalized =
Table.TransformColumns(
Source,
{
{
"納品予定日",
each
if _ = null then
null
else
Text.Replace(Text.From(_), ".", "/"),
type nullable text
}
}
),
ChangedType =
Table.TransformColumnTypes(
Normalized,
{{"納品予定日", type date}}
)
in
ChangedType
Power Query"2024.10.15" → "2024/10/15" → #date(2024, 10, 15)
という流れです。
もう一歩進んだ実務テンプレ:関数化して再利用する
「日付文字列を日付型に変換する関数」を1つ持っておく
書式が混在している現場では、
「日本語入り」「8桁」「スラッシュ」「ハイフン」「ドット」などをまとめて面倒見たいことが多いです。
そこで、「日付文字列をいい感じに日付型にしてくれる関数」を一つ作っておくと便利です。
// クエリ名:fn_TextToDateJP
let
TextToDateJP = (value as nullable any) as nullable date =>
let
// null はそのまま
v =
if value = null then
null
else
Text.Trim(Text.From(value)),
// 空文字は null
v1 =
if v = "" then
null
else
v,
// 日本語をスラッシュに
v2 =
if v1 = null then
null
else
let
s1 = Text.Replace(v1, "年", "/"),
s2 = Text.Replace(s1, "月", "/"),
s3 = Text.Replace(s2, "日", "")
in
s3,
// ドットをスラッシュに
v3 =
if v2 = null then
null
else
Text.Replace(v2, ".", "/"),
// 8桁(YYYYMMDD)の場合はスラッシュを挿入
v4 =
if v3 = null then
null
else if Text.Length(v3) = 8 and Text.Select(v3, {"0".."9"}) = v3 then
let
y = Text.Start(v3, 4),
m = Text.Middle(v3, 4, 2),
d = Text.End(v3, 2)
in
y & "/" & m & "/" & d
else
v3,
// 最後に Date.FromText で日付化(失敗したら null)
result =
if v4 = null then
null
else
try Date.FromText(v4) otherwise null
in
result
in
TextToDateJP
Power Queryこの関数は、ざっくり言うとこういう動きをします。
NULL や空文字はそのまま NULL。
「年」「月」「日」をスラッシュに変える。
ドットをスラッシュに変える。
8桁数字なら YYYY/MM/DD に整形する。
最後に Date.FromText で日付に変換し、失敗したら NULL にする。
これを作っておけば、クエリ側はかなりスッキリ書けます。
let
Source = ・・・前のステップ・・・,
Converted =
Table.TransformColumns(
Source,
{
{"受注日", fn_TextToDateJP, type nullable date},
{"納品予定日", fn_TextToDateJP, type nullable date}
}
)
in
Converted
Power Query「日付文字列を日付型に変換する」という意図が、コードから一目で分かるようになります。
実務での“ハマりポイント”と回避のコツ
ロケール(日付の読み方)に注意する
01/10/2024 が「2024年1月10日」なのか「2024年10月1日」なのかは、
ロケール(地域設定)によって解釈が変わります。
日本ロケールでは、基本的に YYYY/MM/DD を想定しているので、DD/MM/YYYY 形式のデータを扱うときは、
「日」「月」を入れ替える前処理を自分で書く必要があります。
「どの列がどの書式で来るか」を最初に決めておくと、クレンジングの設計が一気に楽になります。
日付型にしておくと何が嬉しいか
日付型にしておくと、次のようなことが“当たり前に”できるようになります。
期間フィルタ(2024/10/01〜2024/10/31 だけ抽出)。
月別・年別の集計(Date.Year、Date.Month など)。
日付差分(納期遅延日数、在庫滞留日数など)の計算。
逆に、text のまま放置すると、
「文字列としての大小比較」になってしまい、"2024/2/1" と "2024/10/1" の順番が崩れたりします。
実務テンプレとしてのまとめ
「日付文字列を日付型変換」の本質は、次の二つです。
Power Query が読める書式(たとえば YYYY/MM/DD)に、文字列をまずそろえる。
そのうえで、type date への型変換、または Date.FromText を使って日付型にする。
これをテンプレとして持っておけば、
受注日・出荷日・請求日・入金日・有効期限など、
あらゆる“日付っぽい文字列”を、迷わず“ちゃんと日付”として扱えるようになります。
