初めに
エクセルで集計していた業務をPowerShellで自動化する際にNETWORKDAYS関数が欲しくなったので作りました。
需要があるかは不明ですがエクセル作業の自動化を検討する際の参考になればよいかなと思います。
NETWORKDAYS関数の概要
NETWORKDAYS関数とは日付から日付の間の営業日の日数を返す関数です。
公式ドキュメントでの解説はこちら。
エクセルで使用する際はNETWORKDAYS(開始日, 終了日, [祭日])のように記載しますがPowerShellっぽく下記のようにしたいと思います。
NETWORKDAYS -StartDate <DateTime> -EndDate <DateTime>
注意
こちら個人的に使用するために作成しただけなので簡易的な関数となります。
実際のエクセル関数では第3引数で祭日を指定してカウントから除外できますが、今回作成したPowerShellの関数では祭日は指定できません。2つの日付間の平日をカウントするのみです。
環境
$PSVersionTable
Name Value
---- -----
PSVersion 5.1.19041.1
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.19041.1
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
完成したスクリプト
下記を$profileへ記載するかsourceコマンドで読み込めば使用できます。
Function NETWORKDAYS {
param(
[DateTime]$StartDate,
[DateTime]$EndDate
)
[String[]]$DayOfWeekHoliday = @("Sunday", "Saturday")
[String[]]$DayOfWeekArray = @()
0..($EndDate - $StartDate).Days | %{ $DayOfWeekArray += $StartDate.AddDays($_).DayOfWeek }
$DayOfWeekHoliday | %{ $DayOfWeekArray = $DayOfWeekArray -ne $_ }
if($EndDate -ge $StartDate){
$DayOfWeekArray.Count
} else {
-($DayOfWeekArray.Count)
}
}
使用例
# 引数へDateTime型を渡します。
NETWORKDAYS -StartDate (Get-Date) -EndDate (Get-Date).AddDays(30)
22
# DateTime型へ変換可能な文字列であれば引数へ使用できます。
NETWORKDAYS -StartDate "2020/08/01" -EndDate "2020/09/01"
22
ExcelのNETWORKDAYS関数と同様、-StartDateと-EndDateで同日を指定された場合、その日が平日であれば1を休日であれば0を返します。
# "2020/09/05"は土曜日
NETWORKDAYS -StartDate "2020/09/05" -EndDate "2020/09/05"
0
# "2020/09/04"は金曜日
NETWORKDAYS -StartDate "2020/09/04" -EndDate "2020/09/04"
1
以上です。
余談
今回のスクリプトは日付間の曜日を格納した配列から土曜日と日曜日を削除してカウントしているだけですが、
もし第3引数で祭日を指定可能にするならば曜日の配列ではなく日付の配列を作成し、第3引数で渡された日付の配列を削除して配列の要素数を返すような処理に変更する必要があります。
私の使用用途にはそれは必要なかったので作りませんでしたが、気分が乗れば作ろうと思います。