---
title: CALCULATE – ฟังก์ชันหลักของ DAX ที่ควบคุม Filter Context
url: https://www.thepexcel.com/functions/dax/filter/calculate-dax/
type: function-explainer
program: DAX
syntax: "CALCULATE(<expression>[, <filter>[, <filter>[, ...]]])"
date: 2025-12-18
scores:
  popularity: 10
  difficulty: 7
  usefulness: 10
---

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

> Evaluate expression ภายใต้ filter context ที่ปรับเปลี่ยนแล้ว (หัวใจของ DAX)

## คำอธิบาย

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

## Syntax

```excel
CALCULATE(&lt;expression&gt;[, &lt;filter&gt;[, &lt;filter&gt;[, ...]]])
```

**Variant**

```excel
CALCULATE(&lt;expression&gt;)
```

Evaluate expression โดยทำ context transition (เปลี่ยน row context เป็น filter context) โดยไม่เพิ่ม filter ใหม่ ใช้เมื่อต้องการให้ aggregation function ทำงานถูกต้องใน calculated column หรือ iterator function

**Variant**

```excel
CALCULATE(&lt;expression&gt;, &lt;boolean_filter&gt;)
```

กรองด้วย Boolean expression เช่น Product[Color] = "Red" ซึ่งจะ override filter เดิมของ column นั้นทั้งหมด เพราะ DAX แปลงเป็น FILTER(ALL(column), condition) โดยอัตโนมัติ

**Variant**

```excel
CALCULATE(&lt;expression&gt;, &lt;table_filter&gt;)
```

กรองด้วย table expression เช่น FILTER(Product, Product[Price] > 100 && Product[Color] = "Blue") ให้ความยืดหยุ่นมากกว่า Boolean expression สามารถใช้เงื่อนไขซับซ้อนและ reference หลายตารางได้

**Variant**

```excel
CALCULATE(&lt;expression&gt;, &lt;filter1&gt;, &lt;filter2&gt;, ...)
```

ใช้หลาย filter พร้อมกัน โดยรวมกันด้วย AND logic (ข้อมูลต้องผ่านทุกเงื่อนไข) ถ้าต้องการใช้ OR logic ต้องเขียนภายใน Boolean expression เดียว

**Variant**

```excel
CALCULATE(&lt;expression&gt;, REMOVEFILTERS(&lt;table_or_column&gt;))
```

ลบ filter ออกจากตารางหรือ column ที่ระบุ เป็นทางเลือกที่ดีกว่า ALL เพราะอ่านง่ายและชัดเจนกว่า แนะนำให้ใช้ใน modern DAX code

**Variant**

```excel
CALCULATE(&lt;expression&gt;, KEEPFILTERS(&lt;filter&gt;))
```

เพิ่ม filter ใหม่โดยไม่ลบ filter เดิม (ใช้ AND logic แทน override) ทำให้เงื่อนไขใหม่และเงื่อนไขเดิมทำงานร่วมกันแบบ intersect ใช้เมื่อต้องการให้ filter ทั้งสองชุดมีผลพร้อมกัน

**Variant**

```excel
CALCULATE(&lt;expression&gt;, ALL(&lt;table_or_column&gt;))
```

ลบ filter ทั้งหมดออกจากตารางหรือ column ที่ระบุ มักใช้เพื่อคำนวณ grand total หรือเปอร์เซ็นต์ของยอดรวมทั้งหมด

**Variant**

```excel
CALCULATE(&lt;expression&gt;, ALLEXCEPT(&lt;table&gt;, &lt;column1&gt;[, &lt;column2&gt;[, ...]]))
```

ลบ filter ทั้งหมดจากตารางที่ระบุ ยกเว้น column ที่กำหนด ใช้เมื่อต้องการเก็บ filter บาง column ไว้แต่ลบที่เหลือทั้งหมด

## Arguments

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

## เคสการใช้งาน

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

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

_เหมาะกับ:_ conditional-aggregation

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

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

_เหมาะกับ:_ percentage-calculation

### Context Transition ใน Iterator และ Calculated Column

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

_เหมาะกับ:_ context-transition

### Time Intelligence Calculations

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

_เหมาะกับ:_ time-intelligence

## ตัวอย่าง

### 1. ตัวอย่างที่ 1: กรองยอดขายสินค้าสีน้ำเงิน (Boolean Filter)

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

**ผลลัพธ์:** `9,602,850.97 (ยอดขายเฉพาะสินค้าสีน้ำเงิน)`

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 แทนครับ

### 2. ตัวอย่างที่ 2: คำนวณเปอร์เซ็นต์รายได้แต่ละช่องทาง (Percentage of Total)

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

**ผลลัพธ์:** `Internet: 26.74%, Reseller: 73.26%`

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

### 3. ตัวอย่างที่ 3: Context Transition ใน Calculated Column

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

**ผลลัพธ์:** `ลูกค้าที่มียอดซื้อรวมน้อยกว่า 2,500 = "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 ได้โดยตรง

### 4. ตัวอย่างที่ 4: ใช้หลาย Filter พร้อมกัน (Multiple Filters with AND Logic)

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

**ผลลัพธ์:** `ยอดขายสินค้าที่เป็นสีน้ำเงิน AND ราคามากกว่า 1,000`

CALCULATE รวม filter หลายตัวด้วย AND logic โดยอัตโนมัติ ข้อมูลต้องผ่านทุกเงื่อนไข (สีน้ำเงิน และ ราคามากกว่า 1,000) ถ้าต้องการใช้ OR logic ต้องเขียน Boolean expression ภายใน filter เดียว เช่น FILTER(Product, Product[Color] = "Blue" || Product[Color] = "Red") หรือถ้ามีเงื่อนไขซับซ้อนมาก แนะนำให้ใช้ VAR เก็บ intermediate result เพื่อให้โค้ดอ่านง่ายขึ้น

### 5. ตัวอย่างที่ 5: KEEPFILTERS สำหรับ Intersect Filter (ไม่ Override)

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

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

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

### 6. ตัวอย่างที่ 6: ใช้ VAR ใน CALCULATE เพื่อความชัดเจน (Multi-step Measure)

```excel
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
```

**ผลลัพธ์:** `0.15 (เติบโต 15% เมื่อเทียบกับปีก่อน)`

ตัวอย่างนี้แสดงการใช้ VAR...RETURN เพื่อแบ่งการคำนวณออกเป็นขั้นตอนชัดเจน ทำให้โค้ดอ่านง่ายและ debug ง่าย CurrentYearSales เก็บยอดขายปีปัจจุบัน LastYearSales ใช้ CALCULATE ร่วมกับ SAMEPERIODLASTYEAR เพื่อเปลี่ยน filter context ของวันที่ไปเป็นปีก่อน GrowthAmount และ GrowthPercent คำนวณการเติบโตเป็นจำนวนและเปอร์เซ็นต์ การใช้ VAR ทำให้แต่ละ variable ถูกคำนวณเพียงครั้งเดียว ช่วยประหยัดเวลาและทำให้ performance ดีขึ้น

## หมายเหตุเพิ่มเติม

⚠️ สำคัญมาก: Filter arguments ทั้งหมดถูกประเมินค่าใน original context ก่อนการเกิด context transition นี่เป็นพฤติกรรมที่สำคัญมากเมื่อมีการซ้อน CALCULATE หรือใช้ร่วมกับ iterator functions เช่น SUMX หรือ FILTER เพราะจะส่งผลต่อผลลัพธ์ที่ได้อย่างมาก

💡 Best Practice: ใช้ VAR...RETURN เพื่อแบ่งการคำนวณออกเป็นขั้นตอนชัดเจน ทำให้โค้ดอ่านง่าย debug ง่าย และ performance ดีขึ้น (เพราะ variable ถูกคำนวณเพียงครั้งเดียว)

💡 Modern DAX: ใช้ REMOVEFILTERS แทน ALL และใช้ KEEPFILTERS เมื่อต้องการ intersect filter ทำให้โค้ดอ่านง่ายและบำรุงรักษาง่ายขึ้น

🔍 Performance Tip: Boolean Filter เร็วกว่า FILTER(ALL(...)) ใน single-column filtering แต่ถ้าต้องการ filter หลาย column จากตารางเดียว ให้ใช้ FILTER(Product, ...) แทนการใช้ Boolean Filter หลายตัว

## คำถามที่พบบ่อย

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

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

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

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

**Q: ความแตกต่างระหว่าง 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 หลายตารางได้

**Q: เมื่อไหร่ควรใช้ 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

**Q: ทำไมต้องใช้ REMOVEFILTERS แทน ALL?**

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

## ฟังก์ชันที่เกี่ยวข้อง

- [CALCULATETABLE – Evaluate Table Expression ใน Modified Filter Context](https://www.thepexcel.com/functions/dax/filter/calculatetable-dax/)
- [FILTER – กรองตารางด้วยเงื่อนไขที่ซับซ้อน (Iterator Function)](https://www.thepexcel.com/functions/dax/filter/filter-dax/)
- [ALL – ลบ Filter หรือคืนค่าทุกแถว](https://www.thepexcel.com/functions/dax/filter/all-dax/)
- [ALLEXCEPT – ล้างตัวกรองทั้งหมดยกเว้นคอลัมน์ที่ระบุ](https://www.thepexcel.com/functions/dax/filter/allexcept-dax/)
- [REMOVEFILTERS – ลบตัวกรองออกจากตาราง/คอลัมน์](https://www.thepexcel.com/functions/dax/filter/removefilters-dax/)
- [KEEPFILTERS – คงตัวกรองเดิมไว้ (Preserve Filters)](https://www.thepexcel.com/functions/dax/filter/keepfilters-dax/)
- [DIVIDE – ฟังก์ชัน DAX](https://www.thepexcel.com/functions/dax/math-and-trig/divide-dax/)
- [SUMX – Iterator Function สำหรับคำนวณผลรวมแบบ Row-by-Row ใน DAX](https://www.thepexcel.com/functions/dax/aggregation/sumx-dax/)
- [USERELATIONSHIP – เลือกใช้ relationship ที่ไม่ใช่ active](https://www.thepexcel.com/functions/dax/relationship/userelationship-dax/)
- [CROSSFILTER – กำหนดทิศทางการกรองข้ามความสัมพันธ์ชั่วคราว](https://www.thepexcel.com/functions/dax/relationship/crossfilter-dax/)
- [SAMEPERIODLASTYEAR – คืนช่วงเวลาเดียวกันของปีก่อนหน้า (Year-over-Year)](https://www.thepexcel.com/functions/dax/time-intelligence/sameperiodlastyear-dax/)
- [DATEADD – เลื่อนช่วงเวลาไปข้างหน้าหรือย้อนหลัง (Shift Dates)](https://www.thepexcel.com/functions/dax/time-intelligence/dateadd-dax/)
- [TOTALYTD – ยอดสะสมตั้งแต่ต้นปี (Year-to-Date)](https://www.thepexcel.com/functions/dax/time-intelligence/totalytd-dax/)
- [VALUES – ดึงค่าที่ไม่ซ้ำจากคอลัมน์ (รวม Blank จากข้อผิดพลาดความสัมพันธ์)](https://www.thepexcel.com/functions/dax/table-manipulation/values-dax/)
- [DISTINCT – ดึงรายการที่ไม่ซ้ำ (Unique Values) พร้อมหลีกหนีค่า Blank Row](https://www.thepexcel.com/functions/dax/table-manipulation/distinct-dax/)
- [FILTERS – คืนค่าตารางของค่าที่ถูกกรองโดยตรง](https://www.thepexcel.com/functions/dax/table-manipulation/filters-dax/)
- [CALENDAR – สร้างตารางวันที่โดยอัตโนมัติระหว่างวันเริ่มต้นและสิ้นสุด](https://www.thepexcel.com/functions/dax/date-and-time/calendar-dax/)

## แหล่งข้อมูลเพิ่มเติม

- [Microsoft Learn: CALCULATE function (DAX)](https://learn.microsoft.com/en-us/dax/calculate-function-dax) _(documentation)_
- [DAX Guide: CALCULATE](https://dax.guide/calculate/) _(documentation)_
- [SQLBI: Context Transition and Filters in CALCULATE](https://www.sqlbi.com/articles/context-transition-and-filters-in-calculate/) _(article)_
- [SQLBI: Understanding Context Transition in DAX](https://www.sqlbi.com/articles/understanding-context-transition-in-dax/) _(article)_
- [SQLBI: Context Transition in DAX Explained Visually](https://www.sqlbi.com/articles/context-transition-in-dax-explained-visually/) _(article)_
- [SQLBI: Filter Context in DAX Explained Visually](https://www.sqlbi.com/articles/filter-context-in-dax-explained-visually/) _(article)_
- [Microsoft Learn: KEEPFILTERS function (DAX)](https://learn.microsoft.com/en-us/dax/keepfilters-function-dax) _(documentation)_

---

_Source: [https://www.thepexcel.com/functions/dax/filter/calculate-dax/](https://www.thepexcel.com/functions/dax/filter/calculate-dax/)_
