Excel 有提供簡單的工作日函數:
- WORKDAY:幾個工作日後的日期 > 回傳日期
- NETWORKDAYS:兩個日期中,共有多少工作日 > 回傳數字
這兩個函數都可以解決國定假日的情況,但在實作上,我們會遇到補班日的問題
這篇文章除了教學 WORKDAY、NETWORKDAYS 的用法之外,還提供了一勞永逸、簡單的方法來計算,包含補班日、國定假日、補假日的工作日計算,就算不用 VBA 也可以輕鬆完成。
如果你很心急地想知道一勞永逸的方法,可以直接跳到最後一個主題「工作日(包含補班日)」。
Excel 範例檔案下載:Excel-Date-workday-networkdays.xlsx
資料整理
首先我們整理出放假與否的對照表
政府行政機關辦公日曆表
每年政府會在五月底、六月初的時候,將隔年度政府行政機關辦公日曆表發表出來,同時上架到「政府資料開放平台」。提供多種資料格式包含 CSV、XML、JSON,因為我們使用的是 Excel,所以選擇最方便的 CSV 格式。
將 CSV 匯入 Excel(Import .CSV)
匯入 .csv 檔案:資料 > 取得及轉換資料 > 從文字/CSV
選擇剛剛下載的檔案後,就會進入匯入的介面。
這邊要注意,因為 CSV 編碼的關係,檔案原點要選擇「950:繁體中文(Big5)」,若選擇其他的可能出現亂碼。
再來分隔符號請選「逗號」:這裡可以直接做資料剖析,這樣後續就不要另外處理。
設定完成後,直接按下載入。Excel 會很貼心地幫我們做表格設計還有篩選功能。
但是這裡有一個最大的問題,就是日期的部分,是以文字格式儲存,並非日期格式,因此我們要先處理一下。
最快的方法就是將〔A2〕這一格輸入「2023/1/1」,再用滑鼠左鍵雙擊儲存格右下的正方形,自動向下填滿,這樣資料就準備齊全了。
WORKDAY
=WORKDAY(a,b,[c])
a:起始日
b:幾個工作日
c:額外的假日
回傳:幾個工作日後的日期
在沒有給予其他的國定假日、彈性假日的情況下,Excel 預設只會將六、日視為非工作日
=WORKDAY(起始日,幾個工作日)
=WORKDAY(A2,B2)
這樣會直接得:「2023/10/05」過 4 個工作日後的日期「2023/10/11」
但 2023 年的 10/9 為調整放假日,而 10/10 為國慶日,這兩天皆為非工作日,直接使用 WORKDAY 並不會將這兩日計算為假日,因此我們需要用到 WORKDAY 的第三個參數。這裡我們會提供 3 種方法供讀者參考,其中我們會細說第三種方法:
- 直接輸入日期「=WORKDAY(A2,B2,{“2023/10/9″,”2023/10/10”})」
- 選取對應放假儲存格「=WORKDAY(A4,B4,A9:A10)」
- 運用 FILTER 函數
延伸閱讀:【Excel Function】FILTER 篩選;SORT、SORTBY 排序
=WORKDAY(起始日,幾個工作日,額外放假日)
=WORKDAY(A2,B2,FILTER('112-calendar'!$A:$A,'112-calendar'!$C:$C=2))
FILTER 只需要顯示有放假的日期,簡單介紹這邊 FILTER 的寫法:
FILTER(‘112-calendar’!$A:$A,‘112-calendar’!$C:$C=2)
- 第一個參數:回傳資料
因為只需要時間,只回傳 A 欄 - 第二個參數:判斷條件
C 欄,放假為 2;沒放假為 0
FILTER 出來會成為一個陣列,這裡會直接顯示為「1900 日期系統」的值,而這個值放到 WORKDAY 的第三個參數,代表這些日期是有放假的日期,這樣在計算工作日時就可以排除這些放假的日期。
NETWORKDAYS
WORKDAY 主要是計算幾個工作天之後的日期,而兩個日期間的工作天就要用 NETWORKDAYS,在英文中 net 有「淨;淨值」的意思,因此 NET-WORKDAYS 就可以想成「淨工作日」。
=NETWORKDAYS(a,b,[c])
a:起始日期
b:結束日期
c:額外的假日
回傳:兩個日期中,共有多少工作日(包含頭尾)
NETWORKDAYS 和 WORKDAY 用法上相當相似,我們直接看利用 FILTER 函數來解決放假日的問題
「2023/10/05」到「2023/10/11」排除假期的部分,有多少工作日?
=NETWORKDAYS(起始日期,結束日期,額外放假日)
=NETWORKDAYS(A5,B5,FILTER('112-calendar'!$A:$A,'112-calendar'!$C:$C=2))
第一個參數直接放入「2023/10/05」
第二個參數則是「2023/10/11」
接著第三個參數和上面一樣,直接使用「FILTER(‘112-calendar’!$A:$A,’112-calendar’!$C:$C=2)」
這樣就可以得到「2023/10/05」到「2023/10/11」有 3 個工作日,注意這裡是包含頭尾的日期。
工作日(包含補班日)
原生的 Excel 提供了 WORKDAY 和 NETWORKDAYS 計算工作日的函數,但是這兩個函數有一個致命的缺點(也許只有台灣有這個問題?),就是補班日,他們沒辦法將補班日列為工作日計算。
因此這裡我提供一個方法,不用 VBA 就可以直接完成包含放假日、補班日的工作日計算方法。運用 INDEX、MATCH、FILTER,這三個函數來完成這個功能。
幾個工作日後的日期(WORKDAY with make-up day)
=INDEX(整年度工作日,MATCH(起始日,整年度工作日)+幾個工作日)
=INDEX(FILTER('112-calendar'!$A:$A,'112-calendar'!$C:$C=0),MATCH(A2,FILTER('112-calendar'!$A:$A,'112-calendar'!$C:$C=0))+B2)
看到一長串的公式不要先害怕,這邊慢慢解釋。首先簡單介紹這三個函數:
- INDEX:回傳 對應陣列的第 n 筆資料
- MATCH:回傳 該值在對應陣列中的順序(index)為多少
- FILTER:回傳 依條件篩選的資料(回傳陣列形式)
延伸閱讀: 【Excel Function】FILTER 篩選;SORT、SORTBY 排序 【Excel Function】INDEX、MATCH、二維資料尋找 (2D Data Search)
運用這三個函數的原理來進行下列步驟:
- 「全部工作日中」的陣列,使用 FILTER 取得
「FILTER(‘112-calendar’!$A:$A,’112-calendar’!$C:$C=0)」 - 首先用 MATCH 取得「2023/9/21」位於全部工作日中的第幾筆(index)資料:「180」
「MATCH(A2,FILTER(‘112-calendar’!$A:$A,’112-calendar’!$C:$C=0)))」 - 將 180 + 6 取得新的順序值(index):「186」
「MATCH(A2,FILTER(‘112-calendar’!$A:$A,’112-calendar’!$C:$C=0)))+6」 - 最後用 INDEX 回傳全部工作日中第 186 筆資料的值:「2023/9/28」
「INDEX(FILTER(‘112-calendar’!$A:$A,’112-calendar’!$C:$C=0),MATCH(A2,FILTER(‘112-calendar’!$A:$A,’112-calendar’!$C:$C=0))+B2)」
利用這種方式,就不在乎工作日、補班日、節慶日、週末。使用行政機關辦公日曆表的資料,直接將其二分為上班日、非上班日,再進行運算即可。
多少工作日(NETWORKDAYS with make-up day)
這個方法相對單純許多,只要用到FILTER、COUNT這兩個函數
=COUNT(期間內資料)
=COUNT(FILTER(資料來源,(條件一)*(條件二)*(條件三)))
=COUNT(FILTER('112-calendar'!$A:$A,('112-calendar'!$C:$C=0)*('112-calendar'!$A:$A>=A2)*('112-calendar'!$A:$A<=B2)))
步驟如下:
- 使用 FILTER 取得兩段時間內需要上班的「陣列資料」:上班日、大於等於起日、小於等於訖日
- 用 COUNT 計算有幾筆資料
延伸閱讀:【Excel Function】COUNT 家族 (上):COUNT、COUNTA、COUNTBLANK 一般統計
這樣就可以得到兩段時間經過幾個工作日,注意這裡的工作日是包含頭尾的日期,若不想包含起始日,可以直接把 COUNT 出來的值減一即可。
Excel 範例檔案下載:Excel-Date-workday-networkdays.xlsx
更多 Excel 文章請至 文章導覽 尋找,也可利用上方「搜尋(Search...)」功能
有任何莫非工具的問題,歡迎至「表單」提問
Excel 是不是很容易
和墨菲一起用 Excel 把工作變簡單
Pingback: 莫非工具 | 文章導覽 - 墨菲莫非