いきなり答える備忘録

Google Workspace・Microsoft 365・LibreOfficeなどに関するメモ

(Excel)COUNTIF関数のワイルドカードで数値・日付をカウントする

 ExcelのCOUNTIF関数ではワイルドカードを使って該当する値をカウントすることができますが、基本的に数値(数字)や日付にワイルドカードを適用することはできません。
 以下ではこれを何とかする方法について紹介します。

  • 作業列を追加して数値や日付を文字列に変換した結果を取得すれば、ワイルドカードでカウントできます。
  • 関数のみで対応する場合、COUNTIF関数での実現は困難なので他の関数で対応することとなります。ただしなかなか面倒です。

数値をカウントする場合

作業列を使う方法

 まずは失敗例です。
 画像ではB列に入力されている数値のうち「1」で始まるものをカウントしようとして、D3セルに「=COUNTIF(B3:B8,"1*")」と入力しています。しかし基本的にワイルドカードは文字列にしか適用できず、数値や日付をカウントすることはできません。

 


 そこで作業列を用意します。
 A列を作業列とし、そこに「=TEXT(B3,"@")」と入力します。これでB3セルの数値を文字列に変換した結果が得られます。
 なお「=ASC(B3)」とか「=B3&""」でも問題ないので好みで選んでください。

 


 そのまま式を下方にフィルコピーします。
 最初からA3セルに「=TEXT(B3:B8,"@")」と入力して一括取得することも可能です(スピル)。

 


 あとはこのA列を対象にしてCOUNTIF関数を適用すればOKです。
 D3セルに「=COUNTIF(A3:A8,"1*")」と入力することで「1」で始まる数値をカウントできました。

MAP/LAMBDA関数等を使う方法

 関数のみでカウントする方法についてです。
 COUNTIF関数での対応は困難なので、次の画像では各種関数を組み合わせて必要な結果を得ています。

 D3セル

=COUNT(MAP(B3:B8,LAMBDA(a,XLOOKUP("1*",TEXT(a,"@"),a,"",2))))

 XLOOKUP関数では検索対象範囲を文字列に置き換えることができ、さらにワイルドカードを使った判定ができます。これを利用して条件に該当する数値はそのままに、該当しない数値は空文字列に置き換えて最後にCOUNT関数でカウントしています。
 ただしXLOOKUP関数だけだと1つ1つのセルがワイルドカードに該当するかを判定できないので、MAP/LAMBDA関数を使うことで実現しています。



 ちなみに上記の式からCOUNT関数を外すと次のようになるので、だいたい何をやっているかわかるかと思います。

 以下は注意点です。

  • TEXT関数部分は「ASC(a)」とか「a&""」とすれば若干短くできます。ただし日付には適用できないので注意してください。
  • 数値を対象とする式になっているのでワイルドカードに該当する文字列(この例では「1億円」などの文字列)が含まれていてもカウントできません。あえてやるなら次のような式が考えられます。
     「=ROWS(TOCOL(MAP(B3:B8,LAMBDA(a,XLOOKUP("1*",TEXT(a,"@"),a,NA(),2))),2))」
  • XLOOKUP関数のワイルドカードを利用しているため「<>」演算子が使えません。以下の日付の例でも同様です。

日付をカウントする場合

作業列を使う方法

 A列を作業列とし、A3セルに「=TEXT(B3,"yyyy/m/d")」と入力します。
 これでB列の日付と同じ形式の文字列が取得できます。

 


 式をB8セルまでフィルコピーします。

 


 あとはこの列を対象としてカウントすればOKです。
 D3セルに「=COUNTIF(A3:A8,"*5")」と入力することで、日付の最後の桁(日付の一の位)が「5」である日付をカウントできました。

 この例ではB列と同じ形式の文字列を作業列に表示させましたが、条件との兼ね合わせにより「月」だけを抽出する(「"yyyy/m/d"」の代わりに「"m"」とする)とか「日」だけ抽出する(「"d"」とする)といった対応も考えられます。

MAP/LAMBDA関数等を使う方法

 関数のみでカウントする方法についてです。
 やはりCOUNTIF関数での対応は困難なので、各種関数を組み合わせて結果を得ています。

 D3セル

=COUNT(MAP(B3:B8,LAMBDA(a,XLOOKUP("*5",TEXT(a,"yyyy/m/d"),a,"",2))))

 数値での例と同様に、XLOOKUP関数を使って条件に該当する日付はそのままに、該当しない日付は空文字列に置き換えて最後にCOUNT関数でカウントしています。MAP/LAMBDA関数を使うことで各行の値の変換を実現しているのも同様です。 
 なおTEXT関数部分を「ASC(a)」とか「a&""」にするとシリアル値の文字列(「33286」など)に変換されるので誤った結果となります。