いきなり答える備忘録

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

(Gスプレッドシート)月の最後の平日を求める

 Googleスプレッドシートで、指定した日が属する月の最後の平日を求める方法についてです。
 土日だけを除くケースと、祝日をも除くケースを試してみます。

  • EOMONTH関数とWORKDAY関数を使って、ある日付が属する月の最後の平日を求めることができます。
  • さらに祝日(実質的に任意の日付)を除いた日を求めることもできます。

手順

祝日を除かない場合

※日付の入ったセルの書式として、カスタム数値形式「yyyy/m/d(ddd)」を設定しています。

 画像では、B列に記したいくつかの日付に対して、その日付が属する月の最後の平日を求めています。
 具体的にはC3セルに次の式を入力して下方にコピーしています。

 C3セル

=WORKDAY(EOMONTH(B3,0)+1,-1)

 EOMONTH関数は月末の日付を求める関数で、「EOMONTH(B3,0)」は日付が属する日の最終日を表します。これに1を加えた「EOMONTH(B3,0)+1」は翌月1日となります。
 そしてWORKDAY関数は(土日を除いて)n日後の平日を求める関数です。「WORKDAY(~,-1)」により「翌月1日の直前の平日」を求めています。
 ここがややこしいところで、素直に「=WORKDAY(EOMONTH(B3,0),0)」などとすると月末が土日でもそのまま返ってくるため、このような求め方をする必要があります。

 ところでB4→C4セルのように、求めた平日の日付が元の日付より前の日付になるということがありえます。このときに翌月最後の平日を求める方法について、3番目以降の例で紹介しています。

祝日を除く場合

 土日だけでなく祝日を除いた日付を求める場合です。
 Googleスプレッドシートは祝日の情報を持っていないので、ユーザーがリストを作っておき、それをWORKDAY関数の引数として指定する必要があります。ここではB3:B8の範囲に(2022年4月~7月の)祝日のリストを作成し、それらの日を除いた月末の平日を求めています。

 E3セル

=WORKDAY(EOMONTH(D3,0)+1,-1,B3:B7)

 求め方は最初の例と同じで、WORKDAY関数の第3引数として祝日リストである「B3:B7」を指定しています。
 リストには祝日に限らず任意の日付を設定することができます。


 すべての日付に対する月末の平日を求めるにあたり、単に式をコピーするとリストB3:B7への参照がズレていきます。
 絶対参照で固定してコピーする方法もありますが、ここではよりモダンにARRAYFORMULAを使い、E3セルの式だけですべての日付を一括して求めています。

 E3セル

=ARRAYFORMULA(WORKDAY(EOMONTH(D3:D8,0)+1,-1,B3:B7))

最後の平日を過ぎていたら翌月最後の平日を求める場合(祝日除かない)

 上記のケースで、月の最後の平日が、基準となる日付よりも後になるケースがありました(例:日付2022/4/30→求めた平日2022/4/29)。
 そうなるときに翌月最後の平日を求めるという例です。

 C3セル

=IF(WORKDAY(EOMONTH(B3,0)+1,-1)<B3,
WORKDAY(EOMONTH(B3,1)+1,-1),
WORKDAY(EOMONTH(B3,0)+1,-1)
)

 IF関数を使い、当月末の平日「WORKDAY(EOMONTH(B3,0)+1,-1)」が日付より前の日だったら翌月末の平日「WORKDAY(EOMONTH(B3,1)+1,-1)」を返す、という式です。
 ちょっと長いですが、上記の月末の平日の求め方が理解できていれば問題ないと思います。

最後の平日を過ぎていたら翌月最後の平日を求める場合(祝日除く)

 さらに祝日リストを設定して、平日から除く例です。
 ここでも式コピー時の参照ズレを防ぐため、ARRAYORMULAを使った式をE3セルに入力し、すべての日付に対する平日を一括して求めています。

 E3セル

=ARRAYFORMULA(IF(
WORKDAY(EOMONTH(D3:D8,0)+1,-1,B3:B7)<D3:D8,
WORKDAY(EOMONTH(D3:D8,1)+1,-1,B3:B7),
WORKDAY(EOMONTH(D3:D8,0)+1,-1,B3:B7)
))

 式はさらに長くなりますが、内容的には上記の例の複合例に過ぎません。
 実務だったら日付の方を翌月初日扱いにしそうなところですが、まじめに求めてみました。