Power Query 実務テンプレ | データ取込・更新系:更新日時を自動列追加

Excel VBA Power Query M Formula Language
スポンサーリンク

ゴールのイメージをそろえる

今回のテーマは「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.FilesDate 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.FilesDate modified を「ファイル更新日時」としてコピーする
  • 必要に応じて、両方を持たせておく

この3つの型を頭に入れておけば、どんな取込クエリにも簡単に組み込めます。

タイトルとURLをコピーしました