はじめに:「最後」に買ったのは?「最新」の記録は?
Excelで家計簿やお小遣い帳をつけている皆さん!こんな経験はありませんか?
「あれ、昨日買った『酒』、一番最後に入力したのはどこのお店だっけ?」
「いや、待てよ。3日前のレシートが出てきた…。これを入力したら、『日付が一番新しい酒』はどっちになるんだ?」
そう、リストの一番下にある「物理的な最後のデータ」と、日付が一番新しい「時系列での最新データ」。
この二つは、必ずしも一致するとは限りません。
今回の記事は、まさにそのお悩みにお応えします!
途中に空白行があったり、日付が昇順に並んでいなかったりする、非常にリアルな家計簿リストを舞台に、「物理的な最後」と「日付的な最新」のデータを、それぞれ関数でスマートに抜き出す方法を探求していきます。
この検索スキル、マスターすればあなたのExcelスキルが爆上がりすること間違いなしですよ!
表の最終行を表示するロジックは以下の記事で紹介していますので、ぜひご覧ください!
本記事では、無料のWeb版Excelを使用して検証および画像の作成を行っています。Windowsはもちろん、MacやLinuxの方もブラウザさえあれば挑戦できます!
準備:臨場感あふれる家計簿
何事も、まずは準備から。
まっさらなシートのA1セルを起点に、以下のようなデータリストを作成してください。
または、下の数式をA1セルに貼り付けてください。
={"日付","カテゴリ","金額","店舗";45962,"食費",1150,"ラルズ";45963,"酒",960,"ツルハ";45964,"外食",2310,"すみれ";45964,"交通費",530,"JR";45965,"酒",620,"アークス";45965,"外食",700,"宮越屋";,,,;45967,"交通費",230,"市電";45966,"食費",1670,"北海市場";,,,;45971,"消耗品",400,"サツドラ";45971,"酒",590,"セコマ";45971,"交通費",330,"地下鉄";45968,"交通費",670,"タクシー";45968,"酒",2900,"エノテカ";45968,"外食",1800,"松尾"}

これは、何を隠そう筆者のとある家計簿です(笑)。
リアリティがあっていいでしょ!
登場する店舗はすべて札幌市内に実在しますよ。
臨場感重視です!
このリストには、今回の冒険の鍵となる「空白行(8行目、11行目)」と、「日付が昇順でない(9行目と10行目、12行目以降もバラバラ)」という、2つの大きな罠が仕掛けられています。
さあ、この難解なリストを攻略していきましょう!
ミッション1:「物理的な最後」の「酒」を探せ!
まずは第1段階。
日付は一切無視して、単純に「リストの一番下から見て、最初に見つかる『酒』は、どこの店で買ったか?」を突き止めます。

(ゴールは、16行目の「エノテカ」ですね!)
アプローチ1:XLOOKUP (逆順検索)
考えかた
最新の検索関数XLOOKUPには、まさにこのための「逆順検索」オプションが搭載されています。これを使わない手はありません。
数式と解説
=XLOOKUP("酒",B:B,D:D,,0,-1)
・XLOOKUP(検索値, 検索範囲, 戻り配列, [見つからない場合], [一致モード], [検索モード]) の引数を見ていきましょう。
- 検索値:
"酒" - 検索範囲:
B:B(カテゴリ列) - 戻り配列:
D:D(店舗列) - [一致モード]:
0(完全一致) - [検索モード]:
-1←(重要!!)
・... , -1): ここが最大のポイント!第6引数「検索モード」を「-1」に設定すると、XLOOKUPはなんとリストの末尾から先頭に向かって(逆順に)検索を開始します。
もしここを省略(または1)にすると、上から検索して最初に見つかるB3セルの「酒」にヒットし、「ツルハ」が返ってしまいます。
しかし、逆順検索なら、下から探して最初に見つかるB16セルの「酒」にヒットし、正しく「エノテカ」を返してくれます!

アプローチ2:LOOKUP (古典的テクニック)
考えかた
XLOOKUPがない古いExcelバージョンでも、LOOKUP関数を使った古典的なテクニックで「最後の値」を見つけることができます。
引数も少なくシンプルですが、ロジックはまさに「初見殺し」です。
数式と解説
=LOOKUP(2,1/(B:B="酒"),D:D)
この数式、内側から見ていきましょう。
1. (B:B="酒"): まず、B列が「酒」かどうかを判定し、{FALSE;TRUE;FALSE;...;TRUE;...;TRUE;...}というTRUE/FALSEの配列を作ります。

2. 1/(...): 次に、このTRUE/FALSE配列で「1」を割ります。
1/TRUE(1/1)は「1」、1/FALSE(1/0)はエラー「#DIV/0!」になります。
結果として、{#DIV/0!;1;#DIV/0!;...;1;...;1;...}という、「1」とエラーが混在した配列が生まれます。

3. LOOKUP(2, ..., D:D): LOOKUP関数で、この特殊な配列から「2」を探します。
LOOKUPは、検索値(2)以上の値がない場合、エラーを無視して配列の中の最後の数値(今回の場合は、B16セルに対応する最後の「1」)を見つけてくれます!
そして、その位置に対応する値を、第3引数の範囲(D:D)から返します。結果は「エノテカ」です。見事ですよね!

アプローチ3:INDEX & XMATCH (逆順検索)
考えかた
柔軟性の鬼、INDEX関数も使ってみましょう。ただし、相棒のMATCH関数では逆順検索ができません。
失敗例: =INDEX(D:D,MATCH("酒",B:B,0))
これでは、MATCH関数が最初に見つかる「酒」(B3)の位置「3」を返してしまい、「ツルハ」が表示されてしまいます。

そこで、MATCHの進化系、XMATCH関数の出番です!
数式と解説
=INDEX(D:D,XMATCH("酒",B:B,0,-1))
・XMATCH("酒",B:B,0,-1): XMATCH関数は、XMATCH(検索値, 検索範囲, [一致モード], [検索モード]) のように使います。
第4引数の「検索モード」に「-1」を指定することで、XLOOKUPと同様に、リストの末尾から逆順に検索ができます!
結果として、B16セルの位置「16」が返されます。

・INDEX(D:D, 16): INDEX関数が、D列の16番目の値、「エノテカ」を返します。

ミッション2:「日付が最新」の「酒」を探せ!
さあ、ここからが本番です!
家計簿をつけていて、「あ!3日前のレシート、入力し忘れてた!」ってこと、ありますよね?(私はよくあります…)
そんな時、リストの「物理的な最後」(エノテカ)ではなく、「日付が最も新しい(最新の)」『酒』は、どこの店で買ったかを知りたくなります。
このリストでは、13行目の「2025/11/10」の「酒」(セコマ)が、16行目の「2025/11/7」の「酒」(エノテカ)よりも日付が新しいですね。

ゴールは「セコマ」です!
アプローチ4:INDEX & MATCH (配列計算の真骨頂)
考えかた
まず、「酒」カテゴリの中で、最も新しい日付(MAX)を特定します。
次に、その「日付」と「”酒”というカテゴリ」が同時に一致する行を探します。
失敗例
=INDEX(D:D,MATCH(MAX(IF(B:B="酒",A:A)),A:A,0))
惜しい!
MAX(IF(B:B="酒",A:A))で、「酒」カテゴリの最新日付「2025/11/10」を特定できています。
しかし、その日付をMATCH(...,A:A,0)で探すと、A列で最初に見つかる「2025/11/10」(12行目の消耗品)にヒットしてしまいます。

これではダメですね。
正解例
=INDEX(D:D,MATCH(1,(MAX(IF(B:B="酒",A:A))=A:A)*(B:B="酒"),0))
これぞ、配列計算の真骨頂です!
1. MAX(IF(B:B="酒",A:A)): まず、「酒」カテゴリの最新日付「2025/11/10」を計算します。

2. (... = A:A): A列全体が、その最新日付と一致するかを判定し、TRUE/FALSEの配列を作ります。(12, 13, 14行目がTRUEになる)

3. (B:B="酒"): B列全体が、「酒」と一致するかを判定し、TRUE/FALSEの配列を作ります。
(3, 6, 13, 16行目がTRUEになる)

4. ( ... ) * ( ... ): ステップ2とステップ3の配列を掛け算します。
両方ともTRUEの場所だけが「1」、それ以外は「0」になる配列ができます。
今回、両方を満たすのは13行目だけです!

5. MATCH(1, ..., 0): この「1」と「0」の配列から、「1」を完全一致で探します。
結果、13行目の位置「13」が返されます。

6. INDEX(D:D, 13): INDEX関数が、D列の13番目の値、「セコマ」を返します。
北海道を代表するコンビニです。私も毎日お世話になっています(笑)。

ちなみに、VLOOKUP関数は?
やろうと思えばできなくはありませんが、CHOOSE関数で仮想的な表を作り直す必要があり、ロジックは上記とほぼ同じになるため、今回はVLOOKUP先生にはお休みを頂いております。
アプローチ5:FILTER (最新・最強の絞り込み)
考えかた
アプローチ4のロジック(「最新日付」かつ「”酒”」)は、最新のFILTER関数を使うと、驚くほどシンプルに記述できます。
数式と解説
=FILTER(D:D,(MAX(IF(B:B="酒",A:A))=A:A)*(B:B="酒"))
・(MAX(IF(B:B="酒",A:A))=A:A)*(B:B="酒"): この部分は、アプローチ4で使った「条件配列」(13行目だけが[1]になる配列)と全く同じものです。

・FILTER(D:D, ...): FILTER関数が、D列(店舗列)を、この条件配列がTRUEの行(つまり13行目)だけ絞り込んで、結果を返します。

数式も短く、やっていることも「条件で絞り込む」と直感的で、非常に可読性が高いですね!
まとめ:その「最後」、本当に「最後」ですか?
「最後」という言葉には、「リストの物理的な最後」と「時系列的な最後(=最新)」の2つの意味があり、どちらを求めるかで数式がガラリと変わることが、お分かりいただけたかと思います。
特に、家計簿のように後からレシートを入力して日付が昇順にならないデータは、実務でもよくある光景ですよね。
XLOOKUPの逆順検索や、LOOKUPの古典テクニック、そしてMAX(IF…)を使った配列計算。
これらのテクニックを使いこなせれば、どんなに複雑なリストでも、あなたが本当に欲しい「最後」のデータを、確実に抜き出せるようになるはずですよ!



