web-dev-qa-db-ja.com

VLOOKUPで「最後の」一致を返す方法は?

私はVLOOKUPでの作業に慣れていますが、今回は挑戦します。 最初に一致する値は必要ありませんが、最後です。どうやって? (私はLibreOffice Calcを使用していますが、MS Excelソリューションも同様に役立つはずです。)

その理由は、数千行の2つのテキスト列があるためです。1つはトランザクションの受取人(Amazon、Ebay、雇用主、食料品店など)のリストであり、もう1つは支出カテゴリ(賃金、税金、世帯、家賃など)。一部のトランザクションは毎回同じ支出カテゴリを持たないため、最近使用したものを取得したいと思います。リストはどちらの列でも(実際には日付で)並べ替えられており、並べ替え順序を変更したくないことに注意してください。

私が持っているもの(エラー処理を除く)は、通常の「最初に一致する」式です。

=VLOOKUP( 
[payee field] , [payee+category range] , [index of category column] , 
0 )

このような solutions を見たことがありますが、#DIV/0!エラー:

=LOOKUP(2 , 1/( [payee range] = [search value] ) , [category range] )

解は、必ずしもVLOOKUPではなく、任意の式にすることができます。また、受取人/カテゴリの列を入れ替えることもできます。ソート列に変更はありません。


最後ではなく最も頻繁な値を選択するソリューションのボーナスポイント!

配列数式を使用して、最後に一致するレコードからデータを取得できます。

_=INDEX(IF($A$1:$A$20="c",$B$1:$B$20),MAX(IF($A$1:$A$20="c",ROW($A$1:$A$20))))
_

を使用して数式を入力してください Ctrl+Shift+Enter

これはINDEXMATCH/VLOOKUP構成と同様に機能しますが、MAXの代わりに条件付きMATCHを使用します。

これは、テーブルが行1から始まると想定していることに注意してください。データが別の行から始まる場合は、一番上の行と1の差を差し引いてROW(...)部分を調整する必要があります。

3
Excellll

(ここでは、ソートされたデータに対する個別の質問がないと答えます)

データがソートされた場合VLOOKUPrange_lookup引数TRUEと共に使用することができます(またはデフォルトなので省略されます) 、Excelでは「近似一致の検索」として公式に説明されています。

つまり、ソートされたデータの場合:

  • 最後の引数をFALSEに設定すると、first値が返されます。
  • 最後の引数をTRUEに設定すると、last値が返されます。

これはほとんど文書化されておらずあいまいですが、VisiCalc(1979)にさかのぼり、今日では少なくともMicrosoft Excel、LibreOffice Calc、およびGoogle Sheetsで保持されています。最終的には、VisiCalcでのLOOKUPの初期実装(およびVLOOKUPHLOOKUP)が原因で、4番目のパラメーターがなかったためです。値は、包括的左境界と排他的右境界(一般的で洗練された実装)を使用して binary search によって検出され、この動作になります。

技術的には、これは候補区間[0, n)で検索を開始することを意味します。ここで、nは配列の長さであり、ループ不変条件はA[imin] <= key && key < A[imax]です(左境界は< =ターゲット、終了後1つから始まる右境界、>ターゲットです。検証するには、前にエンドポイントの値をチェックするか、後の結果をチェックします)。次に、この不変条件を保持する側を連続的に二分して選択します。側は、1項の間隔[k, k+1)に到達するまで、アルゴリズムはkを返します。これは完全に一致する必要はありません(!):これは下からの最も近い一致です。一致が重複する場合、次の値がキーよりも大きいである必要があるため、last一致が返されます(または配列の最後)。重複する場合はsome動作が必要であり、これは合理的で実装が簡単です。

この動作は、この古いマイクロソフトサポート技術情報の記事(強調を追加)に明示的に記載されています。「XL:配列内の最初または最後の一致を返す方法」( Q214069 ):

LOOKUP()関数を使用して、ソートされたデータの配列内の値を検索し、別の配列内のその位置に含まれる対応する値を返すことができます。ルックアップ値が配列内で繰り返される場合、最後に一致したものを返します。この動作は、VLOOKUP()、HLOOKUP()、およびLOOKUP()関数に当てはまります。

一部のスプレッドシートの公式ドキュメントは次のとおりです。どちらも「最後の一致」の動作は述べられていませんが、Googleスプレッドシートのドキュメントにはそれが含まれています。

  • Microsoft Excel

    [〜#〜] true [〜#〜]は、テーブルの最初の列が数値またはアルファベット順にソートされていると想定し、最も近い値

  • Google Sheets

    is_sortedTRUEであるか省略されている場合、最も近い一致以下)検索キー)が返されます

2
Nils von Barth

検索配列の値が連続している場合(つまり、最新の日付などの最大値を探している場合)、INDIRECT関数を使用する必要すらありません。次の簡単なコードを試してください:

=MAX(IF($A$1:$A$20="c",$B$1:$B$20,)

もう一度、CTRL + SHIFT + ENTERを使用して数式を入力します

1
The Stich
=LOOKUP([payee field] , [payee range] , [category range])

これは最後の値を取得します

3年遅れでボーナスポイントはもらえますか?

0
DavePenn

最も頻繁な値で試してみました。 libreOfficeで動作するかどうかはわかりませんが、Excelで動作するようです

= INDEX($ B $ 2:$ B $ 9、MATCH(MAX($ A $ 2:$ A $ 9 = D2)* COUNTIFS($ B $ 2:$ B $ 9、$ B $ 2:$ B $ 9、$ A $ 2 :$ A $ 9、D2))、-($ A $ 2:$ A $ 9 = D2)* COUNTIFS($ B $ 2:$ B $ 9、$ B $ 2:$ B $ 9、$ A $ 2:$ A $ 9、D2 )、0))

列Aは受取人、列Bはカテゴリー、D2はフィルターに使用する受取人です。上記の関数に追加の改行が含まれる理由がわかりません。

最後のセルを見つける私の機能は次のようになります:

= INDIRECT( "B"&MAX(-($ A $ 2:$ A $ 9 = D2)* ROW($ A $ 2:$ A $ 9)))

間接では、返す列を指定して行を直接検索できます(そのため、ヘッダー行の数を減算する必要はありません。

これらの関数は両方とも---(Ctrl + shift + enterを使用して入力する必要があります

0
gtwebb