Thep Excel

List.Generate – สร้าง List แบบวนลูปตามเงื่อนไข (Generator Pattern)

List.Generate เป็น generator function ที่สร้าง list โดยเริ่มจากค่าเริ่มต้น (initial) วนลูปตรวจสอบเงื่อนไข (condition) สร้างค่าถัดไป (next) และ transform ผลลัพธ์ด้วย selector (optional) ทำงานคล้าย while loop ในการเขียนโปรแกรม เหมาะสำหรับสร้างลำดับวันที่, pagination API, การคำนวณทบต้น และ pattern ซับซ้อนที่ List.Numbers ทำไม่ได้

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

By ThepExcel AI Agent
19 December 2025

Function Metrics


Popularity
6/10

Difficulty
9/10

Usefulness
8/10

Syntax & Arguments

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

Argument Type Required Default Description
initial function Yes Function ที่กำหนดค่าเริ่มต้น (candidate value แรก) เขียนในรูปแบบ () => value หรือ () => [record] สำหรับเก็บหลายค่า
condition function Yes Function ที่ตรวจสอบเงื่อนไข รับค่า candidate มาทดสอบ ถ้าผลลัพธ์เป็น true จะเพิ่มค่านั้นใน list และทำรอบต่อ ถ้า false จะหยุดทำงาน เขียนในรูปแบบ each expression (ใช้ _ อ้างอิงค่าปัจจุบัน)
next function Yes Function สำหรับสร้างค่า candidate ถัดไป รับค่าปัจจุบันที่ผ่านเงื่อนไขแล้ว แล้ว transform เป็นค่าถัดไป เขียนในรูปแบบ each expression (เช่น each _ + 1, each Date.AddDays(_, 1))
selector nullable function Optional null Function สำหรับ transform ค่าก่อนเพิ่มใน list ผลลัพธ์ ถ้าไม่ระบุจะใช้ค่าที่ generate ตรงๆ มีประโยชน์เมื่อใช้ record เก็บหลายค่า แต่ต้องการแสดงเฉพาะบางฟิลด์ เขียนในรูปแบบ each expression (เช่น each [fieldName])

How it works

สร้างลำดับวันที่แบบกำหนดเอง

สร้าง list ของวันที่ตั้งแต่วันเริ่มต้นถึงวันสิ้นสุด เพิ่มทีละ 1 วัน, ทุกสัปดาห์, ทุกเดือน หรือข้าม weekend ตาม logic ที่กำหนด

Pagination API Loop

เรียก REST API ที่มี pagination โดยวนลูปเรียกทีละหน้า (page 1, 2, 3…) จนกว่า response จะไม่มี nextPageToken หรือ hasMore = false

คำนวณดอกเบี้ยทบต้น

คำนวณเงินต้นบวกดอกเบี้ยทบต้นแต่ละงวด โดยเริ่มจากเงินต้น คำนวณดอกเบี้ยรอบถัดไปจากยอดรวมก่อนหน้า วนลูปจนครบจำนวนงวดที่กำหนด

สร้าง Fibonacci Sequence

สร้างลำดับ Fibonacci โดยใช้ record เก็บสองค่าก่อนหน้า (a, b) แล้วคำนวณค่าถัดไปเป็น a + b วนลูปจนถึงขนาดที่ต้องการ

Recursive Data Collection

ดึงข้อมูลแบบ recursive เช่น folder structure ที่มี subfolder หลายชั้น หรือ organization hierarchy ที่ต้อง drill down จนถึง leaf node

Examples

ตัวอย่างที่ 1: นับถอยหลังจาก 10 ถึง 1
let Countdown = List.Generate( () => 10, // เริ่มที่ 10 each _ > 0, // ทำต่อเมื่อ > 0 each _ - 1 // ลดค่าลงทีละ 1 ) in Countdown
เริ่มต้นด้วยค่า 10 จาก initial function, ตรวจสอบเงื่อนไข each _ > 0 (ค่าปัจจุบันมากกว่า 0) ถ้าเป็น true ก็เพิ่มค่านั้นใน list แล้วใช้ next function (each _ – 1) ลดค่าลงทีละ 1 วนลูปจนกว่าค่าจะเป็น 0 (เงื่อนไขเป็น false) จึงหยุดและได้ list ตัวเลข 10-1
Power Query Formula:

let
    Countdown = List.Generate(
        () => 10,              // เริ่มที่ 10
        each _ > 0,            // ทำต่อเมื่อ > 0
        each _ - 1             // ลดค่าลงทีละ 1
    )
in
    Countdown

Result:

{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}

ตัวอย่างที่ 2: สร้างลำดับวันที่ 1-7 มกราคม 2025
let StartDate = #date(2025, 1, 1), EndDate = #date(2025, 1, 7), DateList = List.Generate( () => StartDate, // เริ่มที่ 1 ม.ค. each _
สร้าง list ของวันที่โดยเริ่มจาก 1 มกราคม 2025 ใช้ Date.AddDays เพิ่มวันทีละ 1 ในแต่ละรอบ วนลูปจนกว่าวันที่จะเกิน 7 มกราคม 2025 วิธีนี้ใช้ได้กับช่วงวันที่ใดๆ เพียงเปลี่ยน StartDate และ EndDate
Power Query Formula:

let
    StartDate = #date(2025, 1, 1),
    EndDate = #date(2025, 1, 7),
    DateList = List.Generate(
        () => StartDate,                        // เริ่มที่ 1 ม.ค.
        each _ <= EndDate,                      // ทำต่อถ้า <= 7 ม.ค.
        each Date.AddDays(_, 1)                 // เพิ่มวันทีละ 1
    )
in
    DateList

Result:

{2025-01-01, 2025-01-02, 2025-01-03, 2025-01-04, 2025-01-05, 2025-01-06, 2025-01-07}

ตัวอย่างที่ 3: สร้างตัวเลขคี่ 1, 3, 5, 7, 9
let OddNumbers = List.Generate( () => 1, // เริ่มที่ 1 each _ < 10, // ทำต่อถ้า < 10 each _ + 2 // เพิ่มทีละ 2 ) in OddNumbers
สร้างลำดับตัวเลขคี่โดยเริ่มที่ 1 แล้วเพิ่มทีละ 2 (1+2=3, 3+2=5, …) วนลูปจนกว่าค่าจะถึง 9 (รอบถัดไปจะเป็น 11 ซึ่ง >= 10 จึงหยุด) ถ้าต้องการเลขคู่ให้เริ่มที่ 0 หรือ 2 แทน
Power Query Formula:

let
    OddNumbers = List.Generate(
        () => 1,               // เริ่มที่ 1
        each _ < 10,           // ทำต่อถ้า < 10
        each _ + 2             // เพิ่มทีละ 2
    )
in
    OddNumbers

Result:

{1, 3, 5, 7, 9}

ตัวอย่างที่ 4: ใช้ Record เก็บหลายค่า พร้อม Selector
let Result = List.Generate( () => [Counter = 1, DoubleValue = 2], // เริ่มด้วย record each [Counter]
ใช้ record structure เพื่อเก็บสองค่าพร้อมกัน: Counter สำหรับนับรอบ และ DoubleValue สำหรับค่าที่ต้องการจริง ในแต่ละรอบจะเพิ่ม Counter ขึ้น 1 และคำนวณ DoubleValue = Counter * 2 แต่เนื่องจากมี selector (each [DoubleValue]) จึงแสดงเฉพาะค่า DoubleValue ในผลลัพธ์ วิธีนี้เหมาะกับ logic ที่ซับซ้อนต้องเก็บ state หลายตัว
Power Query Formula:

let
    Result = List.Generate(
        () => [Counter = 1, DoubleValue = 2],     // เริ่มด้วย record
        each [Counter] <= 5,                      // ทำต่อถ้า Counter <= 5
        each [                                    // สร้าง record ถัดไป
            Counter = [Counter] + 1,
            DoubleValue = [Counter] * 2
        ],
        each [DoubleValue]                        // เลือกแสดงเฉพาะ DoubleValue
    )
in
    Result

Result:

{2, 4, 6, 8, 10}

ตัวอย่างที่ 5: Fibonacci Sequence (10 ตัวแรก)
let Fibonacci = List.Generate( () => [a = 0, b = 1, result = 0], // เริ่มด้วย 0, 1 each [result] < 10, // สร้าง 10 ตัวแรก (นับด้วย result) each [ // คำนวณค่าถัด…
สร้าง Fibonacci sequence โดยใช้ record เก็บสามค่า: a (ค่าปัจจุบัน), b (ค่าถัดไป), result (ตัวนับ) ในแต่ละรอบจะเลื่อนค่า a = b และคำนวณ b ใหม่จาก a + b ตัวนับ result ใช้ควบคุมจำนวนรอบ selector (each [a]) เลือกแสดงเฉพาะค่า a ซึ่งเป็นลำดับ Fibonacci ที่ต้องการ
Power Query Formula:

let
    Fibonacci = List.Generate(
        () => [a = 0, b = 1, result = 0],         // เริ่มด้วย 0, 1
        each [result] < 10,                       // สร้าง 10 ตัวแรก (นับด้วย result)
        each [                                    // คำนวณค่าถัดไป
            a = [b],
            b = [a] + [b],
            result = [result] + 1
        ],
        each [a]                                  // เลือกแสดงค่า a
    )
in
    Fibonacci

Result:

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

ตัวอย่างที่ 6: API Pagination Pattern (จำลอง)
let AllPages = List.Generate( () => [PageNumber = 1, HasMore = true], // เริ่มหน้า 1 each [HasMore] = true, // ทำต่อถ้ายังมีหน้าถัดไป each [ // จำลองการเรียก AP…
จำลอง pattern การเรียก API แบบ pagination โดยใช้ record เก็บ PageNumber (หมายเลขหน้า) และ HasMore (มีหน้าถัดไปหรือไม่) ในการใช้งานจริงจะเรียก Web.Contents ใน next function และตรวจสอบ response ว่ามี nextPageToken หรือ hasMore field หรือไม่ ถ้ามีก็ทำต่อ ถ้าไม่มีก็หยุด ตัวอย่างนี้จำลองโดยให้หยุดที่หน้า 5
Power Query Formula:

let
    AllPages = List.Generate(
        () => [PageNumber = 1, HasMore = true],   // เริ่มหน้า 1
        each [HasMore] = true,                    // ทำต่อถ้ายังมีหน้าถัดไป
        each [                                    // จำลองการเรียก API
            PageNumber = [PageNumber] + 1,
            HasMore = [PageNumber] < 5            // มี 5 หน้าทั้งหมด
        ],
        each "Page " & Text.From([PageNumber])   // สร้าง label
    )
in
    AllPages

Result:

{"Page 1", "Page 2", "Page 3", "Page 4", "Page 5"}

FAQs

List.Generate ต่างจาก List.Numbers อย่างไร?

List.Numbers สร้างลำดับตัวเลขตาม pattern คงที่ (start, count, increment) เหมาะกับลำดับเลขเรียงง่ายๆ เช่น {1, 2, 3} หรือ {0, 10, 20, 30} แต่ List.Generate ให้คุณควบคุม logic การสร้างค่าได้เองทั้งหมดผ่าน function parameters ทำให้สร้าง pattern ซับซ้อนได้ เช่น Fibonacci, compound growth, หรือ conditional sequence ที่ List.Numbers ทำไม่ได้

ทำไม List.Generate ถึงต้องใช้ () => value แทนที่จะเป็น value ตรงๆ?

เพราะ List.Generate ต้องการ function type สำหรับทุก parameter ไม่ใช่แค่ค่าตายตัว () => value เป็น syntax ของ anonymous function ใน M language ที่ไม่รับ parameter และ return ค่าคงที่ วิธีนี้ทำให้ Power Query สามารถเรียก function เมื่อต้องการได้ แทนที่จะ evaluate ค่าตั้งแต่ตอนเริ่ม ซึ่งสอดคล้องกับ lazy evaluation pattern ของ Power Query

each _ หมายถึงอะไร และใช้เมื่อไหร่?

each เป็น shorthand syntax ของ M language สำหรับเขียน anonymous function ที่รับ parameter เดียว โดย _ คือ placeholder แทนค่า parameter นั้น เช่น each _ > 0 เทียบเท่ากับ (x) => x > 0 ใช้ each กับ condition, next, และ selector parameters ของ List.Generate เพราะ function เหล่านี้รับค่า candidate หรือ item เดียวเป็น input ส่วน initial ใช้ () => value เพราะไม่รับ parameter

Selector parameter มีประโยชน์อย่างไร?

Selector ช่วยให้คุณ transform ค่าก่อนเพิ่มเข้า list ผลลัพธ์ มีประโยชน์มากเมื่อใช้ record structure เก็บหลายค่า (เช่น [x = 1, y = 2]) แต่ต้องการแสดงเฉพาะบางฟิลด์ (เช่น each [y] จะได้เฉพาะค่า y) หรือต้องการคำนวณค่าใหม่จากหลายฟิลด์ (เช่น each [Price] * [Quantity]) ถ้าไม่ระบุ selector จะใช้ค่าที่ generate ตรงๆ

List.Generate มีข้อจำกัดเรื่องจำนวนรอบไหม?

Power Query ไม่มี hard limit สำหรับจำนวนรอบของ List.Generate แต่ถ้าวนลูปเกินไปจะทำให้ performance ช้าและอาจเกิด memory issue ดังนั้นควรมีเงื่อนไข (condition function) ที่รับประกันได้ว่าจะหยุดในที่สุด หลีกเลี่ยง infinite loop โดยตรวจสอบให้มั่นใจว่าค่า candidate จะทำให้เงื่อนไขเป็น false ได้ในที่สุด เช่นใช้ counter หรือเช็คค่า null

สามารถใช้ List.Generate กับ API pagination จริงๆ ได้อย่างไร?

ใช้ record เก็บ URL หรือ pageToken พร้อมกับข้อมูลที่ดึงมา เช่น () => [url = “api.com/data?page=1”, data = {}] ใน next function เรียก Web.Contents กับ URL ปัจจุบัน parse response เพื่อหา nextPageUrl และ append data ที่ได้เข้า list ใน condition ตรวจสอบว่า nextPageUrl มีค่าหรือไม่ (each [nextPageUrl] null) ใน selector ดึงเฉพาะ data ออกมา (each [data]) แล้วใช้ List.Combine รวมทุกหน้าเป็น table เดียว

Resources & Related

Additional Notes

ฟังก์ชัน List.Generate ใน Power Query เป็นเครื่องมือสำหรับสร้าง list แบบ dynamic โดยใช้ generator pattern ซึ่งคล้ายกับการวนลูป while loop ในภาษาโปรแกรมมิ่ง ฟังก์ชันนี้ทำงานโดยเริ่มจากค่าเริ่มต้น (initial value) แล้ววนลูปตรวจสอบเงื่อนไข (condition) และสร้างค่าถัดไป (next value) จนกว่าเงื่อนไขจะเป็นเท็จ

ฟังก์ชันนี้มีประโยชน์อย่างมากในการสร้างข้อมูลที่มี pattern ซับซ้อน เช่น การสร้างลำดับวันที่ระหว่างช่วงเวลา การเรียก API แบบ pagination ที่ต้องวนลูปหลายหน้า หรือการคำนวณแบบทบต้นที่ค่าแต่ละรอบขึ้นอยู่กับค่าก่อนหน้า โดย List.Generate สามารถทำงานกับ record structure เพื่อเก็บสถานะหลายตัวแปรพร้อมกันได้

จุดเด่นของ List.Generate คือความยืดหยุ่นสูง เพราะคุณสามารถกำหนด logic การทำงานได้เองทั้งหมดผ่าน 4 function parameters ซึ่งแตกต่างจาก List.Numbers หรือ List.Dates ที่มี pattern การสร้างค่าแบบตายตัว นอกจากนี้ยังมี optional selector parameter ที่ช่วยให้คุณ transform ค่าผลลัพธ์ก่อนส่งออกมาได้อีกด้วย

เมื่อไหร่ควรใช้ List.Generate

  • สร้างลำดับวันที่แบบกำหนดเอง เมื่อต้องการควบคุมวิธีการเพิ่มวันที่ (ทุกสัปดาห์, ทุกเดือน, skip วันหยุด)
  • เรียก API แบบ pagination วนลูปเรียกหน้าถัดไปจนกว่าจะไม่มีข้อมูล (nextPageToken = null)
  • คำนวณแบบทบต้น เช่น ดอกเบี้ยทบต้น, Fibonacci sequence, compound growth
  • สร้าง pattern ซับซ้อน ที่ List.Numbers หรือ List.Dates ทำไม่ได้
  • จำลองการวนลูป while เมื่อไม่รู้จำนวนรอบล่วงหน้า แต่รู้เงื่อนไขหยุด

Leave a Reply

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