ゴールのイメージをそろえる
今回のテーマは「フォルダの中に同じ形式のファイルがたくさんあっても、“一番古いファイルだけ”を Power Query で自動的に選んで取り込む実務テンプレ」を身につけることです。
「最古ファイルのみ取得」は、ログの初期日、最初のマスタ版、最初の契約書など、“いちばん古い状態”を基準にしたいときに使えます。
やること自体は「最新ファイルのみ取得」とほぼ同じで、違うのは「並べ替えの向き」だけです。
キーワードは Folder.Files と Date modified(更新日時)、そして「並べ替え+先頭1行」です。
基本の考え方:フォルダ一覧から「一番古い1行」を選ぶ
Folder.Files と Date modified 列をおさらい
まず、フォルダを Power Query で扱う入口はいつも Folder.Files です。
let
Source = Folder.Files("C:\Data\Logs")
in
Source
Power Queryこれを実行すると、「そのフォルダにあるファイル一覧」がテーブルとして返ってきます。
このテーブルには、次のような列が含まれます。
Name(ファイル名)
Extension(拡張子)
Date modified(更新日時)
Size(サイズ)
Content(中身のバイナリ)
今回の主役は Date modified です。
ここを「昇順(古い順)」に並べ替え、先頭の1行だけ残せば、それが“最古ファイル”になります。
「最古ファイルだけ」を選ぶ流れ
流れはシンプルです。
更新日時で昇順ソート(古い順)。
先頭の1行だけ残す。
その行の Content を使って中身を読み込む。
「最新」との違いは、ソートの向きが Order.Descending ではなく Order.Ascending になるだけです。
例題1:最古の CSV ファイルだけを取り込むテンプレ
想定する状況
C:\Data\DailyCsv フォルダに、毎日こんなファイルが溜まっているとします。
log_2024-10-01.csv
log_2024-10-02.csv
log_2024-10-03.csv
…
この中から、「一番古い CSV(最初の日のログ)だけを Power Query で読みたい」というケースです。
実務テンプレ M コード(最古 CSV 1つだけ)
let
// 1) フォルダ内のファイル一覧を取得
Source = Folder.Files("C:\Data\DailyCsv"),
// 2) .csv だけに絞り込む
OnlyCsv =
Table.SelectRows(
Source,
each Text.Lower([Extension]) = ".csv"
),
// 3) 更新日時で昇順ソート(古い順)
Sorted =
Table.Sort(
OnlyCsv,
{{"Date modified", Order.Ascending}}
),
// 4) 先頭の 1 行だけ残す(最古ファイル)
OldestOne = Table.FirstN(Sorted, 1),
// 5) そのファイルの Content を CSV として読み込む
OldestContent = OldestOne{0}[Content],
CsvTable =
Csv.Document(
OldestContent,
[
Delimiter = ",",
Encoding = 65001,
QuoteStyle = QuoteStyle.Csv
]
),
// 6) 先頭行をヘッダーに昇格
Promoted =
Table.PromoteHeaders(
CsvTable,
[PromoteAllScalars = true]
)
in
Promoted
Power Queryここで一番大事なのは、次の3行です。
Sorted =
Table.Sort(OnlyCsv, {{"Date modified", Order.Ascending}})
OldestOne = Table.FirstN(Sorted, 1)
OldestContent = OldestOne{0}[Content]
Power QueryOrder.Ascending で「古い順」に並べ替え、Table.FirstN で「先頭1行だけ残し」、
その行の Content を取り出して Csv.Document に渡す——これが“最古ファイルのみ取得”のコアパターンです。
例題2:最古の Excel ファイルだけを取り込むテンプレ
想定する状況
C:\Data\MonthlyBooks に、毎月のマスタブックが溜まっているとします。
マスタ_商品2023-04.xlsx
マスタ商品2023-05.xlsx
マスタ商品_2023-06.xlsx
この中から、「一番古いマスタ(最初の版)の1枚目シートだけを読みたい」というケースです。
実務テンプレ M コード(最古 Excel 1つだけ)
let
// 1) フォルダ内のファイル一覧を取得
Source = Folder.Files("C:\Data\MonthlyBooks"),
// 2) .xlsx だけに絞り込む
OnlyXlsx =
Table.SelectRows(
Source,
each Text.Lower([Extension]) = ".xlsx"
),
// 3) 更新日時で昇順ソート(古い順)
Sorted =
Table.Sort(
OnlyXlsx,
{{"Date modified", Order.Ascending}}
),
// 4) 先頭の 1 行だけ残す(最古ブック)
OldestOne = Table.FirstN(Sorted, 1),
// 5) そのブックの Content を取り出す
OldestContent = OldestOne{0}[Content],
// 6) Excel.Workbook で中身を一覧化
Wb =
Excel.Workbook(
OldestContent,
true,
true
),
// 7) 1 枚目のシートを取得
FirstSheetRow =
Table.SelectRows(Wb, each [Kind] = "Sheet"){0},
FirstSheetTable = FirstSheetRow[Data],
// 8) 先頭行をヘッダーに昇格
Promoted =
Table.PromoteHeaders(
FirstSheetTable,
[PromoteAllScalars = true]
)
in
Promoted
Power QueryCSV のときと同じく、「Sorted → OldestOne → OldestContent」の3ステップが肝です。
そのあとに Excel.Workbook で中身を読むか、Csv.Document で読むかが違うだけで、型はまったく同じです。
重要ポイントの深掘り
「最古」を何で決めるか:更新日時かファイル名か
ここが実務的にはかなり重要です。
Date modified(更新日時)で最古を決めると、「一番最初に作られて、かつその後あまり更新されていないファイル」が選ばれます。
でも、現場によっては「ファイル名に含まれる日付」で最古を決めたいこともあります。
例えば、こんなケースです。
ファイル名:log_2024-01-01.csv
更新日時:2024-03-01(後から追記された)
この場合、「日付として一番古いログ」は 2024-01-01 ですが、
更新日時だけ見ると、もっと新しいファイルより“新しい”と判定されることがあります。
もし「ファイル名の日付で最古を決めたい」なら、次のような流れになります。
Name から日付部分を切り出す(Text.Middle や Text.Range など)。
それを Date 型に変換して「基準日」列を作る。
その列で昇順ソートして、先頭1行だけ残す。
更新日時で十分な現場も多いので、まずは Date modified 版を押さえ、
必要になったら「ファイル名日付版」に発展させる、という順番が現実的です。
Table.FirstN と {0} の関係をちゃんと理解する
ここは Power Query の“感覚”を作るうえで大事なので、もう一度整理します。
Table.FirstN(Sorted, 1) は、「Sorted テーブルの先頭から 1 行だけ残したテーブル」を返します。
つまり、OldestOne は「1行だけを持つテーブル」です。
OldestOne{0} は、「そのテーブルの 0 番目の行(最初の行)をレコードとして取り出す」操作です。
そのレコードの Content 列を取り出すので、OldestOne{0}[Content] という書き方になります。
テーブル
→ 1行だけのテーブル(Table.FirstN)
→ その1行のレコード({0})
→ そのレコードの特定列([Content] や [Name])
この階段を登る感覚に慣れておくと、フォルダ系のクエリは一気に怖くなくなります。
応用:最古ファイル名を列として残しておく
「どのファイルが最古だったか」を後から確認できるようにする
最古ファイルだけを読んでいると、「今どのファイルを見ているのか」を忘れがちです。
そこで、最古ファイルの Name(ファイル名)を列として一緒に持たせておくと、後から確認しやすくなります。
CSV 版に少しだけ手を加えると、こうなります。
let
Source = Folder.Files("C:\Data\DailyCsv"),
OnlyCsv =
Table.SelectRows(
Source,
each Text.Lower([Extension]) = ".csv"
),
Sorted =
Table.Sort(
OnlyCsv,
{{"Date modified", Order.Ascending}}
),
OldestOne = Table.FirstN(Sorted, 1),
OldestContent = OldestOne{0}[Content],
OldestName = OldestOne{0}[Name],
CsvTable =
Csv.Document(
OldestContent,
[
Delimiter = ",",
Encoding = 65001,
QuoteStyle = QuoteStyle.Csv
]
),
Promoted =
Table.PromoteHeaders(
CsvTable,
[PromoteAllScalars = true]
),
WithFileName =
Table.AddColumn(
Promoted,
"元ファイル名",
each OldestName,
type text
)
in
WithFileName
Power Queryこれで、最終テーブルのすべての行に「元ファイル名」として最古ファイルの名前が入ります。
「このデータはどのファイル由来か」「最古の基準が変わっていないか」を簡単にチェックできます。
実務テンプレとしてのまとめ
“最古ファイルのみ取得”の型は、たった一言で表せます。
「フォルダ一覧を更新日時で昇順ソートして、先頭1行だけ残し、その Content を読む」
これを CSV 版・Excel 版で一度手を動かして体に入れてしまえば、
「一番古いログだけ」「最初のマスタだけ」「最初の契約書だけ」といったニーズに、落ち着いて応えられるようになります。
