ในตอนนี้เราจะมาเรียนรู้เรื่องเกี่ยวกับข้อมูลประเภท List กันให้ลึกซึ้งมากขึ้นครับ ซึ่งเดี๋ยวเพื่อนๆ จะได้เห็นว่า พอเราเริ่มเข้าใจการทำงานของฟังก์ชัน List ต่างๆ ในตอนนี้แล้ว ฟังก์ชันกลุ่มอื่นหลายๆ ตัวก็จะมีชื่อคล้ายๆ กันนี่แหละ ทำให้เราจะพอเดาการใช้งานได้ไปด้วย ยิงปืนนัดเดียวได้นกสองตัวเลย!
ถ้าเราไปค้นคว้าข้อมูลเอกสารเกี่ยวกับ M Code เองจะพบว่า M Language มันมีฟังก์ชันให้เลือกเยอะมากๆๆ คือเยอะจนเลือกไม่ถูก ผมคิดว่าฟังก์ชันพื้นฐานกลุ่มที่ควรรู้จักให้ดียิ่งขึ้นนั่นก็คือ List เป็นเพราะว่ามันมักถูกใช้เป็นองค์ประกอบสำคัญในฟังก์ชันอื่นๆ ด้วย ดังนั้นใครที่สามารถจัดการเรื่อง List ได้ดี ก็จะพลิกแพลงทำเรื่องต่างๆ ได้เยอะขึ้น
สารบัญ
List เป็นองค์ประกอบสำคัญในหลายๆ ฟังก์ชัน
เวลาเราไปดูฟังก์ชันที่มีความสามารถเจ๋งๆ ทำเรื่องที่เราต้องการทีไร มักจะมี input หรือ output เป็น List ทุกทีสิน่า!
เวลาใช้ฟังก์ชัน Text.Split ก็ได้ผลเป็น List
Text.Split(text as text, separator as text) as list
เวลาจะรวม Text หลายๆ อันเป็นก้อนเดียว ด้วย Text.Combine ก็ต้องใช้ List
Text.Combine(texts as list, optional separator as nullable text) as text
เวลาดึงข้อมูลหัวตารางจาก Table มาจัดการต่อ ก็ออกมาเป็น List
Table.ColumnNames(table as table) as list
การจะจัดการกับประเภทข้อมูลของหัวตาราง Table ก็ต้องใช้ List
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 มาด้วย ซึ่งตัวพิมพ์ใหญ่มาก่อนพิมพ์เล็กนะ
ถ้าเป็นภาษาไทย ผมแนะนำให้สร้าง {“ก”..”๙”} ไปเลย ดีกว่า {“ก”..”ฮ”} ที่ขาดพวกสระไป ทำให้ดูไม่จืดเลยครับ
// ใช้ ก – เลข 9 ไทย ไปเลย จะได้สระมาด้วยครบถ้วนครับ
รวม List เข้าด้วยกันด้วย &
= {"a".."d"}&{1..5}&{"Sira","Ekabut"}
อ้างอิงข้อมูลใน 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 ได้เลย
ฟังก์ชัน List ที่น่าจะใช้บ่อย
นอกจากคำสั่งพื้นฐานเหล่านี้แล้ว Power Query ก็มีฟังก์ชันเกี่ยวกับ Listให้เลือกอีกมหาศาลเลย แต่ตัวที่ผมคิดว่าสำคัญมีดังนี้
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 ที่ใช้บ่อย โดยจะมีการประยุกต์ใช้ฟังก์ชันเจ๋งๆ ในการจัดการเรื่องต่างๆ เช่น คัดเลือกอักขระที่ต้องการ การจัดการหัวตารางแบบ Dynamic เป็นต้น
สารบัญซีรีส์ M Code
- คัมภีร์สรุป M Code ใน Power Query ตอนที่ 1
- คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each
- คัมภีร์สรุป M Code ใน Power Query ตอนที่ 3: เจาะลึกเรื่องของ List
- คัมภีร์สรุป M Code ใน Power Query ตอนที่ 4: เทคนิค M Code ที่ใช้บ่อย
- Power Query Speed Up Tips : รวมเทคนิคแก้ปัญหา Power Query ช้า ให้ทำงานเร็วขึ้น
- สารพัดวิธีกำจัดอักขระที่ไม่ต้องการออกจากข้อความ (Clean Bad Characters)
- วิธีเขียนสูตรย้อนเวลาแบบ TENET ให้ตัวอักษรกลับหน้าหลัง
- เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ
- วิธีใช้ Power Query ดึงข้อมูลจาก Web API : ตอนที่ 2
- วิธีใช้ Power Query ดึงข้อมูลจาก Web API : ตอนที่ 3
- แนะนำ/วิธีใช้ ThepExcel-Mfx : M Code สำเร็จรูปจาก ThepExcel
- วิธีใช้ Regular Expression (RegEx) ใน Power Query
- วิธีจัดการข้อมูลแย่ๆ ด้วย Power Query ทั้งข้อมูลปนกัน ข้อมูลอยู่บนหัวตาราง
- แก้ปัญหา Power Query มองไม่เห็นการเพิ่มคอลัมน์ใหม่ในไฟล์ CSV
- วิธีแก้ปัญหาเวลาเขียน M Code แบบ each ซ้อนกันหลายอัน
- วิธีใช้ Power Query ดึงข้อมูล EMS Tracking จากไปรษณีย์ไทย ผ่าน Web API
- บันได 10 ขั้น เริ่มเรียนรู้ M Code ขุมพลังของ Power Query
- การใช้ Power Query M Code จัดการข้อมูลที่อยู่ในตำแหน่งไม่แน่นอน
- Round ใน Power Query ได้ผลลัพท์ไม่เหมือนใน Excel!!