いきなり答える備忘録

G Suite・Microsoft 365・LibreOfficeなどに関するメモと日々の実験

(Excel)期間中の第n回目のx曜日を求める

 Excelで、指定した期間内の日付でx曜日であるもののうちn回目のものを求める方法についてです。
 関数を使って求めるとかなり長くなりますが、2020年後半から使えるようになったLET関数を使って短縮する例を紹介します。

  • SEQUENCE関数やFILTER関数などを使って、指定した期間中の第n回目のx曜日の日付を求められます。

手順

期間の初日と末日を指定する例

f:id:accs2014:20200919121912p:plain:right:w550

 画像ではB3:B6の範囲に次のように条件が記されています。

B3…期間の初日
B4…期間の末日
B5…曜日
 (1…日曜,2…月曜……)
B6…回次(何回目か)

 F2セルに式を入力して、この条件にマッチする日付を求めるものとします。

 

 早速F2セルに式を入力して確定しました。結果は数字(シリアル値)となって表示されますので……

f:id:accs2014:20200919121918p:plain:w780

 
 セルの書式設定で表示形式を「日付」に変更して完了です。
 2020年9月1日から30日までの期間のうち、第3回目の日曜日の日付は「2020/9/20」であることが示されました。

f:id:accs2014:20200919121922p:plain:w780

 さて、F2セルに入力した式の内容は次のとおりです。

=LET(期間,SEQUENCE(C3-C2+1,,C2),INDEX(FILTER(期間,WEEKDAY(期間)=C4),C5))

 LET関数を使い、式の短縮を図っています。
 「SEQUENCE(C3-C2+1,,C2)」の部分は、期間の初日から末日までの日付の配列(この例では30行の配列)を返します。これに「期間」という名前を付けています。
 そしてFILTER関数とWEEKDAY関数を使い、「『期間』のうち曜日が日曜であるもの」を抽出し、さらにINDEX関数で「3番目のもの」を求めています。
 これでもやや長い式ですが、LET関数を使うことで「SEQUENCE(C3-C2+1,,C2)」を繰り返す必要がなくなり、実用的と言える程度まで短くできています。基本的に前月末日とか月初日の曜日を考慮する必要がないのも立式の上で有利な点かと思います。
 ありえない条件(月内の10回目の〇曜日、など)を指定するとエラーになるのもメリットです。
 

 ちなみに、次の画像は指定する条件を変えたものです。2020年の火曜日(3)のうち21回目のものを求めています。

f:id:accs2014:20200919121926p:plain:w780

対象となる月(年月)を指定する例

 検索対象の期間を「年」と「月」の数値で指定する場合の例です。
 早速ですが画像を結果で示します。設定と表示形式の変更については上記の例と同様です。

f:id:accs2014:20200919121931p:plain:w780

 F2セルの式は次のとおりです。

=LET(期間,SEQUENCE(DAY(DATE(C2,C3+1,0)),,DATE(C2,C3,1)),INDEX(FILTER(期間,WEEKDAY(期間)=C4),C5))

 基本的に上記の例と同じですが、期間(月)に属するすべての日付を「SEQUENCE(DAY(DATE(C2,C3+1,0)),,DATE(C2,C3,1))」という式で取得しているところが違いです。
 このうち「DAY(DATE(C2,C3+1,0)」は指定した月の日数(この例では30)を返します。同様に「DATE(C2,C3,1)」は月の最初の日付を返します。
 結果的に期間の初日として月の初日を、期間の末日として月の末日を指定して検索が行われます。

対象となる月が属する日付を指定する例

 日付を入力させ、その日付が属する月を対象として検索する例です。
 こちらも早速ですが画像を結果で示します。設定と表示形式の変更については上記の例と同様です。

f:id:accs2014:20200920234544p:plain:w780

=LET(期間,SEQUENCE(DAY(EOMONTH(C2,0)),,EOMONTH(C2,-1)+1),INDEX(FILTER(期間,WEEKDAY(期間)=C3),C4))

 これも最初の例と同様ですが「SEQUENCE(DAY(EOMONTH(C2,0)),,EOMONTH(C2,-1)+1)」の部分で月内のすべての日付を取得しているところが違いです。
 EOMONTH関数が使えるぶん短縮はできていますが、さすがに長いですので作業セルを使って初日と末日の日付を抽出し、最初の例で挙げた式を使った方が楽かもしれません。