เมื่อ TODAY ไม่เท่ากับ วันนี้ [TODAY in DAX Power BI]

ผมตื่นขึ้นมาเช็คตัวเลขก่อนนาฬิกาปลุกร้อง

ตอนเที่ยงคืนเราเพิ่งปล่อยโปรโมชันความหวัง ผ่านมาสี่ชั่วโมงแล้วตัวเลขน่าจะพุ่งทะยาน ถ้าไม่พุ่งบริษัทป่นปี้แน่นอน เพราะทุ่มหมดหน้าตักที่มี

ผมเปิดแอป Power BI ด้วยใจระทึก คลิกไปที่แดชบอร์ด
ตัวเลขที่แสดงคือ 0 !

“เฮ้ย!” ผมสบถเสียงดังจนภรรยาที่นอนข้าง ๆ สะดุ้ง

ใช้นิ้วโป้งรูดหน้าจอแรง ๆ ให้อัพเดต ตัวเลขยังเป็น 0

รูดหน้าจออีกหลายครั้งด้วยแรงที่มากขึ้น ตัวเลขยังคงเป็น 0

“นี่เรื่องจริงใช่ไหม” ประโยคคำถามที่ไม่มีคนตอบ

มือเริ่มสั่น นิ้วไม่มีแรง มือถือร่วงผล็อย

ผมซุกหน้าในอุ้งมือทั้งสอง ตัวสั่นเทิ้ม อึกอักในลำคอ ขนาดโปรโมชันนี้ยังกระตุ้นยอดขายไม่ได้ ไม่รู้จะทำยังไงแล้ว …

ภรรยาเห็นท่าไม่ดี ถามว่ามีอะไร ผมเล่าให้ฟัง

“ลองเช็คข้อมูลดิบดีไหม ระบบอาจจะรวนก็ได้” เธอกล่าว

“จริงด้วย !” ผมเลื่อนอุ้งมือทั้งสองลง สะบัดผ้าห่ม กดปุ่มเปิดคอมพ์

คอมพ์เปิดขึ้นด้วยความรวดเร็วเพราะเมื่อคืนปิดแบบ Hibernate ดับเบิ้ลคลิกโปรแกรม Power BI Desktop แล้วคลิกปุ่มรีเฟรช

ตัวเลขที่แสดงคือ 131.3K !

“มันต้องอย่างนี้!” ผมตะโกนดังลั่นจนภรรยาตกใจ

ลองเช็คข้อมูลดิบ มียอดซื้อเข้ามามากมาย และเข้ามาอย่างต่อเนื่อง

ผมเอนหลัง เงยหน้า หลับตา รู้สึกขอบคุณที่ยังไม่ยอมแพ้

ว่าแต่! ทำไมตัวเลขในแอป Power BI ถึงผิด?

ที่ผิดเพราะนั่นคือ ตัวเลขของเมื่อวาน ไม่ใช่ของวันนี้!

อ้าว! แต่เช็ควันนี้ และตั้งเงื่อนไขให้แสดงข้อมูลของวันนี้ ปัญหาเกิดจากอะไร?

ปัญหาเกิดจากเช็คข้อมูลตอนตีสี่

ยังไง?

เพื่อให้เห็นภาพ มาดูรายละเอียดกันนิดนึง

สมมติ Data Model หน้าตาแบบนี้

ยอดขายที่ต้องการคือ Measure ชื่อ [Sales]
นำ [Sales] ไปสร้าง Card ง่าย ๆ แบบนี้

ตัวเลข 294.0M ในภาพคือยอดขายทั้งหมดตั้งแต่อดีตจนถึงปัจจุบัน
ถ้าต้องการให้เป็นยอดขายของวันนี้ ก็ต้องเพิ่มเงื่อนไขเข้าไป เช่น ใช้วันที่ (คอลัมน์ Date จากตาราง tDate) เป็นเงื่อนไขใน Visual Level Filter

ปรับ Filter type เป็น Relative date และเซ็ตให้เป็น is in this day

ตัวเลขจะลดลงเหลือ 131.3K นั่นคือตัวเลขยอดขายของวันนี้ (จากภาพคือวันที่ 2 กันยายน 2020)

ถ้าเช็คตัวเลขในโปรแกรม Power BI Desktop จะได้ยอดขายของวันนี้ที่ต้องการ

แต่ถ้าเช็คตัวเลขใน Power BI Service (app.powerbi.com, รวมทั้งแอปพลิเคชัน Power BI ในมือถือ) ตัวเลขที่แสดงอาจเป็นยอดขายของวันนี้หรือเมื่อวานก็ได้

ทำไม?

เพราะข้อมูลใน Power BI Desktop และ Power BI Service อ้างอิงเวลาคนละไทม์โซน (Timezone)

Power BI Desktop อยู่บนคอมพิวเตอร์เรา อ้างอิงไทม์โซนของประเทศไทย หรือก็คือ UTC+7 (GMT+7)

Power BI Service (และแอป Power BI) อยู่บนคลาวด์ (Cloud)

คลาวด์คือเซิร์ฟเวอร์ (Server) ซึ่งตั้งอยู่ที่ไหนซักแห่ง โดยเซิร์ฟเวอร์นี้อ้างอิงไทม์โซนแบบ UTC+0 (GMT+0)

ดังนั้นเวลาของ Power BI Service ช้ากว่า Power BI Desktop 7 ชั่วโมง โดยที่เรา(อาจ)ไม่รู้

ถ้าเวลาตอนนี้คือ 2 กันยายน 2020 ตีสี่ เวลาที่ Power BI Service เข้าใจคือ 1 กันยายน 2020 สามทุ่ม
เมื่อสั่งให้แสดงผลข้อมูลของวันนี้ Power BI Service จึงแสดงผลข้อมูลวันที่ 1 กันยายน 2020 (แทนที่จะเป็น 2 กันยายน 2020)

นั่นคือ ถ้าเช็คข้อมูลจาก Power BI Service ก่อนเจ็ดโมงเช้า ตัวเลขที่แสดงคือ ตัวเลขของเมื่อวาน
แต่ถ้าเช็คหลังเจ็ดโมงเช้า ตัวเลขที่แสดงคือ ตัวเลขของวันนี้

ถ้าเช็คข้อมูลรายเดือน รายปี ไม่มีปัญหา
แต่ถ้าเช็ครายวัน มีปัญหาแน่นอน

แล้วจะทำยังไง?

ทางแก้มี 2 ทาง

1. ตกลงกันว่าเช็คข้อมูลได้หลัง 7 โมงเช้า

คือวิธีที่ง่ายที่สุด ถ้าไม่ต้องการตัวเลขแบบเรียลไทม์ หรือโอเคกับการเช็คข้อมูลหลังเจ็ดโมงเช้า ใช้วิธีเดิมได้เลย ไม่ต้องแก้ไขอะไร

วิธีนี้แม้ง่ายแต่ระยะยาวอาจมีปัญหา เพราะบางคนไม่รู้ว่าข้อมูลที่แสดงก่อนเจ็ดโมงเช้าคือข้อมูลเมื่อวาน อาจเกิดความเข้าใจผิดและตบตีกันได้ จึงเป็นที่มาของวิธีที่สอง

2. ใช้ฟังก์ชัน CALCULATE

ถ้าไม่อยากมานั่งจำว่าต้องเช็คข้อมูลหลังเจ็ดโมงเช้า ทางแก้คือห้ามใช้ Filter แบบ Relative date แต่ต้องสร้าง measure ขึ้นมาใหม่แล้วกำหนดเงื่อนไขใน measure ไปเลยว่า “วันนี้”

ถ้าต้องการกำหนดเงื่อนไขใน measure ก็ต้องนึกถึงฟังก์ชัน CALCULATE
ถ้าต้องการ “วันนี้” ก็ต้องนึกถึงฟังก์ชัน TODAY
หรืออาจเขียนสูตรเพื่อให้ได้ยอดขายของวันนี้เป็น

TodaySales = 
CALCULATE( 
    [Sales], 
    tDate[Date]=TODAY()
)

แต่… ถ้าเขียนสูตรแบบนี้ผลลัพธ์ที่ได้ก็ผิดอยู่ดี

ทำไม?

เพราะฟังก์ชัน TODAY() อ้างอิงเวลาของคอมพิวเตอร์ที่ใช้

ถ้าใช้ Power BI Desktop ซึ่งอยู่บนคอมพิวเตอร์ของเรา TODAY() คือวันนี้ของประเทศไทย (UTC+7) สูตรนี้ไม่มีปัญหา

แต่ถ้าใช้ Power BI Service ซึ่งอยู่บนคลาวด์ TODAY() คือวันนี้ของเซิร์ฟเวอร์ (UTC+0) สูตรนี้จะช้าไป 7 ชั่วโมงเหมือนเดิม

งั้นทำไงดี?

ทางแก้คือใช้ฟังก์ชัน TODAY() ( รวมถึงฟังก์ชัน NOW() ) ไม่ได้ แต่ต้องกำหนดเงื่อนไขให้เป็นไทม์โซน์ของประเทศไทยจริง ๆ

โดยใช้ฟังก์ชัน UTCNOW()

UTCNOW คล้ายฟังก์ชัน NOW แต่ให้ผลลัพธ์เป็นเวลาของ UTC+0 โดยไม่สนใจว่าคอมพิวเตอร์เครื่องนั้นอยู่ที่ใด หรืออ้างอิงไทม์โซนแบบใด

เช่น สร้าง measure ชื่อ UTCNow โดยเขียนสูตรเป็น

UTCNow = UTCNOW()

แล้วนำไปสร้างเป็น Card

ผลลัพธ์ที่ได้คือวันที่ 2 กันยายน 2020 เวลา 5:19:38 AM ซึ่งคือเวลาที่ผมกำลังเขียนบทความนี้

ช้าก่อน! ผมไม่ได้ขยันขนาดตื่นมาเขียนบทความตอนตีห้า ผมเขียนบทความนี้ตอนเที่ยง หรือคือ 12:19:38 PM

ใช่ครับ UTCNOW() แสดงผลลัพธ์เป็นเวลา UTC+0

ถ้าอยากปรับให้เป็นเวลาของประเทศไทยต้องบวก 7 ชั่วโมง หรือบวก 7/24 นั่นเอง

Note: Power BI ใช้หลักการคำนวณวันและเวลาเหมือน Excel นั่นคือ 1 วันมีค่าเป็น 1 ส่วน 1 ชั่วโมงมีค่าเป็น 1/24

เพื่อให้เห็นภาพ ผมจะสร้าง measure ใหม่ชื่อ UTCNow+7 โดยเขียนสูตรเป็น

UTCNow+7 = UTCNOW()+7/24

จากนั้นนำไปสร้างเป็น Card ผลลัพธ์ที่ได้คือ

นั่นคือเวลาจริงที่ผมเขียนบทความ

จากนั้นให้นำ UTCNOW()+7/24 ไปแทนที่ TODAY() ใน CALCULATE
แต่แทนที่ตรง ๆ ไม่ได้ เพราะ UTCNOW()+7/24 มีค่าเป็นวันที่และเวลา (Date/Time)

สูตรนี้ต้องการผลลัพธ์เป็นวันที่ (Date) จึงต้องครอบด้วยฟังก์ชัน DATEVALUE

เพื่อให้เห็นภาพ ผมสร้าง measure ใหม่ชื่อ ThailandToday ด้วยสูตร

ThailandToday = 
DATEVALUE(UTCNOW()+7/24)

จากนั้นนำไปสร้างเป็น Card

จะพบว่าได้ผลลัพธ์เป็น 2 กันยายน 2020 เวลา 12:00:00 AM หรือก็คือได้เฉพาะวันที่ ปัดเศษชั่วโมง นาที วินาที ทิ้งไป

นั่นคือ สำหรับประเทศไทย

TODAY() = DATEVALUE(UTCNOW()+7/24)

แปลว่าใช้ DATEVALUE(UTCNOW()+7/24) แทนที่ TODAY() ใน CALCULATE
หรือเขียนสูตรใหม่เป็น

TodaySales = 
CALCULATE( 
    [Sales], 
    tDate[Date] = DATEVALUE(UTCNOW()+7/24) 
)

เมื่อนำ measure [TodaySales] นี้ไปใช้ จะได้ผลลัพธ์ใน Power BI Service (และแอป Power BI) เป็นยอดขายของวันนี้เสมอ

คราวนี้จะเช็คข้อมูลตอนตีหนึ่ง ตีสาม หรือหกโมงเช้าก็ได้วันนี้แน่นอนครับ ^__^

อ้อ! เวลาที่เช็คข้อมูลต้องสัมพันธ์กับความถี่ของการรีเฟรชข้อมูลใน Power BI Service ด้วยนะครับ

ถ้าเชื่อมต่อข้อมูลแบบ Direct Query และปรับการรีเฟรชข้อมูลเป็นแบบ Real Time อันนี้ไม่มีปัญหา

แต่ถ้าเชื่อมต่อข้อมูลแบบปกติ (Import) ต้องเช็คด้วยว่าระบบถูกตั้งให้รีเฟรชข้อมูลตอนไหน (Scheduled Refresh)

ถ้าใช้ Power BI Pro สามารถตั้งความถี่ในการรีเฟรชสูงสุดได้ไม่เกิน 8 ครั้ง/วัน

แปลว่า แม้สร้าง measure แบบวิธีที่สองแล้ว แต่เช็คข้อมูลตอนตีสี่ ถ้าระบบถูกตั้งให้รีเฟรชตอนตีห้า ตัวเลขที่ได้ก็ยังเป็นของเมื่อวานอยู่ดี ต้องรอให้ระบบรีเฟรชตอนตีห้าก่อนถึงจะแสดงข้อมูลของวันนี้

ถ้าจะให้ดี ควรเช็คข้อมูลหลังเวลารีเฟรชอย่างน้อย 20 นาที เพราะบางครั้งระบบใช้เวลารีเฟรชนาน ยิ่งข้อมูลเยอะยิ่งใช้เวลานาน

เป็นยังไงกันบ้าง บทความนี้อาจยาวนิดนึงแต่น่าจะทำให้เข้าใจถึงความแตกต่างของตัวเลขใน Power BI Desktop และ Power BI Service

คราวนี้เช็คข้อมูลไม่พลาดแน่นอน

หืมม์.. พอได้ตัวเลขตอนตีสี่แล้วยังไงน่ะหรือ?

นอนต่อสิ นาฬิกายังไม่ปลุกซะหน่อย ^^

.
ถ้าคุณชอบบทความแนวนี้ อัพเดตบทความใหม่ได้โดยคลิกไลก์ เฟซบุ๊กเพจวิศวกรรีพอร์ต

อย่าลืมแชร์ให้เพื่อนอ่านเพื่อเป็นกำลังใจให้คนเขียนด้วยนะครับ ^__^