---
title: "คัมภีร์สรุป M Code ใน Power Query ตอนที่ 3:  เจาะลึกเรื่องของ List"
url: https://www.thepexcel.com/m-code-power-query-03-list/
type: post
date: 2020-06-24
updated: 2025-12-22
author: Sira Ekabut
categories: [Power Query]
tags: [List.Union, Table.ColumnNames, List.Difference, Table.TransformColumnTypes, List.FindText, List.Accumulate, List.Repeat, List.Select, List.Zip, List.Sort, List.ContainsAny, List.Transform, List.Intersect, Text.Combine, List.PositionOfAny, m code, Text.Split, List.Range, List, List.Max, List.ReplaceRange, List.Count, List.Distinct, Number.ToText, List.Generate]
---

# คัมภีร์สรุป M Code ใน Power Query ตอนที่ 3:  เจาะลึกเรื่องของ List

ในตอนนี้เราจะมาเรียนรู้เรื่องเกี่ยวกับข้อมูลประเภท List กันให้ลึกซึ้งมากขึ้นครับ ซึ่งเดี๋ยวเพื่อนๆ จะได้เห็นว่า พอเราเริ่มเข้าใจการทำงานของฟังก์ชัน List ต่างๆ ในตอนนี้แล้ว ฟังก์ชันกลุ่มอื่นหลายๆ ตัวก็จะมีชื่อคล้ายๆ กันนี่แหละ ทำให้เราจะพอเดาการใช้งานได้ไปด้วย ยิงปืนนัดเดียวได้นกสองตัวเลย!

 

ถ้าเราไปค้นคว้าข้อมูลเอกสารเกี่ยวกับ M Code เองจะพบว่า [M Language มันมีฟังก์ชันให้เลือกเยอะมากๆๆ](https://docs.microsoft.com/en-us/powerquery-m/power-query-m-function-reference) คือเยอะจนเลือกไม่ถูก ผมคิดว่าฟังก์ชันพื้นฐานกลุ่มที่ควรรู้จักให้ดียิ่งขึ้นนั่นก็คือ List เป็นเพราะว่ามันมักถูกใช้เป็นองค์ประกอบสำคัญในฟังก์ชันอื่นๆ ด้วย ดังนั้นใครที่สามารถจัดการเรื่อง List ได้ดี ก็จะพลิกแพลงทำเรื่องต่างๆ ได้เยอะขึ้น

 

## List เป็นองค์ประกอบสำคัญในหลายๆ ฟังก์ชัน

 

เวลาเราไปดูฟังก์ชันที่มีความสามารถเจ๋งๆ ทำเรื่องที่เราต้องการทีไร มักจะมี input หรือ output เป็น List ทุกทีสิน่า!

 

#### เวลาใช้ฟังก์ชัน Text.Split ก็ได้ผลเป็น List

 

```markdown
Text.Split(text as text, separator as text) as list
```

 

#### เวลาจะรวม Text หลายๆ อันเป็นก้อนเดียว ด้วย Text.Combine ก็ต้องใช้ List

 

```markdown
Text.Combine(texts as list, optional separator as nullable text) as text
```

 

#### เวลาดึงข้อมูลหัวตารางจาก Table มาจัดการต่อ ก็ออกมาเป็น List

 

```markdown
Table.ColumnNames(table as table) as list
```

 

#### การจะจัดการกับประเภทข้อมูลของหัวตาราง Table ก็ต้องใช้ List

 

```markdown
Table.TransformColumnTypes(table as table, typeTransformations as list, optional culture as nullable text) as table
```

 

#### การจะจัดการกับ Text ให้เหลือเฉพาะอักขระที่อยากได้ ก็ต้องใช้ List เป็นส่วนประกอบ

 

Text.Select(**text** as nullable text, **selectChars** as any) as nullable text // **selectChars** สามารถใส่เป็น List ได้ว่าให้เก็บอักขระไหนเอาไว้บ้าง (ในชีวิตจริง ใครจะไปใส่ตัวเดียว)

 

#### อยากจะ Filter ข้อมูลในคอลัมน์ของตาราง ให้เป็น Data เฉพาะรายการที่กำหนด

 

แบบนี้ก็สามารถใช้ List.Contains มาช่วยเป็นเงื่อนไขในการ Filter ของ Table.SelectRowsได้ (เดี๋ยวมาดูตัวอย่างกัน) ดังนั้นจะเห็นว่า List นั้นเป็นอะไรที่มีประโยชน์มากๆ และน่าเรียนรู้สุดๆ

 

ซึ่งเดี๋ยวเราจะมาเรียนเรื่องเหล่านี้กันในบทความต่อไป แต่ในตอนนี้เราจะมาปูพื้นฐานเรื่อง List กันให้แน่นขึ้นก่อน

 

## ทบทวนสิ่งสำคัญเกี่ยวกับ List

 

มีหลายเรื่องที่เราได้เรียนรู้เกี่ยวกับ List ไปแล้ว เดี๋ยวผมจะทวนให้เร็วๆ พร้อมกับตัวอย่างที่เยอะขึ้น

 

### สร้าง List ต่อเนื่องด้วย .. (จุดจุด)

 

```
{1..100} // สร้าง List เลข 1-100
{"a".."z"} // สร้าง List a-z
{"A".."Z"} // สร้าง List A-Z
{"a".."e","x".."z"} // สร้าง List a-e ต่อด้วย x-z
```

 

มีตัวที่น่าสนใจ คือ

 

```
{"A".."z"} // สร้าง List A-z แต่ได้อักขระ 6 ตัวที่อยู่ระหว่าง Z กับ a มาด้วย ซึ่งตัวพิมพ์ใหญ่มาก่อนพิมพ์เล็กนะ
```

 ![1](https://www.thepexcel.com/wp-content/uploads/2020/06/List-001.png) 

**ถ้าเป็นภาษาไทย** ผมแนะนำให้สร้าง {“ก”..”๙”} ไปเลย ดีกว่า {“ก”..”ฮ”} ที่ขาดพวกสระไป ทำให้ดูไม่จืดเลยครับ   
 // ใช้ ก – เลข 9 ไทย ไปเลย จะได้สระมาด้วยครบถ้วนครับ

 ![2](https://www.thepexcel.com/wp-content/uploads/2020/06/mcode-04-001.jpg) 

### รวม List เข้าด้วยกันด้วย &

 

```
= {"a".."d"}&{1..5}&{"Sira","Ekabut"}
```

 ![3](https://www.thepexcel.com/wp-content/uploads/2020/06/text-select-004x.png) 

### อ้างอิงข้อมูลใน List ด้วย ชื่อlist{index}

 

สมมติผมสร้าง List ชื่อ SampleList ให้มีค่า {1,2,-5,8,4,2,”a”,”b”,”A”}

 

```
SampleList{0} // จะได้เลข 1
SampleList{1}  // จะได้เลข 2
SampleList{0..2}  // แบบนี้มันไม่ยอมนะ เราต้องใช้ฟังก์ชันมาช่วยแทนครับ
```

 

**ตัวอย่างวิธีเขียน M Code ใน Advanced Editor ให้สามารถแก้ใน Formula Bar ได้ง่ายๆ**

 

```
let 
    SampleList =  {1,2,-5,8,4,2,"a","b","A"},
    Result=SampleList{0}
in
    Result
```

 

ถ้าทำแบบนี้เราจะสามารถไปแก้สูตรใน Formula Bar ได้เลย

 ![4](https://www.thepexcel.com/wp-content/uploads/2020/11/List-002.png) 

## ฟังก์ชัน List ที่น่าจะใช้บ่อย

 

นอกจากคำสั่งพื้นฐานเหล่านี้แล้ว Power Query ก็มี[ฟังก์ชันเกี่ยวกับ List](https://docs.microsoft.com/en-us/powerquery-m/list-functions)ให้เลือกอีกมหาศาลเลย แต่ตัวที่ผมคิดว่าสำคัญมีดังนี้

 

### List.Count : นับจำนวน item ใน List

 

```
List.Count(list as list) as number

=List.Count(SampleList)  // ได้เลข 9  แปลว่ามี 9 item (ซึ่งมี index 0-8)
=List.Count({1,2,-5,8,4,2,"a","b","A"})  // เดี๋ยวผมจะเขียนแบบ Hardcode ค่าแบบนี้เลย เพื่อนๆ จะได้ไม่ต้องไปหาว่า SampleList คืออะไรเนอะ
```

 

### List.Sort : เรียงลำดับข้อมูลใน List

 

```
List.Sort(list as list, optional comparisonCriteria as any) as list

//comparisonCriteria สามารถใส่เป็น Order.Descending, Order.Ascending ได้ 
//ถ้าไม่ใส่คือ ascending คือเรียงน้อยไปมาก

= List.Sort({1,2,-5,8,4,2,"a","b","A"}) // ได้ {-5,1,2,2,4,8,"A","a","b"}
= List.Sort({1,2,-5,8,4,2,"a","b","A"},Order.Descending) // ได้ {"b","a","A",8,4,2,2,1,-5}
```

 

### List.Max : เอาค่ามากสุด ใน List

 

```
List.Max(list as list, optional default as any, optional comparisonCriteria as any, optional includeNulls as nullable logical) as any

=List.Max({1,2,-5,8,4,2,"a","b","A"})   // ได้ "b" (ได้ผลเหมือนเอาตัวแรกสุดหลังจาก Sort มากไปน้อย)
```

 

### List.Transform : ดัดแปลงข้อมูลแต่ละ item ใน List

 

```
List.Transform(list as list, transform as function) as list

=List.Transform({1,2,-5,8,4,2} , each _ *10) // ได้ {10,20,-50,80,40,20}  โดยที่ _ แทน item แต่ละตัว
=List.Transform({1,2,-5,8,4,2} , each Number.ToText(_)) // เปลี่ยนจากเลขเป็น text ได้ {"1","2","-5","8","4","2"}
```

 

### List.Distinct : กำจัดตัวซ้ำใน List ออกให้เหลือแต่ตัวไม่ซ้ำ

 

```
List.Distinct(list as list, optional equationCriteria as any) as list

= List.Distinct({1,2,-5,8,4,2,"a","b","A"}) // ได้ {1,2,-5,8,4,"a","b","A"}   เลข 2 ตัวที่อยู่อันหลังหายไป
= List.Distinct({1,2,-5,8,4,2,"a","b","A"},Comparer.OrdinalIgnoreCase) // ปรับให้เป็น Non Case Sensitive ได้ {1,2,-5,8,4,"a","b"} 2 หลัง กับ A หายไป เพราะ A ถือว่าซ้ำกับ a ถ้า IgnoreCase แล้ว
```

 

## ฟังก์ชันที่ใช้คัดเลือกข้อมูลบางส่วนจาก List

 

### List.Select : คัดกรองให้เหลือเฉพาะ item ที่ตรงตามเงื่อนไข

 

```
List.Select(list as list, selection as function) as list

=List.Select({1,2,-5,8,4,2}, each _ > 3)   // ได้ {8,4} เพราะว่า _ แทน item แต่ละตัว 
```

 

### List.FindText : คัดมาเฉพาะ item ที่ contain หรือมี text ที่ต้องการอยู่

 

```
List.FindText(list as list, text as text) as list

= List.FindText({"batman","superman","thor","ironman"},"man")   // ได้ {"batman","superman","ironman"}
```

 

### List.Intersect : เลือกเฉพาะส่วนที่ซ้ำกันในทุก List ที่ระบุ

 

```
List.Intersect(lists as list, optional equationCriteria as any) as list
// lists ต้องใส่ List ใน List อีกชั้นนึง

=List.Intersect({ {1,2,-5,8,4,2,"a","b","A"} , {1..9}   })   // ได้ {1,2,8,4}
=List.Intersect({ {1,2,-5,8,4,2,"a","b","A"} , {1..9},{3..15}  }) // ได้ {8,4}
=List.Intersect({ {1,2,-5,8,4,2,"a","b","A"} , {"a".."z"} }) // ได้ {"a","b"}
=List.Intersect({ {1,2,-5,8,4,2,"a","b","A"} , {"A".."Z"} }) // ได้ {"A"}
=List.Intersect({ {1,2,-5,8,4,2,"a","b","A"} , {"A".."Z"} },Comparer.OrdinalIgnoreCase) // ได้ {"a","b"}
```

 

### List.Union : เอา List มารวมกัน (ให้ผลเหมือน list1 รวม list2 ที่หัก List.Intersect(list1,list2) )

 

```
List.Union(lists as list, optional equationCriteria as any) as list
// lists ต้องใส่ List ใน List อีกชั้นนึง

=List.Union({ {1,2,-5,8,4,2,"a","b","A"} , {1..9} })   // ได้ {1,2,-5,8,4,2,"a","b","A",3,5,6,7,9}
```

 

### List.Difference : เลือกเอาข้อมูลใน list1 ตั้งแล้วลบข้อมูลจากใน list2 ออกไป (ตัวซ้ำอาจยังอยู่)

 

```
List.Difference(list1 as list, list2 as list, optional equationCriteria as any) as list

= List.Difference({1,2,-5,8,4,2,"a","b","A"} , {1..9})      // ได้ { -5, 2,"a","b","A" }  ซึ่งมี 2 โผล่มาเพราะมีซ้ำ
= List.Difference({1,2,-5,8,4,"a","b","A"} , {1..9})     // ได้ { -5, "a","b","A" }
= List.Difference({1,2,-5,8,4,2,"a","b","A"} , {1..9,2,2,2,2})     // ได้ { -5, "a","b","A" }
```

 

### List.Range : ดึงข้อมูล จาก List ด้วยลำดับ item ที่ต้องการ

 

```
List.Range(list as list, offset as number, optional count as nullable number) as list

List.Range(ชื่อlist, index เริ่มต้น, จะเอากี่ตัว ถ้าไม่ใส่คือเอาหมด) as list
=List.Range({1,2,-5,8,4,2,"a","b","A"} , 2, 3)    // จะได้ {-5,8,4}  เพราะ -5 คือ index ที่ 2
```

 

### List.ReplaceRange : แทนที่ข้อมูลจาก List ในลำดับ item ที่ต้องการ ด้วยข้อมูลอีก List นึง

 

```
List.ReplaceRange(list as list, index as number, count as number, replaceWith as list) as list

=List.ReplaceRange({1,2,-5,8,4,2,"a","b","A"} , 2, 3,{9,8,7,6}) // จะได้ {1,2,9,8,7,6,2,"a","b","A"}
=List.ReplaceRange({1,2,-5,8,4,2,"a","b","A"}, 2, 3,{}) // จะได้ {1,2,2,"a","b","A"} ซึ่ง {-5,8,4} ถูกแทนด้วยว่าง
=List.ReplaceRange({1,2,-5,8,4,2,"a","b","A"}, 6, 99,{}) // จะ error เพราะใส่เผื่อมากไปไม่ได้
= List.ReplaceRange({1,2,-5,8,4,2,"a","b","A"}, 6, List.Count(SampleList)-6,{}) // จะได้ {1,2,-5,8,4,2}
```

 

## ฟังก์ชันที่เอาไว้ตรวจสอบข้อมูลใน List

 

### List.PositionOfAny : หาตำแหน่งของข้อมูลที่ต้องการ ว่าอยู่เป็น item ที่เท่าไหร่ใน List (เอาตัวแรกที่เจอ)

 

```
List.PositionOfAny(list as list, values as list, optional occurrence as nullable number, optional equationCriteria as any) as any

=List.PositionOfAny({1,2,-5,8,4,2,"a","b","A"},{99,8,"b"})  //ได้ 3 เพราะเจอ 8 ที่ index 3
```

 

### List.ContainsAny : ใช้เช็คว่าใน List มีข้อมูล value (list) ที่กำหนดอยู่หรือไม่ โดยให้ผลเป็น true/false

 

```
List.ContainsAny(list as list, values as list, optional equationCriteria as any) as logical

=List.ContainsAny({1,2,-5,8,4,2,"a","b","A"}, {4})   // ได้ true
=List.ContainsAny({1,2,-5,8,4,2,"a","b","A"}, {6})   // ได้ false
=List.ContainsAny({1,2,-5,8,4,2,"a","b","A"}, {6,4})  // ได้ true
```

 

## ฟังก์ชันที่เอาไว้สร้าง List ใหม่จากตัวเดิม

 

### List.Repeat : สร้าง List แบบเดิมขึ้นหลายๆ รอบ

 

```
List.Repeat(list as list, count as number) as list

=List.Repeat({"a","b","A"} , 2)  // ได้ {"a","b","A","a","b","A"}
```

 

### List.Zip : รวบ item ในตำแหน่งเดียวกันของทุก List เข้าด้วยกันเป็น List ซ้อนใน List

 

```
List.Zip(lists as list) as list

lists นั้นต้องใส่เป็น List ซ้อน List
= List.Zip(   {   {1,2,-5,8,4,2,"a","b","A"} ,{1..5}   }  ) 
// จะได้ { {1,1} , {2,2} ,{-5,3} ,{8,4} ,{4,5} , {2,null} ,{"a",null} , {"b",null} , {"A",null} }
```

 

## ฟังก์ชัน List แบบ Advance

 

### List.Generate : สร้าง List ขึ้นมาด้วยเงื่อนไขที่ต้องการ

 

```
List.Generate(initial as function, condition as function, next as function, optional selector as nullable function) as list
```

 

**สังเกตได้ว่า input ทุกตัวเป็นฟังก์ชันหมดเลย แว๊ก!!** ตัวนี้เป็นตัวที่เริ่มยากจริงๆ แล้ว ซึ่ง**เราจะใช้ each และ _ เป็นตัวอ้างอิง**

 
- **initial** : ค่าเริ่มต้น ซึ่งจะเป็น value ตัวแรกของ List
    - มักจะใส่ในรูปแบบของ ()=> ค่าที่ต้องการ
- **condition** : เงื่อนไขในการสร้าง List ซึ่งจะสร้างไปเรื่อยๆ จนกว่าเงื่อนไขนี้จะเป็นเท็จแล้วจะหยุดสร้าง
- **next** : วิธีการเปลี่ยนค่าเมื่อต้องการเปลี่ยนเป็น value ตัวถัดไป
- **selector** : จะแสดงผลลัพธ์แต่ละตัวออกมาในลักษณะไหน

 

#### ตัวอย่างแบบง่าย

 

```
= List.Generate(()=>2, each _ <= 5, each _ + 1)
//จะสร้าง List ที่มีค่าเริ่มต้นที่ 2 และเพิ่มทีละ 1 ไปเรื่อยๆ จนสุดท้ายค่าต้องไม่เกิน 5 นั่นคือ ได้ค่า {2,3,4,5}
```

 

```
= List.Generate(()=>10, each _ < 15, each _ + 2)
//จะสร้าง List ที่มีค่าเริ่มที่ 10 และเพิ่มทีละ 2 ไปเรื่อยๆ จนสุดท้ายค่าต้องน้อยกว่า 15 นั่นคือ ได้ค่า {10,12,14}
```

 

```
= List.Generate(()=>10, each _ > 0, each _ - 1)
//จะสร้าง List ที่มีค่าเริ่มที่ 10 และลดลงทีละ 1 ไปเรื่อยๆ จนสุดท้ายค่าต้องมากกว่า 0 นั่นคือ ได้ค่า { 10,9,8 จนถึง..1}
```

 

```
= List.Generate(()=>10, each _ > 0, each _ - 1, each _*10)
//จะสร้าง List ที่มีค่าเริ่มที่ 10 และลดลงทีละ 1 ไปเรื่อยๆ จนสุดท้ายค่าต้องมากกว่า 0 นั่นคือ ได้ค่า 10,9,8 จนถึง..1 สุดท้ายใน selector บอกให้เอาแต่ละค่าไปคูณ 10 ก่อนแสดงผล ดังนั้นจะได้เป็น {100,90,80,...10}
```

 

#### ตัวอย่างแบบซับซ้อน (**โดยให้ item แต่ละรายการเป็น Record**)

 

```
= List.Generate(()=>[a=2,b=6,c=4], each [b] <= 20, each [a=[a] + 1,b=a*5])
```

 
- ค่าเริ่มต้นเป็นการสร้าง Record ที่มี 3 Field คือ a b c โดย a=2,b=6,c=4
- จากนั้นลำดับถัดไปให้ ค่าใน a เท่ากับค่า a เดิม+1 และ b=a*5 (สังเกตว่าไม่ได้เกี่ยวกับ b เริ่มต้นเลยก็ได้ และ c ก็หายไปได้เลย)
- ให้สร้าง List ไปเรื่อยๆ ตราบใดที่ b ไม่เกิน 20

 

พอกด ok จะได้ผลลัพธ์แบบนี้ ซึ่งออกมาเป็น List 3 item ที่แต่ละอันเป็น Record (เพราะถ้าสร้างตัวที่ 4 จะทำให้ b เกิน 20 ซึ่งผิดเงื่อนไข)

 

```
{ [a=2,b=6,c=4] , [a=3,b=15] , [a=4,b=20] }
```

 

ทีนี้หากเราระบุในส่วน selector เพิ่มว่าต้องการแค่ Field b ดังนี้

 

```
= List.Generate(()=>[a=2,b=6,c=4], each [b] <= 20, each [a=[a] + 1,b=a*5], each [b]) 
```

 

ผลลัพธ์ในแต่ละรายการจะถูก selector เลือกว่าให้แสดงค่าใน Field b เท่านั้น จะได้เป็นแบบนี้

 

```
{ 6, 15, 20 }
```

 

#### ตัวอย่าง : การสร้างเลข Fibonacci ด้วย List.Generate

 

เลข Fibonacci คือเลขที่เริ่มต้นด้วย 0 กับ 1 แล้วบวกกันกลายเป็นตัวถัดไป จากนั้นให้เอาผลลัพธ์บวกกับตัวก่อนหน้าไปเรื่อยๆ ก็จะได้ลำดับ Fibonacci เช่น 0,1,2,3,5,8,13,… ไปเรื่อยๆ

 

เราจะสามารถสร้าง list ของ Fibonacci ที่ไม่เกิน 50 ดังกล่าวได้ด้วย M Code ดังนี้

 

```
= List.Generate(
    ()=>[Previous=0, Current=1],
    each [Previous] + [Current] <= 50,
    each [
        Previous=[Current],
        Current=[Previous] + [Current]        
    ],
    each [Previous] + [Current])
```

 

อธิบายแต่ละส่วน

 
- **initial** : ค่าเริ่มต้น เป็น Record ที่มี 2 Field คือ Previous=0, Current=1
- **condition** : คือค่าใน Field Previous ปัจจุบัน รวมกับ Current ปัจจุบัน ต้องไม่เกิน 50
- **next** : ให้ Previousใหม่ คือ Current เดิม และ Current ใหม่ คือ Field Previous เดิม รวมกับ Current เดิม
- **selector** : แสดงผลลัพธ์ออกมาเป็น Field Previous ปัจจุบัน รวมกับ Current ปัจจุบัน

 

จะได้ออกมาเป็น list ที่มีค่าดังนี้

 

```
{1,2,3,5,8,13,21,34}

step1 : Previous=0 , Current=1 , selector แสดง Previous + Current =0+1=1
step2 : Prev =Curเดิม =1 , Cur =Prevเดิม+Curเดิม = 0+1=1 , selector แสดง Prev+ Cur =1+1=2
step3 : Prev =Curเดิม =1 , Cur =Prevเดิม+Curเดิม = 1+1=2 , selector แสดง Prev+ Cur =1+2=3
step4 : Prev =Curเดิม =2 , Cur =Prevเดิม+Curเดิม = 1+2=3 , selector แสดง Prev+ Cur =2+3=5
step5 : Prev =Curเดิม =3 , Cur =Prevเดิม+Curเดิม = 2+3=5 , selector แสดง Prev+ Cur =3+5=8
step6 : Prev =Curเดิม =5 , Cur =Prevเดิม+Curเดิม = 3+5=8 , selector แสดง Prev+ Cur =5+8=13
step7 : Prev =Curเดิม =8 , Cur =Prevเดิม+Curเดิม = 5+8=13 , selector แสดง Prev+ Cur =8+13=21
step8 : Prev =Curเดิม =13 , Cur =Prevเดิม+Curเดิม = 8+13=21 , selector แสดง Prev+ Cur =13+21=34
step8 : Prev =Curเดิม =13 , Cur =Prevเดิม+Curเดิม = 8+13=21 , selector แสดง Prev+ Cur =13+21=34
step8 : Prev =Curเดิม =21 , Cur =Prevเดิม+Curเดิม = 13+21=34 , selector แสดง Prev+ Cur =21+34=55
```

 

ซึ่งเลขจะจบแค่ 34 เพราะว่าตัวถัดไปจะเป็น 55 ซึ่งเกิน 50 แล้ว ทำให้ condition เป็นเท็จครับ

 

### List.Accumulate : รับค่าจาก List ที่กำหนด แล้วทำการ**คำนวณสะสมค่าใหม่เข้าไปในผลลัพธ์เดิมได้**

 

```
List.Accumulate(list as list, seed as any, accumulator as function) as any
```

 
- **list** คือ list ซึ่งมีข้อมูลที่เราต้องการจะทำการสะสมค่า (Accumulate)
- **seed** คือ ค่าตั้งต้น
- **accumulator** คือ ฟังก์ชันที่จะใช้กับการสะสมค่า

 

```
=List.Accumulate({1, 2, 3, 4}, 0, (state, current) => state + current)
```

 

เรามี **list** ที่จะทำการสะสม คือเลข 1-4

 

**seed** คือ ค่าเริ่มต้นใส่เป็น 0

 

**accumulator **คือ ฟังก์ชันที่รับ input 2 ตัว (ชื่ออะไรก็ได้) มาคำนวณตาม expression

 
- ซึ่ง **input ตัวแรก** (ในที่นี้คือ state) จะมี**ค่าเริ่มต้นเท่ากับ seed** ซึ่งคือ 0
- **ส่วน input ตัวที่สอง** (ในที่นี้คือ current) **จะมีตัวชี้ไปที่ list แต่ละรายการ** ซึ่งค่าเริ่มต้นเท่ากับ list ตัวแรกสุด นั่นคือเลข 1
- expression คือ state+current ก็จะได้ 0+1 =1 ซึ่งค่านี้จะ**ถูกสะสม**กลับไปยังค่า state อีกครั้ง

 

ต่อไป…

 
- state+current ก็จะได้ 1+2 =3 ซึ่งค่านี้จะ**ถูกสะสม**กลับไปยังค่า state อีกครั้ง
- state+current ก็จะได้ 3+3 =6 ซึ่งค่านี้จะ**ถูกสะสม**กลับไปยังค่า state อีกครั้ง
- สุดท้าย…  
  state+current ก็จะได้ 6+4 =10 ซึ่งค่านี้จะ**ถูกสะสม**กลับไปยังค่า state อีกครั้ง และจบการทำงาน

 

ผลลัพธ์จะออกมาได้ 10 ทันที (เอาทุกค่ามาบวกกัน)

 

ตัวนี้ผมมีตัวอย่างในหนังสือละเอียดกว่านี้ครับ เช่น ใช้ Replace ข้อความสะสมไปเรื่อยๆ

 

### สรุปจุดต่างระหว่าง List.Generate กับ List.Accumulate

 

ผมขอสรุปประเด็นสำคัญของทั้งสองฟังก์ชันไว้ดังนี้

 

|   |   |   |
| --- | --- | --- |
| **ประเด็น** | **List.Generate** | **List.Accumulate** |
| จุดประสงค์ | สร้าง List ขึ้นมา โดยกำหนดเงื่อนไขได้   item แต่ละตัวของ List จะเป็นอะไรก็ได้ | สะสมค่าโดยใช้ List มาช่วย ผลลัพธ์จะออกมาเป็น value อะไรก็ได้ |
| เงื่อนไขการวน Loop | ทำซ้ำจนกว่าเงื่อนไขใน Condition จะไม่จริง จะเลิกทำทันที | ทำซ้ำเท่ากับจำนวนค่าที่มีใน List เสมอ หยุดกลางคันไม่ได้ |
| คล้ายๆ กับอะไรในการเขียนโปรแกรมในภาษาอื่นๆ | Do While Loop | For Loop |

 

## ตอนต่อไป

 

ต่อไปจะเป็นการรวม[เทคนิค M Code ที่ใช้บ่อย](https://www.thepexcel.com/m-code-power-query-04-useful-tips/) โดยจะมีการประยุกต์ใช้ฟังก์ชันเจ๋งๆ ในการจัดการเรื่องต่างๆ เช่น คัดเลือกอักขระที่ต้องการ การจัดการหัวตารางแบบ Dynamic เป็นต้น

  

## สารบัญซีรีส์ M Code

---

_Source: [https://www.thepexcel.com/m-code-power-query-03-list/](https://www.thepexcel.com/m-code-power-query-03-list/)_
