CALCULATE เป็นฟังก์ชันหลักที่สำคัญที่สุดใน DAX ใช้สำหรับ evaluate expression ภายใต้ filter context ที่ถูกปรับเปลี่ยน สามารถเพิ่มตัวกรองใหม่ ลบตัวกรองเดิม หรือแทนที่ filter ที่มีอยู่ได้ รองรับทั้ง Boolean expression และ table expression เป็น filter arguments พร้อม filter modifier functions เช่น REMOVEFILTERS, ALL, ALLEXCEPT, KEEPFILTERS เพื่อควบคุมการกรองอย่างละเอียด มีพฤติกรรมพิเศษคือ context transition ที่เปลี่ยน row context เป็น filter context โดยอัตโนมัติ ทำให้เป็นเครื่องมือหลักในการสร้าง measure ที่ซับซ้อนและ calculated column ที่ต้องใช้ aggregation
| อาร์กิวเมนต์ | ชนิด | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|
| expression | scalar | นิพจน์ที่ต้องการ evaluate (เช่น measure, DAX expression, หรือ aggregation function เช่น SUM, AVERAGE) จะถูกคำนวณเป็นลำดับสุดท้ายหลังจากเตรียม filter context ใหม่เสร็จแล้ว รองรับ scalar value เท่านั้น ไม่รองรับ table expression | |
| [filter]ไม่บังคับ | boolean / table / filter modifier | ไม่มีตัวกรองเพิ่มเติม (ไม่บังคับ) | เงื่อนไขการกรองข้อมูล รองรับ 3 รูปแบบหลักที่แตกต่างกัน: (1) Boolean Expression เช่น Product[Color] = “Red” ซึ่งจะถูกแปลงเป็น FILTER(ALL(…)) อัตโนมัติและทำการ override filter เดิมที่มีอยู่ (2) Table Expression เช่น FILTER(Product, Product[Price] > 100) สำหรับสร้างเงื่อนไขการกรองที่ซับซ้อนและยืดหยุ่นมากขึ้น (3) Filter Modifier Functions เช่น REMOVEFILTERS, ALL, ALLEXCEPT, KEEPFILTERS สำหรับควบคุมการกรองอย่างละเอียดและแม่นยำ สามารถใส่ filter หลายตัวได้โดยจะรวมกันด้วย AND logic (ต้องผ่านทุกเงื่อนไข) โปรดทราบว่า filter arguments ทั้งหมดจะถูกประเมินค่าใน original context ก่อนที่จะเกิด context transition นี่เป็นพฤติกรรมที่สำคัญมากสำหรับการเข้าใจผลลัพธ์ที่ถูกต้อง |
[ ] = อาร์กิวเมนต์ที่ไม่บังคับ
CALCULATE คือฟังก์ชันที่มีความสำคัญมากที่สุดในภาษา DAX ทำหน้าที่ประมวลผลนิพจน์ภายใต้บริบทการกรองข้อมูลที่ถูกปรับเปลี่ยนตามเงื่อนไขที่คุณกำหนดไว้
.
เอาจริงๆ ถ้าคุณเข้าใจ CALCULATE อย่างถ่องแท้ คุณจะเข้าใจ DAX ทั้งระบบได้เลยครับ 💡
.
เพราะฟังก์ชันนี้ถือเป็นหัวใจหลักของการควบคุม Filter Context และ Context Transition ซึ่งเป็นแนวคิดพื้นฐานที่สำคัญที่สุดของภาษา DAX ทั้งระบบ เรียกได้ว่าเป็น “ตัวเป็นตัวตาย” ของสาย Power BI เลยก็ว่าได้ 😎
Filter Context คือชุดของตัวกรองที่กำหนดว่าข้อมูลส่วนไหนของตารางจะถูกนำมาใช้ในการคำนวณผลลัพธ์สุดท้าย
.
ตัวอย่างเช่น เมื่อคุณใช้เครื่องมือ Slicer เพื่อเลือกสี “Blue” ใน Power BI ระบบจะสร้าง Filter Context ที่มีเงื่อนไข Product[Color] = “Blue” ขึ้นมา ทำให้การคำนวณทั้งหมดในรายงานจะเห็นและประมวลผลเฉพาะข้อมูลของสินค้าที่มีสีน้ำเงินเท่านั้น
CALCULATE ทำหน้าที่อะไร?
.
ฟังก์ชันนี้ช่วยให้คุณสามารถ ปรับเปลี่ยน Filter Context ได้อย่างยืดหยุ่นเป็นการชั่วคราวสำหรับการคำนวณเฉพาะครั้งนั้น
.
คุณสามารถเพิ่มตัวกรองเงื่อนไขใหม่เข้าไป ลบตัวกรองเดิมออกไป หรือแทนที่ตัวกรองที่มีอยู่เดิมได้ตามความต้องการของการคำนวณในขณะนั้น ส่วนตัวผมใช้ CALCULATE เกือบทุก Measure เลยครับ 😎
CALCULATE รองรับการใช้ filter arguments ได้หลากหลายสองรูปแบบหลักดังนี้:
Product[Color] = "Red" สามารถเขียนได้ง่ายและอ่านได้ง่าย แต่มีข้อจำกัดคือสามารถอ้างอิงได้เฉพาะคอลัมน์จากตารางเดียวเท่านั้น และจะทำการแทนที่ตัวกรองเดิมทั้งหมดเสมอโดยอัตโนมัติFILTER(Product, Product[Price] > 100) มีความยืดหยุ่นมากกว่าแบบแรก สามารถใช้เงื่อนไขที่ซับซ้อนได้หลากหลาย และสามารถอ้างอิงหลายตารางพร้อมกันได้อย่างมีประสิทธิภาพข้อสำคัญที่ต้องเข้าใจ: เมื่อคุณใช้ Boolean Expression เช่น Product[Color] = "Blue" ระบบ DAX จะทำการแปลงให้เป็นรูปแบบ FILTER(ALL(Product[Color]), Product[Color] = "Blue") โดยอัตโนมัติในเบื้องหลัง
.
นี่คือเหตุผลที่สำคัญว่าทำไม Boolean Filter ถึงต้องแทนที่ตัวกรองเดิมทั้งหมดเสมอ เพราะฟังก์ชัน ALL จะทำการลบตัวกรองเดิมออกไปก่อนทั้งหมด เรื่องนี้เจอบ่อยมากครับ 😅
Context Transition เป็นพฤติกรรมพิเศษของ CALCULATE ที่จะเกิดขึ้นเมื่อมี row context อยู่ (เช่นใน calculated column หรือ iterator function อย่าง SUMX) CALCULATE จะเปลี่ยน row context นั้นให้เป็น filter context โดยอัตโนมัติ นี่เป็นกลไกที่สำคัญมากสำหรับการทำงานของ DAX
ตัวอย่างการทำงาน: ใน calculated column แต่ละแถวจะมี row context (แถวปัจจุบันที่กำลังประมวลผล) ถ้าคุณใช้ CALCULATE(SUM(Sales[Amount]), ...) ระบบ DAX จะเปลี่ยน row context ให้เป็นตัวกรองที่กรองเฉพาะแถวนั้น ทำให้ SUM สามารถคำนวณได้ถูกต้องตามที่ต้องการ
ข้อควรระวังสำคัญ: การเรียกใช้ measure ภายใน DAX expression จะมีการใส่ CALCULATE ครอบให้อัตโนมัติ ทำให้เกิด context transition ได้โดยที่คุณอาจไม่รู้ตัวว่ามีการเปลี่ยนแปลงเกิดขึ้น
เพื่อให้เข้าใจผลลัพธ์ที่ถูกต้องและแม่นยำ คุณต้องทราบลำดับการทำงานภายในของ CALCULATE ดังนี้:
การเข้าใจลำดับนี้จะช่วยให้คุณหลีกเลี่ยงข้อผิดพลาดที่พบบ่อย โดยเฉพาะอย่างยิ่งเมื่อใช้ตัวกรองที่ซับซ้อนหรือมีการซ้อน CALCULATE หลายชั้นในสูตรเดียวกัน
CALCULATE สนับสนุน filter modifier functions หลายตัวที่ให้คุณควบคุมการกรองได้อย่างละเอียดและแม่นยำ:
ใช้ CALCULATE เพื่อคำนวณยอดรวมที่กรองเฉพาะบางเงื่อนไข เช่น ยอดขายเฉพาะสินค้าสีน้ำเงิน หรือยอดขายเฉพาะ channel ที่กำหนด โดยไม่สนใจ filter ที่มีอยู่จาก Slicer หรือ visual
ใช้ CALCULATE ร่วมกับ REMOVEFILTERS หรือ ALL เพื่อลบ filter บาง column ออก ทำให้คำนวณ grand total ได้ แล้วนำมาหารกับยอดย่อยเพื่อคำนวณเปอร์เซ็นต์
ใช้ CALCULATE เพื่อทำ context transition เปลี่ยน row context เป็น filter context ทำให้ aggregation function เช่น SUM, AVERAGE ทำงานถูกต้องใน calculated column หรือภายใน iterator function เช่น SUMX, FILTER
ใช้ CALCULATE ร่วมกับ time intelligence functions เช่น SAMEPERIODLASTYEAR, DATEADD เพื่อเปรียบเทียบข้อมูลในช่วงเวลาต่างกัน เช่น sales ปีก่อน, YTD (Year-To-Date), MTD (Month-To-Date)
CALCULATE ใช้ Boolean Expression Product[Color] = "Blue" เป็น Filter Argument ซึ่ง DAX จะแปลงเป็น FILTER(ALL(Product[Color]), Product[Color] = "Blue") โดยอัตโนมัติ
นี่คือเหตุผลที่ Boolean Filter จะ Override Filter เดิมเสมอ เพราะ ALL ลบ Filter เดิมทิ้งก่อนแล้วค่อยใส่ Filter ใหม่
ผลลัพธ์คือยอดขายเฉพาะสินค้าสีน้ำเงินเท่านั้น ไม่สนใจว่า Slicer เลือกสีอะไรอยู่ ถ้าต้องการให้ Filter ทำงานร่วมกับ Filter เดิม (Intersect) ต้องใช้ KEEPFILTERS แทนครับ
ตัวเศษคำนวณยอดขายของแต่ละ Channel ตามปกติ (ยังคงมี Filter Context จาก Visual) ส่วนตัวหารใช้ CALCULATE ร่วมกับ REMOVEFILTERS(Sales[Channel]) เพื่อลบ Filter ของ Channel ออก ทำให้ได้ Grand Total ของทุก Channel
การหารทั้งสองค่าจึงได้เปอร์เซ็นต์ของแต่ละ Channel
REMOVEFILTERS เป็น Filter Modifier ที่แนะนำให้ใช้แทน ALL เพราะอ่านง่ายกว่าและชัดเจนว่าต้องการลบ Filter อะไร Pattern นี้ใช้บ่อยมากใน DAX สำหรับคำนวณเปอร์เซ็นต์ครับ 😎
นี่คือ calculated column ที่ทำงานใน row context (แถวละแถว) เมื่อใช้ CALCULATE จะเกิด context transition โดยอัตโนมัติ คือ row context ของลูกค้าปัจจุบันจะถูกแปลงเป็น filter context ALLEXCEPT(Customer, Customer[CustomerKey]) จะลบ filter ทั้งหมดจากตาราง Customer ยกเว้น CustomerKey ทำให้ SUM(Sales[Sales Amount]) คำนวณยอดขายรวมของลูกค้าคนนั้นทั้งหมด ไม่ใช่แค่ยอดขายในแถวเดียว ถ้าไม่มี CALCULATE การใช้ SUM ใน calculated column จะให้ผลผิดพลาด เพราะ row context ไม่สามารถใช้กับ aggregation function ได้โดยตรง
CALCULATE รวม filter หลายตัวด้วย AND logic โดยอัตโนมัติ ข้อมูลต้องผ่านทุกเงื่อนไข (สีน้ำเงิน และ ราคามากกว่า 1,000) ถ้าต้องการใช้ OR logic ต้องเขียน Boolean expression ภายใน filter เดียว เช่น FILTER(Product, Product[Color] = "Blue" || Product[Color] = "Red") หรือถ้ามีเงื่อนไขซับซ้อนมาก แนะนำให้ใช้ VAR เก็บ intermediate result เพื่อให้โค้ดอ่านง่ายขึ้น
KEEPFILTERS เปลี่ยนพฤติกรรมของ CALCULATE จาก override เป็น intersect ถ้า Slicer เลือกสีแดงอยู่ การใช้ KEEPFILTERS(Product[Color] = "Blue") จะทำให้ filter context มี Red AND Blue ซึ่งไม่มีข้อมูล ผลลัพธ์จึงเป็น blank ในขณะที่การใช้ Boolean filter ปกติ (ไม่มี KEEPFILTERS) จะ override filter เดิม ทำให้ได้ Blue เสมอไม่ว่า Slicer จะเลือกอะไร ใช้ KEEPFILTERS เมื่อต้องการให้ filter ใหม่และ filter เดิมทำงานร่วมกันแบบ AND logic
ตัวอย่างนี้แสดงการใช้ VAR…RETURN เพื่อแบ่งการคำนวณออกเป็นขั้นตอนชัดเจน ทำให้โค้ดอ่านง่ายและ debug ง่าย CurrentYearSales เก็บยอดขายปีปัจจุบัน LastYearSales ใช้ CALCULATE ร่วมกับ SAMEPERIODLASTYEAR เพื่อเปลี่ยน filter context ของวันที่ไปเป็นปีก่อน GrowthAmount และ GrowthPercent คำนวณการเติบโตเป็นจำนวนและเปอร์เซ็นต์ การใช้ VAR ทำให้แต่ละ variable ถูกคำนวณเพียงครั้งเดียว ช่วยประหยัดเวลาและทำให้ performance ดีขึ้น
เพราะ DAX แปลง Boolean expression เป็น FILTER(ALL(column), condition) โดยอัตโนมัติ และ ALL(column) ทำงานได้เฉพาะ single column เท่านั้น ถ้าต้องการกรองหลายตารางพร้อมกัน ต้องใช้ table expression เช่น FILTER(Product, …) แทน Boolean expression
เกิดขึ้นเมื่อ CALCULATE ถูกเรียกใช้ใน row context (เช่นใน calculated column หรือภายใน iterator function เช่น SUMX, FILTER) CALCULATE จะเปลี่ยน row context เป็น filter context โดยอัตโนมัติ ทำให้ aggregation function ทำงานได้ถูกต้อง สำคัญมาก: Filter arguments ถูกประเมินก่อน context transition จึงไม่ได้รับผลจาก context transition
Boolean Filter เช่น Product[Color] = "Red" จะถูกแปลงเป็น FILTER(ALL(Product[Color]), Product[Color] = "Red") โดยอัตโนมัติ ดังนั้นทั้งสองรูปแบบให้ผลลัพธ์เหมือนกัน แต่ Boolean Filter เขียนสั้นกว่าและอ่านง่ายกว่า ข้อจำกัดคือ Boolean Filter ต้อง reference column จากตารางเดียว ส่วน FILTER(…) ยืดหยุ่นกว่า ใช้เงื่อนไขซับซ้อนและ reference หลายตารางได้
ใช้ KEEPFILTERS เมื่อต้องการให้ filter ใหม่ทำงานร่วมกับ filter เดิมแบบ intersect (AND logic) แทนการ override Boolean Filter ปกติจะ override filter เดิมทิ้งเสมอ ตัวอย่าง: ถ้า Slicer เลือกสีแดงอยู่ การใช้ CALCULATE(…, Product[Color] = "Blue") จะได้ Blue (override) แต่การใช้ CALCULATE(…, KEEPFILTERS(Product[Color] = "Blue")) จะได้ blank เพราะไม่มีข้อมูลที่เป็นทั้ง Red และ Blue
REMOVEFILTERS และ ALL ให้ผลลัพธ์เหมือนกันเมื่อใช้เป็น filter modifier ใน CALCULATE แต่ REMOVEFILTERS อ่านง่ายกว่าและชัดเจนกว่า เพราะชื่อบอกว่าทำอะไร (ลบ filter) ในขณะที่ ALL มีหลายความหมายขึ้นอยู่กับบริบท Microsoft และ SQLBI แนะนำให้ใช้ REMOVEFILTERS ใน modern DAX code เพื่อให้โค้ดอ่านง่ายและบำรุงรักษาง่ายขึ้น
ฟังก์ชันที่ผู้เขียนโยงไว้กับ CALCULATE จัดกลุ่มตามหมวด · ชี้ที่ชื่อใดชื่อหนึ่ง แล้วฟังก์ชันที่ใช้คู่กันจะมีจุดทอง
CLOSINGBALANCEMONTH ประเมิน Expression ณ วันสิ้นเดือนของบริบทวันที่ปัจจุบัน เหมาะกับการทำมาตรวัดยอดคงเหลือปลายเดือน และรองรับการใส่ตัวกรองเพิ่มเติม
CLOSINGBALANCEQUARTER ประเมิน Expression ณ วันสิ้นไตรมาสของบริบทวันที่ปัจจุบัน เหมาะกับมาตรวัดยอดคงเหลือปลายไตรมาส และรองรับตัวกรองเพิ่มเติม
CLOSINGBALANCEWEEK ประเมินนิพจน์ (มาตรวัด) ที่วันสิ้นสัปดาห์ของบริบทวันที่ปัจจุบัน สำคัญสำหรับรายงานปิดสัปดาห์และ snapshot ยอดคงเหลือ
ฟังก์ชันเวลา Intelligence ที่ประเมิน Expression ณ วันสิ้นปีของปีในบริบทปัจจุบัน รองรับปีบัญชี (Fiscal Year) และตัวกรองเพิ่มเติม เหมาะสำหรับมาตรวัด Semi-additive เช่น ยอดคงเหลือ ยอดเงินสด
DATEADD คืนค่าตารางวันที่ ที่ถูกเลื่อนออกไปจากช่วงวันที่ใน Context ปัจจุบัน ตามจำนวน (NumberOfIntervals) และหน่วย (Interval) ที่กำหนด เช่น เลื่อนย้อนหลัง 1 เดือน หรือเลื่อนไปข้างหน้า 1 ปี
DATESBETWEEN คืนตารางวันที่ที่อยู่ระหว่าง StartDate และ EndDate (รวมวันเริ่ม/วันจบ) เหมาะกับการใช้เป็นตัวกรองเวลาใน CALCULATE เพื่อคำนวณตามช่วงวันที่ที่กำหนดเอง
DATESINPERIOD คืนตารางวันที่แบบเคลื่อนที่ โดยเริ่มจาก StartDate และขยายไปตามจำนวนช่วงและหน่วยที่กำหนด เหมาะกับการทำคำนวณแบบ rolling YTD, rolling average, ย้อนหลัง หรือล่วงหน้าแบบยืดหยุ่น
DATESMTD คืนตารางวันที่ของช่วงตั้งแต่ต้นเดือนถึงวันที่ล่าสุดใน filter context เหมาะกับการทำยอดสะสมตั้งแต่ต้นเดือน (MTD) โดยใช้ร่วมกับ CALCULATE และควรใช้คู่กับ ShowValueForDates pattern เพื่อไม่ให้แสดงค่าในวันที่ยังไม่มีข้อมูล
DATESQTD คืนตารางวันที่ของช่วงตั้งแต่ต้นไตรมาสถึงวันที่ล่าสุดในบริบทปัจจุบัน เหมาะสำหรับสร้างมาตรวัด QTD ใน CALCULATE โดยทำงานร่วมกับ Time Intelligence Functions ตัวอื่นๆ ได้ดี และควรใช้คู่กับ ShowValueForDates pattern เพื่อป้องกันการแสดงค่าในอนาคต
ALL มีพฤติกรรมแตกต่างกัน 2 แบบ: ใช้เป็น Table Expression จะคืนทุกแถวในตาราง หรือทุกค่าในคอลัมน์ โดยไม่สนใจ Filter ใดๆ เหมาะสำหรับใช้ร่วมกับ FILTER, COUNTROWS, SUMMARIZE หรือใช้เป็น CALCULATE Modifier เพื่อลบ Filter ออกจากตารางหรือคอลัมน์ที่ระบุ ทำให้สามารถคำนวณ Grand Total หรือหาเปอร์เซ็นต์เทียบกับยอดรวมได้
ALLCROSSFILTERED ใช้ล้างตัวกรองทั้งหมดออกจากตารางที่ระบุ รวมถึงตัวกรองที่ส่งผ่านมาจากตารางอื่น (Cross-filter) ใช้ได้เฉพาะเป็น Modifier ใน CALCULATE/CALCULATETABLE เท่านั้น ไม่สามารถคืนค่าเป็นตารางได้
ALLEXCEPT ใช้สำหรับ “ล้างตัวกรองเกือบทั้งหมด” โดยคงตัวกรองไว้เฉพาะคอลัมน์ที่ระบุ เหมาะกับการคำนวณ Sub-total/สัดส่วนภายในกลุ่ม เช่น ยอดขายต่อหมวดหมู่ โดยไม่สนตัวกรองอื่น ๆ แนวคิดหลักคือ ลบตัวกรองของตาราง แล้วคงตัวกรองของคอลัมน์ที่เลือกไว้
ALLNOBLANKROW ทำงานคล้าย ALL แต่มีจุดเด่นคือ “ตัดแถวว่าง” ที่ระบบสร้างขึ้นอัตโนมัติเมื่อข้อมูลหลุดความสัมพันธ์ เช่น คีย์ในตารางข้อเท็จจริงไม่พบในตารางมิติ จึงเหมาะกับการคำนวณยอดรวม/สัดส่วนที่ไม่ต้องการให้แถวว่างเข้ามาปนผลลัพธ์ และยังใช้เป็นตัวช่วยตรวจจับปัญหาคุณภาพข้อมูลในโมเดลได้ด้วย
ALLSELECTED เป็น DAX function ที่ลบ filter context จาก Visual (row และ column filters) แต่คง filter context จาก Slicer, Page Filter และ Report Filter ไว้ ทำให้สามารถคำนวณ Visual Total ได้ ซึ่งเป็นยอดรวมของข้อมูลที่ผู้ใช้เลือกดูในปัจจุบัน ไม่ใช่ Grand Total ทั้งหมด ฟังก์ชันนี้ทำงานผ่าน Shadow Filter Context ซึ่งเป็น filter context ที่ DAX Engine เก็บไว้ก่อนที่ Visual จะเพิ่ม row/column filter เมื่อเรียก ALLSELECTED จะเรียกคืน shadow context นี้ ใช้ร่วมกับ CALCULATE และ SUM, AVERAGE, DIVIDE เพื่อคำนวณ Visual Total, Percentage of Selected, Dynamic Benchmark, Ranking within Selection และ Time Intelligence ที่เคารพ Slicer ต้องระวังการใช้งานใน iterator functions เช่น SUMX, FILTER เพราะอาจให้ผลลัพธ์ที่ไม่คาดคิด และระวัง Expanded Table Caveat ที่จะลบ filter ของ related table ด้วย
CALCULATETABLE evaluate table expression ภายใต้ filter context ที่ถูกปรับเปลี่ยน แล้วคืนค่าเป็น table (ตาราง) ซึ่งแตกต่างจาก CALCULATE ที่คืนค่าเป็น scalar value รองรับ filter arguments 3 รูปแบบ: Boolean expression, table expression, และ filter modifier functions (REMOVEFILTERS, ALL, KEEPFILTERS, USERELATIONSHIP, CROSSFILTER) มีพฤติกรรมเหมือน CALCULATE ในทุกแง่มุมของการจัดการ filter context รวมถึง context transition แต่เหมาะสำหรับการสร้าง intermediate table ที่ถูกกรองแล้วส่งต่อให้ iterator functions หรือใช้ใน calculated table มักมี performance ดีกว่า FILTER ใน simple filtering scenarios เพราะ DAX engine สามารถทำ cardinality estimation และ optimization ได้ดีกว่า
AVERAGE คำนวณค่าเฉลี่ยเลขคณิตของตัวเลขทั้งหมดในคอลัมน์ โดยข้าม blank cells และข้อความ แต่นับค่า 0 เข้าในการคำนวณ ซึ่งทำให้ค่าเฉลี่ยอาจต่ำลงถ้ามีค่า 0 จำนวนมาก ทำงานภายใต้ filter context ปัจจุบันและทำ context transition ใน calculated column ทำให้สามารถอ้างอิงคอลัมน์จากตารางอื่นผ่าน relationship ได้
AVERAGEX เป็น Iterator Function ที่วนลูปตารางทีละแถว คำนวณ Expression แล้วนำผลลัพธ์มาหาค่าเฉลี่ย เหมาะสำหรับกรณีที่ต้องการเฉลี่ยค่าที่คำนวณได้ เช่น ราคา×จำนวน หรือค่าเฉลี่ยของ Measure ในแต่ละกลุ่ม
COUNT นับจำนวนแถวที่คอลัมน์มีค่าไม่ว่าง (non-blank) รองรับตัวเลข วันที่ และข้อความ แต่ไม่นับ Boolean ทำงานภายใต้ filter context และเกิด context transition เมื่อใช้ใน row context เหมาะสำหรับนับรายการที่มีข้อมูลในคอลัมน์เฉพาะ แต่ควรใช้ COUNTROWS แทนเมื่อนับแถวทั้งหมด
COUNTA นับจำนวนเซลล์ที่มีค่าไม่ว่าง (non-blank) ในคอลัมน์ โดยรวมตัวเลข ข้อความ วันที่ และค่าตรรกะ ต่างจาก COUNT ที่นับเฉพาะตัวเลขเท่านั้น
ADDCOLUMNS เป็นฟังก์ชัน table transformation ที่ใช้สำหรับเพิ่มคอลัมน์ใหม่ (Calculated Columns) เข้าไปในตารางที่มีอยู่เดิม โดยคำนวณค่าในแต่ละแถวผ่าน Row Context และส่งคืนตารางเดิมพร้อมคอลัมน์ใหม่ต่อท้าย
ตรวจสอบว่าเงื่อนไขตรรกะทั้งหมดเป็นจริงหรือไม่ และคืนค่า TRUE เมื่อทุกเงื่อนไขเป็น TRUE
CONTAINSSTRING ตรวจสอบว่าข้อความหนึ่งมีข้อความอื่นเป็นส่วนหนึ่งหรือไม่ แล้วคืนค่า TRUE หรือ FALSE ตัวเลือกนี้ไม่สนใจตัวพิมพ์ใหญ่เล็ก
CROSSFILTER กำหนดทิศทางการกรองข้ามความสัมพันธ์ระหว่าง 2 คอลัมน์ชั่วคราว (มักใช้ใน CALCULATE) เพื่อควบคุมการไหลของตัวกรองหรือปิดการกรองข้ามในบางการคำนวณ
CURRENCY แปลงค่าตัวเลขให้เป็นชนิด Currency โดยเก็บเลขทศนิยมเพียง 4 ตำแหน่ง เหมาะสำหรับการคำนวณค่าเงินที่ต้องความแม่นยำในการปัดเศษ
DATESWTD คืนตารางวันที่ตั้งแต่ต้นสัปดาห์จนถึงวันที่ในบริบทปัจจุบัน ใช้เป็นตัวกรองเวลาใน CALCULATE เพื่อคำนวณยอดสะสมตั้งแต่ต้นสัปดาห์
DATESYTD คืนตารางวันที่ของช่วงตั้งแต่ต้นปีถึงวันที่สุดท้ายที่มองเห็นใน Filter Context ใช้เป็นตัวกรองเวลาใน CALCULATE สำหรับการคำนวณยอดสะสมตั้งแต่ต้นปี รองรับทั้งปีปฏิทินและปีบัญชี (Fiscal Year) ด้วย YearEndDate argument
ENDOFMONTH คืนตารางวันที่ของวันสิ้นเดือนตามปฏิทิน เหมาะกับ Semi-Additive Calculations เช่น ยอดคงเหลือ, Inventory, หรือ Closing Balance ที่ต้องการ snapshot ณ สิ้นเดือน ไม่ว่าจะมีข้อมูลจริงในวันนั้นหรือไม่
ENDOFQUARTER คืนตารางวันที่ของวันสิ้นไตรมาสตามบริบทวันที่ปัจจุบัน เหมาะกับการใช้เป็นตัวกรองเวลาใน CALCULATE เพื่อประเมินมาตรวัด ณ วันสิ้นไตรมาส
ฟังก์ชัน ENDOFWEEK คืนตารางวันที่ที่แสดงวันสิ้นสุดของสัปดาห์ตามบริบทวันที่ปัจจุบัน ใช้สำหรับการวิเคราะห์ข้อมูลตามระดับสัปดาห์ และการเปรียบเทียบเมตริกส์ณวันปิดสัปดาห์
ENDOFYEAR คืนตารางวันที่ของวันสิ้นปีตามบริบทวันที่ปัจจุบัน และรองรับการกำหนดวันสิ้นปีบัญชี เหมาะกับการใช้เป็นตัวกรองเวลาใน CALCULATE เพื่อประเมินมาตรวัดที่วันสิ้นปี
FIRSTDATE คืนค่าวันที่แรกในบริบทตัวกรองปัจจุบัน เหมาะใช้เป็นตัวกรองให้ CALCULATE เพื่อหายอดขาย/จำนวนของวันแรกในช่วงที่เลือก
FIRSTNONBLANK คืนค่าตัวแรกของ Column ที่ทำให้ Expression ไม่เป็น BLANK ใช้บ่อยเพื่อหา "ค่าแรกที่มีข้อมูล" เช่นวันแรกที่มียอดขาย (คืนค่าเป็นวันที่) และมักใช้ร่วมกับ time intelligence
FIRSTNONBLANKVALUE คืนค่าแรกที่ไม่เป็น BLANK ของ Expression เมื่อประเมินตามลำดับของ Column ซึ่งมีประโยชน์ในการหาค่าเริ่มต้นหรือค่าแรกที่มีข้อมูลจริง เช่นยอดขายของวันแรกที่มีการขาย
LASTDATE คืนค่าตารางที่มีวันที่สุดท้ายในบริบทตัวกรองปัจจุบัน มักใช้เป็นตารางตัวกรองให้ CALCULATE เพื่อคำนวณ measure ณ วันสุดท้ายของช่วงที่เลือก และสามารถใช้ MAXX เพื่อแปลงผลเป็น scalar date ได้
LASTNONBLANK คืนค่าตัวสุดท้ายจากคอลัมน์ที่ทำให้ expression ไม่เป็น BLANK ใช้บ่อยกับ semi-additive measures และเวลาต้องการหา "วันล่าสุดที่มีข้อมูล" ตามลำดับแถวของคอลัมน์
LASTNONBLANKVALUE คืนค่าสุดท้ายที่ไม่เป็น BLANK ของ Expression เมื่อประเมินตามลำดับของ Column ในบริบทตัวกรองปัจจุบัน ใช้หา "ค่าล่าสุดที่มีข้อมูล" เช่นยอดขายของวันล่าสุดที่มีค่า
NEXTDAY คืนตารางวันที่ของวันถัดไปจากวันที่ในบริบทปัจจุบัน มักใช้เป็นตารางตัวกรองใน CALCULATE เพื่อคำนวณค่าแบบ “วันถัดไป” ตามช่วงวันที่ที่ถูกกรอง
NEXTMONTH คืนตารางวันที่ของเดือนถัดไปจากบริบทวันที่ปัจจุบัน มักใช้เป็นตารางตัวกรองใน CALCULATE เพื่อคำนวณค่าแบบ “เดือนถัดไป” ตามช่วงวันที่ที่ถูกเลือก/กรอง
NEXTQUARTER คืนตารางวันที่ของไตรมาสถัดไปจากบริบทวันที่ปัจจุบัน มักใช้เป็นตารางตัวกรองใน CALCULATE เพื่อคำนวณค่าแบบ “ไตรมาสถัดไป”
NEXTWEEK คืนตารางวันที่ของสัปดาห์ถัดไปจากบริบทวันที่ปัจจุบัน มักใช้เป็นตารางตัวกรองใน CALCULATE เพื่อคำนวณค่าแบบ "สัปดาห์ถัดไป"
NEXTYEAR คืนตารางวันที่ของปีถัดไปจากบริบทวันที่ปัจจุบัน มักใช้เป็นตารางตัวกรองใน CALCULATE เพื่อคำนวณค่าแบบ “ปีถัดไป”
OPENINGBALANCEMONTH ประเมิน Expression ณ จุดเปิดเดือน (วันสิ้นเดือนก่อนหน้า) เหมาะสำหรับหา opening balance ของยอดคงเหลือ สต็อก หรือสถิติ ณ จุดเริ่มเดือน
OPENINGBALANCEQUARTER ประเมิน Expression ณ วันที่เทียบเท่ากับวันสิ้นไตรมาสก่อนหน้า ภายใต้บริบทตัวกรองที่กำหนด ใช้เพื่อหา “ค่าเปิดงวดรายไตรมาส”
OPENINGBALANCEWEEK ประเมิน Expression ณ จุดเปิดสัปดาห์ (คือวันสิ้นสัปดาห์ก่อนหน้า) ใช้เพื่อเปรียบเทียบค่าเปลี่ยนแปลงระหว่างเปิดและปิดสัปดาห์
OPENINGBALANCEYEAR คำนวณค่า Expression ณ วันแรกของปี โดยดึงค่าจากวันสิ้นปีปีก่อนหน้า เหมาะสำหรับการหา opening balance ของคงเหลือ บัญชี สต็อก และค่าที่วัดได้แค่ที่จุดเวลาเดียว
PARALLELPERIOD คืนตารางวันที่ที่ขนานกับช่วงเวลาปัจจุบัน แต่เลื่อนไปข้างหน้าหรือย้อนหลัง และขยายขอบเขตให้ครอบคลุมทั้งหน่วยเวลาที่ระบุ (MONTH/QUARTER/YEAR) เสมอ เหมาะกับการเทียบยอดรวมทั้งเดือน/ไตรมาส/ปี
PREVIOUSDAY คืนตารางวันที่ของวันก่อนหน้า ตามบริบทวันที่ปัจจุบัน เหมาะสำหรับทำตัวชี้วัดแบบเทียบวันต่อวัน โดยนำตารางวันที่ไปใช้เป็นตัวกรองเวลา
PREVIOUSMONTH คืนตารางวันที่ทั้งหมดของเดือนก่อนหน้า โดยอ้างอิงจากวันแรกของบริบทปัจจุบัน เหมาะกับการทำ Measure เปรียบเทียบ Month-over-Month เช่น ยอดขายเดือนก่อนหน้า ข้อแตกต่างสำคัญกับ DATEADD คือ PREVIOUSMONTH คืนทั้งเดือนเสมอ ไม่ว่าจะเลือกวันไหนก็ตาม
PREVIOUSQUARTER คืนตารางวันที่ของไตรมาสก่อนหน้า ตามวันที่แรกในบริบทปัจจุบัน ใช้สำหรับสร้าง Measure เปรียบเทียบ Quarter-over-Quarter (QoQ) โดยคืนวันที่ครบทั้งไตรมาสเสมอ ไม่ว่าจะเลือกวันที่ใดก็ตาม ภายในใช้ PARALLELPERIOD(FIRSTDATE(dates), -1, QUARTER)
PREVIOUSWEEK คืนตารางวันที่ของสัปดาห์ก่อนหน้า ตามบริบทวันที่ปัจจุบัน เหมาะสำหรับตัวชี้วัดแบบ Week-over-Week โดยนำตารางวันที่ไปใช้เป็นตัวกรองเวลา
PREVIOUSYEAR คืนตารางวันที่ของปีก่อนหน้า ตามบริบทวันที่ปัจจุบัน เหมาะสำหรับตัวชี้วัดแบบ Year-over-Year โดยนำตารางวันที่ไปใช้เป็นตัวกรองเวลา
SAMEPERIODLASTYEAR คืน table ของวันที่ที่เลื่อนย้อนกลับไป 1 ปีจากช่วงวันที่ใน filter context ปัจจุบัน ใช้สำหรับการเปรียบเทียบ Year-over-Year (YoY) โดยต้องการ date table ที่ครบถ้วนต่อเนื่องและควร mark เป็น date table ในโมเดล
.
มักใช้ร่วมกับ CALCULATE เพื่อคำนวณค่าของปีก่อนหน้าในช่วงเดียวกัน ทำให้ได้ผลลัพธ์แบบ apples-to-apples comparison ที่แม่นยำโดยไม่ต้อง hard-code ช่วงวันที่ เหมาะสำหรับ measures และ calculated columns แต่ไม่รองรับ DirectQuery mode และไม่แนะนำสำหรับ visual calculations
STARTOFMONTH คืนวันแรกของเดือนเป็นตาราง 1 แถว ใช้กับการวัดที่ขึ้นต่อจุดเวลา เช่น ยอดคงเหลือ บัญชี หรือสินค้าคงคลัง
STARTOFQUARTER คืนตารางวันที่ที่มีวันแรกของไตรมาสในบริบทตัวกรองปัจจุบัน (single-row table) ใช้เป็นตารางตัวกรองใน CALCULATE หรือใช้ MINX เพื่อแปลงเป็น scalar date
STARTOFWEEK คืนตารางที่มีวันแรกของสัปดาห์ตามปฏิทินที่กำหนด ใช้เป็นตัวกรองใน CALCULATE หรือดึงค่าสเกลาร์ด้วย MINX ฟังก์ชันนี้จำเป็นต้องมีตารางวันที่ที่ถูกกำหนดไว้เป็น Date Table
STARTOFYEAR คืนตาราง 1 แถวที่มีวันที่วันแรกของปีในบริบทปัจจุบัน ใช้สำหรับ semi-additive measure เช่น inventory balance หรือเปรียบเทียบ year-to-date
คำนวณยอดสะสมตั้งแต่ต้นเดือน (Month-to-Date) ของ Expression ตามคอลัมน์วันที่ที่กำหนด เป็นทางลัดของ CALCULATE + DATESMTD
TOTALQTD คำนวณยอดสะสมตั้งแต่วันแรกของไตรมาส (Q1/Q2/Q3/Q4) จนถึงวันที่ล่าสุดใน filter context ปัจจุบัน
.
ส่วนตัวผมใช้บ่อยมากตอน analyze quarterly performance และการวิเคราะห์ KPI รายไตรมาสครับ
คำนวณยอดสะสมตั้งแต่ต้นสัปดาห์ (Week-to-Date) ของ Expression ตามคอลัมน์วันที่ที่กำหนด โดยรวมข้อมูลจากวันแรกของสัปดาห์จนถึงวันปัจจุบันในบริบท
TOTALYTD คำนวณยอดสะสมตั้งแต่ต้นปี (Year-to-Date) ของ expression ใดๆ โดยอิงจาก Date table และสามารถกำหนด fiscal year end date เพื่อรองรับปีงบประมาณที่ไม่ตรงกับปีปฏิทินได้
.
ส่วนตัวผมใช้บ่อยมากตอนต้องวิเคราะห์ยอดขาย KPI และรายงานทางการเงินที่ต้องการติดตามความก้าวหน้าตลอดทั้งปีครับ
FILTER ใช้กรองแถวในตารางตามเงื่อนไขที่ซับซ้อน โดยวนลูปทุกแถวและประเมินเงื่อนไข เหมาะกับการกรองด้วย Measure หรือ Expression ซึ่ง Boolean Expression ทำไม่ได้ แต่ต้องระวังเรื่อง Performance เพราะเป็น Iterator Function ที่ช้ากว่า Boolean Expression ดังนั้นควรใช้เฉพาะเมื่อจำเป็น และอย่าใช้ FILTER กับ RELATED เพื่อกรองข้ามตาราง ให้กรองที่ Dimension Table โดยตรงแทน
KEEPFILTERS เป็นฟังก์ชันปรับตัวกรองที่ใช้ภายใน CALCULATE เพื่อ “คงตัวกรองเดิมไว้” แล้วนำตัวกรองใหม่มารวมกันแบบ AND (ตัดกันเฉพาะส่วนที่ตรงกัน) แทนพฤติกรรมปกติที่มักเขียนทับตัวกรองเดิมของคอลัมน์เดียวกัน
LOOKUP ค้นหาและดึงค่าจากเมทริกซ์ภาพ (visual matrix) ในการคำนวณภาพโดยการระบุเงื่อนไขการกรอง ใช้เฉพาะในการคำนวณภาพเท่านั้น
LOOKUPVALUE เป็นฟังก์ชันค้นหาที่ยืดหยุ่น โดยจะดึงค่าจากคอลัมน์หนึ่งโดยการค้นหาตามเงื่อนไขหลายตัวในเวลาเดียวกัน
LOOKUPWITHTOTALS ค้นหาตำแหน่งที่ตรงเงื่อนไขในตารางสรุป/กริด แล้วคืนค่าเดี่ยวจากคอลัมน์ผลลัพธ์หรือคำนวณนิพจน์จากชุดที่ตรงเงื่อนไข โดยถือว่าคอลัมน์ที่ไม่ระบุในเงื่อนไขอยู่ในสถานะรวม (total) ซึ่งต่างจาก LOOKUP
REMOVEFILTERS ลบ Filter ออกจากตารางหรือคอลัมน์ที่ระบุ ใช้ได้ใน CALCULATE เท่านั้น เทียบเท่า ALL เมื่อใช้เป็น CALCULATE Modifier แต่ชัดเจนและอ่านโค้ดง่ายกว่า แนะนำใช้แทน ALL เพราะสื่อความหมายได้ดีกว่า
SELECTEDVALUE ตรวจสอบว่า Filter Context ลดลงเหลือเพียงค่าเดียวแล้ว ถ้าใช่ให้คืนค่านั้น ถ้าไม่ใช่ให้คืนค่าอื่นแทน
EVALUATEANDLOG คำนวณนิพจน์และส่งผลลัพธ์ไปยัง log สำหรับการตรวจสอบและดีบัก ทำให้เห็นค่าระหว่างกลางของการคำนวณ DAX โดยไม่ต้องเขียนตารางชั่วคราว
ตรวจว่าคอลัมน์ถูก filter โดยตรงให้เหลือค่าเดียวหรือไม่ เหมาะกับการควบคุมการแสดงผลตามสถานะการเลือกของผู้ใช้
HASONEVALUE ตรวจสอบว่า Column ที่ผ่านการ Filter มีเพียงค่าเดียวเท่านั้น Return TRUE หากตรงตามเงื่อนไข FALSE หากไม่ใช่ ใช้หลักเพื่อสร้าง Measure ที่ "ฉลาด" ตามการเลือก Filter ของผู้ใช้
ISFILTERED ตรวจสอบว่าคอลัมน์ที่ระบุมีตัวกรองโดยตรงหรือไม่ ใช้เพื่อสร้าง Dynamic Measures ที่เปลี่ยนพฤติกรรมตามการกรองของผู้ใช้
SELECTEDMEASURE() คืนค่าของ Measure ต้นทางที่กำลังถูกประมวลผลอยู่ในบริบท Calculation Group ช่วยให้สร้าง Calculation Item ที่ยืดหยุ่น สามารถนำไปใช้งานกับหลาย Measure พร้อมกันได้อย่างมีประสิทธิภาพ
FILTERS คืนค่าเป็นตาราง (table) ของค่าที่ถูกกรองโดยตรง (direct filters) บนคอลัมน์ที่ระบุ เช่น ค่าที่ผู้ใช้เลือกจากตัวแบ่งส่วนข้อมูล ต่างจาก ALL/ALLEXCEPT ที่เคลียร์ตัวกรอง FILTERS ช่วยตรวจสอบและจัดการบริบทตัวกรองอย่างชาญฉลาด
NONVISUAL ใช้ทำเครื่องหมายว่า filter expression นี้เป็น non-visual ซึ่งหมายความว่ามันจะส่งผลต่อการคำนวณ measure แต่จะไม่ไปทำให้แถวที่แสดงในตารางสรุปเปลี่ยนไป มักใช้ร่วมกับ SUMMARIZECOLUMNS เพื่อควบคุมพฤติกรรมของตัวกรองอย่างละเอียด
คืนตาราง Top N แถวจากตารางที่กำหนด โดยเรียงตามนิพจน์หนึ่งตัวหรือมากกว่า สามารถระบุทิศทางการเรียงลำดับแยกต่างหากสำหรับแต่ละเกณฑ์
TREATAS เป็นเสมือนการสร้าง "virtual relationship" โดยไม่ต้องแก้โมเดล ช่วยให้ส่งเงื่อนไขข้ามตารางที่ไม่เชื่อมกัน หรือเมื่อต้องการส่งหลายคีย์พร้อมกัน
PRODUCTX วนประเมิน Expression บน Table แล้วคูณผลลัพธ์ของแต่ละแถวเข้าด้วยกันเป็นค่าเดี่ยว เหมาะกับการคูณปัจจัย/อัตราการเปลี่ยนแปลงต่อเนื่องหลายงวด และควรระวัง BLANK/ศูนย์/ค่าติดลบตามตรรกะงาน
SUM รวมค่าตัวเลขทั้งหมดจากคอลัมน์เดียวภายใต้ filter context ปัจจุบัน ข้ามค่า BLANK และข้อความ แต่รวมค่า 0 หากต้องรวมจาก expression ให้ใช้ SUMX แทน
SUMX เป็น iterator function ที่ทรงพลังใน DAX ออกแบบมาเพื่อวนลูปทีละแถวในตารางที่กำหนด แล้วคำนวณ expression ที่ซับซ้อนสำหรับแต่ละแถวก่อนนำผลลัพธ์ทั้งหมดมารวมกัน ต่างจาก SUM ที่รวมเฉพาะค่าใน column เดียว SUMX สร้าง row context สำหรับแต่ละแถว ทำให้สามารถคำนวณ expression อย่าง Quantity × Price หรือใช้ RELATED ดึงข้อมูลข้ามตารางได้ มีกลไก context transition อัตโนมัติเมื่อเจอ measure ในนั้น เหมาะสำหรับการคำนวณซับซ้อนระดับแถวข้อมูล ประหยัดพื้นที่ model เพราะไม่ต้องสร้าง calculated column แต่ช้ากว่า SUM และไม่รองรับ DirectQuery mode ใน calculated columns หรือ RLS rules
MOVINGAVERAGE คำนวณค่าเฉลี่ยเคลื่อนที่ (moving average) บนแกนของ Visual Calculations ในตารางข้อมูล เหมาะสำหรับทำเส้นแนวโน้มที่เรียบขึ้นและลดความผันผวนของข้อมูล
RUNNINGSUM คำนวณยอดสะสมของคอลัมน์/นิพจน์ตามลำดับบนแกนของ Visual Calculations โดยสามารถกำหนด Axis, OrderBy, Blanks และ Reset เพื่อควบคุมลำดับและจุดเริ่มสะสม
EXTERNALMEASURE ใช้สำหรับการวิเคราะห์ข้อมูล DAX
USERELATIONSHIP ช่วยให้คุณใช้ relationship ที่ไม่ใช่ active หรือเปลี่ยน relationship ที่ใช้ในการคำนวณ เหมาะสำหรับสถานการณ์เช่น sales data ที่มีหลาย date columns (OrderDate, ShippingDate, DeliveryDate)
Comments
อีเมลของคุณจะไม่ถูกเผยแพร่