0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PowerShellでExcelのNETWORKDAYS関数を再現する

Posted at

初めに

エクセルで集計していた業務をPowerShellで自動化する際にNETWORKDAYS関数が欲しくなったので作りました。
需要があるかは不明ですがエクセル作業の自動化を検討する際の参考になればよいかなと思います。

NETWORKDAYS関数の概要

NETWORKDAYS関数とは日付から日付の間の営業日の日数を返す関数です。
公式ドキュメントでの解説はこちら。
エクセルで使用する際はNETWORKDAYS(開始日, 終了日, [祭日])のように記載しますがPowerShellっぽく下記のようにしたいと思います。

powershell
NETWORKDAYS -StartDate <DateTime> -EndDate <DateTime>

注意

こちら個人的に使用するために作成しただけなので簡易的な関数となります。
実際のエクセル関数では第3引数で祭日を指定してカウントから除外できますが、今回作成したPowerShellの関数では祭日は指定できません。2つの日付間の平日をカウントするのみです。

環境

powershell
$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コマンドで読み込めば使用できます。

profile.ps1
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)
    }
}

使用例

powershell
# 引数へ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を返します。

powershell
# "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引数で渡された日付の配列を削除して配列の要素数を返すような処理に変更する必要があります。
私の使用用途にはそれは必要なかったので作りませんでしたが、気分が乗れば作ろうと思います。

参考

公式ドキュメント

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?