---
title: GENERATEALL – สร้าง Cartesian Product แบบคงแถวว่าง
url: https://www.thepexcel.com/functions/dax/table-manipulation/generateall-dax/
type: function-explainer
program: DAX
syntax: "GENERATEALL(<table1>, <table2>)"
date: 2025-12-13
updated: 2025-12-25
scores:
  popularity: 4
  difficulty: 6
  usefulness: 4
---

# GENERATEALL – สร้าง Cartesian Product แบบคงแถวว่าง

> GENERATEALL วนแถวของตาราง 1 แล้วสร้าง Cartesian product กับผลลัพธ์ของตาราง 2 โดยคงแถวที่ไม่มีข้อมูลย

## คำอธิบาย

GENERATEALL วนแถวของตาราง 1 แล้วสร้าง Cartesian product กับผลลัพธ์ของตาราง 2 โดยคงแถวที่ไม่มีข้อมูลย่อย ต่างจาก GENERATE ตรงที่ไม่ตัดแถวหลักออก

## Syntax

```excel
GENERATEALL(&lt;table1&gt;, &lt;table2&gt;)
```

**Variant**

```excel
GENERATEALL(&lt;Table1&gt;, &lt;Table2&gt;)
```

รวมผลของ Table2 ต่อแถวของ Table1 โดยคงผลลัพธ์ในกรณีที่ Table2 ไม่มีแถวตามพฤติกรรมของ GENERATEALL

## Arguments

| Name | Required | Type | Default | Description |
| --- | --- | --- | --- | --- |
| table1 | Yes | table |  | ตารางหลักที่จะวนแถวทีละแถว ต้องเป็นนิพจน์ DAX ที่คืนตาราง |
| table2 | Yes | table |  | นิพจน์ตารางที่ประเมินแยกต่อแถวของ table1 ใน row context ของแถวปัจจุบัน อาจคืนผลว่าง (ไม่มีแถว) แต่จะถูกเก็บไว้ในผลลัพธ์ final |

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

### คงแถวของตารางหลักแม้ตารางย่อยไม่มีแถว

เหมาะกับงานตรวจสอบ/การวิเคราะห์ที่ไม่อยากให้แถวหายไปเมื่อไม่มีข้อมูลย่อย

_เหมาะกับ:_ keep-parents

### สร้างตารางขยายเพื่อทำรายงานความครอบคลุม

เช่น ตรวจว่ารายการไหนไม่มีข้อมูลย่อย

_เหมาะกับ:_ coverage-report

## ตัวอย่าง

### 1. ตัวอย่างที่ 1: คงสินค้าที่ไม่มีรายการขาย

```excel
Product Sales Coverage =
GENERATEALL(
    Products,
    FILTER(Sales, Sales[ProductID] = Products[ProductID])
)
```

**ผลลัพธ์:** `ตารางที่มีสินค้าทั้งหมด รวมสินค้าที่ไม่มี Sales record`

ใช้ GENERATEALL กับ FILTER เพื่อขยายแต่ละสินค้าไปกับรายการขายที่ตรงกัน ถ้าสินค้าไม่มีขายเลย GENERATEALL ยังคงให้ผลลัพธ์ 1 แถวของสินค้านั้นโดยมี null columns สำหรับ Sales ช่วยให้เห็นสินค้าใดขายไม่ออก

### 2. ตัวอย่างที่ 2: เปรียบเทียบกับ GENERATE

```excel
GENERATE Example =
GENERATE(
    Products,
    FILTER(Sales, Sales[ProductID] = Products[ProductID])
)
```

**ผลลัพธ์:** `ตารางเฉพาะสินค้าที่มี Sales record (ตัดสินค้าที่ไม่มีขายออก)`

GENERATE และ GENERATEALL มี syntax เหมือนกัน แต่ถ้า FILTER ไม่มีแถวสำหรับสินค้าใด GENERATE จะไม่รวมสินค้านั้นในผลลัพธ์ ส่วน GENERATEALL จะรวมไว้ คำเลือกขึ้นอยู่ว่าต้องการเห็นแถวว่างหรือไม่

### 3. ตัวอย่างที่ 3: ขยาย Date Range แบบเก็บช่วงว่าง

```excel
Date Range Expansion =
GENERATEALL(
    DISTINCT(Orders[OrderDate]),
    FILTER(
        CALENDAR([OrderDate], DATE(2025, 12, 31)),
        [Date] >= Orders[OrderDate]
    )
)
```

**ผลลัพธ์:** `ตารางขยายที่มีทุกวันตั้งแต่ Order Date ไป ปลายปี แม้ไม่มีรายการ`

สร้างชุดวันที่สำหรับแต่ละ order date ถึง 31 Dec 2025 แม้บางวันไม่มีข้อมูลธุรกรรม GENERATEALL เก็บไว้ ใช้สำหรับสร้างรายงาน timeline หรือ Gantt chart

### 4. ตัวอย่างที่ 4: ใช้ VAR เพื่อ debug ผลลัพธ์ไม่มีข้อมูล

```excel
Product Analysis =
VAR ProductsSummary = ADDCOLUMNS(
    Products,
    "Sales Count", COUNTROWS(FILTER(Sales, Sales[ProductID] = Products[ProductID]))
)
RETURN
GENERATEALL(
    ProductsSummary,
    IF(
        [Sales Count] > 0,
        FILTER(Sales, Sales[ProductID] = Products[ProductID]),
        BLANK()
    )
)
```

**ผลลัพธ์:** `ตารางขยายที่มีผลลัพธ์เฉพาะสินค้าที่มีขาย แต่คงโครงสร้างเดียว`

ขั้นแรก สร้าง ProductsSummary ด้วย ADDCOLUMNS บวกจำนวนขายต่อสินค้า แล้ว GENERATEALL ใช้ IF เพื่อตัดสินใจว่าประเมิน FILTER หรือ BLANK ตามจำนวนขาย ตัวอย่างนี้แสดงการ combine logic ซับซ้อนในลำดับชั้น table generation

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

- ผมแนะนำให้คิดถึง outer apply vs cross apply ถ้าคิดว่าต้อง keep all rows from left table แบบ SQL LEFT JOIN ให้ใช้ GENERATEALL แต่ถ้า INNER JOIN ก็ GENERATE พอ

- ระวังจำนวนแถวผลลัพธ์ GENERATEALL อาจขยายตารางขึ้นไปเป็นจำนวนมากหากแต่ละแถวของ table1 match กับหลายแถว table2 ทดสอบกับ small dataset ก่อน

- ส่วนตัวผมชอบใช้ GENERATEALL + ISBLANK หรือ COALESCE ในการทำ conditional measure เพื่อแยกวิเคราะห์แถวว่างกับแถวที่มีข้อมูล

- ถ้า table2 มีโอกาสว่างบ่อยๆ อาจลองใช้ ADDCOLUMNS + IF ก่อนเพื่อเปิดวิวแบบชัด ๆ ว่าข้อมูลไหนขาด

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

**Q: GENERATEALL ต่างจาก GENERATE เมื่อไรถึงเห็นผลชัด?**

เวลา table2 ให้ผลว่าง (ไม่มีแถว) สำหรับบางแถวของ table1 GENERATE ตัดแถวเหล่านั้นออก แต่ GENERATEALL เก็บไว้พร้อม null values ที่เหมาะสำหรับการตรวจสอบครบถ้วน

**Q: GENERATEALL จะช่วยตรวจหา missing values ได้ไหม?**

ได้ ผม มักใช้ GENERATEALL รวมกับ COUNTROWS หรือ COALESCE เพื่อตรวจว่าแถวไหนไม่มีข้อมูลจาก table2 ลองแล้วจะเห็นความ valuable ในการ audit

**Q: GENERATEALL vs CROSSJOIN ต่างกันอย่างไร?**

CROSSJOIN สร้าง Cartesian product ธรรมชาติ (ทุกคู่) GENERATEALL วนแถว table1 แล้วประเมิน table2 ต่อแถว ซึ่ง table2 อาจขึ้นกับบริบท (row context) ของ table1 GENERATEALL เหมาะกว่าเมื่อต้องการ conditional logic

**Q: ตัวอย่างจริงคำใดที่ GENERATEALL มีประโยชน์เหมาะสุด?**

ผมเจอบ่อยที่สุดคือ hierarchical expand - เช่น Region-Product matrix ต้องเห็นคู่ไหนไม่มี data ถ้าใช้ GENERATE มันตัดคู่เหล่านั้นออก แต่ GENERATEALL เก็บไว้เพื่อให้รายงาน audit ครบถ้วน

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

- generate
- [FILTER – กรองตารางด้วยเงื่อนไขที่ซับซ้อน (Iterator Function)](https://www.thepexcel.com/functions/dax/filter/filter-dax/)
- crossjoin
- addcolumns
- countrows
- summarize

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

- [Microsoft Learn: GENERATEALL](https://learn.microsoft.com/en-us/dax/generateall-function-dax) _(official)_
- [DAX.guide: GENERATEALL](https://dax.guide/generateall/) _(guide)_
- [SQLBI: GENERATE and GENERATEALL](https://www.sqlbi.com/) _(guide)_

---

_Source: [https://www.thepexcel.com/functions/dax/table-manipulation/generateall-dax/](https://www.thepexcel.com/functions/dax/table-manipulation/generateall-dax/)_
