วิธีแก้ปัญหาเวลาเขียน M Code แบบ each ซ้อนกันหลายอัน 1

วิธีแก้ปัญหาเวลาเขียน M Code แบบ each ซ้อนกันหลายอัน

มีแฟนเพจที่ติดตามอยู่ได้ถามคำถามมาว่า เวลาเขียน M Code แล้วมีการอ้างอิงฟังก์ชันซ้อนในอีกฟังก์ชันนึงจะมีปัญหาพอสมควร เช่น กรณีที่ต้องการจะ SUM ข้อมูลยอดขายของสินค้าที่ต้องการ ถ้าเราอ้างอิงชื่อสินค้าไปเลยตรงๆ จะทำได้ไม่มีปัญหา แต่ถ้าหากพยายามจะอ้างอิงสินค้าที่อยู่ในบรรทัดนั้นๆ จะพบปัญหา

เช่น กรณีอ้างอิงชื่อสินค้าไปเลย สามารถทำได้ โดย Add Custom Column แบบนี้ โดยใช้ Table.SelectRows เพื่อ Filter ข้อมูล MyTable ให้เหลือเฉพาะบรรทัดที่ต้องการ

Table.SelectRows(MyTable,each [สินค้า]="อาหาร")

ซึ่งจะได้ผลเป็น M Code เต็มๆ แบบนี้ ซึ่งจะมี each 2 ตัว ซ้อนกันอยู่ ซึ่งนี่แหละจะทำให้เกิดปัญหา เวลาไปอ้างอิงคอลัมน์แบบปกติ

= Table.AddColumn(MyTable, "ยอดขายของสินค้า", each Table.SelectRows(MyTable,each [สินค้า]="อาหาร"))
วิธีแก้ปัญหาเวลาเขียน M Code แบบ each ซ้อนกันหลายอัน 2

แต่ถ้าเราพยายามจะแก้คำว่า “อาหาร” ในสูตร ให้เป็น [สินค้า] เพื่อพยายามจะอ้างอิงสินค้าในบรรทัดนั้นๆ จะเจอปัญหาทันที เพราะสูตร [สินค้า]=[สินค้า] มันจะเป็นจริงเสมอนั่นเอง ผลลัพธ์จึงไม่มีการ Filter อะไรเลย

Table.SelectRows(MyTable,each [สินค้า]=[สินค้า])
วิธีแก้ปัญหาเวลาเขียน M Code แบบ each ซ้อนกันหลายอัน 3

แล้วเราจะทำให้มันไปอ้างอิงว่า ให้ Filter คอลัมน์ สินค้า ของ MyTable ให้มีค่าเท่ากับสินค้าในบรรทัดนั้นๆ ได้ยังไง?

เราต้องข้าใจก่อนว่า each [สินค้า] เนี่ย มันย่อมาจาก (_) => _[สินค้า] หรือ (x) =>x[สินค้า] โดย x คือ parameter ของฟังก์ชัน ซึ่งจะตั้งชื่ออะไรก็ได้ เช่น ผมอาจตั้งชื่อว่า main ก็ได้ เพื่ออ้างอิงถึง each ตัวข้างนอกสุด สรุปว่าได้แบบนี้

ซึ่ง main[สินค้า] จะหมายถึงคอลัมน์ของ Table.AddColumn แต่ [สินค้า] จะหมายถึงคอลัมน์ตอนที่ใช้ Table.SelectRows

= Table.AddColumn(MyTable, "ยอดขายของสินค้า", (main)=> Table.SelectRows(MyTable,each [สินค้า]=main[สินค้า]))
วิธีแก้ปัญหาเวลาเขียน M Code แบบ each ซ้อนกันหลายอัน 4

พออ้างอิงตารางได้แล้ว ก็เลือกเอาคอลัมน์ยอดขายออกมา ด้วยการใส่ [ยอดขาย] ต่อท้าย เช่น

= Table.AddColumn(MyTable, "ยอดขายของสินค้า", (main)=> Table.SelectRows(MyTable,each [สินค้า]=main[สินค้า])[ยอดขาย])
วิธีแก้ปัญหาเวลาเขียน M Code แบบ each ซ้อนกันหลายอัน 5

สุดท้ายก็ใช้ List.Sum มาทำการหาผลรวมซะ จะได้แบบนี้

= Table.AddColumn(MyTable, "ยอดขายของสินค้า", (main)=> List.Sum(Table.SelectRows(MyTable,each [สินค้า]=main[สินค้า])[ยอดขาย]))
วิธีแก้ปัญหาเวลาเขียน M Code แบบ each ซ้อนกันหลายอัน 6

และนี่คือแนวทางจัดการเวลามี each ซ้อนกันหลายชั้นครับ นั้นคือ ให้เปลี่ยน each แต่ละตัวเป็นชื่อ parameter เต็มๆ คู่กับ => แบบไม่ต้องย่อว่า each แบบปกตินั่นเอง