ゴールのイメージをそろえる
今回のテーマは「Power Query でデータを取り込むたびに、“いつ更新したか”を自動で列として残す実務テンプレ」です。
つまり、最終テーブルの1列として「更新日時」や「更新日」を持たせておき、
「この行はいつの更新時点のデータか」を後から確認できるようにする、という発想です。
ここでは、プログラミング初心者向けに
- クエリを更新した“時刻”を列に入れるパターン
- ファイルの“更新日時”を列に入れるパターン
の2つを、例題付きでかみ砕いて説明します。
パターン1:クエリを更新した「時刻」を列として追加する
基本の考え方とキーワード
「更新した瞬間の時刻」を列に入れたいときに使うのが、DateTime.LocalNow() や DateTimeZone.FixedLocalNow() です。
ざっくり言うと、
DateTime.LocalNow()…「今この瞬間(ローカル時間)」DateTimeZone.FixedLocalNow()…「今この瞬間(タイムゾーン付き)」
どちらも「クエリを実行したタイミング」で評価されます。
つまり、[更新]ボタンを押すたびに、その時点の時刻が新しく入る、という動きになります。
一番シンプルなテンプレ(単一テーブルに更新日時列を足す)
たとえば、すでに何らかのテーブル SourceTable があるとして、
そこに「更新日時」列を追加する最小コードはこうなります。
let
Source = SourceTable,
// 1) 更新時刻を一度だけ変数に取る
RefreshDateTime = DateTime.LocalNow(),
// 2) その値を全行に同じように追加する
AddedRefreshColumn =
Table.AddColumn(
Source,
"更新日時",
each RefreshDateTime,
type datetime
)
in
AddedRefreshColumn
Power Queryここでの重要ポイントは「DateTime.LocalNow() を列の中で直接呼ばず、先に変数に入れている」ことです。
もしこう書いてしまうと、
Table.AddColumn(Source, "更新日時", each DateTime.LocalNow(), type datetime)
Power Query行ごとに DateTime.LocalNow() が評価されるため、
行によって微妙に時刻がズレることがあります(特に行数が多いとき)。
一度だけ RefreshDateTime に評価してから、それを全行に入れることで、
「すべての行が同じ更新時刻を持つ」きれいな状態になります。
日付だけ欲しい場合のテンプレ
「時刻まではいらない、日付だけでいい」という場合は、DateTime.Date で日付部分だけを取り出して使います。
let
Source = SourceTable,
RefreshDate = DateTime.Date(DateTime.LocalNow()),
AddedRefreshDate =
Table.AddColumn(
Source,
"更新日",
each RefreshDate,
type date
)
in
AddedRefreshDate
Power Queryこれで、すべての行に「更新日(例:2025-03-23)」が入ります。
パターン2:ファイルの「更新日時」を列として追加する
「いつ更新したか」ではなく「ファイルがいつ更新されたか」を残したい場合
フォルダ内の CSV や Excel を一括取込している場合、
「クエリを更新した時刻」ではなく「元ファイルの更新日時」を列として持たせたい、
というニーズもよくあります。
この場合は、Folder.Files が返してくれる Date modified 列をそのまま使うのが一番シンプルです。
フォルダ一括取込+ファイル更新日時列のテンプレ(CSV 例)
CSV をフォルダから一括取込する典型パターンに、「ファイル更新日時」列を足した例です。
let
// 1) フォルダ内のファイル一覧を取得
Source = Folder.Files("C:\Data\DailyCsv"),
// 2) .csv だけに絞り込む
OnlyCsv =
Table.SelectRows(
Source,
each Text.Lower([Extension]) = ".csv"
),
// 3) 元ファイル名と更新日時を列としてコピー
WithMeta =
Table.TransformColumns(
OnlyCsv,
{
{"Name", each _, type text},
{"Date modified", each _, type datetime}
}
),
RenamedMeta =
Table.RenameColumns(
WithMeta,
{
{"Name", "元ファイル名"},
{"Date modified", "ファイル更新日時"}
}
),
// 4) Content を CSV としてテーブル化
AddedCsvTable =
Table.AddColumn(
RenamedMeta,
"CsvTable",
each
Csv.Document(
[Content],
[
Delimiter = ",",
Encoding = 65001,
QuoteStyle = QuoteStyle.Csv
]
),
type table
),
// 5) ヘッダー昇格
WithHeader =
Table.TransformColumns(
AddedCsvTable,
{
"CsvTable",
each
Table.PromoteHeaders(
_,
[PromoteAllScalars = true]
),
type table
}
),
// 6) 列名を取得して展開
SampleTable = WithHeader[CsvTable]{0},
ColNames = Table.ColumnNames(SampleTable),
Combined =
Table.ExpandTableColumn(
WithHeader,
"CsvTable",
ColNames,
ColNames
)
in
Combined
Power Queryこの Combined テーブルには、明細列に加えて
- 元ファイル名
- ファイル更新日時
が列として残ります。
ここでのポイントは、「更新日時を自分で計算しているのではなく、ファイルシステムが持っている Date modified をそのまま使っている」ということです。
「この行は、いつ更新されたファイルから来たのか」を知りたいときに、とても役に立ちます。
「更新時刻」と「ファイル更新日時」の使い分け
何を知りたいのかで選ぶ
ざっくり整理すると、こうなります。
- 「Excel でいつ[更新]ボタンを押したか」を残したい
→DateTime.LocalNow()を使って「更新日時」列を追加する - 「元ファイルがいつ更新されたか」を残したい
→Folder.FilesのDate modifiedを列としてコピーする
どちらも「更新日時」っぽいですが、意味が違います。
前者は「取り込み処理の実行タイミング」、後者は「データが書き出されたタイミング」に近いです。
実務では、両方持たせることもあります。
- 更新日時(クエリ実行時刻)
- ファイル更新日時(元データの更新時刻)
この2つがあると、「データが更新されたのに、クエリをまだ更新していない」といったズレも見つけやすくなります。
重要ポイントの深掘り
DateTime.LocalNow を「一度だけ評価する」理由
さっきも触れましたが、ここは本当に大事なので、もう少しだけ噛み砕きます。
Table.AddColumn の第3引数(each の中)に DateTime.LocalNow() を直接書くと、
行ごとに関数が呼ばれます。行数が多いと、評価に数秒〜十数秒かかることもあります。
その間、時計は進み続けるので、先頭行と末尾行で時刻がズレることがあります。
「更新日時」という意味では、これはあまり気持ちよくありません。
そこで、
RefreshDateTime = DateTime.LocalNow()
Power Queryと先に一度だけ評価しておき、each RefreshDateTime で全行に同じ値を入れる、という書き方にします。
これで、
- 評価は1回だけなので速い
- すべての行が同じ時刻を持つ
という、実務的にきれいな状態になります。
型(type)の指定も一緒に覚えておく
更新日時を列として追加するときは、型もきちんと指定しておくと後が楽です。
- 日付+時刻 →
type datetime - 日付だけ →
type date
たとえば、
Table.AddColumn(Source, "更新日時", each RefreshDateTime, type datetime)
Power Queryのように書いておくと、後でフィルタや並べ替えをするときに、
「文字列」ではなく「日付時刻」として正しく扱われます。
実務テンプレとしてのまとめ
「更新日時を自動列追加」というテーマは、実務で地味に効いてくる部分です。
DateTime.LocalNow()を一度だけ評価して「更新日時」列にするFolder.FilesのDate modifiedを「ファイル更新日時」としてコピーする- 必要に応じて、両方を持たせておく
この3つの型を頭に入れておけば、どんな取込クエリにも簡単に組み込めます。
