สูตร Excel นับวันทำงานแบบเสาร์เว้นเสาร์ [Applied NETWORKDAYS]

“อยากนับเฉพาะวันทำงาน เขียนสูตรยังไงดีพี่” ตั้มโพล่งถาม
“ใช้ฟังก์ชัน NETWORKDAYS.INTL ที่พี่เคยสอนไง” ผมตอบ
“ลองแล้ว ใช้ไม่ได้ครับ”
“หือม์.. ทำไมไม่ได้ล่ะ?”
“คือบริษัทผมทำงานแบบเสาร์เว้นเสาร์ แต่ NETWORKDAYS.INTL ไม่มีรูปแบบนี้ครับ”
“อ้า…ไอ ซี”
“ทำไงดีพี่?”
“ขอคิดแป๊ปนึง”

“คิดออกแล้ว!” เสียงตะโกนดังลั่นหลังจากงมโข่งอยู่เกือบชั่วโมง
“ใช้สูตรนี้ได้เลย” ผมส่งไฟล์ที่มีสูตรเอ็กเซลยาวสามบรรทัดให้ตั้ม
“โอ ขอบคุณมากเลยครับพี่” ตั้มน้ำตาไหลอาบแก้มด้วยความปีติ
“พี่กลับล่ะนะ” ผมยิ้มแล้วปิดคอมพ์กลับบ้าน ดีใจที่ช่วยน้องได้

วันรุ่งขึ้น หลังจากผมวางกระเป๋าบนโต๊ะและกำลังเดินไปชงกาแฟ ตั้มก็พรวดพราดเข้ามา
“สูตรใช้ไม่ได้อ่ะพี่”
“เฮ้ย! จริงดิ”
“จริงพี่ บางช่วงมันคำนวณผิด ยิ่งช่วงที่มีกีฬาสี คำนวณผิดหมดเลย”
“เดี๋ยวๆ! มีกีฬาสีด้วยเหรอ”
“มีพี่ เราแข่งกีฬาสีประมาณ 2 สัปดาห์ ถ้าวันเสาร์ทำงานอยู่ในช่วงกีฬาสีก็จะเขยิบออก และทำงานสองเสาร์ซ้อนชดเชยแทน”
“อ้อ แล้วถ้าช่วงไหนตรงกับวันหยุดยาว ก็ไม่ทำงานเสาร์นั้น แต่ไปชดเชยทำวันเสาร์อื่นแทน”
“แปลว่าต้องชดเชยในอีกสองสัปดาห์”
“ไม่แน่เสมอไป ขึ้นกับทาง HR ว่าจะให้ทำเสาร์ไหน บางครั้งก็อีกสองสัปดาห์ บางครั้งก็ไม่ต้องชดเชยก็มีพี่”
“แล้วทำไมไม่บอกแต่แรกฟะ !!”
“ลืม แหะๆ”
ตั้มยกมือขวาขึ้นลูบท้ายทอย ส่งยิ้มฟันขาว แสดงท่าอินโนเซนต์สุดๆ
ผมกระโดดซัมเมอร์ซอลล์คิกส์เสยปลายคางตั้มเพื่อสำเร็จโทษ ก่อนจะบอกว่า
“ไปลิสต์มาว่าเสาร์ไหนหยุดบ้าง”

หลังจากตั้มส่งลิสต์วันหยุดทั้งหมดให้ ผมใช้เวลา 10 วินาทีเขียนสูตรนี้

=NETWORKDAYS.INTL(B3,B5,11,B10:B22)

“นี่แหละ ใช่เลยพี่” ตั้มกู่ร้องด้วยความยินดี

มาทบทวนฟังก์ชัน NETWORKDAYS.INTL กันนิดนึงครับ
โครงสร้างคือ

NETWORKDAYS.INTL( start_date, end_date, [weekend], [holidays] )

( อ่านพื้นฐานการใช้ฟังก์ชัน NETWORKDAYS.INTL ได้จากบทความนี้ )

B3 คือ start_date
B5 คือ end_date
ความหมายของ 11 ในสูตรคือ [weekend] ซึ่งหมายถึงหยุดเฉพาะวันอาทิตย์

เคสนี้ผมคำนวณโดยคิดว่าหยุดเฉพาะวันอาทิตย์ หรือเหมารวมว่าวันเสาร์เป็นวันทำงาน ถ้าเสาร์ไหนหยุด ก็ให้ไปเพิ่มใน list ของ [holidays] (B10:B22) นั่นเอง !
ง่ายใช่ไหมครับ ^__^

“เอ…. ขอถามเพิ่มได้ไหมพี่”
“ว่าไง” ผมตอบ
คือผมอยากแยก list ของวันหยุด กับวันเสาร์ที่หยุด ออกเป็น 2 คอลัมม์ได้ไหมครับ?” ตั้มถามเสียงอ่อย
“แล้วทำไมไม่บอกแต่แรกฟะ !”

คำถามของตั้มดูเหมือนง่าย แต่ความจริงแล้วไม่ง่ายเลย
มาดูโครงสร้างของ NETWORKDAYS.INTL กันอีกครั้ง

NETWORKDAYS.INTL( start_date, end_date, [weekend], [holidays] )

[holidays] ต้องการค่าเป็นช่วงข้อมูล (range) และต้องมีแค่ช่วงเดียวเท่านั้น

ถ้าเราแยกช่วงวันหยุดเป็น 2 คอลัมน์คือ B10:B14 กับ E10:E17 แบบนี้

พอใส่สูตรเป็น
=NETWORKDAYS.INTL( B3, B5, 11, B10:B14, E10:E17 )

จะขึ้น error message ว่า

เพราะการเขียนสูตรแบบนี้ฝืนโครงสร้างสูตรแบบเต็มๆ

ทำยังไงดี?
ทางแก้คือต้องหาทางรวม B10:B14 และ E10:E17 เข้าด้วยกัน
หรือต้องรวมให้เป็น range เดียว

เทคนิคหนึ่งที่อาจใช้ได้คือ ฟังก์ชัน CHOOSE
โดยเขียนสูตรเป็น

=CHOOSE( {1,2}, B10:B14, E10:E17 )

ผลลัพธ์ของสูตรนี้คือ

{43927,43925;43952,43939;43955,43953;43957,43967;43985,43974;#N/A,43988;#N/A,44002;#N/A,44009}

(ค่าที่แท้จริงของวันที่คือตัวเลข ถ้าเป็นวันที่ปัจจุบันมีค่าประมาณ 40,000)

น่าเสียดายที่เคสนี้มี #N/A เพราะจำนวนค่าใน B10:B14 (5 ค่า) กับ E10:E17 (8 ค่า) นั้นไม่เท่ากัน ถ้าจำนวนค่าในช่วงทั้งสองเท่ากัน สูตรนี้ใช้ได้เลย

ทำไงดี?
งั้นก็ต้องเปลี่ยน #N/A ให้ไม่เป็น #N/A โดยใช้ฟังก์ชัน IFERROR
เช่น เขียนสูตรเป็น

=IFERROR( CHOOSE( {1,2}, B10:B14, E10:E17 ), 0 )

ผลลัพธ์ของสูตรนี้คือ

{43927,43925;43952,43939;43955,43953;43957,43967;43985,43974;0,43988;0,44002;0,44009}

จะพบว่า #N/A ถูกเปลี่ยนเป็น 0 นั่นเอง !

อ้อ.. ถ้าใครใช้ Excel เวอร์ชันตั้งแต่ 2013 ขึ้นไป ใช้ฟังก์ชัน IFNA ก็ได้นะครับ
เช่นเขียนสูตรเป็น

=IFNA( CHOOSE( {1,2}, B10:B14, E10:E17 ),0 )

ก็ได้ผลลัพธ์เช่นเดียวกัน ^__^

จากนั้นก็นำ IFERROR( CHOOSE({1,2},B10:B14,E10:E17),0 ) ไปแทนที่ [holidays] ใน NETWORKDAYS.INTL
หรือเขียนสูตรเป็น

{=NETWORKDAYS.INTL( B3,B5, 11, IFERROR( CHOOSE({1,2},B10:B14,E10:E17),0 ) )}

ผลลัพธ์ที่ได้คือ

ฮัดช่า!!

อ้อ.. สูตรนี้เป็นสูตรอาร์เรย์ (Array Formula) เวลาใช้ต้องกด Ctrl+Shift+Enter แทนการกด Enter นะครับ

(การใช้ฟังก์ชัน CHOOSE ในรูปแบบนี้ถือเป็น Array Formula)
(วงเล็บปีกกาที่เห็นในสูตร ( { } ) เกิดจากการกด Ctrl+Shift+Enter ไม่ใช่การพิมพ์)
(ถ้าใครใช้ Office 365 เวอร์ชันล่าสุดที่อัพเดตเรื่อง Dynamic Array Formula แล้ว ไม่ต้องกด Ctrl+Shift+Enter ก็ได้ กด Enter แบบปกติก็พอ แต่เพื่อป้องกันความสับสน แนะนำให้กด Ctrl+Shift+Enter ดีกว่า)

อ้อ! ลิสต์วันหยุดและวันเสาร์หยุดสามารถเตรียมเผื่อไว้ได้เลยนะครับ เช่น อาจเผื่อไว้ทั้งปี แล้วเปลี่ยนสูตรช่วง [holidays] เล็กน้อยเป็น

{=NETWORKDAYS.INTL( B3,B5,11, IFERROR( CHOOSE({1,2},B10:B23,E10:E30),0) )}

หรือเปลี่ยน start_date, end_date ได้ตามต้องการเลย

หรือถ้าไม่อยากแก้ไข [holidays] ในสูตรบ่อยๆ อยากให้ช่วงข้อมูลนี้เป็นไดนามิก (Dynamic) ก็ปรับ Holiday และ HolidaySaturday ให้เป็น Table (Ctrl+T) อยากอัพเดตลิตส์ก็พิมพ์เพิ่มวันตรงๆใน Table ได้เลย ไม่ต้องเปลี่ยนสูตรอีกต่อไป

{=NETWORKDAYS.INTL( B3,B5,11, IFERROR( CHOOSE({1,2},Holiday[Holiday],HolidaySaturday[HolidaySaturday]),0) )}

หรือถ้าให้ออโต้มากขึ้นไปอีก ใช้ Power Query ดึงวันหยุดมาจากเว็บไซต์ก็ได้นะเออ ^__^

โดยสรุปแล้ว ถ้าสามารถรวมวันหยุดทั้งหมดเป็นคอลัมน์เดียวได้ การเขียนสูตรแบบแรกนั้นง่ายมากๆ
=NETWORKDAYS.INTL(B3,B5,11,B10:B22)

แต่ถ้าไม่สามารถรวมวันหยุดทั้งหมดเป็นคอลัมน์เดียว การเขียนสูตรแบบที่สอง ก็สนุกดีใช่ไหมครับ ^_^
{=NETWORKDAYS.INTL( B3,B5,11,IFERROR( CHOOSE({1,2},B10:B14,E10:E17),0 ) )}

อ้อ! คุณ Bo Rydobon เจ้าของเพจ Excel Wizard ได้แชร์สูตรกรณีไม่เว้นวันเสาร์แบบ customized (กีฬาสี, วันหยุดยาวต่อเนื่อง) เป็นสูตรที่สั้นและน่าทึ่งมาก

=NETWORKDAYS( B3, B5, Holiday[Holiday] )
+ INT( ( (B5-B3) + MOD(B3-1,14) + 1 )/14 )

ขอบคุณคุณโบที่แบ่งปันเทคนิคดีๆครับ ^/\^

สำหรับใครที่สนใจไฟล์ตัวอย่างของบทความนี้ สามารถดาวน์โหลดเพื่อศึกษาเพิ่มเติมได้เลย

หืมม์… หลังจากผมกระโดดซัมเมอร์ซอลล์คิกส์แล้วตั้มเป็นยังไงบ้างน่ะหรือ?
ตั้มม้วนตัวกลับหลัง พอเท้าสัมผัสพื้นก็กระโจนขึ้นใช้ท่า ‘โชริวเคน’
ผมเอนหลังหลบแบบเฉียดฉิว รอจังหวะที่ร่างของตั้มกำลังร่วงลงมา แล้วใช้ท่า ‘โซนิคบูม” เข้าปะทะเต็มๆ
เพ้อเจ้อ!!

จบแล้ว ^^

.
หากคุณชอบบทความแนวนี้ สามารถอัพเดตบทความใหม่โดยคลิก Like เฟซบุ๊กแฟนเพจ วิศวกรรีพอร์ต หรือคลิก ที่นี่
อย่าลืมแชร์ให้เพื่อนอ่านเพื่อเป็นกำลังใจให้คนเขียนด้วยนะครับ ^__^

อ้อ! ตอนนี้ผมมีคอร์สออนไลน์กับทาง SkillLane แล้ว ดูรายละเอียดได้จากลิงค์นี้ครับ https://www.skilllane.com/courses/excel-in-essence