Thep Excel

CALCULATE – ฟังก์ชันหลักของ DAX ที่ควบคุม Filter Context

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

=CALCULATE(<expression>[, <filter>[, <filter>[, ...]]])

By ThepExcel AI Agent
18 December 2025

Function Metrics


Popularity
10/10

Difficulty
7/10

Usefulness
10/10

Syntax & Arguments

=CALCULATE(<expression>[, <filter>[, <filter>[, ...]]])

Argument Type Required Default Description
expression scalar Yes นิพจน์ที่ต้องการ evaluate (เช่น measure, DAX expression, หรือ aggregation function เช่น SUM, AVERAGE) จะถูกคำนวณเป็นลำดับสุดท้ายหลังจากเตรียม filter context ใหม่เสร็จแล้ว รองรับ scalar value เท่านั้น ไม่รองรับ table expression
filter boolean / table / filter modifier Optional ไม่มีตัวกรองเพิ่มเติม (ไม่บังคับ) เงื่อนไขการกรองข้อมูล รองรับ 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 นี่เป็นพฤติกรรมที่สำคัญมากสำหรับการเข้าใจผลลัพธ์ที่ถูกต้อง

How it works

คำนวณยอดรวมที่มีเงื่อนไข (Conditional Totals)

ใช้ CALCULATE เพื่อคำนวณยอดรวมที่กรองเฉพาะบางเงื่อนไข เช่น ยอดขายเฉพาะสินค้าสีน้ำเงิน หรือยอดขายเฉพาะ channel ที่กำหนด โดยไม่สนใจ filter ที่มีอยู่จาก Slicer หรือ visual

คำนวณเปอร์เซ็นต์ของยอดรวม (Percentage of Total)

ใช้ CALCULATE ร่วมกับ REMOVEFILTERS หรือ ALL เพื่อลบ filter บาง column ออก ทำให้คำนวณ grand total ได้ แล้วนำมาหารกับยอดย่อยเพื่อคำนวณเปอร์เซ็นต์

Context Transition ใน Iterator และ Calculated Column

ใช้ CALCULATE เพื่อทำ context transition เปลี่ยน row context เป็น filter context ทำให้ aggregation function เช่น SUM, AVERAGE ทำงานถูกต้องใน calculated column หรือภายใน iterator function เช่น SUMX, FILTER

Time Intelligence Calculations

ใช้ CALCULATE ร่วมกับ time intelligence functions เช่น SAMEPERIODLASTYEAR, DATEADD เพื่อเปรียบเทียบข้อมูลในช่วงเวลาต่างกัน เช่น sales ปีก่อน, YTD (Year-To-Date), MTD (Month-To-Date)

Examples

ตัวอย่างที่ 1: กรองยอดขายสินค้าสีน้ำเงิน (Boolean Filter)
Blue Revenue = CALCULATE( SUM(Sales[Sales Amount]), Product[Color] = "Blue" )
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 แทนครับ
DAX Formula:

Blue Revenue = 
CALCULATE(
    SUM(Sales[Sales Amount]),
    Product[Color] = "Blue"
)

Result:

9,602,850.97 (ยอดขายเฉพาะสินค้าสีน้ำเงิน)

ตัวอย่างที่ 2: คำนวณเปอร์เซ็นต์รายได้แต่ละช่องทาง (Percentage of Total)
Revenue % Total Channel = DIVIDE( SUM(Sales[Sales Amount]), CALCULATE( SUM(Sales[Sales Amount]), REMOVEFILTERS(Sales[Channel]) ) )
ตัวเศษคำนวณยอดขายของแต่ละ Channel ตามปกติ (ยังคงมี Filter Context จาก Visual) ส่วนตัวหารใช้ CALCULATE ร่วมกับ REMOVEFILTERS(Sales[Channel]) เพื่อลบ Filter ของ Channel ออก ทำให้ได้ Grand Total ของทุก Channel
.
การหารทั้งสองค่าจึงได้เปอร์เซ็นต์ของแต่ละ Channel
.
REMOVEFILTERS เป็น Filter Modifier ที่แนะนำให้ใช้แทน ALL เพราะอ่านง่ายกว่าและชัดเจนว่าต้องการลบ Filter อะไร Pattern นี้ใช้บ่อยมากใน DAX สำหรับคำนวณเปอร์เซ็นต์ครับ 😎
DAX Formula:

Revenue % Total Channel = 
DIVIDE(
    SUM(Sales[Sales Amount]),
    CALCULATE(
        SUM(Sales[Sales Amount]),
        REMOVEFILTERS(Sales[Channel])
    )
)

Result:

Internet: 26.74%, Reseller: 73.26%

ตัวอย่างที่ 3: Context Transition ใน Calculated Column
Customer Segment = IF( CALCULATE( SUM(Sales[Sales Amount]), ALLEXCEPT(Customer, Customer[CustomerKey]) ) < 2500, "Low", "High" )
นี่คือ 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 ได้โดยตรง
DAX Formula:

Customer Segment = 
IF(
    CALCULATE(
        SUM(Sales[Sales Amount]),
        ALLEXCEPT(Customer, Customer[CustomerKey])
    ) < 2500,
    "Low",
    "High"
)

Result:

ลูกค้าที่มียอดซื้อรวมน้อยกว่า 2,500 = "Low", ที่เหลือ = "High"

ตัวอย่างที่ 4: ใช้หลาย Filter พร้อมกัน (Multiple Filters with AND Logic)
High Value Blue Sales = CALCULATE( SUM(Sales[Sales Amount]), Product[Color] = "Blue", Product[List Price] > 1000 )
CALCULATE รวม filter หลายตัวด้วย AND logic โดยอัตโนมัติ ข้อมูลต้องผ่านทุกเงื่อนไข (สีน้ำเงิน และ ราคามากกว่า 1,000) ถ้าต้องการใช้ OR logic ต้องเขียน Boolean expression ภายใน filter เดียว เช่น FILTER(Product, Product[Color] = "Blue" || Product[Color] = "Red") หรือถ้ามีเงื่อนไขซับซ้อนมาก แนะนำให้ใช้ VAR เก็บ intermediate result เพื่อให้โค้ดอ่านง่ายขึ้น
DAX Formula:

High Value Blue Sales = 
CALCULATE(
    SUM(Sales[Sales Amount]),
    Product[Color] = "Blue",
    Product[List Price] > 1000
)

Result:

ยอดขายสินค้าที่เป็นสีน้ำเงิน AND ราคามากกว่า 1,000

ตัวอย่างที่ 5: KEEPFILTERS สำหรับ Intersect Filter (ไม่ Override)
Blue Sales (Intersect) = CALCULATE( SUM(Sales[Sales Amount]), KEEPFILTERS(Product[Color] = "Blue") )
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
DAX Formula:

=Blue Sales (Intersect) = 
CALCULATE(
    SUM(Sales[Sales Amount]),
    KEEPFILTERS(Product[Color] = "Blue")
)

Result:

ยอดขายสินค้าสีน้ำเงิน แต่ถ้า Slicer เลือกสีแดง ผลลัพธ์จะเป็น blank

ตัวอย่างที่ 6: ใช้ VAR ใน CALCULATE เพื่อความชัดเจน (Multi-step Measure)
Sales vs Last Year Growth = VAR CurrentYearSales = SUM(Sales[Sales Amount]) VAR LastYearSales = CALCULATE( SUM(Sales[Sales Amount]), SAMEPERIODLASTYEAR(Calendar…
ตัวอย่างนี้แสดงการใช้ VAR…RETURN เพื่อแบ่งการคำนวณออกเป็นขั้นตอนชัดเจน ทำให้โค้ดอ่านง่ายและ debug ง่าย CurrentYearSales เก็บยอดขายปีปัจจุบัน LastYearSales ใช้ CALCULATE ร่วมกับ SAMEPERIODLASTYEAR เพื่อเปลี่ยน filter context ของวันที่ไปเป็นปีก่อน GrowthAmount และ GrowthPercent คำนวณการเติบโตเป็นจำนวนและเปอร์เซ็นต์ การใช้ VAR ทำให้แต่ละ variable ถูกคำนวณเพียงครั้งเดียว ช่วยประหยัดเวลาและทำให้ performance ดีขึ้น
DAX Formula:

Sales vs Last Year Growth = 
VAR CurrentYearSales = SUM(Sales[Sales Amount])
VAR LastYearSales = 
    CALCULATE(
        SUM(Sales[Sales Amount]),
        SAMEPERIODLASTYEAR(Calendar[Date])
    )
VAR GrowthAmount = CurrentYearSales - LastYearSales
VAR GrowthPercent = DIVIDE(GrowthAmount, LastYearSales, 0)
RETURN
    GrowthPercent

Result:

0.15 (เติบโต 15% เมื่อเทียบกับปีก่อน)

FAQs

ทำไม Boolean Filter ต้อง Reference Column จากตารางเดียวเท่านั้น?

เพราะ DAX แปลง Boolean expression เป็น FILTER(ALL(column), condition) โดยอัตโนมัติ และ ALL(column) ทำงานได้เฉพาะ single column เท่านั้น ถ้าต้องการกรองหลายตารางพร้อมกัน ต้องใช้ table expression เช่น FILTER(Product, …) แทน Boolean expression

Context Transition เกิดขึ้นเมื่อไหร่?

เกิดขึ้นเมื่อ CALCULATE ถูกเรียกใช้ใน row context (เช่นใน calculated column หรือภายใน iterator function เช่น SUMX, FILTER) CALCULATE จะเปลี่ยน row context เป็น filter context โดยอัตโนมัติ ทำให้ aggregation function ทำงานได้ถูกต้อง สำคัญมาก: Filter arguments ถูกประเมินก่อน context transition จึงไม่ได้รับผลจาก context transition

ความแตกต่างระหว่าง Boolean Filter กับ FILTER(ALL(…), condition) คืออะไร?

Boolean Filter เช่น Product[Color] = “Red” จะถูกแปลงเป็น FILTER(ALL(Product[Color]), Product[Color] = “Red”) โดยอัตโนมัติ ดังนั้นทั้งสองรูปแบบให้ผลลัพธ์เหมือนกัน แต่ Boolean Filter เขียนสั้นกว่าและอ่านง่ายกว่า ข้อจำกัดคือ Boolean Filter ต้อง reference column จากตารางเดียว ส่วน FILTER(…) ยืดหยุ่นกว่า ใช้เงื่อนไขซับซ้อนและ reference หลายตารางได้

เมื่อไหร่ควรใช้ KEEPFILTERS แทน Boolean Filter ปกติ?

ใช้ 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?

REMOVEFILTERS และ ALL ให้ผลลัพธ์เหมือนกันเมื่อใช้เป็น filter modifier ใน CALCULATE แต่ REMOVEFILTERS อ่านง่ายกว่าและชัดเจนกว่า เพราะชื่อบอกว่าทำอะไร (ลบ filter) ในขณะที่ ALL มีหลายความหมายขึ้นอยู่กับบริบท Microsoft และ SQLBI แนะนำให้ใช้ REMOVEFILTERS ใน modern DAX code เพื่อให้โค้ดอ่านง่ายและบำรุงรักษาง่ายขึ้น

Resources & Related

Related functions

Additional Notes

CALCULATE คือฟังก์ชันที่มีความสำคัญมากที่สุดในภาษา DAX ทำหน้าที่ประมวลผลนิพจน์ภายใต้บริบทการกรองข้อมูลที่ถูกปรับเปลี่ยนตามเงื่อนไขที่คุณกำหนดไว้
.
เอาจริงๆ ถ้าคุณเข้าใจ CALCULATE อย่างถ่องแท้ คุณจะเข้าใจ DAX ทั้งระบบได้เลยครับ 💡
.
เพราะฟังก์ชันนี้ถือเป็นหัวใจหลักของการควบคุม Filter Context และ Context Transition ซึ่งเป็นแนวคิดพื้นฐานที่สำคัญที่สุดของภาษา DAX ทั้งระบบ เรียกได้ว่าเป็น “ตัวเป็นตัวตาย” ของสาย Power BI เลยก็ว่าได้ 😎

Filter Context คืออะไร และทำงานอย่างไร?

Filter Context คือชุดของตัวกรองที่กำหนดว่าข้อมูลส่วนไหนของตารางจะถูกนำมาใช้ในการคำนวณผลลัพธ์สุดท้าย
.
ตัวอย่างเช่น เมื่อคุณใช้เครื่องมือ Slicer เพื่อเลือกสี “Blue” ใน Power BI ระบบจะสร้าง Filter Context ที่มีเงื่อนไข Product[Color] = “Blue” ขึ้นมา ทำให้การคำนวณทั้งหมดในรายงานจะเห็นและประมวลผลเฉพาะข้อมูลของสินค้าที่มีสีน้ำเงินเท่านั้น

CALCULATE ทำหน้าที่อะไร?
.
ฟังก์ชันนี้ช่วยให้คุณสามารถ ปรับเปลี่ยน Filter Context ได้อย่างยืดหยุ่นเป็นการชั่วคราวสำหรับการคำนวณเฉพาะครั้งนั้น
.
คุณสามารถเพิ่มตัวกรองเงื่อนไขใหม่เข้าไป ลบตัวกรองเดิมออกไป หรือแทนที่ตัวกรองที่มีอยู่เดิมได้ตามความต้องการของการคำนวณในขณะนั้น ส่วนตัวผมใช้ CALCULATE เกือบทุก Measure เลยครับ 😎

Filter Arguments: Boolean กับ Table Expression

CALCULATE รองรับการใช้ filter arguments ได้หลากหลายสองรูปแบบหลักดังนี้:

  • Boolean Expression: เช่น Product[Color] = "Red" สามารถเขียนได้ง่ายและอ่านได้ง่าย แต่มีข้อจำกัดคือสามารถอ้างอิงได้เฉพาะคอลัมน์จากตารางเดียวเท่านั้น และจะทำการแทนที่ตัวกรองเดิมทั้งหมดเสมอโดยอัตโนมัติ
  • Table Expression: เช่น FILTER(Product, Product[Price] > 100) มีความยืดหยุ่นมากกว่าแบบแรก สามารถใช้เงื่อนไขที่ซับซ้อนได้หลากหลาย และสามารถอ้างอิงหลายตารางพร้อมกันได้อย่างมีประสิทธิภาพ

ข้อสำคัญที่ต้องเข้าใจ: เมื่อคุณใช้ Boolean Expression เช่น Product[Color] = "Blue" ระบบ DAX จะทำการแปลงให้เป็นรูปแบบ FILTER(ALL(Product[Color]), Product[Color] = "Blue") โดยอัตโนมัติในเบื้องหลัง
.
นี่คือเหตุผลที่สำคัญว่าทำไม Boolean Filter ถึงต้องแทนที่ตัวกรองเดิมทั้งหมดเสมอ เพราะฟังก์ชัน ALL จะทำการลบตัวกรองเดิมออกไปก่อนทั้งหมด เรื่องนี้เจอบ่อยมากครับ 😅

Context Transition (การเปลี่ยน Row Context เป็น Filter Context)

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 ได้โดยที่คุณอาจไม่รู้ตัวว่ามีการเปลี่ยนแปลงเกิดขึ้น

Order of Evaluation (ลำดับการทำงานภายใน)

เพื่อให้เข้าใจผลลัพธ์ที่ถูกต้องและแม่นยำ คุณต้องทราบลำดับการทำงานภายในของ CALCULATE ดังนี้:

  1. ประเมินค่า Filter Arguments: ประเมินค่าตัวกรองทั้งหมดใน original context ก่อนการเปลี่ยนแปลงใดๆ (ขั้นตอนนี้สำคัญมาก!)
  2. Context Transition: ถ้ามี row context อยู่จะถูกแปลงเป็น filter context โดยอัตโนมัติ
  3. ประเมิน Modifiers: ฟังก์ชันปรับแต่งเช่น REMOVEFILTERS, ALL, KEEPFILTERS ถูกประเมินและดำเนินการ
  4. นำ Filters มาใช้: นำตัวกรองทั้งหมดมาใช้กับ filter context (ปกติจะใช้ AND logic และแทนที่ตัวกรองเดิม)
  5. ประเมินผล Expression: สุดท้ายจึงคำนวณนิพจน์หลักภายใต้บริบทใหม่ที่เตรียมไว้แล้ว

การเข้าใจลำดับนี้จะช่วยให้คุณหลีกเลี่ยงข้อผิดพลาดที่พบบ่อย โดยเฉพาะอย่างยิ่งเมื่อใช้ตัวกรองที่ซับซ้อนหรือมีการซ้อน CALCULATE หลายชั้นในสูตรเดียวกัน

Filter Modifier Functions (ฟังก์ชันปรับแต่งตัวกรอง)

CALCULATE สนับสนุน filter modifier functions หลายตัวที่ให้คุณควบคุมการกรองได้อย่างละเอียดและแม่นยำ:

  • REMOVEFILTERS: ลบตัวกรองทั้งหมดออกจากตารางหรือคอลัมน์ที่กำหนด (อ่านง่ายกว่า ALL)
  • ALL และ ALLEXCEPT: ลบตัวกรองออกจากคอลัมน์หรือตาราง (ALL ลบทั้งหมด ALLEXCEPT เก็บบางคอลัมน์ไว้)
  • KEEPFILTERS: เพิ่มตัวกรองใหม่โดยไม่ลบตัวกรองเดิม (ใช้ AND logic แทนการแทนที่)
  • USERELATIONSHIP: เปิดใช้งาน inactive relationship ชั่วคราวสำหรับการคำนวณครั้งนั้น
  • CROSSFILTER: เปลี่ยนทิศทางการกรองหรือปิด relationship ชั่วคราว

เมื่อไหร่ควรใช้ CALCULATE?

  • คำนวณยอดรวมที่ต้องการกรองเฉพาะบางเงื่อนไข (เช่น ยอดขายเฉพาะสินค้าสีน้ำเงิน)
  • คำนวณเปอร์เซ็นต์โดยเปรียบเทียบกับยอดรวมทั้งหมด (ต้องลบตัวกรองบางคอลัมน์ออก)
  • ใช้ใน calculated column เมื่อต้องการรวมข้อมูล (ต้องมี context transition)
  • สร้าง time intelligence measures (เช่น ยอดขายปีก่อน, ยอดขายเดือนก่อน)
  • เปรียบเทียบข้อมูลในบริบทการกรองที่แตกต่างกัน

Leave a Reply

Your email address will not be published. Required fields are marked *