Author: Sira Ekabut

  • หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน

    หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน

    สมมติว่าเรามีข้อมูลอยู่แบบซ้ายมือของรูป แต่อยากให้ผลลัพธ์รวมเป็นข้อความเดียวกันกลายเป็นแบบด้านขวามือ เราจะใช้วิธีไหนได้บ้าง? มาดูกันครับ คิดว่าบทความสั้นๆ อันนี้น่าจะช่วยเปิดหูเปิดตาให้เพื่อนๆ ได้รู้จักวิธีแก้ปัญหาที่หลากหลายมากขึ้นนะครับ

    หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน 1

    ก่อนอื่นเราทำข้อมูลให้เป็น Table (Insert->Table หรือ Ctrl+T) ก่อน จะได้รองรับ Data mี่เพิ่มขึ้นได้ง่ายๆ ครับ และตั้งชื่อว่า MyData

    วิธีใช้สูตรของ Excel 365 รวมเป็นข้อความเดียวกัน

    วิธีที่เข้าใจง่ายที่สุดเลย ก็คือสูตรของ Excel 365 ซึ่งมีความสามารถแบบ Array Formula ที่ขี้โกงและใช้ง่ายกว่าสูตรใน Version เก่ามากๆ

    โดยเราจะเริ่มจากเอา Group ทั้งหมดออกมาก่อนด้วย UNIQUE (และถ้าอยากเรียงด้วยก็ซ้อน SORT เข้าไปก็ได้)

    =UNIQUE(MyData[Group])

    หรือ

    =SORT(UNIQUE(MyData[Group]))
    หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน 2

    จากนั้นเราจะทำการคำนวณ item แต่ละอันภายใต้แต่ละ Group ออกมาด้วยฟังก์ชัน FILTER ดังนี้

    =FILTER(MyData[Item],MyData[Group]=D2)
    หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน 3

    แต่เราอยากจะให้เอาข้อมูลที่ Filter มาได้ เอามาเชื่อมต่อเป็นข้อความเดียวกัน จึงใช้ TEXTJOIN มาช่วยอีกที

    =TEXTJOIN(", ",TRUE,FILTER(MyData[Item],MyData[Group]=D2))
    หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน 4

    ถ้าเรา Copy สูตรมาข้างล่างก็จะได้ครบทุกตัว

    หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน 5

    สูตรนี้เข้าใจง่าย แต่ก็มีข้อเสียว่า สูตรด้านขวาสุดมันไม่งอก item ของ group ใหม่ออกมาอัตโนมัติเมื่อมี Group เพิ่ม ถ้าอยากให้งอกสูตรจะยากกว่านี้ ซึ่งผมขอเก็บปัญหานี้ไว้ก่อนนะ

    วิธีใช้ DAX รวมเป็นข้อความเดียวกัน

    ก่อนอื่นเราก็เอาข้อมูล MyTable ต้นฉบับเข้าไป Pivot แบบ Data Model ซะ เพื่อให้มันรองรับการใช้ DAX

    หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน 6

    จากนั้นเราลาก Group ไปที่ Rows แล้ว คลิ๊กขวาที่ชื่อตารางแล้ว + Add Measure…

    หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน 7

    จากนั้นตั้งชื่อ Measure แล้วเขียนสูตรดังนี้ ก็จบเลย

    =CONCATENATEX(MyData,[Item],", ")

    ซึ่งภายใต้แต่ละ group มันก็จะมองเห็นเฉพาะ item ของตัวมันเอง (Concept ของ Filter Context) ผมจึงสามารถใช้ CONCATENATEX รวมทุก item เข้าด้วยกันในลักษณะเดียวกับ TEXTJOIN ของสูตร Excel ได้เลย โดยไม่ต้องมีฟังก์ชัน FILTER แบบสูตร Excel อีก

    แต่ถ้าหากคิดว่า รายการ item ย่อย อาจมีซ้ำกันได้ ก็ให้ใส่ DISTINCT ครอบ MyData[Item] เพื่อให้แน่ใจว่าได้ item ย่อยที่ไม่ซ้ำกันก่อน

    =CONCATENATEX(DISTINCT(MyData[Item]),[Item],", ")
    หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน 8

    จากนั้นเราจะได้ Measure ใหม่ที่สัญลักษณ์ fx ก็ให้ลากลง Values ได้เลย

    หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน 9

    การใช้ CONCATENATEX จริงๆ แล้วมีความยืดหยุ่นกว่า TEXTJOIN มากๆ ตรงที่สามารถกำหนดการเรียง item ได้อีกว่าจะให้เรียงตามอะไร เรียงทิศทางไหน เช่น ให้เรียงตามยอดขายแบบมากไปน้อยก็ยังได้ ดังนั้นผมจึงบอกได้เลยว่าวิธีใช้ DAX คือสุดยอดที่สุดแล้วครับ

    วิธีใช้ Power Query รวมเป็นข้อความเดียวกัน

    หากใช้ Power Query ก็ให้ Get Data from Table เข้าไปก่อนเลยครับ

    หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน 10

    จากนั้นทำการ Group by แบบ all rows ดังนี้

    หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน 11

    ผลลัพธ์มันจะทำให้เหลือ Group แบบไม่ซ้ำกัน แต่ภายใต้แต่ละ Group จะมี Table ที่มองเห็นเฉพาะทุกคอลัมน์ใน Group นั้นเท่านั้น (ซึ่งดูได้หากคลิ๊ก “ข้างๆ คำว่า Table” ของแต่ละ Group)

    หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน 12

    ทีนี้เราต้องการผลลัพธ์เฉพาะคอลัมน์ item ให้ออกมาเป็น list ดังนั้นผมแนะนำให้ Add Custom Column ใหม่แล้วใส่สูตรดังนี้ เพื่อเอามาเฉพาะคอลัมน์ item จากตารางใน all (ซึ่งการเขียน [ ] เป็นสัญลักษณ์การอ้างอิง Record ในภาษา M ซึ่งพิมพ์เล็กพิมพ์ใหญ่ต้องเป๊ะนะ)

    =[all][Item]
    หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน 13

    พอลิ๊กดูที่ข้างๆ คำว่า List จะเห็นเฉพาะคอลัมน์ Item แล้ว

    หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน 14

    จากนั้นเราจะสามารถคลิ๊กที่มุมขวาบนของคอลัมน์ แล้วเลือก Extract Values… เพื่อรวม list เข้าด้วยกันได้เลย

    หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน 15

    จากนั้นเราเลือกตัวคั่นได้ แต่ผมอยากให้คั่นด้วย comma และมีเว้นวรรคด้วย ก็เลยต้องเลือกแบบ Custom

    หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน 16

    แล้วมันก็จะแสดงผลลัพธ์ออกมาได้ในที่สุด

    หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน 17

    ถ้าเราไม่ต้องการคอลัมน์ all ก็ลบทิ้งไปได้เลย จากนั้นก็ Close & Load เอาผลลัพธ์ออกมาได้เลย

    สรุป

    หลากวิธีเอาข้อมูลในกลุ่มเดียวกันไปรวมเป็นข้อความเดียวกัน 18

    ส่วนตัวแล้ว ถ้าการแสดงผลแบบนี้คือผลลัพธ์สุดท้ายที่ต้องการ ผมจะเลือกใช้วิธี DAX ก่อน เพราะเป็นวิธีที่ง่าย และยืดหยุ่นที่สุดในความคิดของผม แต่ถ้าผมต้องรวมรายการแบบนี้ เพื่อนำไป Merge หรือไปทำอะไรบางอย่างกับตารางอื่นต่ออีก ผมก็จะใช้ Power Query ทำครับ

    อย่างไรก็ตามทั้งวิธี DAX และ Power Query มันจะต้องมีการ Refresh ข้อมูลถ้าข้อมูลต้นทางเปลี่ยน ซึ่งวิธีใช้สูตรไม่ต้อง Refresh เลย มันจะเปลี่ยนอัตโนมัติครับ (แค่ตอนนี้สูตรที่ผมใช้มันยังไม่งอก item ของ group ใหม่เอง)

    ซึ่งจริงๆ แล้วยังมีวิธีอื่นๆ ที่ทำงานแบบนี้ได้อีกนะครับ เช่น VBA ก็ทำได้ ดังนั้นใครมีวิธีอื่นเจ๋งๆ อีก ก็ comment แนะนำมาได้เลยนะครับ

  • มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน

    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน

    พอผมไปศึกษาเรื่อง Iterative Calculation ใน Excel ก็ได้ไปพบเรื่องเกี่ยวกับ Conway’s Game of Life ซึ่งเป็น Simulation ที่อยู่บนตาราง ที่ให้เราตั้งค่าจุดเริ่มต้นของเกมว่าเริ่มต้นจะให้ช่องไหนมีชีวิตบ้าง (เรียกว่า seed) จากนั้นเกมจะพัฒนาแต่ละ Stage ไปตาม set ของกติกาที่ชัดเจนด้วยตัวมันเอง (คล้ายๆ มันมีชีวิตของมันเอง) ดังนี้

    กติกาการมีชีวิต/ตาย

    การตัดสินว่า Stage ถัดไป ช่องนั้นจะเกิดอะไรขึ้น จะดูจากช่องรอบตัวมันเอง ทั้ง 8 ช่อง (ทิศเฉียงด้วย) ดังนี้

    1. Cell ที่มีชีวิต ถ้ามีเพื่อนรอบด้านที่มีชีวิตเหลือน้อยกว่า 2 ช่อง จะตาย (คนน้อยเกิน)
    2. Cell ที่มีชีวิต ถ้ามีเพื่อนรอบด้านที่มีชีวิตเหลือ 2-3 ช่อง จะมีชีวิตต่อไป (คนกำลังดี)
    3. Cell ที่มีชีวิต ถ้ามีเพื่อนรอบด้านที่มีชีวิตเหลือมากกว่า 3 ช่อง จะตาย (คนมากเกิน)
    4. Cell ที่ตายอยู่ ถ้ารอบด้านมีเพื่อนที่มีชีวิต 3 ช่องพอดี Cell ที่ตายจะกลับมามีชีวิต (ออกลูกใหม่)

    ซึ่งถ้าอ่าน Logic จริงๆ มันก็เหลือแค่นี้แหละ

    1. Cell ที่มีชีวิต ถ้ามีเพื่อนรอบด้านที่มีชีวิตเหลือ 2-3 ช่อง จะมีชีวิตต่อไป (คนกำลังดี)
    2. Cell ที่ตายอยู่ ถ้ารอบด้านมีเพื่อนที่มีชีวิต 3 ช่องพอดี Cell ที่ตายจะกลับมามีชีวิต (ออกลูกใหม่)
    3. นอกนั้น Cell จะตาย

    เตรียมพื้นที่ใน Excel

    ก่อนอื่น ให้สร้าง Excel ไฟล์เปล่า ขึ้นมา 2 sheet คือ output (แสดงผลลัพธ์) กับ seed (เราตั้งค่าจุดเริ่มต้นที่นี่) แล้วเปลี่ยนความกว้างคอลัมน์ให้พอๆ กับ row (เช่น 28px) (เราทำทั้ง 2 ชีทพร้อมกันได้ ด้วยการเลือกทั้ง 2 sheet ไว้ก่อน)

    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน 19

    จากนั้นสร้างขอบเลขของพื้นที่ ว่าจะให้ Simulation กินพื้นที่ใหญ่ได้แค่ไหน ของผมเอาซัก 40×40 ละกัน ดังนั้นให้ตีกรอบนอกเอาไว้ โดยให้พื้นที่ข้างในเป็น 40×40 ช่องซะ (ทำทั้ง 2 ชีทนะ)

    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน 20

    กำหนด seed เริ่มต้น

    จากนั้นไปกำหนด seed เริ่มต้น ว่าจะให้ช่องไหนมีชีวิตบ้าง ซึ่งตรงนี้เราต้องคิดสัญลักษณ์ก่อนว่า อะไรแปลว่ามีชีวิต อะไรแปลว่าตาย ซึ่งผมจะให้สัญลักษณ์เป็น 1=มีชีวิต กับ blank=ไม่มีชีวิต แล้วกัน

    ทีนี้ก็ใส่เลข 1 มั่วๆ ไปตามต้องการได้เลย เช่น ผมใส่แบบนี้น้อยๆ ก่อน เพื่อทำความเข้าใจสูตร

    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน 21

    ทำความเข้าใจกติกาก่อน

    สร้างชีทใหม่อีกอัน เพื่อทำความเข้าใจกติกาก่อน หากพิจารณาทีละช่องวา่าควรมีชีวิต หรือตาย มันจะได้ตามนี้

    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน 22

    ตั้งค่า Option Excel

    ตั้งค่า Option Excel เป็น Iterative Calculation เพื่อให้รองรับการคำนวณแบบงูกินหางได้ และตั้งค่า Iterate ทีละ 1 step จะได้เห็นผลลัพธ์ทีละขั้นได้ง่ายๆ

    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน 23

    เขียนสูตรที่ sheet Output

    จากนั้นเรากลับไปที่ Output แล้วจะมาเขียน Condition กัน

    (หลักการผมศึกษามาจากเว็บ http://dailydoseofexcel.com/archives/2011/04/06/conways-game-of-life-simulation-in-excel/
    แต่ผมแก้สุตรให้ง่ายขึ้นมาก)

    Logic เบื้องต้นคือ เราจะเขียนสวิตที่เอาไว้ reset เกมขึ้นมาซักช่องนึงใน Output เช่น D1 (ตั้งชื่อ defined name ว่า reset ก็ได้) ถ้าค่า reset เป็น Y ก็ให้เอาค่าเริ่มต้นจาก seed มาได้ทันทีโดยไม่ต้องใช้กติกาเกม แต่ถ้า reset ไม่ใช่ Y ก็ให้ดำเนินการตามกติกาของเกมต่อไปได้เลย

    ดังนั้นผมจะเขียนสูตรที่มุมซ้ายของกระดาน 40×40 ของเราแบบนี้

    =IF(reset="Y",IF(seed!C3="","",seed!C3),rules)
    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน 24

    ทีนี้เราก็ต้องมากำหนดกติกาการมีชีวิต ว่าจะให้คำนวณยังไง ซึ่ง logic เป็นดังนี้

    1. หาก Cell นี้ที่มีชีวิต ถ้ามีเพื่อนรอบด้านที่มีชีวิตเหลือ 2-3 ช่อง จะมีชีวิตต่อไป (คนกำลังดี)
    2. หาก Cell นี้ตายอยู่ ถ้ารอบด้านมีเพื่อนที่มีชีวิต 3 ช่องพอดี Cell ที่ตายจะกลับมามีชีวิต (ออกลูกใหม่)
    3. นอกนั้น Cell จะตาย

    ซึ่งหากพิจารณาใน C3 แต่ละข้อจะเขียนสูตรได้ดังนี้

    =IF(C3=1,IF(OR(SUM(B2:D4)-1=2,SUM(B2:D4)-1=3),1,""),กรณี2)

    ตรง SUM(B2:D4)-1 ผม -1 เพื่อให้ไม่นับตัวมันเองนะครับ เพราะมั่นใจได้ว่าตัวมันเองเป็น 1 เลย -1 ได้เลย

    =IF(C3<>1,IF(SUM(B2:D4)=3,1,""),กรณี3)
    =""

    พอรวมกันก็จะเป็น rules แบบนี้

    =IF(C3=1,IF(OR(SUM(B2:D4)-1=2,SUM(B2:D4)-1=3),1,""),
     IF(C3<>1,IF(SUM(B2:D4)=3,1,""),""))

    พอรวมกับการ reset ด้วยจะเป็นแบบนี้

    =IF(reset="Y",IF(seed!C3="","",seed!C3),
     IF(C3=1,IF(OR(SUM(B2:D4)-1=2,SUM(B2:D4)-1=3),1,""),
     IF(C3<>1,IF(SUM(B2:D4)=3,1,""),"")))

    จากนั้น Copy สูตรไปให้ครอบคลุมทั้งตาราง

    ทดสอบสูตร

    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน 25

    ตอนนี้ กด F9 ไปก็จะยังไม่มีอะไรเปลี่ยนแปลง เพราะ Reset ยังเป็น Y อยู่

    ลองเปลี่ยน Reset ไม่ใช่ Y เช่น ให้เป็น N แทน ค่าที่ได้จะเปลี่ยนไป แต่มันไม่ออกมาเป็นอย่างที่คิด!!

    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน 26

    ผลลัพธ์ที่ถูกต้อง ควรจะมีเลข 1 ออกมาในกรอบสีแดงที่ผมตีไว้เท่านั้น ช่องอื่นจะต้องหายไปทั้งหมด (เหมือนที่เราทำความเข้าใจ)

    แต่ทำไมผลลัพธ์ถึงไม่ใช่ตามที่เราคิด????

    สาเหตุเป็นเพราะ Excel ทำการคำนวณทีละช่องว่าควรมีค่าเท่าไหร่ โดยที่มันไม่ได้จำภาพ Stage เดิมเอาไว้ แต่มันเอาสถานะที่เปลี่ยนไปแล้ว มาเป็นจุดตั้งต้นสำหรับ cell อื่น คำตอบมันก็เลยเพี้ยนไป…

    แล้วจะแก้ไขปัญหายังไง?

    คำตอบก็คือ เราต้องสร้าง Board ของหน้า Output ขึ้นมาเป็น 3 บอร์ด เพื่อให้มันจำภาพ Stage ที่แล้วเอาไว้ให้ได้ก่อน แล้วค่อยคำนวณต่อ

    แก้ปัญหามันไม่จำ Stage ก่อนหน้า

    ให้สร้างบอร์ดใน sheet output ทั้งหมด 3 บอร์ด ดังนี้

    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน 27

    หลักการคือ

    • Board ทด 1 ถ้า reset= Y จะอ่านค่าจาก Seed ถ้า Reset ไม่ใช่ Y จะอ่านค่าจาก Board ทด 2 แล้วทำตามกติกา
    • Board ทด 1 ถ้า reset=Y จะใส่ค่า Blank ไป ถ้าไม่ใช่ Y จะอ่านค่าจาก Board ทด 1 แล้วทำตามกติกา

    โดยผมจะสร้าง cell ที่ชื่อ stage ขึ้นมาก่อน เพื่อบอกว่ามันคือการคำนวณครั้งที่เท่าไหร่ สูตรคือ

    =IF(reset="Y",0,stage+1)

    และผมจะต้องมีการทดก่อนว่า การทำงานครั้งนั้นๆ เป็นการคำนวณบอร์ดไหน โดยผมจะสร้าง cell ที่ชื่อว่า board ขึ้นมาโดยใส่สูตรดังนี้

    =MOD(stage,2)+1

    เพื่อให้พอ reset แล้ว จะใช้ Board1 ก่อน พอกด F9 ปุ๊ปก็จะสลับเป็น board2 และ board1 สลับไปมาเรื่อยๆ

    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน 28

    ทีนี้พอเราสร้าง cell ที่คิดเรื่อง board ที่จะใช้เสร็จแล้ว ก็จะไปเขียนสูตรที่แต่ละ Board อีกที

    ดังนั้นสูตรที่มุมซ้ายบนของ Board ทด 1 จะเปลี่ยนจากการอ้างอิงตัวเอง ไปอ้างอิงบอร์ดทด 2 แทน ดังนี้ แต่ต้องเขียน Condition ด้วยว่าถ้า cell board เป็น 2 (กำลังคำนวณ Board 2 อยู่) ให้คงค่าตัวเองเอาไว้ก่อน

    =IF(reset="Y",IF(seed!C3="","",seed!C3),
       IF(board=2,C3,
    IF(C46=1,IF(OR(SUM(B45:D47)-1=2,SUM(B45:D47)-1=3),1,""),
       IF(C46<>1,IF(SUM(B45:D47)=3,1,""),""))))

    จากนั้น Copy สูตรให้ทั่ว Board ทด 1

    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน 29

    แล้วช่องซ้ายบนของ Board 2 ก็แก้ เป็นดังนี้

    =IF(reset="Y","",
     IF(board=1,C46,
      IF(C3=1,IF(OR(SUM(B2:D4)-1=2,SUM(B2:D4)-1=3),1,""),
      IF(C3<>1,IF(SUM(B2:D4)=3,1,""),""))))

    จากนั้น Copy สูตรให้ทั่ว Board ทด 2

    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน 30

    จากนั้นพอเปลี่ยนย Reset เป็น N มันก็จะทำตามกติกา จะเห็นว่า Board 2 แสดงค่าได้ถูกต้องแล้ว

    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน 31

    กำหนดการแสดงผลใน Output สุดท้าย

    จากนั้นเราก็ไปที่ Board Output สุดท้าย เพื่อเขียนเงื่อนไขว่า ถ้า board=1 ให้เอากระดานบน นอกนั้นเอากระดานล่าง ที่ช่องซ้ายบนสุดจะได้สูตรแบบนี้ แล้วก็ Copy ให้ทั่ว Board

    =IF(board=1,C3,C46)

    จากนั้นเพื่อความสวยงาม เราจะกำหนด Conditional Format ใน Board Output จริงๆ ว่า ถ้าค่าใน Cell เป็น 1 ให้ถมสี

    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน 32

    คราวนี้พอกด F9 มันก็จะทำการคำนวณ และสลับ Board ไปมา แต่ปรากฎว่า ตอนที่ผมเปลี่ยน Reset จาก Y เป็น N ค่าใน Board Final มันหายไป!!

    สาเหตุเพราะว่ามันดันไปอ้างอิงบอร์ดที่ยังไม่ได้ทันคำนวณค่า (เราต้องให้มันคำนวณค่าบอร์ดทดทั้ง 1 กับ 2 ให้เสร็จก่อน)

    ดังนั้นผมจะต้องย้าย Board Output ไปอยู่ข้างล่างของ Board ทด 2 แทน เพื่อให้มั่นใจว่ามันคำนวณหลังสุดแน่ๆ (อยู่ล่างหรืออยู่ขวาก็ได้)

    คราวนี้กด F9 ไปเรื่อยๆ ก็จะได้เกมที่ Logic เสร็จสมบูรณ์แล้วล่ะ ทีนี้ก็ถึงเวลาแก้ seed แล้ว

    แก้ Seed ให้จุดเริ่มต้นเปลี่ยนไป

    ผมลองทำการแก้ Seed เป็นดังนี้

    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน 33

    จากนั้นกลับมาที่ Output แลว้ซ่อน Row ของ board ทดทั้ง 1 และ 2 ไปซะ

    สภาพตั้งต้นจะเป็นดังนี้

    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน 34

    พอเปลี่ยน Reset เป็น N จะเข้าสู่ Stage 1 และจะได้ผลดังนี้ (ค่าไม่หายแล้ว)

    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน 35

    พแกด F9 อีกทีจะได้ดังนี้

    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน 36

    ถ้าลองทำเป็นภาพเคลื่อนไหวเลยจะได้ดังนี้

    มาสร้าง Simulation ชื่อว่า Conway’s Game of Life ใน Excel กัน 37

    จะเห็นว่าบางรูปแบบมันจะคงที่ไม่เปลี่ยน (ถ้าไม่มีตัวอื่นวิ่งมาชนมันนะ) บางอันก็วน Loop บางรูปแบบมันวิ่งไปได้เรื่อยๆ ได้ ถ้าสนใจลองดูรูปแบบต่างๆใน Wiki ได้เลย

    ขอให้สนุกกับการทำ Simulation นะครับ!

  • อธิบายละเอียดยิบเรื่องการเงิน NPV, XNPV, IRR, XIRR ต่างกันยังไง ใช้อะไรดี?

    อธิบายละเอียดยิบเรื่องการเงิน NPV, XNPV, IRR, XIRR ต่างกันยังไง ใช้อะไรดี?

    ผมได้เคยสอนใช้ฟังก์ชันทางการเงินอย่าง NPV และ IRR กันไปคร่าวๆแล้ว ซึ่งมันเป็นฟังก์ชันทางการเงินที่มีประโยชน์ในการช่วยตัดสินใจได้ว่า Project ให้ผลตอบแทนคุ้มค่าแค่ไหน น่าลงทุนหรือไม่? แต่ถ้าเราสังเกตดูแล้วมันจะมีฟังก์ชันชื่อคล้ายๆ กันอย่าง XNPV และ XIRR อยู่ด้วย แถมใน DAX ของ Power BI, Power Pivot ก็มีแค่ XNPV กับ XIRR ให้ใช้อีก

    แบบนี้มันสามารถใช้แทนกันได้มั้ย หรือมีความแตกต่างกันอย่างไร? เดี๋ยวบทความนี้ผมจะอธิบายให้เข้าใจอย่างละเอียดกันทั้งหมดตั้งแต่ NPV IRR ปกติกันเลยครับ

    พื้นฐานของ NPV และ IRR

    ปกติแล้ว Concept ของ NPV ก็คือการเปลี่ยน Cashflow ตลอดทั้งโครงการให้ไปอยู่ที่จุดเดียวกันคือเริ่มต้น (ใช้ PV กับทุก Cashflow) แล้วทำการ Net หักลบ Cashflow ที่เป็นบวกกับลบ เพื่อให้ได้ Cash Flow สุทธินั่นเอง ซึ่งสามารถใช้ฟังก์ชัน NPV ช่วยหาได้ (แต่ไม่ต้องเลือก CF ที่ 0)

    อธิบายละเอียดยิบเรื่องการเงิน NPV, XNPV, IRR, XIRR ต่างกันยังไง ใช้อะไรดี? 38

    ส่วน IRR คือ ค่า rate% อัตราผลตอบแทน ที่ทำให้ NPV เป็น 0 พอดี

    สามารถคำนวณด้วยสูตร IRR ครอบ CF ทั้งหมด หรือจะ Goal Seek ให้ค่า NPV เป็น 0 ก็ได้

    อธิบายละเอียดยิบเรื่องการเงิน NPV, XNPV, IRR, XIRR ต่างกันยังไง ใช้อะไรดี? 39

    ถ้าลองเอาค่า % ที่ได้ไปแทนค่า ก็จะทำให้ NPV เป็น 0 พอดีเป๊ะ

    อธิบายละเอียดยิบเรื่องการเงิน NPV, XNPV, IRR, XIRR ต่างกันยังไง ใช้อะไรดี? 40

    ทุกอย่างก็ดูดีไม่ได้มีปัญหาอะไร… แต่สังเกตหรือไม่ว่า เวลาเราใช้ NPV หรือ IRR เราไม่ต้องระบุวันที่ที่เกิด Cash Flow แต่ละก้อนเลย…

    นั่นก็เป็นเพราะว่าเจ้า NPV และ IRR นั้น ตั้งอยู่บน Assumption ที่สำคัญมากๆ อันนึงก็คือ Cash Flow แต่ละก้อนนั้นต้องห่างเท่ากันเป๊ะๆๆๆๆๆ ทุกก้อน และหน่วยของ period ต้องต้องกับ rate% ด้วย เช่น

    • ถ้า Cashflow แต่ละก้อนห่างกัน 1 ปี ตัว Rate% ก็ต้องคิดต่อ 1 ปี
    • ถ้า Cashflow แต่ละก้อนห่าง 1 เดือน ตัว Rate% ก็ต้องคิดต่อ 1 เดือนด้วย

    ทำความเข้าใจเรื่องการคิดดอกเบี้ย

    อัตราดอกเบี้ยที่ธนาคารบอกเรานั้น จริงๆ แล้วมีอยู่ 2 ลักษณะ คือ Annual Percentage Rate (APR) กับ Effective Interest Rate (EIR) ซึ่งเราต้องทำความเข้าใจดีๆ ว่าเลขที่เรากำลังเห็นคืออะไรกันแน่? เพราะว่า Annual Percentage Rate เป็นแค่การแปลงหน่วยเป็นต่อปี โดยไม่ได้สนใจการคิดดอกเบี้ยทบต้น ในขณะที่ Effective Interest Rate นั้นสนใจเรื่องดอกเบี้ยทบต้น (ซึ่งจะตรงกับความจริงมากกว่า)

    สมมติว่าเราไปกู้เงิน 100 บาท ที่ต้องคิดดอกเบี้ยเดือนละครั้ง โดยอัตราดอกเบี้ยอยู่ที่เดือนละ 0.5% …

    ถ้าถามว่า Annual Percentage Rate (APR) มีค่าเป็นเท่าไหร่? มันก็คือการเอาดอกเบี้ย 0.5% /เดือน * 12 เดือน/ปี = 6% ต่อปี ตรงๆ ง่ายๆ แบบนี้เลย (ซึ่งการคิด APR บางทีก็จะเรียกว่า Nominal Rate)

    แต่ถ้าถามว่า Effective Interest Rate (EIR) มีค่าเท่าไหร่? วิธีคิดคือ ต้องทำให้เป็นดอกเบี้ยทบต้น 12 รอบด้วย ดังนั้นจะคำนวณได้จาก (1+0.5%)^12 -1 = 6.168% ต่อปี ซึ่งจะเห็นว่ามันมากกว่า APR นิดหน่อย

    ซึ่งเวลาที่ธนาคารต่างๆ บอกดอกเบี้ยต่างๆ มักจะบอกเป็น APR ครับ แต่เวลาคิดดอกเบี้ยจริงๆ จะคิดแบบ EIR นะ (แถมไม่ได้คิดดอกเบี้ยทุกเดือน แต่คิด Compound ทุกวันด้วยซ้ำ)

    ดังนั้นถ้าบอกว่า ดอกเบี้ยต่อปี คือ 10% APR เวลาที่คิด EIR ก็อาจจะได้ค่าต่างกัน ถ้าความถี่ในการคิดดอกเบี้ยทบต้นต่างกัน (ยิ่งถี่ยิ่ง EIR สูงขึ้น)

    อธิบายละเอียดยิบเรื่องการเงิน NPV, XNPV, IRR, XIRR ต่างกันยังไง ใช้อะไรดี? 41

    ซึ่งการคิด NPV ที่เราเรียนรู้ไป ตัว %Rate ก็ต้องเป็น EIR ต่อ Period ของ Cash Flow นั้นๆด้วยนะครับ

    กรณีที่ Cashflow สอดคล้องกับความถี่การคิดดอกเบี้ย

    ตัวอย่างเช่นแบบนี้ครับ ตัวข้างบนคิดดอกเบี้ยปีละครั้ง ตัวล่างคิดดอกเบี้ยเดือนละครั้ง ถ้ามันสอนคล้องกับ Cashflow ที่ให้มาก็จะง่ายหน่อย คือให้คิด EIR ต่อ Period นั้นๆ เลย

    อธิบายละเอียดยิบเรื่องการเงิน NPV, XNPV, IRR, XIRR ต่างกันยังไง ใช้อะไรดี? 42

    ถ้า Cashflow ไม่สอดคล้องกับความถี่การคิดดอกเบี้ย

    แต่ถ้า Cashflow ไม่สอดคล้องกับ Period การคิดดอกเบี้ย ก็จะยุ่งยากขึ้น เช่น Cashflow มีเดือนละครั้ง แต่ดันคิดดอกเบี้ยทุกวัน แบบนี้จะเป็นยังไงมาดูกัน

    ทางเลือกแรกก็คือ ทำให้ %Rate มันสอดคล้องกับ Period Cashflow ซะ เช่น ถ้า CF มาเดือนละครั้ง เราก็ต้องทำ EIR แบบต่อ 1 เดือนซะ

    แต่ปัญหาอยู่ที่ว่า จะคิดว่า 1 เดือน ต้อง Compound ดอกเบี้ยทุกวันกี่รอบดี? 30, 31 หรือจะเป็น 365/12 รอบ? ซึ่งค่าที่ได้ไม่เท่ากัน

    อย่างไรก็ตาม จะเห็นว่าค่าที่ได้ก็จะไม่ต่างจากการคิด Compound เดือนละรอบ (901.966) นักหรอกครับ… ถ้าไม่ซีเรียสมากก็คิดว่า Compound เดือนละรอบไปเลยก็ได้

    อธิบายละเอียดยิบเรื่องการเงิน NPV, XNPV, IRR, XIRR ต่างกันยังไง ใช้อะไรดี? 43

    คราวนี้สมมติว่า ถ้าเราสามารถลงรายละเอียดวันที่ ที่เกิด Cash Flow ได้เลยล่ะ มันจะคำนวณ NPV ได้เท่าไหร่? ถ้ามัน Compound ทุกวัน แต่ Cashflow มาทุกสิ้นเดือน โดยที่เริ่ม CF 1 ที่สิ้นมกรา 2021 โดยที่ผสมใส่ Cashflow เป็นรายวันเลยให้ครบทุกวัน (วันที่ไม่มี CF ต้องใส่เป็น 0 ไปนะ ห้ามเว้น แต่ในรูปผม Hide Row ไว้) จะเห็นว่าได้ผลลัพธ์เป็น 902.826 ซึ่งก็ไม่ได้ตรงกับตัวไหนเลย (แต่ตัวนี้เป๊ะสุด จริงมั้ย?)

    อธิบายละเอียดยิบเรื่องการเงิน NPV, XNPV, IRR, XIRR ต่างกันยังไง ใช้อะไรดี? 44

    XNPV และ XIRR คิดตามวันที่เกิด Cash Flow จริงๆ

    จริงๆ แล้วถ้าเราสามารถระบุวันที่ของ Cashflow ได้ และไม่อยากมาใส่ข้อมูลทุกวันแบบตารางข้างบน ทาง Microsoft จึงได้มีการพัฒนาฟังก์ชัน XNPV และ XIRR ขึ้นมา ซึ่งเป็นฟังก์ชันที่เราจะต้องระบุวันที่ ที่เกิด Cashflow แต่ละก้อนควบคู่ไปด้วย ซึ่งมันจะฉลาดกว่า NPV ธรรมดาตรงที่มันไม่ต้อง Assume ว่าแต่ละ Cashflow มีระยะห่างเท่ากัน (เพราะเราระบุวันที่ให้แล้วไง) อย่างไรก็ตาม ตัว %Rate ของ XNPV จะต้องใส่เป็น EIR ต่อ 1 ปีเท่านั้นนะครับ (อันนี้ไม่เกี่ยวกับ Period ของ Cashflow) เช่น

    การใช้ XNPV เราจะสามารถเลือกให้ครอบคลุม CF0 ได้เลย ไม่ต้องเว้นไว้แบบ NPV ปกติ โดยที่ XNPV จะไม่ Discount CF0 แต่จะ Discount CF อื่นๆทั้งหมดไปยังวันที่ของ CF0 นั่นเอง

    จะเห็นว่า ถ้าเราใช้ XNPV เราแค่ระบุ CF ตามวันที่ที่เกิด CF นั้นๆ พอ ไม่ต้องใส่ 0 ให้ครบทุกวัน ซึ่งชีวิตจะง่ายขึ้นมาก และค่าที่ได้ก็ยังถูกต้องด้วย คือ ได้ 902.826 ตามตัวอย่างข้างบนเป๊ะเลย

    อธิบายละเอียดยิบเรื่องการเงิน NPV, XNPV, IRR, XIRR ต่างกันยังไง ใช้อะไรดี? 45

    Assumption สำคัญ ของ XNPV

    XNPV นั้นดูเหมือนจะ Perfect กว่า NPV ปกติทุกอย่าง อย่างไรก็ตาม XNPV มันมี Assumption สำคัญอย่างหนึ่งก็คือ สูตร XNPV นั้นทำการ Discount บนฐานปีที่มี 365 วันเสมอ ดังนั้น ถ้า Cashflow จริงๆ มี 366 วัน ตัว XNPV มันก็จะได้ผลลัพธ์ไม่เท่ากับการ Discount Manual ด้วย PV ปกตินะครับ

    อธิบายละเอียดยิบเรื่องการเงิน NPV, XNPV, IRR, XIRR ต่างกันยังไง ใช้อะไรดี? 46

    จะเห็นว่าถ้ามี 366 วันเมื่อไหร่ XNPV มันก็จะ Discount ผิดคือได้น้อยไปนิดหน่อย (หลักทศนิยม) แต่ถ้ามีระยะห่างของวันในแต่ละ Cash Flow ไม่เท่ากัน (เช่นบางปีมี 365 วัน บางปีมี 366 วัน) เจ้า NPV ธรรมดาก็ถือว่าคำนวณผิดไปนิดหน่อยอยู่ดี…

    เช่น ลองดูตัวอย่างนี้ได้ กลับมา Compound ปีละครั้ง แบบ Basic เลย

    อธิบายละเอียดยิบเรื่องการเงิน NPV, XNPV, IRR, XIRR ต่างกันยังไง ใช้อะไรดี? 47

    จะเห็นว่า ถ้าจำนวนวันในแต่ละปีห่างกัน 365 วันตลอด XNPV จะคำนวณได้เท่ากับ NPV เป๊ะเลย (ซึ่งหาช่วงเวลาที่จะมี 365 ปีตลอดหลายๆ ปียากอยู่นะ) แต่พอเรามาดูช่วงเวลาปกติ ที่จะมี 365 วันบ้าง 366 วันบ้าง จะเห็นว่า XNPV นั้นมีค่าน้อยกว่า NPV เล็กน้อย เพราะว่าการ Discount CF กลับไปยังจุดปัจจุบัน มันใช้เวลามากขึ้น 1 วันนั่นเอง (แม้จะผิดนิดหน่อย)

    สรุปแล้วใช้อะไรดี?

    ความเห็นของผมคือ ค่า XNPV จะถูกต้องมากกว่า NPV โดยเฉพาะอย่างยิ่งหากมี Cash Flow ที่ระยะห่างไม่เท่ากันเมื่อไหร่นี่ต้องใช้ XNPV เท่านั้นเลยครับ แม้ว่าปีที่มี 366 วันค่ามันจะผิดไปนิดหน่อย แต่ส่วนตัวผมคิดว่ามันเล็กน้อยมากๆ ครับ

    แต่ถ้าเราสามารถ Assume ได้ว่า CF แต่ละก้อนห่างกันเท่าๆ กันหมด เราก็สามารถใช้ NPV ได้เช่นกันนะครับ ค่าที่ได้ก็ไม่ได้ต่างจาก XNPV ขนาดนั้นนะ

    อย่างไรก็ตามใน DAX ของ Power BI และ Power Pivot จะไม่มี NPV ธรรมดาให้ใช้นะครับ อันนั้นก็ต้องเลือก XNPV เท่านั้นล่ะ

    แล้ว XIRR ล่ะ?

    ถ้าเราเข้าใจตัว XNPV แล้ว เจ้า XIRR ก็ใช้งานเหมือนๆ กันเลยครับ ซึ่งความหมายของวันคือ จะคำนวณ %Rate EIR ต่อปี ที่ทำให้ XNPV เป็น 0 เป๊ะ นั่นเองครับ ซึ่งผลจาก XIRR จะมีหน่วยเป็นต่อ 1 ปีเสมอนะครับ

    ดังนั้นข้อสรุปของการคิด IRR ก็เช่นเดียวกันครับ ถ้ามี Cash Flow ระยะห่างไม่เท่ากัน ยังไงก็ควรใช้ XIRR มากกว่า IRR ครับผม

    xnpv xirr npv irr finance

    ค่าที่ได้ในที่นี้ คิดออกมาแล้ว XIRR ได้ % มากกว่า IRR เล็กน้อยครับ แปลว่าในความเป็นจริง เราได้ %Return จาก Project นี้มากกว่าที่เคยคิดได้จาก IRR นิดหน่อยนะ 555

    สรุปของสรุป

    ถ้าคุณใช้ DAX ใน Power BI หรือ Power Pivot คุณต้องใช้ XNPV กับ XIRR เท่านั้น ไม่มีทางเลือก

    ถ้าคุณใช้ Excel แล้วสามารถระบุวันที่ที่เกิด CF ได้ ควรใช้ XNPV กับ XIRR

    แต่ถ้าคุณใช้ Excel แล้วไม่สามารถระบุวันที่ได้ หรือว่าคิดว่า Assumption เรื่องระยะห่างของ CF ต้องเท่ากันนั้น ok สำหรับโปรเจคคุณ คุณก็ใช้ NPV กับ IRR ปกติได้เช่นกัน (ค่าที่ได้แต่ละวิธีก็ไม่ได้ต่างกันมากหรอครับ)

  • สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft – Part2

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft – Part2

    เอาล่ะ ในที่สุดเราก็มาถึงตอนที่ 2 ของซีรีส์นี้กันแล้วครับ ซึ่งในตอนนี้เราจะมาลงมือแกะสูตรว่าคนทำ Template เค้าใช้สูตรยังไงในการแก้ปัญหา Sudoko ออกมาได้ ซึ่งก่อนจะเข้าใจสูตรได้ สิ่งหนึ่งที่ต้องทำความเข้าใจก่อนก็คือหลักการแก้ปัญหา ดังนั้นเรามาดูกันดีกว่าว่าหลักการแก้ปัญหาของเค้าคืออะไร

    ปกติแล้วการเล่น Sudoku มันคือ การต้องใส่เลข 1-9 ลงไปในช่องว่าง โดยที่แต่ละแถว แต่ละคอลัมน์ และแต่ละพื้นที่สี่เหลี่ยม 3×3 นั้น มีเลข 1-9 ไม่ซ้ำกันเลย (คนที่มาอ่านบทความนี้ถึงตอนที่ 2 ได้น่าจะพอรู้กติกาอยู่แล้วเนอะ)

    ในแต่ละช่องแรกเริ่มเดิมทีจะมีเลขที่เป็นไปได้ 9 ตัว… ดังนั้นแนวทางแก้ปัญหาคือ เราต้องดูว่ามีเลขอะไรที่โผล่มาแล้วในแถว ในคอลัมน์ และในพื้นที่บ้าง ถ้ามีเลขไหนไปแล้ว เราก็จะตัดเลขนั้นทิ้งจากเลขที่เป็นไปได้ ตัดไปเรื่อยๆ ถ้าเหลือเลขที่เป็นไปได้แค่ตัวเดียว เราก็มั่นใจได้เลยว่าเลขนั้นต้องเป็นคำตอบอย่างแน่นอน ถ้าเป็น Sudoku แบบง่ายหลักการง่ายๆ แค่นี้ ซึ่งเราจะมาดูแบบง่ายกันก่อนนะครับ

    อย่าลืม Unprotect Sheet

    ทีนี้พอเรารู้หลักการแล้ว เราจะมาเริ่มแกะสูตรกัน แต่ปรากฏว่าเรามองไม่เห็นสูตรที่เค้าเขียนไว้ เพราะเค้าทำการ Protect Sheet ไว้อยู่ ดังนั้นให้เราทำการไปที่ Review -> Unprotect Sheet ก่อน

    สูตรที่ Final Position Board

    ถ้าเรา Double Click สูตรใน B15 จะเห็นเป็นดังนี้

    =IF(COUNT($W$5:$Y$7)=1,SUM($W$5:$Y$7),IF(COUNT($AZ$5:$BB$7)=1,SUM($AZ$5:$BB$7),""))
    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft – Part2 48

    จะเห็นได้ว่า มันใช้หลักการ Basic อย่างที่เราคิดนี่แหละ โดยจะเช็ค Possible Numbers ในตารางฝั่งซ้ายก่อน ถ้ามีเหลือ possible number ตัวเดียว (ใช้การ COUNT) ก็จะเอาตัวนั้นเลย (ใช้การ SUM) ถ้ามีหลายตัวค่อยเช็คฝั่งขวาด้วยหลักการเดียวกันคือถ้ามีตัวเดียวเอาตัวนั้น แต่ถ้ามีหลายตัวจะปล่อยให้เป็นช่องว่างไปด้วย “” (แสดงว่ายังไม่แน่ใจในคำตอบนั่นเอง)

    ดูสูตรใน Possible Number ตารางซ้าย

    ถ้าลองดับเบิ้ลคลิ๊กที่ AU8 จะได้ดังนี้

    =IF(OR(GameState=0,$J$6=1,$J$16=1,AND($J$6="",OR($J$16=1,$J$16=""),$B$16<>1,$C$16<>1,$D$16<>1,$E$16<>1,$F$16<>1,$G$16<>1,$H$16<>1,$I$16<>1,$J$15<>1,$J$17<>1,$J$18<>1,$J$19<>1,$J$20<>1,$J$21<>1,$J$22<>1,$J$23<>1,$H$15<>1,$I$15<>1,$J$15<>1,$H$16<>1,$I$16<>1,$H$17<>1,$I$17<>1,$J$17<>1,OR($W$5<>"",$Z$5<>"",$AC$5<>"",$W$11<>"",$Z$11<>"",$AC$11<>""),OR($AF$5<>"",$AI$5<>"",$AL$5<>"",$AF$11<>"",$AI$11<>"",$AL$11<>""),OR($AO$14<>"",$AO$17<>"",$AO$20<>"",$AR$14<>"",$AR$17<>"",$AR$20<>""),OR($AO$23<>"",$AO$26<>"",$AO$29<>"",$AR$23<>"",$AR$26<>"",$AR$29<>""))),1,"")

    ตอนนี้อย่าเพิ่งสนใจว่าเค้าเขียนสูตรแบบไหน ทำไมถึงดูถึกขนาดนี้ เอาเป็นว่าเราสนใจหลักการก่อนนะครับ วิธีเขียนสูตรให้สามารถ copy paste ง่ายๆ เดี๋ยวค่อยว่ากันทีหลัง

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft – Part2 49

    จะเห็นว่าสูตรมันพยายามเขียน Logic ออกมาว่าเมื่อไหร่ควรจะแสดงเลข 1 (ช่อง AU8 เป็น Possible Number ของเลข 1) เมื่อไหร่ควรจะปล่อยเป็น Blank

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft – Part2 50

    สูตรแม้จะดูวุ่นวาย แต่ส่วน Logical Test ก็มีหลักการดังนี้

    ถ้าตรงตามเงื่อนไขอย่างน้อยอันใดอันหนึ่งของสี่เงื่อนไขนี้ จะได้ผลลัพธ์เป็น 1 ทันที นอกนั้นจะได้เป็น Blank

    • GameState=0
    • ช่อง Starting Position ใส่เป็นเลข 1 ไว้แล้ว
    • ช่อง Final Position เป็นเลข 1
    • เงื่อนไขพิเศษ (เงื่อนไขข้อนี้แหละที่ยาวมากๆ เดี๋ยวขอเขียนอธิบายเพิ่ม)

    เงื่อนไขพิเศษมี Logic ดังนี้ (โดยทุกข้อย่อยต้องเป็นจริง)

    • ช่อง Starting Position ยังว่าง (ตัวนี้จะช่วยตัด Possible Number ได้มหาศาล)
    • ช่อง Final Position เป็นเลข 1 หรือยังว่าง
    • Final Position ในแถวเดียวกัน (ยกเว้นช่องตัวเอง) ไม่มีเลข 1
    • Final Position ในคอลัมน์เดียวกัน (ยกเว้นช่องตัวเอง) ไม่มีเลข 1
    • Final Position ในพื้นที่ 3×3 (ยกเว้นช่องตัวเอง) ไม่มีเลข 1
    • Possible Number เป็นไปตามเงื่อนไขนี้ (ซึ่งก็ซับซ้อนอีก)
    =AND(...,
    OR($W$5<>"",$Z$5<>"",$AC$5<>"",$W$11<>"",$Z$11<>"",$AC$11<>""),
    OR($AF$5<>"",$AI$5<>"",$AL$5<>"",$AF$11<>"",$AI$11<>"",$AL$11<>""),
    OR($AO$14<>"",$AO$17<>"",$AO$20<>"",$AR$14<>"",$AR$17<>"",$AR$20<>""),
    OR($AO$23<>"",$AO$26<>"",$AO$29<>"",$AR$23<>"",$AR$26<>"",$AR$29<>"")
    )
    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft – Part2 51

    คือดูในพื้นที่แนวเดียวกันว่าใน block นั้นอย่างน้อยตัวในตัวหนึ่งใน block จะต้องไม่ว่าง (แต่ละ block อยู่ภายใต้ OR 1 ชุด) แต่ไม่สนใจตัวที่อยู่ในแถวและคอลัมน์เดียวกันนะ โดยเงื่อนไขจะต้องเป็นจริงทุก block (เพราะว่าอยู่ภายใต้ AND)

    การเขียนแบบนี้หมายถึงอะไร? ทำไมต้องเช็คว่าตัวใดตัวหนึ่งจะต้องไม่ว่างด้วย?

    การเช็คว่าตัวใดตัวหนึ่งไม่ว่าง มันก็คือ การมองว่าในแต่ละ block 3×3 มีการลงเลข possible number นั้นๆ ไปแล้วในแนวอื่นที่ไม่ตรงกับตัวมันนั่นเอง เรียกได้ว่าถ้ามีการลงเลข 1 ในแนวอื่นแล้ว แสดงว่าช่องมันเองยังเป็นไปได้ที่จะเป็นเลข 1 อยู่นั่นเองครับ

    สูตรทั้งหมดเป็นสูตรแบบงูกินหาง

    ถ้าสังเกตดู สูตรใน Final Position มีการอ้างอิงจาก Possible Number และสูตรใน Possible Number ก็มีการคำนวณจาก Final position ด้วย แถม Possible Number ก็อ้างอิงกันเองพันกันมั่วไปหมดอีก ถ้าเราใช้สูตรพวกนี้ในโหมดการทำงานปกติ มันจะด่าเราว่าเราเขียนสูตรแบบ Circular Reference ทันที

    เพื่อให้สูตร Circular Reference ทำงานได้ เราจึงต้องเปิดโหมดการทำงานแบบ Iterative Calculation ด้วย ซึ่งใน Template นี้มันเลือกไว้ให้อยู่แล้ว และตั้งให้ทำทีละ 1 Step แถมทำในโหมด Manual Cal ที่ต้องกด F9 เองด้วย

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft – Part2 52

    ลองใส่เลขทดสอบสูตร

    ลองทดสอบการทำงานของสูตร โดยใส่ Starting Position เป็น 1 ลงไปช่องนึง แล้วปรับ Game Stage เป็น 1 แล้ว F9 รัวๆ

    จะเห็นว่าการกด F9 ทีแรก จะทำให้ Possible Number ในพื้นที่ AR8:AT10 นั้นมีเลข 1 โผล่มาตัวเดียวเลย (เพราะเงื่อนไขช่อง Starting Position ยังว่าง $I$6=”” นั้นเป็นเท็จไปแล้ว) ทำให้ Final Position สามารถมีเลข 1 โผล่ออกมาได้เพราะ COUNT ได้ตัวเดียวในที่สุด

    พอกด F9 ครั้งต่อๆ ไปจะทำให้ Possible Number ได้มีการตัดเลข 1 ในแนวเดียวกันออกจนหมดอีกด้วย อันนี้เป็นเพราะว่่าใน Final Position มีการลงเลข 1 ไปแล้วในแนวเดียวกัน ทำให้เงื่อนไขพิเศษที่เช็คใน Final Position เป็น FALSE นั่นเอง พอเป็น FALSE ทำให้ได้ค่า “” ออกมาในที่สุด

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft – Part2 53

    ผมลองใส่เลข 1 เพิ่ม ในระดับที่มันควรตอบได้แล้วว่าเลข 1 ตัวสุดท้ายอยู่ที่ไหน แต่มันก็ดันไม่ให้คำตอบออกมา เพราะ Possible Number ยังคงมีหลายเลขอยู่ แสดงว่า Logic เท่านี้ยังไม่เพียงพอ

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft – Part2 54

    ในทีุ่ดก็ถึงเวลาของ Solution Numbers ที่เป็น Game Stage 2 ซักที

    หากไปดูสูตรใน BL14 จะเห็นสูตรนี้

    =IF(AND(GameState=2,OR(AND($W$14="",$Z$14="",$AC$14="",$AF$14="",$AL$14="",$AO$14="",$AR$14="",$AU$14=""),AND($AI$5="",$AI$8="",$AI$11="",$AI$17="",$AI$20="",$AI$23="",$AI$26="",$AI$29=""),AND($AF$14="",$AL$14="",$AF$17="",$AI$17="",$AL$17="",$AF$20="",$AI$20="",$AL$20=""))),1,"")
    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft – Part2 55

    เงื่อนไขที่มันจะแสดงเลข Solution เช่นเลข 1 ออกมาคือ ต้องมี Game Stage เป็น 2 และต้องทำเงื่อนไขพิเศษของ Solution Board ดังนี้ (อย่างน้อยข้อใดข้อหนึ่งต้องเป็นจริง)

    • ในแถวเดียวกันนั้นว่างทั้งหมด
    • ในคอลัมน์เดียวกันนั้นว่างทั้งหมด
    • ในพื้นที่ Block เดียวกันนั้นว่างทั้งหมด

    นี่คือสาเหตุที่ว่าพอเราปรับ Game Stage เป็น 2 แล้วกด F9 มันจึงมีเลขโผล่มาที่ Solution Numbers ซึ่งทำให้เลขโผล่ที่ Final Position ได้ในที่สุด (Game Stage2 ก็ยังสามารถคำนวณ Possible Numbers เพิ่มได้อยู่นะ)

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft – Part2 56

    สรุป

    และนี่ก็คือหลักการคิดของตัว Sudoku Solver นี้ครับ ซึ่งสูตรที่แสดงออกมาใน Template ล่าสุดที่เราใช้กันอยู่นี้นั้นดูถึกอย่างมาก ซึ่งจริงๆ แล้วในอดีต Template นี้สูตรไม่ได้ถึกขนาดนี้ แต่เกิดจากการเขียนสูตรพวก INDEX ผสมกับ ROW/COLUMN/MOD ที่ซับซ้อนผสมอยู่ใน Defined Name ต่างหาก (ไม่แน่ใจเหมือนกันว่าทำไมถึงมาแก้สูตรให้กลายเป็นแบบถึก)

    ดังนั้นในเมื่อเราได้รู้หลักการในการคิดแล้ว ในตอนหน้าเราจะพยายามมาแก้สูตรใน Template นี้ให้ถึกน้อยลงกันดีกว่า เช่น ทำให้มัน Copy Paste ได้สะดวกขึ้น ไม่ต้องมานั่งเขียนสูตรใหม่ทุกช่อง ตายพอดี

  • สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft – Part1

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft – Part1

    ผมได้เคยแนะนำ Template ตัวนึงที่เจ๋งมากๆ จากทาง Microsoft นั่นก็คือ Sudoku puzzle solver ซึ่งนี้สามารถโหลดมาใช้ได้ฟรีๆ ที่นี่ https://templates.office.com/en-us/sudoku-puzzle-solver-tm10080972

    ทุกครั้งที่เห็นไฟล์นี้ผมเองรู้สึกทึ่งมากๆ เพราะมันเป็น Template ที่สามารถแก้ปัญหา Sudoku ได้ด้วยสูตร Excel ล้วนๆ (โดยใช้เทคนิค Iterative Calculation) โดยไม่ได้พึ่งพาการเขียนโปรแกรมหรือการใช้ add in Solver อะไรทั้งสิ้น ซึ่งน่าอัศจรรย์มากๆ !

    ใน Series นี้ผมจะสอนใช้งาน Template นี้ และจะพยายามแกะสูตรว่ามันใช้วิธีการยังไงในการทำงานจนได้คำตอบออกมาให้เราครับ ใครสนใจก็อ่านต่อยาวๆ ได้เลย ซึ่งบทความภาคแรกนี้จะเป็น Part การใช้งาน Template ก่อนนะครับ

    วิธีการใช้งานแบบง่าย

    ก่อนอื่นก็ไปหาคำถาม sudoku มาจากในเน็ต เดี๋ยวเราเอาโจทย์ระดับกลางๆ มาละกัน สมมติเป็นอันนี้

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft - Part1 57

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

    ก่อนอื่นให้กรอกตัวโจทย์ลงใน Starting Position ให้ครบ แล้วแก้ Game State ให้เป็นเลข 1 แล้วกด F9 เพื่อ Calculate จะเห็นว่าตัวเลขใน Possible Numbers นั้นหายไปบางส่วน ก็ให้กด F9 เพื่อ Cal ต่อไป

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft - Part1 58

    แล้วก็กด F9 ต่อไปอีก มันจะตัดตัวที่เป็นไปไม่ได้ออกไปเรื่อยๆ

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft - Part1 59

    กด F9 ต่อไปอีก มันจะเริ่มแสดงคำตอบเพิ่มมาแล้ว เช่น เลข 5 ที่ผมวงไว้

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft - Part1 60

    กด F9 ไปเรื่อยๆ จนได้ครบทุกคำตอบ จบ…

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft - Part1 61

    วิธี Reset ค่าใหม่

    ให้ลบค่าใน Starting Position ออกให้หมด (ลากคลุมแล้วกดปุ่ม Del บน Keyboard ได้เลย) จากนั้นเลือก Game Stage เป็น 0 แล้วกดปุ่ม F9 เพื่อ Cal ใหม่ไปรัวๆ จนกว่าค่าจะหายหมด

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft - Part1 62

    ลองโจทย์แบบยากขึ้น

    คราวนี้เราจะลองโจทย์ยากดูบ้าง ว่าจะติดปัญหาอะไรหรือไม่ โดยโจทย์ที่ผมลองจะเป็นอันนี้

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft - Part1 63

    พอลองกรอกลงไปแล้ว ตั้ง Game Stage เป็น 1 แล้ว F9 รัวๆๆๆ มันจะไปสุดที่นี่ คือ กด F9 ต่อก็ไม่มีคำตอบเพิ่มแล้ว

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft - Part1 64

    วิธีทำต่อคือให้ตั้งค่า Game Stage เป็น 2 แล้วค่อย F9 ต่อ คราวนี้คำตอบจะเริ่มโผล่มาแล้ว

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft - Part1 65

    พอ F9 ไปเรื่อยๆ สุดท้ายก็จะได้คำตอบครบ จบ!

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft - Part1 66

    แล้วมีโจทย์ที่ Template แก้ไม่ได้มั้ย?

    มีสิ อย่างอันนี้คือระดับที่โคตะระยากมากๆๆๆๆ ผมลองใส่โจทย์นี้ไปแล้วแม้จะลอง Set Game Stage เป็น 2 ก็ตาม มันแก้เพิ่มไม่ได้เลยซักกะค่าเดียว 555

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft - Part1 67

    Game Stage 1 สุดที่เท่านี้

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft - Part1 68

    Game Stage 2 ก็ไม่ต่างกัน

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft - Part1 69

    ซึ่งวิธีไปต่อคือ เราต้องเป็นคนช่วยโปรแกรมพิมพ์ค่าที่เป็นไปได้ เพิ่มลงไปใน Starting position แล้วค่อยกด F9 ต่อ ซึ่งตรงนี้แหละที่ยาก เพราะโปรแกรมมันยังคิดไม่ออกเลยว่าจะใส่ค่าไหนดี 555

    มันก็ต้องดูว่าช่องไหนเหลือค่าที่เป็นไปได้น้อยๆ แล้วก็ต้องทดลองเอาทีละค่า ว่ามันเปฺ็นไปได้มั้ย? เช่น ที่ผมวงไว้ จะมีที่เป็นไปได้ 2 ค่า กับ 3 ค่า

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft - Part1 70

    คือพอลองใส่ค่าดูแล้ว F9 ไปเรื่อยๆ ถ้าสุดท้าย Final Position มันตัน ก็แปลว่าเลขที่เราลองมันไม่ใช่ครับ เช่น แบบนี้

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft - Part1 71

    ถ้าจะลองค่าใหม่ก็ต้องไล่ Set Stage เป็น 0,1,2 ใหม่อีกทีนะครับ…

    ผมลองมั่วอีกที เกือบออก แต่ก็ไม่ออกครับ 55

    สอนใช้งานและแกะสูตร Template Sudoku Solver ของ Microsoft - Part1 72

    สรุปแล้ว ข้อนี้ตอบอะไรกันนะ… ใครหาคำตอบได้บอกที ยากจริงๆ T_T

    และนี่ก็คือวิธีใช้งาน Template นะครับ ส่วนเรื่องการแกะสูตร รออ่านต่อหน้าได้เลย ยากสะใจแน่นอน

  • สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel

    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel

    คำถามเกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel เป็นคำถามยอดฮิตอีกอันนึงที่คนถามกันมาเยอะมาก แต่ผมก็ยังไม่เคยสรุปเนื้อหาเกี่ยวกับเรื่องนี้ซักที และผมก็คิดว่าถึงเวลาแล้วล่ะที่จะสรุปเนื้อหาเรื่องนี้ให้ทุกคน และมันก็ออกมาเป็นบทความนี้นั่นเองนะครับ

    โดยที่ผมจะมีไฟล์อยู่ 2 ไฟล์ คือ Book1 กับ Book2 โดยที่ผมต้องการ Link ข้อมูลจาก Book1 ไปยัง Book2 นะครับ

    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 73

    version วีดีโอ

    การ Link ข้อมูลข้ามไฟล์ Excel ผมก็แบ่งออกเป็น 3 วิธีหลักๆ นั่นคือ ใช้สูตร ใช้ VBA และ ใช้ Power Query ครับ

    ใช้สูตร

    การใช้สูตรแบบที่ Simple ที่สุด ก็คือ การใช้เครื่องหมายเท่ากับ link ไปทีละช่องที่ต้องการเลย คือ

    1. ไปที่ช่องปลายทาง
    2. พิมพ์เครื่องหมายเท่ากับ
    3. แล้วเอา Mouse จิ้มไปที่ช่องต้นทาง (ใช้วิธีเอา Mouse ไปจิ้มข้ามไฟล์เอานะ ไม่ต้องไปพิมพ์พวก [ ] เอง)
    4. กด Enter
    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 74

    แต่ถ้า Link แบบนี้ เราจะ Copy Paste ให้คลุมทุกช่องที่ต้องการทันทีไม่ได้ เพราะมัน Lock$ ไว้ทำให้ได้ตัวเดิมตลอด ดังนั้นเราจะต้องกด F4 เพื่อปลด $ ออกก่อนดังนี้ แล้วค่อย Copy Paste

    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 75

    แต่ถ้าเรา Link สูตรแบบ Array (Link ทีเดียวหลายช่อง) ก็ทำได้เช่นกัน ดังนี้

    =[Book1.xlsx]Sheet1!$A$1:$B$3
    • ถ้าใช้ Excel 365 เราแค่เลือกที่ A1 ของปลายทาง แล้ว =คลุมทุกช่องต้นทาง แล้วกด Enter ได้เลย
    • ถ้าใช้ Excel version เก่า ต้องเลือก A1:B3 ของปลายทางไว้ก่อน แล้ว=คลุมทุกช่องต้นทาง แล้วกด Ctrl+Shift+Enter
    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 76

    ถ้าที่ต้นทางข้อมูลบางช่องขาดหายไป มันจะขึ้นเลข 0 มาแทน

    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 77

    เราอาจใช้ IF ดักไว้ก็ได้

    =IF([Book1.xlsx]Sheet1!$A$1:$B$3="","",[Book1.xlsx]Sheet1!$A$1:$B$3)
    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 78

    การใช้ฟังก์ชันต่างๆ

    นอกจากใช้ =Link ตรงๆ แล้ว เราก็สามารถเขียนสูตร ใช้ฟังก์ชันต่างๆ ข้ามไฟล์ได้ตามปกติ (ใช้วิธีเอา Mouse ไปจิ้มข้ามไฟล์เอานะ ไม่ต้องไปพิมพ์พวก [ ] เอง)

    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 79

    การ Link ด้วยสูตรทั่วไป รวมถึงพวก VLOOKUP เราจะสามารถปิดไฟล์ต้นทางได้ ไฟล์ปลายทางจะยังเห็นข้อมูลอยู่โดยที่สูตรไม่พัง (เพราะมันเก็บไว้ใน Cache ของไฟล์ปลายทาง ขนาดของไฟล์ปลายทางจะใหญ่ขึ้นด้วย)

    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 80

    แต่มันจะมีสูตรบางตัว ที่จะไม่สามารถใช้ได้ หากปิดไฟล์ต้นทาง เช่น พวก SUMIFS COUNTIFS รวมถึงสูตรที่เป็น Volatile Function (ต้องคำนวณใหม่ตลอดเวลา) เช่น OFFSET INDIRECT เป็นต้น

    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 81

    พอปิดไฟล์ต้นทางแล้ว หากมีการเข้าไปแก้สูตรแล้ว Enter ใหม่ หรือแก้ bb เป็น cc เพื่อบังคับให้ Calculate ใหม่ มันจะเจ๊งเลย

    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 82

    การเปลี่ยนตำแหน่งไฟล์ต้นทาง

    หากเรา Link สูตรไว้แล้ว เช่น VLOOKUP แล้วมีการเปลี่ยนตำแหน่งไฟล์ต้นทาง เวลาเปิดไฟล์ปลายทางขึ้นมาใหม่ มันจะบอกว่าหาไฟล์ต้นทางไม่เจอ

    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 83

    ถ้าเรากด Continue มันจะเอาค่าที่จำไว้มาใช้ (ซึ่งอาจไม่ใช่ค่าที่อัปเดทล่าสุดก็ได้) ดังนั้นทางแก้ที่เหมาะสมคือ ต้องกด Edit Links… แล้วกด Change Source… เพื่อแก้ที่อยู่ไฟล์ใหม่ซะ

    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 84

    ใช้ VBA

    วิธีต่อไปคือการใช้ VBA ซึ่งเราสามารถสั่งให้มันเอาค่าจากอีกไฟล์มาใส่ยังไฟล์ที่เราต้องการได้ ซึ่งถ้าเขียน Code ไม่เป็น ก็ใช้ Macro Recorder ที่อยู่ใน Ribbon Developer แล้ว Copy Paste ตามปกติได้ ซึ่งถ้าไล์เปิดไว้อยู่แล้ว ก็จะได้ Code ออกมาดังนี้

    Sub Macro1()
     '
     ' Macro1 Macro
     '
     '
         Windows("Book1.xlsx").Activate
         Range("A1:B3").Select
         Selection.Copy
         Windows("Book2.xlsx").Activate
         Range("A1").Select
         ActiveSheet.Paste
     End Sub

    แต่ code ทั้งบนจะใช้ได้ก็ต่อเมื่อเปิดไฟล์ค้างไว้ทั้งคู่ ดังนั้นเวลาเรา Record Macro ควรจะปิดไฟล์ต้นทางไว้ก่อน มันจะได้บันทึกการเปิดไฟล์ต้นทางไว้ด้วย ดังนี้

    Sub Macro2()
     '
     ' Macro2 Macro
     '
     '
         Workbooks.Open Filename:="D:\ThepExcel\link file\sub\Book1.xlsx"
         Range("A1:B3").Select
         Selection.Copy
         Windows("Book2.xlsx").Activate
         Range("A1").Select
         ActiveSheet.Paste
     End Sub

    จากนั้นเราค่อยเอา Macro2 นี้ไปสั่ง Run เมื่อกดปุ่ม หรือมี event บางอย่างอีกทีก็ได้

    ใช้ Power Query

    วิธีสุดท้ายที่จะแนะนำคือ Power Query ซึ่งทำงานได้ดีขณะที่ไฟล์ต้นทางปิดอยู่ครับ (ถ้าเปิดอยู่ ก็ต้อง save ก่อน จึงจะเห็นข้อมูลล่าสุด) ให้เลือก Get Data จากไฟล์ Excel แล้วเลือกไฟล์ต้นทางที่เราต้องการ

    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 85

    จากนั้นเลือก sheet หรือ table ที่ต้องการ และถ้าอยากตรวจสอบหรือดัดแปลงข้อมูลก่อนก็ให้กด Transform Data แต่ถ้ามั่นใจว่าข้อมูล ok ก็จะกด Load Data ออกมาเลยก็ได้

    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 86

    พอกด Transform Data ก็จะเปิด Power Query Editor ขึ้นมา ซึ่งในนี้เรายังทำอะไรได้อีกมาก เช่น ลบคอลัมน์ที่ไม่ต้องการ หรือ Filter ให้เหลือเฉพาะข้อมูลที่ต้องการได้เลย

    ถ้าข้อมูลดู ok แล้วกดกด Close & Load to… ได้เลย

    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 87

    จากนั้นก็เลือกได้ว่า จะเอา Data ออกมาเป็นอะไร เช่น Table และจะไว้ตรงไหนก็ได้

    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 88

    จะได้ผลลัพธ์ออกมาเป็น Table แบบนี้

    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 89

    ถ้ามีแก้ข้อมูลต้นทาง แล้ว Save แล้ว ให้มาที่ข้อมูลปลายทางแล้วกด คลิ๊กขวาที่ตารางปลายทาง แล้ว Refresh ได้เลย

    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 90

    ถ้ามีการย้ายตำแหน่งไฟล์ต้นทาง ให้ไปแก้ที่อยู่ได้ที่ Data Source Setting ตามรูปได้เลย

    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 91
    สรุปทุกอย่างที่ควรรู้เกี่ยวกับการ Link ข้อมูลข้ามไฟล์ Excel 92

    พอแก้ตำแหน่งไฟล์แล้ว คราวนี้ก็จะ Refresh ได้ครับ

    จบแล้ว

    ถ้าอ่านจบแล้ว ใครสงสัยตรงไหนหรือไม่คำถามอะไรก็ถามไว้ได้เลยนะครับ

  • วิธีดับเบิ้ลคลิ๊กแสดงข้อมูลรายะเอียดใน Pivot แบบ Data Model ให้เกิน 1000 บรรทัด

    วิธีดับเบิ้ลคลิ๊กแสดงข้อมูลรายะเอียดใน Pivot แบบ Data Model ให้เกิน 1000 บรรทัด

    บทความนี้เป็น Trick สั้นๆ ครับ ปกติแล้ว ถ้าเราใช้ Pivot Table แบบปกติ เราจะสามารถ Double Click ที่ผลลัพธ์แต่ละช่องเพื่อจะแสดงข้อมูลที่มาของเลขนั้นๆ ได้ครบเลย แต่ถ้าเป็น Pivot Table โหมด Data Model มันจะแสดงข้อมูลได้แค่ 1000 บรรทัดแรกของการ Filter นั้นๆ ซึ่งเป็นเรื่องที่น่าหงุดหงิดมาก

    ลองลงมือทำให้เกิดปัญหา Pivot ได้แค่ 1000

    สมมติเรามีข้อมูลสมมติโดยสร้างเป็นเลข 1-200,000 ไว้ (ผมใช้ Home->Fill-> Series ช่วยสร้างจะได้เร็วๆ)

    วิธีดับเบิ้ลคลิ๊กแสดงข้อมูลรายะเอียดใน Pivot แบบ Data Model ให้เกิน 1000 บรรทัด 93

    แล้วสร้างคอลัมน์ Group อีกซักอันให้มีกลุ่มละ 90,000 ตัว ด้วยการเขียนสูตรว่า

    =ROUNDUP(A2/90000,0)
    วิธีดับเบิ้ลคลิ๊กแสดงข้อมูลรายะเอียดใน Pivot แบบ Data Model ให้เกิน 1000 บรรทัด 94

    จากนั้นเรา convert เป็น Table ซะ แล้วเอาเข้า Pivot แบบ Data Model

    วิธีดับเบิ้ลคลิ๊กแสดงข้อมูลรายะเอียดใน Pivot แบบ Data Model ให้เกิน 1000 บรรทัด 95

    เรา Pivot ข้อมูลอะไรก็แล้วแต่ สมมติได้ดังนี้

    วิธีดับเบิ้ลคลิ๊กแสดงข้อมูลรายะเอียดใน Pivot แบบ Data Model ให้เกิน 1000 บรรทัด 96

    แล้วเราอยากรู้ว่าเลข 135000.5 มาจากข้อมูลบรรทัดไหนบ้าง เราก็กด ดับเบิ้ลคลิ๊กได้เลย มันจะสร้าง sheet ใหม่ แล้ว แสดงข้อมูลบรรทัดที่เป็นแหล่งที่มาของเลข 135000.5 นั้น (แสดงผลการ Drill Through จาก Filter Context นั่นเอง)

    ปัญหาคือ ถ้าเป็น Pivot ปกติจะแสดงครับ แต่ Pivot แบบ Data Model จะแสดงตัวอย่างแค่ 1000 บรรทัดแรก!

    วิธีดับเบิ้ลคลิ๊กแสดงข้อมูลรายะเอียดใน Pivot แบบ Data Model ให้เกิน 1000 บรรทัด 97

    ถ้าเราอยากเห็นมากกว่า 1000 แถวต้องทำไง?

    ให้เราไปแก้ Setting ของ connection ตามรูปนี้ โดยคลิ๊กขวาที่ ThisWorkbookDataModel แล้วเลือก Properties…

    วิธีดับเบิ้ลคลิ๊กแสดงข้อมูลรายะเอียดใน Pivot แบบ Data Model ให้เกิน 1000 บรรทัด 98

    จากนั้นแก้ตัวเลขใน OLAP Drill Through ให้เยอะๆ ไปเลย เช่น เท่ากับจำนวนแถว Excel

    วิธีดับเบิ้ลคลิ๊กแสดงข้อมูลรายะเอียดใน Pivot แบบ Data Model ให้เกิน 1000 บรรทัด 99

    คราวนี้ลบผลการ Drill Through อันเดิมที่ได้ 1000 แถวทิ้งไปซะ (ลบทั้งชีทเลยก็ได้) แล้วลองดับเบิ้ลคลิ๊กใหม่ครับ

    นี่ไง คราวนี้ออกมาครบเลย เย้!

    วิธีดับเบิ้ลคลิ๊กแสดงข้อมูลรายะเอียดใน Pivot แบบ Data Model ให้เกิน 1000 บรรทัด 100
  • ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering  แบบไม่ง้อ VBA

    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA

    การแบ่งกลุ่มข้อมูลนั้นจริงๆ สามารถทำได้หลายวิธี ซึ่งวันนี้ผมจะมานำเสนอวิธีที่เรียกว่า K-Means Clustering นั่นคือ ให้โปรแกรมพยายามจัดกลุ่มที่มีความใกล้เคียงกันเข้าอยู่เป็นกลุ่มเดียวกันได้ด้วยตัวมันเอง โดยที่เราไม่ต้องเป็นคนบอกมันว่าแบบไหนควรอยู่กลุ่มอะไร ซึ่งมันต้องมีการวน Loop คำนวณซ้ำๆ หลายรอบ

    หลายคนอาจคิดว่าการวน Loop จะต้องใช้ VBA เขียนโปรแกรมเอาแน่ๆ แต่ในบทความนี้ผมจะทำให้ดูว่า วิธีการเขียนสูตรธรรมดาๆ ในโหมดที่เรียกว่า Iterative Calculation ก็สามารถทำได้ครับ! รับรองว่าคุณจะได้เห็นแง่มุมใหม่ๆ ในการใช้สูตร Excel แบบที่ปกติไม่ค่อยได้เห็นแน่นอนครับ ^^

    ลองลงมือทำดู

    เราจะใช้ข้อมูลลูกค้าในห้าง อันนี้ https://www.kaggle.com/shwetabh123/mall-customers

    โดยที่ผมจะลองแบ่งกลุ่มจากข้อมูลแค่ 2 แกน คือ Annual Income (k$) และ Spending Score (1-100) เท่านั้นครับ ซึ่งหากลองทำ Scatter Plot จะได้ดังนี้

    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 101

    ซึ่งถ้าดูจากกราฟที่ออกมา ผมคิดว่าน่าจะแบ่งลูกค้าเป็น 5 กลุ่ม (เรียกจำนวนกลุ่มว่า k=5)

    ขั้นตอนต่อไป ผมสร้าง sheet ใหม่แล้วเราจะ random สร้างจุดขึ้นมา 5 จุดจาก Range ของข้อมูลที่มี เสร็จแล้วทำให้กลายเป็น Value ไว้ด้วย จะได้ไม่เปลี่ยนอีก (x คือ Income, y คือ spending)

    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 102

    จากนั้นคำนวณว่าแต่ละจุดอยู่ใกล้ Point กลางอันไหนเท่าไหร่ ด้วยสูตรระยะห่างระหว่างจุด จากความสัมพันธ์เพื่อคำนวณด้านตรงข้ามสามเหลี่ยมมุมฉากสมัยเด็กๆ (ผมมีเปลี่ยนชื่อคอลัมน์เป็น Income กับ spending ด้วยจะได้ง่ายๆ)

    Warning : การหาระยะห่าง ควรทำให้ข้อมูลตัวเลขมีปริมาณที่เป็น Standard ใกล้เคียงกันก่อน เพราะหากเลขเยอะๆ เช่น รายได้เป็นหมื่นเป็นล้าน มาหาระยะห่างกับเลขน้อยๆ เช่น อายุ ที่เป็นแค่หลักสิบ ระยะห่างจากรายได้มันจะกลับ effect ของอายุหมดเลย แต่พอดีข้อมูลนี้เลขมันค่อนข้างมีปริมาณพอๆ กันอยู่แล้วเลยไม่มีปัญหา

    =SQRT((x1-x2)^2+(y1-y2)^2)
    =SQRT(([@Income]-VLOOKUP(F$1,Pointกลาง!$A:$C,2,0))^2+([@Spending]-VLOOKUP(F$1,Pointกลาง!$A:$C,3,0))^2)
    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 103

    แล้วเราก็ดูว่าห่างจากจุดกลางอันไหนน้อยที่สุด จะถือว่าข้อมูลอยู่ในกลุ่มนั้น ซึ่งเราก็เขียนสูตรหาได้ดังนี้

    MinDistance (คอลัมน์ K) ก็ใช้ฟังก์ชัน MIN ปกติเลย

    =MIN(F2:J2)

    ส่วนอยู่กลุ่มไหน (คอลัมน์ L) คำนวณดังนี้

    =INDEX($F$1:$J$1,MATCH([@MinDistance],F2:J2,0))
    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 104

    จากนั้นกลับมาอีกชีทนึง แล้วผมก็ใช้ countifs เพื่อนับว่าแต่ละกลุ่มมีกี่จุด ดังนี้

    =COUNTIFS(Mall_Customers[อยู่กลุ่มไหน],Pointกลาง!A2)
    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 105

    ความหมายของ K-Means

    ขั้นตอนต่อไปคือ เราจะเอาจุดในกลุ่มเดียวกันมาหาค่าเฉลี่ย แล้วสถานปนาให้กลายเป็นจุด Center ตัวใหม่ แล้ววน Loop ทำแบบนี้ไปเรื่อยๆ จนกว่าจุด Center จะไม่เปลี่ยนอีกแล้ว ถึงจะจบขั้นตอน มันก็เลยเรียกว่า k-means ไงล่ะ เพราะเป็นการหาค่าเฉลี่ยของสมาชิกในกลุ่ม

    แล้วเราจะทำเรื่องแบบนี้ใน Excel ได้ยังไง…

    หลายคนอาจคิดว่ายังไงก็ต้องใช้ VBA ทำแน่ๆ แต่ในบทความนี้ผมจะลองทำอีกวิธีนึงนั่นก็คือ การใช้สูตรแบบ Iterative Calculation ครับ ซึ่งเป็นโหมดที่รองรับสูตรแบบงูกินหางหรือที่เรียกใช้ตัวเองซ้ำๆ ได้ โดยจะใช้งานได้จะต้องไปเปิดโหมดนี้ใน Excel Option ซะก่อน ซึ่งผมจะตั้งค่าให้มันทำทีละ 1 ครั้ง และเปิดโหมด Cal แบบ Manual ที่ต้องกด F9 ซะก่อน (จะได้เห็นภาพชัดๆ ว่าคืออะไรกันแน่?)

    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 106

    Iterative Calculation ทำงานยังไง?

    สมมติเราเขียนสูตรในช่อง F2 ว่า

    =F2+1

    ซึ่งจะเห็นว่าสูตรนี้มันเรียกข้อมูลจากตัวเองมาบวก 1 ซึ่งถ้าเป็นโหมดทำงานปกติใน Excel มันจะด่าเราว่าเป็น Circular Reference แล้วผลลัพธ์จะออกมาเป็น 0 ตลอด

    แต่ถ้าเราเปิดโหมด Iterative Calculation แล้ว สูตรนี้จะทำงานได้แบบไม่ Error โดยที่ถ้า Maximum Iteration เป็น 1 เมื่อกด F9 1 ทีมันก็จะคำนวณ 1 รอบ ทำให้ช่อง F2 มีค่าเพิ่มเรื่อยๆ ทีละ 1 หลังจากกด F9

    เอา Iterative Calculation มาวน Loop

    เราก็มาแก้สูตรของ Center แต่ละตัว ให้เป็นการเฉลี่ยภายในกลุ่มตัวเอง ซึ่งผมจะใช้ AVERAGEIFS มาช่วยครับ (สูตรนี้เป็นสูตรงูกินหาง เพราะกลุ่มก็คิดจากจุด Center แล้วจุด Center ดันคิดจากกลุ่มอีก)

    คำนวณค่า X (ลาก B2:B6 ใส่สูตรแล้วกด Ctrl+Enter เพื่อใส่สูตรพร้อมกัน)

    =AVERAGEIFS(Mall_Customers[Income],Mall_Customers[อยู่กลุ่มไหน],Pointกลาง!A2)

    คำนวณค่า Y (ลาก C2:C6 ใส่สูตรแล้วกด Ctrl+Enter เพื่อใส่สูตรพร้อมกัน)

    =AVERAGEIFS(Mall_Customers[Spending],Mall_Customers[อยู่กลุ่มไหน],Pointกลาง!A2)

    แล้วจะได้ผลลัพธ์ตามนี้ ซึ่งจำนวณจุดจะยังไม่เปลี่ยน (เพราะยังไม่ได้กด F9 เพื่อ Calculate)

    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 107

    คราวนี้เรากด F9 สูตรทั้งไฟล์จะคำนวณ 1 ครั้ง จะได้ผลดังนี้

    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 108

    คราวนี้เรากด F9 สูตรทั้งไฟล์จะคำนวณอีก 1 ครั้ง จะเห็นว่าจุดเปลี่ยนตำแหน่งไป (ลอง Plot กราฟดูก็ดีนะ)

    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 109

    กด F9 ดูอีกซักรอบ จะเห็นเลยว่าจุดค่อยๆ ขยับ

    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 110

    คราวนี้เราขี้เกียจมานั่งกด F9 หลายๆ รอบ ดังนั้นเราไปแก้ Option ให้มัน iterate ทีละ 10 ดีกว่า

    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 111

    แล้วเราก็ลองกด F9 ดู จะเห็นว่าคราวนี้มันทำทีเดียว 10 รอบต่อการกด F9 1 ครั้งเลย

    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 112

    ถ้ากดอีกที ก็จะเพิ่มอีก 10 จะเห็นว่าจุดไม่เปลี่ยนตำแหน่งแล้ว แสดงว่านี่แหละคือจุดสมดุลย์ที่จะเป็นจุดกึ่งกลางของแต่ละกลุ่มของเราแล้วล่ะครับ

    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 113

    หมายเหตุ : จริงๆ เราสามารถใส่จำนวน Iteration เยอะๆ เช่น 100 และทำแบบ Auto Calculate ก็ได้นะครับ แค่ผมทำแบบ Manual ให้ดูจะได้เห็นผลชัดๆ เฉยๆ

    ลอง Random จุดเริ่มต้นใหม่อีกที

    มันมีความเป็นไปได้ที่จุดเริ่มต้นแบบนึง ก็จะได้ผลลัพธ์แบบนึง ดังนั้นเราจะลอง Random จุดเริ่มต้นใหม่ โดยเราจะสร้าง Cell ขึ้นมาทำหน้าที่เป็น Switch เช่น H2 โดยเงื่อนไขคือ ถ้า H2=1 เราจะทำการ Random ใหม่นั่นเอง

    ดังนั้นเราจะแก้สูตรของค่า X,Y ของ Center เป็นแบบนี้แทน

    คำนวณค่า X (ลาก B2:B6 ใส่สูตรแล้วกด Ctrl+Enter เพื่อใส่สูตรพร้อมกัน)

    =IF($H$2="Y",RANDBETWEEN($B$9,$B$10),AVERAGEIFS(Mall_Customers[Income],Mall_Customers[อยู่กลุ่มไหน],Pointกลาง!A2))

    คำนวณค่า Y (ลาก C2:C6 ใส่สูตรแล้วกด Ctrl+Enter เพื่อใส่สูตรพร้อมกัน)

    =IF($H$2="Y",RANDBETWEEN($C$9,$C$10),AVERAGEIFS(Mall_Customers[Spending],Mall_Customers[อยู่กลุ่มไหน],Pointกลาง!A2))

    แล้วเราก็แก้ F2 ใหม่ด้วย เป็นดังนี้

    =IF(H2="Y",1,F2+1)

    ซึ่งพอใส่ให้ H2 เป็น Y แล้วกด F9 จะพบว่าจุดจะเปลี่ยนที่เพราะถูก Random ใหม่ และจำนวนรอบถูก Reset

    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 114

    คราวนี้ลองลบค่า Y ออกจากช่อง H2 แล้วกดปุ่ม F9 จะได้ว่าจุดจะเปลี่ยนที่เพราะคำนวณค่า Mean ของกลุ่ม พอกดไปเรื่อยๆ คราวนี้จะไปสมดุลย์ที่นี่

    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 115

    เดี๋ยวเราจะลอง Random ค่าหลายๆ แบบ แล้ว Plot กราฟให้เห็นกลุ่ม และจุดศูนย์กลางชัดๆ

    Plot กราฟ แยกกลุ่มให้เห็นภาพชัดๆ

    เพื่อที่จะ Plot Scatter Plot แยกสีตามกลุ่มได้ เราต้องมี Data หลายๆ คอลัมน์ตามกลุ่มซะก่อน โดยผมใช้ Power Query Pivot Column แตก Group ออกมาเป็นหลายๆ คอลัมน์ซะ อันนี้เป็น MCode ของ query ที่ผมสร้างจาก table Mall_Customers นะครับ (code ดูน่าปวดหัว แต่จริงๆ เกิดจากการกดปุ่มไปเรื่อยๆ ไม่มีอะไรต้องเขียนเองเลย)

    let
         Source = Excel.CurrentWorkbook(){[Name="Mall_Customers"]}[Content],
         #"Renamed Columns1" = Table.RenameColumns(Source,{{"Annual Income (k$)", "Income"}, {"Spending Score (1-100)", "Spending"}}),
         #"Removed Other Columns1" = Table.SelectColumns(#"Renamed Columns1",{"อยู่กลุ่มไหน", "Income", "Spending"}),
         #"Changed Type" = Table.TransformColumnTypes(#"Removed Other Columns1",{{"อยู่กลุ่มไหน", type text}, {"Income", Int64.Type}, {"Spending", Int64.Type}}),
         #"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 1, 1, Int64.Type),
         #"Pivoted Column" = Table.Pivot(#"Added Index", List.Distinct(#"Added Index"[อยู่กลุ่มไหน]), "อยู่กลุ่มไหน", "Spending", List.Sum),
         #"Sorted Rows" = Table.Sort(#"Pivoted Column",{{"Index", Order.Ascending}}),
         #"Removed Other Columns" = Table.SelectColumns(#"Sorted Rows",{"Income", "Center1", "Center2", "Center3", "Center4","Center5"}),
         #"Renamed Columns" = Table.RenameColumns(#"Removed Other Columns",{{"Center1", "Group1"}, {"Center2", "Group2"}, {"Center3", "Group3"}, {"Center4", "Group4"}, {"Center5", "Group5"}})
     in
         #"Renamed Columns"
    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 116

    แล้วค่อยสร้างกราฟ จาก Data ที่ Link จาก PrepareChart มาอีกที (ถ้าสร้างจากผลลัพธ์ query ตรงๆ แล้วบางที cell มันเลื่อนตำแหน่ง) โดยเขียนสูตรประมาณนี้

    =IF(PrepareChart!A2="",NA(),PrepareChart!A2)
    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 117

    จะเห็นว่าการจัดกลุ่มแต่ละรอบอาจไม่เหมือนกันก็ได้ บางอันก็ดูดีกว่าอันอื่น เช่นอันนี้ ผมว่าดูดีที่สุดในความคิดผม

    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 118

    ส่วนอันอื่นๆ ก็ได้ผลเปลี่ยนไป ขึ้นอยู่กับ Random ตอนแรกไปลงแถวๆ ไหน

    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 119
    ลองทำ Machine Learning ใน Excel เทคนิค K-Means Clustering แบบไม่ง้อ VBA 120

    จบแล้ว

    ในบทความนี้ก็เป็นการแนะนำ Concept ของการใช้เทคนิค K-Means Clustering และการใช้โหมด Iterative Calculation ใน Excel ครับ แต่ว่ายังไม่ได้แสดงวิธีหาจำนวนกลุ่มที่ Optimize ที่สุดนะครับ ว่า k ควรจะมีค่าเป็นเท่าไหร่? ไว้เดี๋ยวมีโอกาสจะเขียนแนะนำวิธีตัดสินใจให้อีกที แต่ถ้าใครอยากรู้ตอนนี้ก็สามารถไปอ่านเพิ่มเติมได้ที่นี่ก่อนได้ครับ

  • แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 2 Static DAX

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 2 Static DAX

    จากเนื้อหาตอนที่แล้วผมได้แสดงวิธีทำ RFM Analysis กันด้วยสูตร Excel ปกติกันไปแล้ว คราวนี้ผมจะมาแสดงวิธีทำด้วยสูตร DAX กันบ้าง ซึ่งจะสามารถใช้ได้ทั้งใน Power BI และใน Power Pivot ของ Excel ด้วยนะครับ

    ซึ่งผมคิดไว้ว่าวิธีการจัด Segment ด้วย RFM Analysis ด้วย DAX ผมจะเขียนถึงใน 2 ลักษณะ คือ แบบ Static โดยมองลูกค้าทั้งหมดมาเทียบกันเสมอ นั่นคือลูกค้าคนนึงจะถูก Assign Segment ครั้งเดียวจบ ได้อะไรก็อันนั้นเลย (เหมือนที่ผมทำใน Excel) และแบบ Dynamic คือ จะเปรียบเทียบกันเฉพาะลูกค้าที่มองเห็นอยู่ภายใต้ Filter ที่เลือกเท่านั้น ดังนั้นลูกค้าคนนึงอาจเป็นสุดยอดลูกค้าในกลุ่มนึง แต่เป็นลูกค้าประจำในอีกกลุ่มนึงที่ใหญ่กว่าก็ได้

    ซึ่งใน Post นี้ผมขอพูดถึงในแบบ Static ก่อน ซึ่งจะง่ายกว่าแบบ Dynamic แต่ก็มีหลายประเด็นน่าสนใจครับ เช่น สูตรบางอัน Excel มีแต่ DAX ไม่มี ก็ต้องแก้ปัญหาด้วยวิธีที่แตกต่างกัน เป็นต้น

    ไฟล์ประกอบ

    ผมจะใช้ไฟล์เดิม โดยเอาจาก https://www.kaggle.com/kyanyoga/sample-sales-data นะครับ แต่คราวนี้เอาเข้าไปทุกคอลัมน์ได้เลยครับ เผื่อเราจะวิเคราะห์อย่างอื่นด้วย

    พอโหลดข้อมูลเข้าไป จะได้แบบนี้ โดยผมตั้งชื่อตารางว่า sales_data นะครับ

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 2 Static DAX 121

    เริ่มเตรียมข้อมูลเพื่อทำ RFM แบบ Static กัน

    อันนี้จะคล้ายๆ กับที่เราทำใน Excel เลย คือ มีการสร้างคอลัมน์ต่างๆ ขึ้นมาจริงๆ เพื่อคำนวณเรื่องที่เราสนใจ แต่คราวนี้ผมจะใช้ Concept ของ Data Model มาช่วยด้วยนะครับ ดัังนั้นผมจะสร้างตารางลูกค้าออกมาด้วยคำสั่ง ALL ดังนี้ (จะใช้ DISTINCT หรือ VALUES ก็ได้)

    เราใช้ DAX New Table ดังนี้

    customer_table = ALL(sales_data[CUSTOMERNAME])

    ก็จะได้ตารางใหม่ขึ้นมาเป็นชื่อลูกค้าแบบไม่ซ้ำกัน ซึ่งอย่าลืมสร้าง Relationship กันตารางหลักด้วยนะ (ถ้าใน Excel จะสร้าง DAX New Table ไม่ได้ ให้ใช้ Power Query สร้างด้วยการ Remove Duplicates นะครับ)

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 2 Static DAX 122

    พอสร้าง Relationship แล้วจะเห็นว่าตาราง customer_table จะสามารถไหลไป filter sales_data ได้นะครับ (จากทิศลูกศร)

    สร้าง Measure เพื่อคำนวณประเด็นหลักๆ

    สร้าง New Measure ในตาราง sales_data เพื่อคำนวณเรื่องหลักๆ ก่อน

    LastOrderDate = MAX(sales_data[ORDERDATE])
    OrderCount = COUNTROWS(sales_data)
    TotalSalesAmt = SUM(sales_data[SALES])

    ทีนี้ จากที่ผมได้แก้ไขใน Version Excel ไปว่า ยอดเงินที่คิด ควรจะคิดยอดเงินเฉลี่ยต่อครั้งมากกว่าที่จะใช้ยอดเงินรวม ดังนั้นผมจะสร้างอีกคอลัมน์ขึ้นมาดังนี้

    AvgSalesAmt = DIVIDE([TotalSalesAmt],[OrderCount])

    สร้างคอลัมน์เพิ่มในตาราง customer

    เราจะสร้างวันที่ล่าสุดที่ซื้อ ความถี่ที่ซื้อ และจำนวนเงินทั้งหมดที่จ่ายออกมาดังนี้

    ให้ไปที่ cutomer_table แล้ว New Column ขึ้นมานะครับ

    CustLastOrderDate = [LastOrderDate]
    CustOrderCount = [OrderCount]
    CustTotalSalesAmt = [TotalSalesAmt]
    CustAvgSalesAmt = [AvgSalesAmt]

    สูตรพวกนี้ทำงานได้เป็นข้อมูลรายลูกค้า เพราะการอ้างอิง Measure ตรงๆ จริงๆ แล้วจะมีผลเหมือนใช้ฟังก์ชัน CALCULATE ไปครอบสูตรของ Measure นั้นอีกที ซึ่งกระตุ้นให้เกิด Context Transition ที่สามารถเปลี่ยน Row Context ให้เป็น Filter Context ได้ครับ (ถ้าไม่มี Context Transition ผลลัพธ์แต่ละบรรทัดจะเท่ากันหมด เพราะไม่มี Filter)

    สรุปได้ผลลัพธ์ดังนี้

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 2 Static DAX 123

    พอได้แบบนี้แล้วต่อไปผมก็จะต้องคำนวณพวก Percentile Rank ต่างๆ ออกมา แต่ปัญหาคือ ใน DAX มันไม่มี PERCENTRANK ให้ใช้เหมือนกับใน Excel

    ดังนั้นผมจะคำนวณด้วย PERCENTILE.INC ปกติ แล้วเทียบค่าเอา แต่พอลองทำกับข้อมูลวันที่แล้วมันไม่ยอมอีก ดังนั้นผมจึงต้องสร้างอีกคอลัมน์ให้วันที่เป็นเลขธรรมดาๆ ก่อน ดังนี้

    CustLastOrderDateNum = customer_table[CustLastOrderDate]*1

    จากนั้นเราก็จะสามารถคำนวณ Group ต่างๆ ได้แล้ว ด้วยการ Add Column ดังนี้

    คำนวณกลุ่มเรื่อง Recency

    R Group = 
    VAR P20value=PERCENTILE.INC(customer_table[CustLastOrderDateNum],0.2)
    VAR P40value=PERCENTILE.INC(customer_table[CustLastOrderDateNum],0.4)
    VAR P60value=PERCENTILE.INC(customer_table[CustLastOrderDateNum],0.6)
    VAR P80value=PERCENTILE.INC(customer_table[CustLastOrderDateNum],0.8)
    RETURN SWITCH(TRUE(),
    customer_table[CustLastOrderDateNum]<=P20value,1,
    customer_table[CustLastOrderDateNum]<=P40value,2,
    customer_table[CustLastOrderDateNum]<=P60value,3,
    customer_table[CustLastOrderDateNum]<=P80value,4,
    5)

    Tips : จะเห็นว่าผมใช้ VAR มาช่วยประกาศตัวแปร เพื่อแบ่งสูตรออกเป็นส่วนๆ จะได้ลดความมึนงงลงได้ ตอนอ่านสูตรจะง่ายขึ้น นอกจากนี้ยังใช้ SWITCH + TRUE มาช่วยเขียนเงื่อนไขหลายเงื่อนไขแทนการใช้ IF ซ้อน IF ได้ด้วย

    คำนวณกลุ่มเรื่อง Frequency

    F Group = 
    VAR P20value=PERCENTILE.INC(customer_table[CustOrderCount],0.2)
    VAR P40value=PERCENTILE.INC(customer_table[CustOrderCount],0.4)
    VAR P60value=PERCENTILE.INC(customer_table[CustOrderCount],0.6)
    VAR P80value=PERCENTILE.INC(customer_table[CustOrderCount],0.8)
    RETURN SWITCH(TRUE(),
    customer_table[CustOrderCount]<=P20value,1,
    customer_table[CustOrderCount]<=P40value,2,
    customer_table[CustOrderCount]<=P60value,3,
    customer_table[CustOrderCount]<=P80value,4,
    5)

    คำนวณกลุ่มเรื่อง Monetary

    M Group = 
    VAR P20value=PERCENTILE.INC(customer_table[CustAvgSalesAmt],0.2)
    VAR P40value=PERCENTILE.INC(customer_table[CustAvgSalesAmt],0.4)
    VAR P60value=PERCENTILE.INC(customer_table[CustAvgSalesAmt],0.6)
    VAR P80value=PERCENTILE.INC(customer_table[CustAvgSalesAmt],0.8)
    RETURN SWITCH(TRUE(),
    customer_table[CustAvgSalesAmt]<=P20value,1,
    customer_table[CustAvgSalesAmt]<=P40value,2,
    customer_table[CustAvgSalesAmt]<=P60value,3,
    customer_table[CustAvgSalesAmt]<=P80value,4,
    5)

    จะได้ผลลัพธ์ดังรูป

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 2 Static DAX 124

    เตรียมตารางเกณฑ์การจัด RFM Segment

    ต่อไปเราก็สร้างตารางอ้างอิงว่าคะแนนอะไรจะอยู่กลุ่มไหน โดยจะ Get Data จาก Excel ที่ทำไว้ในตอนที่แล้วก็ได้ ซึ่งหน้าตาใน Excel เป็นแบบนี้

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 2 Static DAX 125
    SegmentDescriptionRFM
    สุดยอดลูกค้าสุดยอดลูกค้า ดีสุดในทุกด้าน4,54,54,5
    เคยเป็นสุดยอดแต่หายไปนานเคยสุดยอด แต่ไม่ซื้อนานแล้ว1,24,54,5
    ลูกค้าใหม่จ่ายเยอะลูกค้าใหม่ เพิ่งมาซื้อครั้งแรกๆ ซื้อก้อนโต4,514,5
    ลูกค้าใหม่จ่ายน้อยลูกค้าใหม่ เพิ่งมาซื้อครั้งแรกๆ ซื้อนิดเดียว4,511,2,3
    นานมาทีจ่ายเยอะนานๆ มาที ซื้อก้อนใหญ่3,4,51,24,5
    นานมาทีจ่ายเยอะแต่หายไปนานนานๆ มาที ซื้อก้อนใหญ่ แต่ไม่ซื้อนานแล้ว1,21,24,5
    มาบ่อยจ่ายน้อยมาบ่อยๆ แต่ซื้อนิดเดียว3,4,54,51,2
    มาบ่อยจ่ายน้อยแต่หายไปนานมาบ่อยๆ แต่ซื้อนิดเดียว แต่ไม่ซื้อนานแล้ว1,24,51,2
    ลูกค้าประจำลูกค้าประจำ ซื้อบ่อย3,4,53,4,51,2,3,4,5
    ลูกค้าประจำแต่หายไปนานเคยเป็นลูกค้าประจำ แต่ไม่ซื้อนานแล้ว1,23,4,51,2,3,4,5
    ไม่ค่อยสำคัญน้อยในทุกด้าน1,21,21,2
    อื่นๆไม่เข้าพวกข้างบน 1,2,3,4,5 1,2,3,4,5 1,2,3,4,5
    ตารางเกณฑ์ RFM อันนี้ผมคิดขั้นเอง ใครจะเอาไปใช้ก็เอาไปใช้ได้เลย ไม่ต้องมาขอผมก็ได้ครับ แค่ให้เครดิต ThepExcel ก็พอครับ

    ก่อนอื่นใน Power Query Editor ให้เรา Add Index Column เพื่อให้มันบันทึกการเรียงลำดับของเราไว้ก่อน (เพราะลำดับ Priority นั้นสำคัญครับ)

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 2 Static DAX 126

    จากนั้นเพื่อให้เขียนสูตรง่ายขึ้น เราจะใช้ Power Query แตกตัวเลขที่คั่นด้วย Comma ออกเป็นหลายๆ บรรทัดไปเลย ด้วยคำสั่ง Split by Delimiter ด้วย Comma แต่ให้ Split into Rows แทน (กดทีละคอลัมน์)

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 2 Static DAX 127

    ทำไปเรื่อยๆ กับทั้ง 3 คอลัมน์ จะได้ผลลัพธ์ของทุก Combination แล้วกด Close & Apply เพื่อ Load Data ออกมายัง Data Model

    จากนั้นในส่วนของ Data แล้วให้เรากำหนดให้คอลัมน์ Segment ให้ Sort by Column ที่ชื่อว่า Index ด้วยนะครับ แล้วลองเรียงน้อยไปมากดู จะได้แบบนี้

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 2 Static DAX 128

    Assign Segment ให้ลูกค้า

    คราวนี้ให้เรากลับมาที่ customer_table เพื่อที่จะคำนวณ Segment ให้ลูกค้าของเราได้ซักที

    หลักการคือ เราจะเอาข้อมูล r f m group ของลูกค้าแต่ละคน ไป Filter ตาราง RFMtable แล้วเอาผลลัพธ์ตัวบนสุดมา ซึ่งเราจะใช้ CACULATETABLE ในการ Filter เงื่อนไขก่อน (ใช้ FILTER ก็ได้ แต่ CALCULATETABLE จะคำนวณเร็วกว่า) แล้วใช้ TOPN เพื่อคัดมาแค่บนสุดแถวเดียวโดยยึดตาม index จากน้อยไปมาก จากนั้นค่อยเลือกเอาคอลัมน์ segment ออกมาด้วย SELECTCOLUMNS ดังนี้

    สรุปคือ เรา Add New Column แล้วใส่สูตรดังนี้

    StaticSegment = 
    VAR CurrentR=customer_table[R Group]
    VAR CurrentF=customer_table[F Group]
    VAR CurrentM=customer_table[M Group]
    VAR filterTable=CALCULATETABLE(RFMtable,
    RFMtable[R]=CurrentR,
    RFMtable[F]=CurrentF,
    RFMtable[M]=CurrentM)
    VAR Top1=TOPN(1,filterTable,[Index],ASC)
    VAR getSegment=SELECTCOLUMNS(Top1,"FilterSegment",[Segment])
    RETURN getSegment

    จะได้ Segment ของลูกค้ามาดังรูป

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 2 Static DAX 129

    กำหนดการเรียง Segment

    เพื่อทำให้ StaticSegment เรียงตามที่ผมคิด ผมจึงต้องสร้างตาราง RFMRableRef ที่บรรทัดไม่เบิ้ลขึ้นมาอีกตารางนึง (ไม่ต้อง Split) เพื่อกำหนดวิธีการเรียงไว้ เพื่อที่คราวนี้เราจะ SortbyColumn index ให้กับคอลัมน์ Segment ด้วยครับ เวลาลากลง Visual จะได้เรียงได้

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 2 Static DAX 130

    แล้วลากเส้นเชื่อมกับ customer_table ซะเพื่อให้มันไป Filter customer_table ได้ แล้วจะไหลไป filter sales data ต่อได้อีก

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 2 Static DAX 131

    จากนั้นอาจสร้าง Measure เพิ่มเติม เช่น นับจำนวนลูกค้าแบบไม่ซ้ำกันด้วย DISTINCTCOUNT

    CustCount = DISTINCTCOUNT(sales_data[CUSTOMERNAME])

    สร้าง Visual

    พอสร้าง visual จะได้แบบนี้ ซึ่งได้ผลลัพธ์เหมือนใน Excel เป๊ะๆ แล้ว

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 2 Static DAX 132

    แต่ใน Power BI มันดีกว่า Excel ตรงที่เราสร้างกราฟอื่น ให้มัน interactive กันได้ เช่น

    คลิ๊กเลือกดู Segment ที่สนใจ กราฟข้างล่างเปลี่ยน

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 2 Static DAX 133

    คลิ๊กดูช่วงวันที่ที่สนใจ กราฟอื่นๆ ก็เปลี่ยน

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 2 Static DAX 134

    จบการทำ RFM แบบ Static

    และนี่ก็คือตัวอย่างการใช้ Power BI ทำ RFM Analysis แบบ static ครับ ในตอนหน้าเราจะมาทำแบบ Dynamic กัน นั่นคือ สมมติเลือกลูกค้าแค่ USA ก็จะทำการจัด RFM เปรียบเทียบ Ranking เฉพาะลูกค้าใน USA เท่านั้น ไม่สนใจประเทศอื่น เป็นต้น แปลว่าระหว่างไม่ Filter อะไรเลย ลูกค้าคนนึงก็อาจเป็น Segment นึง แต่พอการเลือก Filter เปลี่ยนไป ลูกค้าคนเดิมนั้นอาจเปลี่ยน Segment ได้ด้วย ก็เลยเรียกว่าแบบ Dynamic ครับ ซึ่งจะยากกว่าเดิมพอสมควร

  • แบ่ง Segment ลูกค้าด้วย RFM Analysis  : ตอนที่ 1 ทำด้วย Excel

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 1 ทำด้วย Excel

    การแบ่งกลุ่มลูกค้าหรือ การทำ Customer Segmentation เพื่อบริหารจัดการลูกค้าแต่ละกลุ่มอย่างเหมาะสมเป็นเรื่องที่สำคัญต่อการทำธุรกิจมาก เพราะว่าเราไม่สามารถลงแรงเพื่อดูแลลูกค้าทุกคนเท่าๆ กันได้ขนาดนั้น (ลองคิดตามกฎ 80:20 สิ)

    แต่เราจะแบ่งลูกค้ายังไงดีล่ะ? แบ่งตามอะไร? แค่แบ่งตามยอดซื้อเท่านั้นเหรอ?
    Model หนึ่งที่สามารถใช้ Data มาช่วยในการแบ่งกลุ่มลูกค้าได้นั่นก็คือ RFM Model หรือ RFM Analysis นั่นเอง

    RFM Analysis คืออะไร?

    RFM Analysis คือเทคนิคที่ใช้ Data เกี่ยวกับพฤติกรรมการซื้อของของลูกค้าในการแบ่งกลุ่มลูกค้า โดยขึ้นกับปัจจัย 3 ตัว ซึ่งย่อเป็น RFM นั่นก็คือ

    • Recency : ซื้อครั้งล่าสุดสดๆ ร้อนๆ แค่ไหน? (Recent ที่แปลว่าไม่นานมานี้)
    • Frequency : ซื้อบ่อยแค่ไหน?
    • Monetary : มูลค่าเงินที่ซื้อเยอะแค่ไหน?

    Edit : เดิมที ผมเขียนบทความนี้คิด Monetary เป็นยอดเงินรวมที่ลูกค้านั้นจ่ายทั้งหมดเลย แต่มีผู้รู้ คือ อาจารย์เช็ค Thanachart Ritbumroong ได้ให้คำแนะนำว่า ควรจะคิดจากมูลค่าเงินเฉลี่ยต่อครั้ง (Ticket Size) จะดีกว่าการคิดรวม (ซึ่งเป็นวิธีโบราณ) เพราะลูกค้าแต่ละคนมีอายุการเป็นลูกค้าไม่เท่ากัน ซึ่งผมก็เห็นด้วยเลยครับ การคิดจากยอดรวมมันมีความซ้ำซ้อนกับความถี่ในการซื้อไปแล้วด้วยซ้ำ ดังนั้นผมจึงจะขอแก้บทความนี้ใหม่ เป็นคิดเงินจากยอดเฉลี่ยต่อครั้งแล้วกันครับ

    จากนั้นก็เอาข้อมูลของลูกค้ามาให้คะแนนในแต่ละด้าน โดยอาจจะให้คะแนน 1-5 ก็ได้ (1 คือคะแนนน้อย, 5 คือเยอะ) หรือบางค่ายอาจแบ่งเป็น 4 ท่อนก็ได้ อันนี้แล้วแต่เลยครับ แต่ในที่นี้ผมจะแบ่ง 5 ให้ดู เพราะแบ่ง 4 มันง่ายไป อิอิ

    จากนั้นก็เอาผลที่ได้มาแบ่งเป็น Segment อีกทีซึ่งมีหลายสูตรมากๆ บางสำนักก็แบ่งเป็น 6 กลุ่มบ้าง 12 กลุ่มบ้าง ซึ่งผมว่ามันไม่ใช่สาระสำคัญ แต่สิ่งสำคัญคือการคัดเลือกกลุ่มที่เราควรจะเข้าไปจัดการต่อมากกว่า ว่าจะจัดการกลุ่มไหนยังไงดี? บางทีแบ่งเยอะไปก็จัดการไม่ถูกนะ

    ข้อมูลตัวอย่าง

    เพื่อให้เห็นภาพมากขึ้น เรามาลองวิเคราะห์ข้อมูลตัวอย่างอันนี้กันครับ เป็นไฟล์ csv นะ
    https://www.kaggle.com/kyanyoga/sample-sales-data

    คัดเลือกข้อมูลที่ต้องการ

    ในไฟล์จะมีข้อมูลที่ไม่เกี่ยวข้องอยู่ด้วยเต็มไปหมด ผมจะขอคัดเลือกมาเฉพาะที่ต้องการ ซึ่งผมจะขอใช้ Power Query ทำเพราะสามารถจัดการประเภทข้อมูลได้ด้วยง่ายดี (แต่เพื่อนๆ จะใช้ Excel ปกติทำก็ได้นะ)

    สรุปแล้ว ผมใช้ Data แค่นี้ก็เพียงพอต่อการทำ RFM แล้วล่ะ นั่นก็คือ ชื่อลูกค้า วันที่ซื้อของ และมูลค่าการซื้อครั้งนั้น

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 1 ทำด้วย Excel 135

    พอได้ข้อมูลแบบนี้ เดี๋ยวเราจะเอาไปเข้า PivotTable ต่อเลย เพื่อหาข้อมูลเป็นรายลูกค้า (จริงๆ จะใช้ Group By ใน Power Query ก็ได้ แต่กลัวบางคนใช้ไม่เป็น)

    พอเอาเข้า Pivot Table เราก็จะลากสรุปข้อมูลรายลูกค้าดังนี้

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 1 ทำด้วย Excel 136

    ผมลาก OrderDate ลงมา 2 รอบ ซึ่งมันจะทำการสรุปด้วย Count ให้ ผมจะเปลี่ยนให้สรุปด้วยการใช้ค่า Max แทน เพื่อให้ได้วันที่ล่าสุดที่ซื้อ (อย่าลืมว่าวันที่คือตัวเลข ดังนั้นหาค่า Max ได้) ส่วน OrderDate2 เป็นการนับซึ่งผมจะถือว่าเป็น Frequency การซื้อของลูกค้าคนนั้นไปซะ

    การเปลี่ยนวันที่ในคอลัมน์ B เป็น MAX จะได้เลข 3 หมื่นเกือบ 4 หมื่นออกมา ซึ่งมันคือค่าที่แท้จริงของวันที่ เราแค่กดคลิ๊กขวา Number Format แล้วเปลี่ยน Format เป็นวันที่ได้เลย ส่วนยอดเงินเฉลี่ยต่อครั้งในคอลัมน์ E ก็เกิดจากการเอายอดเงินรวมหารด้วยจำนวนครั้งที่ซื้อครับ (อันนี้ใช้วิธีหารเอาข้างๆ แบบลูกทุ่งเลย ในความเป็นจริงจะใช้ Calculated Field หรือ Measure ก็ได้นะครับ)

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 1 ทำด้วย Excel 137

    ที่นี้เราก็ได้ค่า R F M แล้วดังนี้

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 1 ทำด้วย Excel 138

    แบ่งคะแนนด้วยวิธีไหนดี?

    หากเราเอาแค่ค่าน้อยสุดมากสุดมาแบ่งเป็น 5 ท่อนเฉยๆ มันจะไม่ Work อย่างแรง เนื่องจากข้อมูลมันเบ้ขวามากๆ ทำให้แต่ละท่อนมีข้อมูลต่างกันมากเลย ดังนั้นวิธีที่น่าจะ Work ที่สุดก็คือการหาค่า Percentile ที่ 20,40,60,80 มาเป็นตัวแบ่งนั่นเอง

    หมายเหตุ : ที่เราสามารถคำนวณข้อมูลวันที่ได้เลยตรงๆ ไม่ต้องเอามาลบหาระยะห่างวัน เพราะถ้าวันที่ใหม่ เลขจะเยอะ ทำให้ได้อยู่ในกลุ่มคะแนนมากอยู่แล้ว

    แต่ถ้าหากเราทำใน Excel เราสามารถใช้ PERCENTRANK มาช่วยหาได้ว่าค่าที่สนใจอยู่ที่ Percentile เท่าไหร่ แล้วเราค่อยมาปรับให้เป็น 1-5 อีกทีก็ได้ ดังนี้

    อันนี้คำนวณอันดับ Percentile ของแต่ละค่าออกมาก่อน

    =PERCENTRANK.INC(G$2:G$93,G2)
    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 1 ทำด้วย Excel 139

    จากนั้นปรับให้เป็น Score 1-5 ซะ

    =IF(K2=0,1,CEILING.MATH(K2/0.2,1))
    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 1 ทำด้วย Excel 140

    ได้เวลาจัด Segment

    การจัด Segment นั้นทำได้หลายแบบมากๆ เช่น ถ้าไปดูตามเว็บต่างๆ จะเห็นว่ามีจัดเป็น Champions, Loyal Customer, New Customers อะไรแบบนี้ ซึ่งจริงๆ มันไม่ได้มีมาตรฐานสากลอะไร เช่น อันนี้คือไปเจอมาจากเว็บเมืองนอกดังนี้

    SegmentDescriptionRFM
    ChampionsBought recently, buy often and spend the most4 – 54 – 54 – 5
    Loyal CustomersSpend good money. Responsive to promotions2 – 43 – 44 – 5
    Potential LoyalistRecent customers, spent good amount, bought more than once3 – 51 – 31 – 3
    New CustomersBought more recently, but not often4 – 5< 2< 2
    PromisingRecent shoppers, but haven’t spent much3 – 4< 2< 2
    Need AttentionAbove average recency, frequency & monetary values3 – 43 – 43 – 4
    About To SleepBelow average recency, frequency & monetary values2 – 3< 3< 3
    At RiskSpent big money, purchased often but long time ago< 32 – 52 – 5
    Can’t Lose ThemMade big purchases and often, but long time ago< 24 – 54 – 5
    HibernatingLow spenders, low frequency, purchased long time ago2 – 32 – 32 – 3
    LostLowest recency, frequency & monetary scores< 2< 2< 2
    https://blog.rsquaredacademy.com/customer-segmentation-using-rfm-analysis/

    ถ้าพิจารณาดูแล้ว จะเห็นว่า คะแนนในตารางข้างบนที่ผมหามาได้ ตัว M ของเค้าหมายถึงยอดเงินรวม ไม่ใช่ยอดเฉลี่ยต่อครั้งเหมือนอันใหม่ที่ผมทำ ดังนั้นตารางนี้จึงไม่เหมาะกับผม

    ในบทความนี้ผมจึงคิดเกณฑ์ใหม่ขึ้นมาเองให้เหมาะสมกับการให้คะแนนของผมเอง ตามตารางนี้ครับ (เราคิดการแบ่งของเราเองได้นะ ไม่ได้ผิด!) โดยที่หากลูกค้าคนใดสามารถอยู่ได้หลายกลุ่มพร้อมกัน ผมจะถือว่าให้เค้าอยู่ในกลุ่มที่สูงที่สุดยึดตาม Priority ใน List นี้ด้วยครับ

    ผมเอาคะแนนที่เป็นไปได้ใส่ลงไปใน Cell โดยคั่นด้วย comma เลยแบบนี้ จะได้อ่านค่าได้ตรงๆ ด้วย FIND, SEARCH ได้ง่าย

    SegmentDescriptionRFM
    สุดยอดลูกค้าสุดยอดลูกค้า ดีสุดในทุกด้าน4,54,54,5
    เคยเป็นสุดยอดแต่หายไปนานเคยสุดยอด แต่ไม่ซื้อนานแล้ว1,24,54,5
    ลูกค้าใหม่จ่ายเยอะลูกค้าใหม่ เพิ่งมาซื้อครั้งแรกๆ ซื้อก้อนโต4,514,5
    ลูกค้าใหม่จ่ายน้อยลูกค้าใหม่ เพิ่งมาซื้อครั้งแรกๆ ซื้อนิดเดียว4,511,2,3
    นานมาทีจ่ายเยอะนานๆ มาที ซื้อก้อนใหญ่3,4,51,24,5
    นานมาทีจ่ายเยอะแต่หายไปนานนานๆ มาที ซื้อก้อนใหญ่ แต่ไม่ซื้อนานแล้ว1,21,24,5
    มาบ่อยจ่ายน้อยมาบ่อยๆ แต่ซื้อนิดเดียว3,4,54,51,2
    มาบ่อยจ่ายน้อยแต่หายไปนานมาบ่อยๆ แต่ซื้อนิดเดียว แต่ไม่ซื้อนานแล้ว1,24,51,2
    ลูกค้าประจำลูกค้าประจำ ซื้อบ่อย3,4,53,4,51,2,3,4,5
    ลูกค้าประจำแต่หายไปนานเคยเป็นลูกค้าประจำ แต่ไม่ซื้อนานแล้ว1,23,4,51,2,3,4,5
    ไม่ค่อยสำคัญน้อยในทุกด้าน1,21,21,2
    อื่นๆไม่เข้าพวกข้างบน 1,2,3,4,5 1,2,3,4,5 1,2,3,4,5
    ตารางเกณฑ์ RFM อันนี้ผมคิดขั้นเอง ใครจะเอาไปใช้ก็เอาไปใช้ได้เลย ไม่ต้องมาขอผมก็ได้ครับ แค่ให้เครดิต ThepExcel ก็พอครับ

    โดยที่ผมสร้าง Table ขึ้นมาว่า RFMtable ดังนี้

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 1 ทำด้วย Excel 141

    เพื่อให้เห็นภาพชัดที่สุด ผมจะเอา 12 Segment นี้ไปเป็นหัวตาราง แล้วคำนวณว่าลูกค้าแต่ละคนเข้า Segment นั้นได้หรือไม่ ดังนี้

    สูตรใน S2 เป็นดังนี้ (ใช้ Logic AND ในการคิดแต่ละช่อง)

    =AND(ISNUMBER(FIND($O2,INDEX(RFMtable[R],MATCH(S$1,RFMtable[Segment],0)))),
     ISNUMBER(FIND($P2,INDEX(RFMtable[F],MATCH(S$1,RFMtable[Segment],0)))),
     ISNUMBER(FIND($Q2,INDEX(RFMtable[M],MATCH(S$1,RFMtable[Segment],0)))))
    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 1 ทำด้วย Excel 142

    ทีนี้เราจะหาว่า FinalSegment โดยหลักการคือ หาว่า TRUE ตัวแรกอยู่ที่อันไหน อันนี้ใช้ INDEX+MATCH มาช่วยได้ดังนี้

    =INDEX($S$1:$AD$1,MATCH(TRUE,S2:AD2,0))
    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 1 ทำด้วย Excel 143

    พอเอาข้อมูลไป Pivot ก็จะได้ผลลัพธ์ประมาณนี้

    แบ่ง Segment ลูกค้าด้วย RFM Analysis : ตอนที่ 1 ทำด้วย Excel 144

    สรุป

    จะเห็นว่าวิธีที่ผมทำให้ดูในบทความนี้ ค่อนข้างทุกลักทุเลหน่อยๆ คือมี Pivot แล้วมาทำต่อข้างนอก Pivot แล้วเอาไป Pivot ใหม่อีกที แต่มันก็สามารถได้คำตอบเหมือนกัน

    ในตอนต่อไป ผมจะทำด้วยวิธีใช้ DAX ใน Power BI ซึ่งจะสามารถเขียน Measure ออกมาคำนวณให้ได้ผลลัพธ์ที่ต้องการได้แบบอัตโนมัติกว่านี้ครับ ใครสนใจก็รอติดตามได้เลยครับ

  • Math Skill vs Stage of Life : Excel Version

    Math Skill vs Stage of Life : Excel Version

    คิดว่าเพื่อนๆ คงพอเคยเห็น Meme ตัวนี้มาแล้วว่า เรียน Math ยากๆ เช่น Calculus มาแทบตาย สุดท้ายมาถึงวัยทำงานก็เหลือแค่ Spreadsheet หรือ Excel ที่ใช้แค่การบวกลบคูณหารธรรมดาๆ…

    เพื่อให้ภาพมันครบขึ้น ก็เลยลองวาดเส้นต่อดูว่าในความคิดของผม เวลาใช้ Excel จริงๆ มันก็มีเรื่องที่ยากขึ้นเรื่อยๆ แล้วก็กลับมาง่ายแล้วก็ยากใหม่สลับไปมาเช่นกันตัวอย่างเช่น เราใช้ Excel จากพื้นฐานไปจนถึง ทำ Pivot ได้ (ซึ่งการทำ Pivot เป็นนี่ง่ายกว่าแก้สมการสมัยเด็กจริงๆ นะ 555) สามารถเขียนสูตร Array Formula ยากๆ ได้ ใช้ VBA เขียนโปรแกรมซับซ้อนได้… (อันนี้มีตั้งแต่ง่าย จนยากพอๆ กับ Calculus แหละ)

    ไปๆ มาๆ ในช่วงหลังผมใช้แค่ Power Query อย่างเดียวสามารถเตรียมข้อมูลทดแทนสูตรยากๆ และ VBA ได้เกือบหมดเลย ซึ่งมีตั้งแต่กดเครื่องมือง่ายๆ อย่างเดียว ไปจนถึงการใช้งานที่ลึกขึ้นไปเรื่อยๆ ก็จะเจอเรื่องยากอีกครั้งนั่นคือ Power Query M Code

    พอใช้ Power Query เตรียมข้อมูลได้ ก็ไปถึงขั้นสรุปข้อมูล ที่ต้องเปลี่ยนจาก Pivot Table ธรรมดาที่มีข้อจำกัด ไปใช้ Power Pivot/Power BI แทน ซึ่งต้องใช้ ภาษา DAX ซึ่งมีความสามารถเยอะมากๆ แล้วก็ลึกมากๆ เช่นกัน

    ผมมองว่าเจ้า Power Query M Code และ DAX เนี่ยมีเนื้อหาเยอะจนเรียนกันไม่มีวันสิ้นสุดเลย ขอบอกกกก และหลายเรื่องมันลึกซึ้งและใช้ Logic สูงไม่แพ้การทำโจทย์ Calculus และการเขียนโปรแกรมเลยนะ

    แล้วเพื่อนๆ เองคิดยังไงกับกราฟนี้บ้างครับ? มองว่าอะไรง่าย อะไรยาก เวลาใช้งานจริงใช้แค่ไหน? คล้ายกันกับของผมมั้ยครับ ^^

    หากอย่างเรียนรู้เกี่ยวกับ Excel และ Power BI มากกว่านี้ ลองดูคอร์สออนไลน์ของผมได้ครับ

  • บันได 10 ขั้น แห่งการฝึกวิชา DAX

    บันได 10 ขั้น แห่งการฝึกวิชา DAX

    ภาษา DAX (Data Analysis eXpression) เป็นภาษาที่ใช้ในการเขียนสูตรของ Power BI และ Power Pivot ซึ่งเป็นภาษาที่มีหน้าตาภายนอกคล้ายคลึงสูตรของ Excel มากๆ แต่เบื้องลึกนั้นอาจมีความต่างพอสมควร…

    Concept การทำงานของ DAX นั้นจะผูกโยงกับ Data Model หรือโครงสร้างความสัมพันธ์ของข้อมูลในตาราง และขึ้นอยู่กับบริบทของการ Filter ข้อมูลเป็นอย่างมาก ดังนั้นคนที่ใช้ Excel มาก่อนจำชำนาญแล้ว ก็ยังจำเป็นต้องศึกษา DAX เพิ่มเติมอีกเยอะเลยกว่าจะใช้ได้ DAX ได้เก่ง

    จากที่ผมได้เคยอ่านบทความ 10 ขั้นวิทยายุทธ Excel ที่พี่บิว “วิศวกรรีพอร์ต” ได้เขียนไว้นานแล้ว ผมคิดว่ามันทำให้คนอ่านเห็นภาพรวมได้ง่ายขึ้นว่าทักษะ Excel โดยรวมมีอะไร และทักษะตัวเราเองอยู่ประมาณขั้นไหน ผมก็เลยอยากเขียนบทความที่คล้ายๆ กัน แต่เป็นเรื่องของ DAX บ้าง

    หวังว่าบทความนี้จะสามารถเป็นเหมือนแผนที่ให้เพื่อนๆ ได้เห็นภาพรวม และเข้าใจการเขียนรู้ DAX ได้มากขึ้นนะครับ ซึ่งแน่นอนว่าการแบ่งขั้นพวกนี้ ไม่ได้มีหลักเกณฑ์สากลอะไรมาแบ่งหรอกครับ แต่เป็นความคิดเห็นของผมที่ใช้ DAX มาเยอะพอสมควร จึงอยากลองเอาความรู้ที่มีมาลองแบ่งดูครับ

    ถ้าพร้อมแล้วไปดูกันเลยว่ามีขั้นอะไรบ้าง? แล้วลองอ่านเล่นๆ ดูสิว่าตัวคุณเองน่าจะอยู่ขั้นไหนแล้ว ^^

    ขั้นที่ 1 : รู้จักพื้นฐานของ DAX

    บันได 10 ขั้น แห่งการฝึกวิชา DAX 145
    • รู้จักประเภทข้อมูลใน DAX
    • รู้ว่า =SUM(TableName[ColumnName]) ควรจะเขียนเป็น New Column หรือ New Measure
    • รู้วิธีอ้างอิงคอลัมน์ (TableName[ColumnName]) อ้างอิงตาราง (TableName) อ้างอิง Measure ([MeasureName])
    • สามารถใช้ฟังก์ชัน DAX ง่ายๆ เช่น SUM, IF, RELATED, DIVIDE, COUNTROWS, DISTINCTCOUNT ได้

    ขั้นที่ 2 : เริ่มใช้ลูกเล่นใน DAX

    dax
    • สามารถใช้เครื่องหมายพิเศษต่างๆ ในสูตรได้ เช่น เครื่องหมาย &&, ||, IN, NOT, { }
    • รู้ว่า DAX แปลงประเภทข้อมูลให้เราแบบไหน เช่น เอา Text บวกกันได้อะไร?
    • ใช้ SWITCH + TRUE เพื่อเขียนเงื่อนไขแทนการใช้ IF ซ้อน IF
    • สามารถใช้ Iterator เช่น SUMX เพื่อหาผลรวมข้อมูล 2 คอลัมน์ที่คูณกันได้
    • ใช้ VAR + RETURN เพื่อประกาศตัวแปรขึ้นมาเก็บการคำนวณในสูตรได้
    • เขียน Comment ในสูตร ( ขึ้นต้นด้วย // ) เพื่ออธิบายการทำงานของสูตรได้
    • สามารถสร้าง Date Table ขึ้นมาได้ด้วยตัวเองด้วย CALENDAR และเพิ่มคอลัมน์ได้ดั่งใจด้วย FORMAT ได้

    ขั้นที่ 3 : สามารถใช้ฟังก์ชัน CALCULATE เบื้องต้นได้

    บันได 10 ขั้น แห่งการฝึกวิชา DAX 146
    • สามารถรู้ได้ว่า ณ จุดที่เราพิจารณาอยู่นั้น มีการ Filter อะไรอยู่บ้าง (Filter Context)
    • สามารถใช้ CALCULATE Filter ข้อมูล 1 เงื่อนไขเทียบกับค่าคงที่ได้
    • สามารถใช้ CALCULATE Filter ข้อมูล 2 เงื่อนไขแบบ AND ได้
    • รู้ว่าการเขียนเงื่อนไขเปรียบเทียบใน CALCULATE จะปลด Filter เดิมก่อนทำการ Filter เงื่อนไขใหม่
    • สามารถใช้ CALCULATE ปลด Filter ด้วย REMOVEFILTERS, ALL, ALLSELECTED, ALLEXCEPT ได้

    ขั้นที่ 4 : จัดการเงื่อนไขเกี่ยวกับ Filter ที่ระดับต่างๆ ในรายงาน

    บันได 10 ขั้น แห่งการฝึกวิชา DAX 147
    • ใช้ฟังก์ชัน FILTER ควบคู่เงื่อนไข AND, OR ได้อย่างเหมาะสม
    • รู้ว่า DAX สามารถมอง Table ที่มี 1 Row 1 Column ให้กลายเป็นค่า Scalar ได้
    • ใช้ ISFILTERED, ISCROSSFILTERED, ISINSCOPE แบ่งแยก Level ของ Hierarchy ได้ (เช็คจากตัวย่อยไปใหญ่)
    • ใช้ SELECTEDVALUE เพื่อดึงค่าที่ถูกเลือกจาก Slicer ได้
    • ใช้ TOPN เพื่อคัดเลือกข้อมูลที่ต้องการได้
    • ใช้ LOOKUPVALUE ดึงค่าที่ต้องการตามเงื่อนไขที่กำหนดได้

    ขั้นที่ 5 : สามารถใช้ CALCULATE ที่ซับซ้อนขึ้นได้

    บันได 10 ขั้น แห่งการฝึกวิชา DAX 148
    • รู้ว่าจริงๆ แล้วเงื่อนไข Filter ของ CALCULATE คือ Table
    • สามารถใช้ CALCULATE ควบคู่กับ Time Intelligence Function ได้
    • ใช้ VAR ร่วมกับ CALCULATE เพื่อ Filter ข้อมูลเทียบกับ สูตรหรือ Measure ได้
    • หลังปลด Filter แล้ว ใส่ Filter เข้าไปใหม่เฉพาะ Field ที่ต้องการด้วย VALUES ได้
    • สามารถใช้ CALCULATE จัดการเส้น Relationship ด้วย USERELATIONSHIP/CROSSFILTER ได้
    • รู้จัก Effect ของ Sort by Column ที่มีผลต่อการปลด Filter
    • รู้จัก Effect ของ คอลัมน์ Date ใน Date Table ที่มีผลต่อการปลด Filter

    ขั้นที่ 6 : ใช้ Context Transition กับ Iterator ให้เป็นประโยชน์ได้

    บันได 10 ขั้น แห่งการฝึกวิชา DAX 149
    • แยกความแตกต่างระหว่าง Row Context และ Filter Context ได้
    • รู้ว่าการอ้าวอิง Measure ทุกครั้งมี CALCULATE แฝงอยู่ และสามารถเกิด Context Transition ได้
    • เข้าใจความแตกต่างของ DISTINCT, VALUES และ ALL และใช้สร้างตารางจำลองใน Measure ได้
    • สามารถใช้ Context Transition คู่กับ Iterator เช่น SUMX, MAXX, CONCATENATEX, RANKX ได้
    • เข้าใจลำดับขั้นตอนในการคำนวณของ CALCULATE เวลามีหลายเงื่อนไขพร้อมกัน รวมถึงเวลาใช้ CALCULATE 2 ตัวซ้อนกัน

    ขั้นที่ 7 : ใช้ Expanded Table ให้เป็น

    บันได 10 ขั้น แห่งการฝึกวิชา DAX 150
    • เข้าใจแนวคิดของ Expanded Table ว่ามันคือตารางหลัก + ดึงคอลัมน์ที่เกี่ยวข้องทั้งหมดจากตารางฝั่งที่เป็นเลข 1
    • เข้าใจว่าจริงๆ แล้วการทำงานของ RELATED นั้นเป็นการเข้าถึง Column ใน Expanded Table
    • รู้ว่าการอ้างอิง Table หมายถึง Expanded Table เสมอ
    • เข้าใจความแตกต่างของ Column Filter และ Table Filter (Expanded Table) และเลือกใช้ให้ถูกต้อง
    • สามารถใช้ Expanded Table เป็นเงื่อนไขของ CALCULATE ได้อย่างเหมาะสม

    ขั้นที่ 8 : รู้จักสร้าง/จัดการตารางจำลอง

    บันได 10 ขั้น แห่งการฝึกวิชา DAX 151
    • สามารถสร้างคอลัมน์จำลองในตารางจำลองด้วย ADDCOLUMNS และเลือกคอลัมน์ด้วย SELECTCOLUMNS
    • รู้ว่าสามารถอ้างอิงคอลัมน์ในตารางจำลองที่สร้างขึ้นใน VAR ด้วย [ColumnName] ได้
    • เลือกใช้ CALCULATETABLE (มี Context Transition) แทน Filter ได้อย่างเหมาะสม
    • ใช้ UNION, INTERSECT และ EXCEPT เพื่อสร้างตารางผลลัพธ์ใหม่ที่ต้องการ
    • เข้าใจความแตกต่างของ SUMMARIZE , GROUPBY, CROSSJOIN, GENERATE, GENERATESERIES
    • รู้จักแนวคิดของ Data Lineage
    • สามารถใช้ TREATAS ใน CALCULATE เพื่อเลียนแบบ Relationship จากคอลัมน์อื่น / สร้าง Virtual Relationship ได้
    • สามารถใช้ INTERSECT แทน TREATAS ได้กรณีที่ไม่มีให้ใช้ (เช่น ใน Excel)

    ขั้นที่ 9 : เข้าใจ/สร้างสูตร DAX ที่ซับซ้อนได้

    บันได 10 ขั้น แห่งการฝึกวิชา DAX 152
    • เข้าใจ DAX Pattern ต่างๆ ใน DaxPatterns.com ได้
    • สามารถสร้างสูตร DAX เพื่อตอบโจทย์ธุรกิจที่ต้องการได้ เช่น คำนวณสินค้าคงค้างเฉลี่ย, คำนวณต้นทุน FIFO, คำนวณยอดเงิน Balance ล่าสุดในบัญชี เป็นต้น
    • จัดการปัญหาใน Data Model ที่มีความสัมพันธ์แบบ Many to Many ได้
    • สามารถใช้ Calculation Group ได้
    • เข้าใจการทำงานที่แท้จริงของ ALLSELECTED (เกี่ยวกับ Shadow Filter Context)

    ขั้นที่ 10 : Optimize การทำงานของ DAX ให้เร็วขึ้น

    บันได 10 ขั้น แห่งการฝึกวิชา DAX 153
    • สามารถใช้ DAX Studio เพื่อสร้าง/ทดสอบ DAX Query ได้
    • เข้าใจการทำงานของ DAX Engine ทั้งส่วนของ Formula Engine และ Storage Engine
    • เข้าใจการทำงานของ Vertipaq Storage Engine
    • ใช้ Vertipaq Analyzer เพื่อดูข้อมูลเกี่ยวกับสูตรต่างๆ และ Data Model ได้
    • สามารถค้นหา DAX/MDX Query ที่เป็นตัวปัญหาที่ทำให้รายงานช้าได้
    • สามารถตัดสินใจว่าเมื่อไหร่ควรจะสร้าง New Column ขึ้นมาจริงๆ เพื่อให้เกิด Performance ที่ดีที่สุด
    • สามารถวิเคราะห์ DAX Query Plan และ Server Timing เพื่อหาตัว Bottlenecks หรือคอขวดได้
    • เลือกใช้ฟังก์ชันและวิธีที่เหมาะสมในการแก้ปัญหาแทนวิธีการเดิมที่เชื่องช้าได้

    คุณล่ะ คิดว่าตัวเองอยู่ประมาณขั้นไหน?

    บันได 10 ขั้น แห่งการฝึกวิชา DAX 154
    https://pixabay.com/photos/forest-glade-enlightenment-mystical-4571929/

    ถ้าจะให้ลองประเมินตัวเองเล่นๆ ตอนนี้ผมเองก็น่าจะอยู่ขั้น 8-9 เท่านั้นครับ (ยังไม่ถึง 10 แน่นอน) ดังนั้นเป็นไปได้ว่า อาจจะยังมีสิ่งที่ยากกว่าขั้นที่ 10 อีกแต่ผมยังไม่รู้ ดังนั้นหากใครที่มีความเชี่ยวชาญ DAX อยากจะเสนอแนะอะไรก็สามารถบอกได้เลยไม่ต้องเกรงใจนะครับ

    ป.ล. 10 ขั้นที่เขียนนี้พูดแค่เรื่องในมิติของ DAX เท่านั้นนะครับ ซึ่งไม่ได้รวมถึงเรื่องสำคัญอื่นๆ ใน Power BI เช่น Power Query / Data Model / ส่วน Report Visualization นะครับ ซึ่งยังต้องเก่งเรื่องพวกนี้อีกถึงจะใช้ Power BI ได้เต็มที เฮ้อ…เหนื่อย! (แต่มันคุ้มนะ เพราะมันเจ๋งมากจริงๆ)

    ส่วนตัวผมเองคิดว่าจะนำลำดับขั้นเหล่านี้ไปปรับปรุงคอร์ส Power BI ของผมให้ดียิ่งขึ้นด้วยครับ และน่าจะเป็นแนวทางที่ดีในการพัฒนาคอร์ส DAX Advance ในอนาคตด้วยครับ ^^

  • วิธีหาจำนวน และตำแหน่งที่เกิดค่าที่เราต้องการแบบต่อเนื่องกันมากที่สุด (Consecutive Value)

    วิธีหาจำนวน และตำแหน่งที่เกิดค่าที่เราต้องการแบบต่อเนื่องกันมากที่สุด (Consecutive Value)

    หลายๆ ครั้งเรามักมีความต้องการอยากจะหาว่าค่าที่เราสนใจนั้น เกิดขึ้นแบบต่อเนื่องกัน (Consecutive Value) มากที่สุดกี่ครั้ง? เกิดขึ้นตรงไหน?

    เช่น มีวันหยุดต่อเนื่องกันมากสุดกี่วัน หรือ เกิดยอดขายเกินกว่า xxx ต่อเนื่องกันกี่เดือน หรือทำงานสำเร็จต่อเนื่องกันสูงสุดกี่ครั้ง เป็นต้น ซึ่งการหาจำนวน และตำแหน่ง ที่มี “ค่าตามที่เราต้องการเกิดขึ้นต่อเนื่องมากสุด” นั้นไม่ใช่เรื่องง่ายๆ ที่จะคิดเองได้

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

    สมมติเรามีข้อมูลอยู่แบบนี้ (ซึ่งจะเป็น Range ธรรมดา หรือจะเป็น Table ก็ได้) แล้วเราอยากจะหาว่า x เกิดขึ้นต่อเนื่องกันมากที่สุดกี่ครั้ง และเกิดขึ้นตรงไหน? เราจะหาคำตอบได้ยังไง มาดูกันครับ

    วิธีหาจำนวน และตำแหน่งที่เกิดค่าที่เราต้องการแบบต่อเนื่องกันมากที่สุด (Consecutive Value) 155

    หาจำนวนที่เกิดต่อเนื่องมากที่สุด

    วิธีใช้สูตรปกติ

    เราก็สามารถสร้างข้อมูลในคอัมน์ข้างๆ ให้นับ x ไปเรื่อยๆ โดยเงื่อนไข IF ว่าถ้าค่าในช่องด้านซ้ายมือตรงกับเงื่อนไขที่เราต้องการ (เช่น ตรงกับค่า x)ก็ให้นับเพิ่ม +1 ไป ถ้าไม่ใช่ให้ reset เป็น 0 ดังนี้

    =IF(A3="x",B2+1,0)
    วิธีหาจำนวน และตำแหน่งที่เกิดค่าที่เราต้องการแบบต่อเนื่องกันมากที่สุด (Consecutive Value) 156

    จากนั้นก็หาค่า Max จบเลย

    วิธีหาจำนวน และตำแหน่งที่เกิดค่าที่เราต้องการแบบต่อเนื่องกันมากที่สุด (Consecutive Value) 157

    วิธีนี้เข้าใจง่ายมากๆ แต่มีข้อเสียคือเปลืองพื้นที่ อย่างไรก็ตาม ถ้าเราต้องการจะรวบทุกอย่างให้อยู่ในช่องเดียว อาจจะต้องใช้ Array Formula ดังนี้

    วิธีที่ใช้ Array Formula

    ก่อนอื่น ให้เราเขียนเงื่อนไข IF ว่าถ้าค่าใน Range ตรงกับเงื่อนไขที่เราต้องการ (เช่น ตรงกับค่า x) ให้แสดง Row ออกมา นอกนั้นปล่อยเป็น FALSE ไป (ถ้าข้อมูลเป็นแนวนอน ก็ให้แสดง Column ออกมาแทนที่จะใช้ Row นะ)

    =IF(A3:A13="x",ROW(A3:A13))

    Excel version เก่าอย่าลืมกดปุ่ม Ctrl+Shift+Enter ด้วยนะ เพราะเป็นสูตรแบบ Array

    วิธีหาจำนวน และตำแหน่งที่เกิดค่าที่เราต้องการแบบต่อเนื่องกันมากที่สุด (Consecutive Value) 158

    จากนั้นเราทำแบบเดียวกันอีกชุดนึง แต่คราวนี้เช็คว่าถ้าไม่ตรงกับเงื่อนไขที่เราต้องการ (เช่น ไม่ใช่ x) ให้แสดง Row ออกมา นอกนั้นปล่อยเป็น FALSE ไป เช่นเดิม

    วิธีหาจำนวน และตำแหน่งที่เกิดค่าที่เราต้องการแบบต่อเนื่องกันมากที่สุด (Consecutive Value) 159

    จากนั้นใช้ฟังก์ชัน FREQUENCY ครอบทั้งสอง Range ที่สร้างขึ้นมาดังนี้

    จะได้ผลลัพธ์ว่า มีตัว <=5 อยู่ 2 อัน, <=6 อยู่ 0 อัน, <=10 อยู่ 3 อัน, <=11 อยู่ 1 อัน และ >11 อยู่ 2 อัน

    ใครไม่เข้าใจการทำงานของ FREQUENNCY ไปอ่านได้ที่นี่

    วิธีหาจำนวน และตำแหน่งที่เกิดค่าที่เราต้องการแบบต่อเนื่องกันมากที่สุด (Consecutive Value) 160

    ที่นี้เราก็จะรู้แล้วว่ามันต่อเนื่องกันมากสุดเท่าไหร่ โดยใช้ MAX มาครอบผลลัพธ์จาก FREQUENCY อีกที ดังนี้

    วิธีหาจำนวน และตำแหน่งที่เกิดค่าที่เราต้องการแบบต่อเนื่องกันมากที่สุด (Consecutive Value) 161

    ซึ่งถ้ารวบทุกสูตรเข้าด้วยกันเหลือช่องเดียวจะได้ดังนี้

    =MAX(FREQUENCY(IF(A3:A13="x",ROW(A3:A13)),IF(A3:A13<>"x",ROW(A3:A13))))
    วิธีหาจำนวน และตำแหน่งที่เกิดค่าที่เราต้องการแบบต่อเนื่องกันมากที่สุด (Consecutive Value) 162

    หาตำแหน่งที่เกิดต่อเนื่องมากที่สุด

    เพื่อให้สะดวกต่อการระบุตำแหน่ง เราจะแปลงค่าให้เป็น 1,0 ให้หมดก่อน จะได้มั่นใจว่า 1 ช่องคือ 1 ตัวอักษร ดังนี้

    วิธีหาจำนวน และตำแหน่งที่เกิดค่าที่เราต้องการแบบต่อเนื่องกันมากที่สุด (Consecutive Value) 163

    ถ้ามี CONCAT / TEXTJOIN

    จากนั้นเราแค่ใช้ CONCAT / TEXTJOIN เพื่อรวม 1,0 เข้าด้วยกันเป็นข้อความเดียว แบบนี้

    =CONCAT((A3:A12="x")*1)
    วิธีหาจำนวน และตำแหน่งที่เกิดค่าที่เราต้องการแบบต่อเนื่องกันมากที่สุด (Consecutive Value) 164

    จากนั้นใช้ SEARCH หรือ FIND เพื่อหาตำแหน่ง “111” ในข้อความนั้นก็จะได้คำตอบแล้วครับ แบบนี้

    =SEARCH(REPT("1",C3),CONCAT((A3:A12="x")*1))
    วิธีหาจำนวน และตำแหน่งที่เกิดค่าที่เราต้องการแบบต่อเนื่องกันมากที่สุด (Consecutive Value) 165

    ถ้าไม่มี CONCAT / TEXTJOIN

    ถ้าเอาแบบเข้าใจง่ายสุด ก็อาจจะใช้ & เชื่อมต่อข้อความเข้าด้วยกันก่อน แล้วค่อยใช้ SEARCH ค้นหา “111” ในนั้นอีกทีก็ได้ครับ

    วิธีหาจำนวน และตำแหน่งที่เกิดค่าที่เราต้องการแบบต่อเนื่องกันมากที่สุด (Consecutive Value) 166

    สรุป

    หวังว่าบทความนี้จะช่วยให้เพื่อนๆ สามารถเขียนสูตรเพื่อคำนวณสิ่งที่ต้องการได้ ไม่ว่าจะเป็น หาว่ามีวันหยุดต่อเนื่องกันมากสุดกี่วัน หรือ เกิดยอดขายเกินกว่า xxx ต่อเนื่องกันกี่เดือน เป็นต้น

  • สอนทำ Simulation ใน Excel เพื่อประมาณค่า Pi

    สอนทำ Simulation ใน Excel เพื่อประมาณค่า Pi

    เพื่อนๆ รู้จักค่า Pi มาบ้างใช่มั้ยครับ? (ไอ้เลข 3.14159… นั่นแหละ)

    ในบทความนี้เราจะลองสมมติว่าเราไม่เคยรู้มาก่อนเลยว่าค่า Pi คือเลขอะไร แต่เราดันอยากจะลองประมาณค่า Pi ขึ้นมาด้วยความรู้ทางคณิตศาสตร์พื้นฐาน เช่น ระยะทางระหว่างจุด (ซึ่งก็คือเรื่องเดียวกับสามเหลี่ยมมุมฉากนั่นแหละ)
    หากถามว่าจะทำไปเพื่ออะไร! ในเมื่อแค่ใช้ฟังก์ชัน PI() ก็ได้ผลลัพธ์แล้ว ?

    ก็ต้องบอกว่าทำเพื่อความสนุกแบบ Nerd ล้วนๆ และเพื่อหัดทำ Simulation ใน Excel ครับ เพราะการทำ Simulation เป็นจะช่วยให้เราเข้าใจอะไรหลายๆ อย่างได้ดีขึ้น เช่น อาาจไปใช้ทดสอบการลงทุนหุ้นอะไรแบบนี้ก็ได้ครับ

    ทฤษฎีที่ควรรู้

    ถ้าใครสังเกตจะพบว่าค่า Pi นั้นมีความเกี่ยวข้องกับรูปวงกลมอยู่อย่างมากเลย ตอนที่พวกเราเรียนวิชาคณิตศาสตร์สมัยเด็กๆ ก็ทำให้เรารู้ว่า พื้นที่ของวงกลมคำนวณได้ดังนี้

    Area = \pi r^2

    ความน่าสนใจคือ ถ้าเราลองสมมติให้รัศมีของวงกลมมีค่าเป็น 1 หน่วย แบบนี้วงกลมก็จะมีพื้นที่เท่ากับค่า Pi ตารางหน่วย พอดีเลยจริงมั้ยครับ?

    Area วงกลมรัศมี 1 หน่วย= \pi *1*1

    ทีนี้ถ้าเราเอาวงกลมรัศมี 1 หน่วย ไปยัดลงในสี่เหลี่ยมจตุรัสแบบพอดีๆ เราจะพบว่า สี่เหลี่ยมนั้นจะมีพื้นที่ =2*2 = 4 ตารางหน่วย ดังรูปข้างล่างจริงมั้ยครับ? (ตอนวาดรูปนี้ใช้ Shape -> Align -> Snap to Grid เพื่อให้วาดได้เป๊ะครับ)

    สอนทำ Simulation ใน Excel เพื่อประมาณค่า Pi 167

    ดังนั้นถ้าถามว่า “อัตราส่วน” ของพื้นที่วงกลมต่อพื้นที่สี่เหลี่ยมเป็นเท่าไหร่? มันก็คือ แบบนี้

    \dfrac{พื้นที่วงกลม}{พื้นที่สี่เหลี่ยม} = \dfrac{\pi}{4}

    ถ้าความสัมพันธ์เป็นแบบนี้ หากเราลอง “สุ่ม” จุดลงไปในพื้นที่สี่เหลี่ยม แบบเยอะๆ รัวๆ เลย มันก็น่าจะเข้าส่วนที่เป็นวงกลมในอัตราส่วน Pi/4 % นั่นเอง

    วิธีการคือ เราจะสุ่มค่า x และ y ตั้งแต่ -1 จนถึง 1 แล้วดูว่ามันอยู่ในวงกลมหรือไม่? โดยใช้ความรู้เรื่องระยะทางระหว่างจุดมาช่วยครับ

    เช่น พอเราสุ่มค่ามาแล้วได้ค่า x กับค่า y มา เราจะหาว่ามันห่างจากจุด 0,0 เท่าไหร่ (ให้เป็นระยะ d) มันก็คือการคำนวณจากระยะด้านตรงข้ามมุมฉากของรูปสามเหลี่ยมนั่นเอง

    ระยะ d = \sqrt(x^2+y^2)
    สอนทำ Simulation ใน Excel เพื่อประมาณค่า Pi 168

    งั้นเราลอง Random ค่า x กับ y ระหว่าง -1 ถึง 1 แล้วหาค่า d กันครับ ถ้ามันไม่เกิน 1 แสดงว่ายังอยู่ในวงกลมนั่นเองครับ

    และนี่คือตัวอย่างของการ Random 1 ครั้งครับ

    สอนทำ Simulation ใน Excel เพื่อประมาณค่า Pi 169

    ถ้าเรามีการให้ Excel คำนวณใหม่ หรือกด F9 เพื่อให้ Recal ค่าที่ได้ก็อาจจะเปลี่ยนไป

    สอนทำ Simulation ใน Excel เพื่อประมาณค่า Pi 170

    ซึ่งถ้าเราสุ่มจำนวนครั้งมากพอ แล้วหาอัตราส่วนว่ามันอยู่ในวงกลมกี่ % เราก็จะหาค่า Pi ได้ในที่สุดครับ ซึ่งการทำ Simulation จากการสุ่มมีชื่อเรียกว่า Monte Carlo Simulation นั่นเองครับ

    และถ้าย้ายข้างหาค่า Pi ก็จะได้ดังนี้

    \pi=\dfrac{จำนวนที่สุ่มลงวงกลม}{จำนวนที่สุ่มลงสี่เหลี่ยม} *4

    แล้วเราจะสุ่มค่าจำนวนหลายๆ ครั้งแล้วบันทึกค่าไว้ได้ยังไง? เพราะถ้าเรากด F9 ทุกอย่างก็จะเปลี่ยนไปหมดเลย…

    วิธีการทำ Simulation นั้นมีอยู่ 2 วิธีครับ

    วิธีแรก : Copy สูตรไปหลายๆ ช่องเลย

    วิธีการแรก คือ การทำแบบตรงไปตรงมาสุดๆ นั่นคือ ให้ Copy สูตรให้ครบจำนวนเยอะๆ ตามที่ต้องการ (เช่น พัน, หมื่น, แสน, ล้านครั้ง ยิ่งเยอะยิ่งแม่น) ซึ่งถ้าเราต้องการ 1 ล้านครั้ง ก็ให้ Copy สูตรลงไปล้านบรรทัด ซึ่งเราใช้ Fill Series มาช่วยสร้างค่า 1 ล้านค่าได้โดยไม่ต้องลากลงไปเอง ดังนี้

    สอนทำ Simulation ใน Excel เพื่อประมาณค่า Pi 171

    จากนั้นก็ Copy สูตรลงไป (จุดนี้ระวังเครื่องแฮงค์…) แล้วนับว่ามี TRUE กี่อัน จากจำนวนการทดลอง 1 ล้านครั้ง

    สอนทำ Simulation ใน Excel เพื่อประมาณค่า Pi 172

    ถ้าลอง Plot กราฟ จะได้ประมาณนี้ (แต่กราฟนี้ผมเอาแค่ 1000 จุด)

    สอนทำ Simulation ใน Excel เพื่อประมาณค่า Pi 173

    พอเรา เอาอัตราส่วนดังกล่าวไป*4 ก็จะได้ค่า Pi ที่เราประมาณค่าขึ้นมาได้นั่นเอง ซึ่งจะพบว่าก็ใกล้เคียงกับค่า 3.14159 ที่เราเรียนมาพอสมควรครับ (ยิ่งสุ่มเยอะ ยิ่งแม่น)

    วิธีที่ 2 : ใช้ Data Table

    ถ้าเราไม่อยาก Copy สูตรลงมาเยอะๆ เรายังสามารถทำอีกวิธีได้คือใช้เครื่องมือ Data Table ใน What-if Analysis มาช่วยครับ (ใครยังไม่เคยใช้ Data Table ลองอ่านบทความนี้ก่อนได้)

    ก่อนอื่นก็ให้เตรียมพื้นที่ที่จะแสดงผลลัพธ์ทั้ง 1 ล้านครั้งซะก่อนดังรูป โดยที่ Cell ด้านบนที่เป็นหัวของผลลัพธ์ 1 ล้านครั้งนั้น ให้ Link ค่ากับ Cell ที่ต้องการแสดงออกมา ซึ่งก็คือเขียนว่า =B5 ดังรูป

    สอนทำ Simulation ใน Excel เพื่อประมาณค่า Pi 174

    จากนั้นให้เลือกคลุมข้อมูล D1:E1000001 แล้วเลือก Data -> What if Analysis -> Data Table…

    ซึ่ง Trick คือให้เลือก Column Input Cell เป็นช่องอะไรก็ได้ที่ไม่เกี่ยวกับสูตรเลย (ทั้งนี้เพื่อให้ไม่ต้องเกิดการเอาค่า 1,2,3,4 ไปใส่ในสูตรจริงๆ เพราะมันไม่เกี่ยวกัน)

    สอนทำ Simulation ใน Excel เพื่อประมาณค่า Pi 175

    พอกด Ok เราก็จะได้ผลลัพธ์ 1 ล้านครั้ง (จุดนี้ระวังเครื่องแฮงค์…) และสามารถหาค่าประมาณการของค่า Pi ได้เช่นเดิมครับ วิธีนี้จะเห็นแค่ผลลัพธ์จำนวน 1 ล้านครั้ง โดยไม่ต้องมี input ตัวอื่นโผล่มาให้เกะกะเลย

    สอนทำ Simulation ใน Excel เพื่อประมาณค่า Pi 176

    สรุป

    เวลาเราทำการ Random สุ่มค่าจำนวนครั้งเยอะๆ นอกจากจะใช้การ Copy Paste ออกมาจำนวนมากแล้ว เรายังสามารถใช้ Data Table มาช่วยในการสร้างผลลัพธ์หลายๆ ค่าได้ด้วยครับ

    แม้ว่าการทำใน Excel จะค่อนข้างช้าเมื่อเทียบกับการใช้เครื่องมือเขียนโปรแกรมอย่าง R, Python แต่ว่าก็ยังเป็นวิธีที่สะดวกสำหรับคนทั่วไปที่เขียนโปรแกรมไม่เป็นอยู่ครับผม

  • การออกแบบตารางบันทึกข้อมูลที่ดีใน Excel (ลักษณะของ Database ที่ถูกต้อง)

    การออกแบบตารางบันทึกข้อมูลที่ดีใน Excel (ลักษณะของ Database ที่ถูกต้อง)

    เรื่องที่น่าปวดหัวที่สุดเวลาที่เราต้องสรุปข้อมูล ไม่ว่าจะใช้ PivotTable หรือพวก SUMIFS สรุปก็ตาม ก็คือ การบันทึกตารางข้อมูลในรูปแบบที่ไม่ถูกต้อง (ไม่ว่าจะทำเอง หรือ ได้มาจากคนอื่น) ซึ่งมาจากการออกแบบตารางที่ผิด

    การบันทึกข้อมูล “ไม่ถูกรูปแบบ” จะทำให้หลายคนสรุปข้อมูลไม่ได้ดั่งใจ หรือทำได้ลำบากกว่าที่ควรจะเป็นมากๆ ใน Post นี้ผมจะแนะนำให้ว่า การบันทึกข้อมูลแบบไหนที่ไม่ควรทำ และแบบไหนที่ควรทำ รวมถึงแนวทางแก้ไขเบื้องต้นด้วยครับ

    คลิปวีดีโอ

    ปัญหาเกี่ยวกับหัวตาราง

    การออกแบบตารางบันทึกข้อมูลที่ดีใน Excel (ลักษณะของ Database ที่ถูกต้อง) 177
    การออกแบบตารางบันทึกข้อมูลที่ดีใน Excel (ลักษณะของ Database ที่ถูกต้อง) 178

    หัวตาราง 2 ชั้น ทำให้มีปัญหาในการใส่ Filter และ การนำเข้า PivotTable อย่างรุ่นแรง อันนี้น่าจะเป็นเรื่องที่ผิดพลาดแบบเด่นชัดมากที่สุดเลยครับ วิธีที่ถูกต้อง ทุกครั้งให้ทำหัวตารางแค่บรรทัดเดียวเท่านั้น และต้องมีครบทุกคอลัมน์ด้วย

    แต่ถ้าจำเป็นต้องทำ 2 ชั้นจริงๆ เพราะความสวยงาม ให้ทำแยกบรรทัดไปอีก section ด้านบนโดยไม่ต้องอยู่ติดกับตารางไปเลย แล้วค่อนซ่อนตัวบรรทัดเดียวไปซะเพื่อความสวยงาม

    การออกแบบตารางบันทึกข้อมูลที่ดีใน Excel (ลักษณะของ Database ที่ถูกต้อง) 179
    การออกแบบตารางบันทึกข้อมูลที่ดีใน Excel (ลักษณะของ Database ที่ถูกต้อง) 180

    แม้ว่าการแยกข้อมูลในเรื่องเดียวกันเป็นหลายคอลัมน์ จะสามารถเอาเข้าไปใช้ใน Pivot Table ได้ แต่ก็จะทำให้มีปัญหาตอนทำยอดสรุปรวมหลายๆ สินค้าเข้าด้วยกัน เช่น จะหายอดรวมของ หนังสือกับอาหาร ตอนสรุปด้วย PivotTable แบบนี้ก็จะยากแล้ว

    การทำข้อมูลเรื่องเดียวกันให้มาอยู่ในคอลัมน์เดียวกัน จะช่วยให้ตอนสรุปยอดรวมใน Pivot Table รวมถึงการ Filter ง่ายขึ้นมาก

    แนวทางแก้ไข : วิธีแก้ไขที่ง่ายที่สุด สามารถใช้เครื่องมือ Unpivot ของ Power Query ได้ครับ

    ปัญหาเกี่ยวกับตัว Data

    การออกแบบตารางบันทึกข้อมูลที่ดีใน Excel (ลักษณะของ Database ที่ถูกต้อง) 181
    การออกแบบตารางบันทึกข้อมูลที่ดีใน Excel (ลักษณะของ Database ที่ถูกต้อง) 182

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

    การใส่ข้อมูลแบบไม่เว้นว่าง ทำให้ Computer เข้าใจได้ถูกต้อง แม้จะดูลายตา แต่เวลานำไปทำรายงานใน PivotTable สามารถทำให้ไม่ลายตาได้อยู่แล้ว

    แนวทางแก้ไข : สามารถใช้เครื่องมือ Fill Down ของ Power Query ได้ครับ

    การออกแบบตารางบันทึกข้อมูลที่ดีใน Excel (ลักษณะของ Database ที่ถูกต้อง) 183
    การออกแบบตารางบันทึกข้อมูลที่ดีใน Excel (ลักษณะของ Database ที่ถูกต้อง) 184

    การมีบรรทัดสรุปปนมา ทำให้ตอนนำข้อมูลเข้าไปสรุปต่ออีก จะทำให้ตัวเลขเบิ้ลเกินความเป็นจริงได้

    แนวทางแก้ไข : ตัดบรรทัดสรุปทิ้งไปซะก่อนจะ pivot ซึ่งจะทำแบบปกติ หรือจะใช้ Power Query ก็ได้ครับ

    วิธีแก้ปัญหา เวลาเจอการออกแบบตารางที่ผิด

    ใครเจอปัญหาน่าปวดหัวแบบใน Post นี้ สามารถใช้ความรู้ของ Power Query มาแก้ไขปัญหาได้นะครับ นอกจากแก้ปัญหาจากไฟล์ที่บันทึกมาผิดๆ ได้แล้ว ยังสามารถรวบรวมข้อมูลจากหลายๆ ที่ได้ด้วย

    ใครสนใจอยากเรียนรู้ ขอแนะนำคอร์สออนไลน์ Power Query ของผม (เพิ่งจะอัปเดทปรับปรุงใหม่ในปี 2021 นี้)

    ที่สำคัญ ช่วงนี้กำลังลดราคาพิเศษอยู่พอดีเลยครับ (หมดเขต 19 มีค. 64)

    ดูรายละเอียดใน link นี้นะครับ :

  • สอนใช้ SUMIFS บวกแบบมีเงื่อนไข เข้าใจไม่มีวันลืม

    สอนใช้ SUMIFS บวกแบบมีเงื่อนไข เข้าใจไม่มีวันลืม

    ผมจะมาสอนใช้ฟังก์ชัน SUMIFS ซึ่งสามารถบวกข้อมูลตามเงื่อนไขที่ต้องการได้ บอกเลยว่ามันเป็นหนึ่งในฟังก์ชันสรุปข้อมูลที่ใช้บ่อยที่สุดใน Excel เลยล่ะ!

    วิธีใช้สูตร

    =SUMIFS(sum_range,criteria_range,criteria,…)
    =SUMIFS(ช่วงผลรวม,ช่วงเงื่อนไข,ค่าเงื่อนไขที่ต้องการ,…)

    trick ในการจำคือ ถ้ามีคำว่า range ให้เลือกเป็นช่วง ( เช่น sum_range criteria_range)
    ส่วน criteria ไม่มีคำว่า range ให้เลือกค่าช่องเดียว

    วิธีใช้สูตรนี้แบบง่ายสุดคือ ใช้กับ Table ซึ่งจะทำให้เลือกช่วงข้อมูลได้ง่ายขึ้นมาก แค่เลือกที่ขอบบนของ Table มันก็จะเลือก Data ทั้งคอลัมน์ของตารางให้เอง

    SUMIFS เงื่อนไขเดียว

    สอนใช้ SUMIFS บวกแบบมีเงื่อนไข เข้าใจไม่มีวันลืม 185

    SUMIFS หลายเงื่อนไข

    เราสามารถใส่เงื่อนไขได้หลายชุด โดยใส่เครื่องหมาย comma คั่นไปเรื่อยๆ โดยที่เราจะใส่ sum_range แค่ครั้งเดียวนะ

    =SUMIFS(sum_range,  criteria_range1,criteria1,   criteria_range2,criteria2,  …)
    =SUMIFS(ช่วงผลรวม,  ช่วงเงื่อนไข1,ค่าเงื่อนไขที่ต้องการ1,   ช่วงเงื่อนไข2,ค่าเงื่อนไขที่ต้องการ2,  …)
    สอนใช้ SUMIFS บวกแบบมีเงื่อนไข เข้าใจไม่มีวันลืม 186

    ลูกเล่นตรง Criteria

    สามารถใส่เครื่องหมายเปรียบเทียบได้ เช่น

    • <>หนังสือ แปลว่า เอาทุกอันที่ไม่ใช่หนังสือ
    • >300 แปลว่า เอาที่ค่ามากกว่า 300
    • <=10 แปลว่า เอาที่ค่าไม่เกิน 10

    ถ้าจะหมายถึง “ระหว่าง” ให้ใช้ 2 เงื่อนไข เช่น

    ระหว่าง 100 ถึง 300 ต้องมี 2 เงื่อนไข คือ

    • >=100
    • <=300

    สามารถใช้เครื่องหมาย wildcard ได้

    • ? แทน ตัวอะไรก็ได้ 1 ตัวอักษร
    • * แทน ตัวอะไรก็ได้ กี่ตัวอักษรก็ได้ (ไม่มีเลยก็ได้)

    ตัวอย่าง

    • หนัง* แปลว่า ขึ้นต้นด้วยคำว่าหนัง
    • *หนัง แปลว่า จบด้วยคำว่าหนัง
    • *หนัง* แปลว่า มีคำว่าหนังอยู่
    • * แปลว่า เป็น text อะไรก็ได้ (รวมถึง blank text)
  • รวม Link สอน Python / Programming / AI/ Machine Learning แบบฟรีๆ

    รวม Link สอน Python / Programming / AI/ Machine Learning แบบฟรีๆ

    ในฐานะที่ผมกำลังฝึกฝนการเขียนโปรแกรมด้วย Python อยู่ ก็เลยขอรวบรวมแหล่งเรียนรู้ที่ผมคิดว่าผมศึกษาแล้วเข้าใจง่ายมาไว้ด้วยกันครับ เผื่อเพื่อนๆ จะได้เรียนรู้ไปด้วย

    ภาษาไทย

    AI บ้านบ้าน (AI บ้านบ้าน)

    จากช่อง ภาษาศาสตร์คอมพิวเตอร์ Thai NLP

    ภาษาอังกฤษ

  • หัด Python สำหรับคนเป็น Excel : ตอนที่ 8 – การสร้างกราฟด้วย Matplotlib

    หัด Python สำหรับคนเป็น Excel : ตอนที่ 8 – การสร้างกราฟด้วย Matplotlib

    ในบทความนี้เราจะมาเรียนรู้เรื่องการสร้างกราฟใน Python ด้วย Library ที่ชื่อว่า Matplotlib กันครับ การสร้างกราฟใน Python ด้วย Matplotlib นั้นเป็นอะไรที่ต่างจากการสร้างกราฟที่เราเคยทำใน Excel หรือ Power BI แบบสุดๆ เพราะว่าใน Excel แล้วใช้ User Interface เป็นหลัก เพื่อกำหนดว่ากราฟจะเป็นแบบไหน สีอะไร แต่ใน Python จะต้องใช้การเขียน Code เพื่อสั่งมัน

    Matplotlib เป็น Module พื้นฐานในการสร้างกราฟใน Python โดยที่เราจะนำไปต่อยอดด้วย Module อื่นที่ทำกราฟได้สวยขึ้นเช่น Seaborn ด้วย (จะพูดถึงในตอนถัดไป)

    ซึ่งความรู้ทั้งหมดนี้นี่จะช่วยให้พวกเราสามารถสร้างกราฟหน้าตาแปลกๆ ขึ้นมาใช้เองด้วยการเรียกใช้ Python Script ใน Power BI ได้ด้วยนะครับ ดังนั้นเรียนรู้ไว้ไม่เสียหายแน่นอน

    Install Matplotlib

    คำสั่งนี้เรียกครั้งเดียวใน command prompt เพื่อให้ computer เราโหลด script ของ library ตัวนี้มาจาก internet นะ

    pip install matplotlib

    Import Matplotlib

    import matplotlib.pyplot as plt

    Concept การทำงานของ Matplotlib

    การสร้างกราฟใน Python ด้วย Matplotlib นั้นเราจะต้องเขียน Code เพื่อสั่งว่ากราฟของเราจะมีส่วนประกอบอะไร หน้าตายังไงบ้าง?

    เช่น กราฟเป็นประเภทอะไร? ค่า x และ y เป็นอะไร? title แกน x,y คืออะไร? ซึ่งสามารถใส่คำสั่งเพิ่มไปได้เรื่อยๆ (ไม่จำเป็นต้องสั่งรวดเดียวก็ได้)

    โดยที่หลังจากที่เราบอกมันว่าส่วนประกอบเป็นอะไรบ้าง ถ้าเป็นการทำ python ใน script ปกติเราจะยังคงมองไม่เห็นผลลัพธ์ทันที ถ้าอยากจะเห็นว่าเป็นยังไง ต้องสั่งให้มัน show กราฟออกมาจึงจะเห็นได้นะครับ

    ซึ่งคำสั่ง plt.show() จะไปไล่หาว่ามี object กราฟอะไรถูกสร้างขึ้นมาบ้าง แล้วก็จะแสดงออกมาทุกอันเลย (อาจมีหลายอันก็ได้)

    แต่ถ้าเราทำใน colab มันก็จะแสดงกราฟออกมาเลยทันทีโดยครับ

    เริ่มสร้างกราฟด้วย Matplotlib

    เริ่มจากกราฟเส้น

    หากเราสั่ง plt.plot(….) มันจะสร้างกราฟเส้นทันที (ถ้าจะ plot กราฟประเภทอื่นต้องสั่งด้วยคำสั่งอื่น) โดยเราสามารถระบุค่า x และ ค่า y ที่ต้องการได้ ดังนี้

    import matplotlib.pyplot as plt
    x = [1,3,4,8]
    y = [7,10,8,9]
    plt.plot(x,y)
    plt.show()  #บรรทัดนี้ใน colab ใส่ก็ได้ ไม่ใส่ก็ได้

    มันจะให้ผลแบบนี้ ซึ่งจะเห็นว่าเป็นกราฟเส้นซึ่ง plot ค่าระหว่าง x กับ y ต่างๆ

    หัด Python สำหรับคนเป็น Excel : ตอนที่ 8 – การสร้างกราฟด้วย Matplotlib 187

    การใส่ชื่อกราฟ และ Legend

    ถ้าเราจะ plot หลายเส้นในกราฟเดียวก็สั่งเพิ่มไปเลยแบบนี้ และยังระบุ title กราฟ และ legendได้ด้วย

    x = [1,3,4,8]
    y = [7,10,8,9]
    x2 = [1,2,6,8]  # กำหนดค่ากราฟ series ที่สอง
    y2 = [3,6,8,10]
    plt.plot(x,y,label='Series1')  #ระบุ label สำหรับ legend ได้
    plt.plot(x2,y2,label='Series2') # plot กราฟ series ที่สอง
    plt.xlabel('x-title') #ชื่อแกน x
    plt.ylabel('y-title') #ชื่อแกน y
    plt.title('ChartTitle1\nChartTitle2') #ชื่อกราฟ ขึ้นบรรทัดใหม่ได้ด้วย \n
    plt.legend()  #แสดง Legend
    plt.show()  #บรรทัดนี้ใน colab ใส่ก็ได้ ไม่ใส่ก็ได้
    หัด Python สำหรับคนเป็น Excel : ตอนที่ 8 – การสร้างกราฟด้วย Matplotlib 188

    กราฟแท่ง และการกำหนดสี

    ถ้าอยากจะให้ plot กราฟแท่ง ก็ให้ใช้คำสั่ง plt.bar แทนที่จะเป็น plt.plot แค่นั้นเอง นอกจากนั้นเราสามารถกดหนดสีของแท่งได้ด้วย argument ที่ชื่อว่า color

    x = [1,3,4,8]
    y = [7,10,8,9]
    x2 = [1,2,6,8]  
    y2 = [3,6,8,10]
    plt.bar(x,y,label='Series1') #ใช้ plt.bar สร้างกราฟแท่ง 
    plt.bar(x2,y2,label='Series2', color='red') #กำหนดสีได้ 
    plt.xlabel('x-title') 
    plt.ylabel('y-title') 
    plt.title('ChartTitle1\nChartTitle2') 
    plt.legend()  
    plt.show()  #บรรทัดนี้ใน colab ใส่ก็ได้ ไม่ใส่ก็ได้
    หัด Python สำหรับคนเป็น Excel : ตอนที่ 8 – การสร้างกราฟด้วย Matplotlib 189

    กราฟอื่นๆ

    นอกจาก plt.plot และ plt.bar แล้ว ก็ยังมีกราฟอื่นๆ อีกเพียบเลย ดูตัวอย่างได้ที่นี่

    ลองสร้าง Histogram จากข้อมูล dataframe ของ csv

    สมมติว่าผมมีข้อมูลความสูงของตัวละครใน Dragonball เป็นไฟล์ csv ผมก็เอามาทำ histogram ได้ดังนี้

    import pandas as pd
    DBZ=pd.read_csv('https://raw.githubusercontent.com/ThepExcel/download/master/DBZ.csv')
    CharHeight=DBZ['Height'] #ดึงค่าคอลัมน์ Height จาก csv มา
    
    bins=range(0,300,20)  # สร้าง list (หรือ array ก็ได้) ที่เว้นทีละ 20 จาก 0 ถึง 300
    
    plt.hist(CharHeight,bins,histtype='bar',rwidth=0.9)  # กำหนดความกว้างแท่งคือ 0.9 เพราะ 1 จะติดกันเลย
    plt.show()  #บรรทัดนี้ใน colab ใส่ก็ได้ ไม่ใส่ก็ได้
    หัด Python สำหรับคนเป็น Excel : ตอนที่ 8 – การสร้างกราฟด้วย Matplotlib 190

    สร้างกราฟหลายอันในรูปเดียว

    การสร้างกราฟหลายๆ กราฟใน figure รูปเดียว นั้นเราสามารถวางตำแหน่งได้ตามต้องการว่าจะวางกราฟแต่ละอันเอาไว้ตรงไหน ซึ่งทำได้หลายวิธี เช่น ใช้คำสั่ง subplot หรือ subplot2grid ก็ได้

    แต่วิธีที่ผมคิดว่ายืดหยุ่นดีคือการใช้คำสั่ง subplot2grid ซึ่งจะเป็นการสร้าง grid จำลองขึ้นมา แล้วให้เราระบุว่าจะ plot กราฟไว้ตรงไหนของ grid แล้วให้มันกินพื้นที่ไปแค่ไหน

    import matplotlib.pyplot as plt
    #subplot2grid(shape, loc, rowspan, colspan)
    
    #ในพื้นที่ 4Rx3C ให้plotตำแหน่ง 0,0 ลงไป 1 แถว ไปทางขวา 3 คอลัมน์
    chrt1=plt.subplot2grid((4,3),(0,0),rowspan=1,colspan=3)  
    
    #ในพื้นที่ 4Rx3C ให้plotตำแหน่ง 1,0 ลงไป 2 แถว ไปทางขวา 1 คอลัมน์
    chrt2=plt.subplot2grid((4,3),(1,0),rowspan=2,colspan=1)  
    
    #ในพื้นที่ 4Rx3C ให้plotตำแหน่ง 1,1 ลงไป 3 แถว ไปทางขวา 2 คอลัมน์
    chrt3=plt.subplot2grid((4,3),(1,1),rowspan=3,colspan=2)  
    
    #ในพื้นที่ 4Rx3C ให้plotตำแหน่ง 3,0 ลงไป 1 แถว ไปทางขวา 1 คอลัมน์
    chrt4=plt.subplot2grid((4,3),(3,0),rowspan=1,colspan=1)  
    หัด Python สำหรับคนเป็น Excel : ตอนที่ 8 – การสร้างกราฟด้วย Matplotlib 191

    ทีนี้เราลองสั่ง plot แต่ละกราฟออกมาได้เลย

    import matplotlib.pyplot as plt
    
    #เตรียมพื้นที่
    #subplot2grid(shape, loc, rowspan, colspan)
    chrt1=plt.subplot2grid((4,3),(0,0),rowspan=1,colspan=3)  
    chrt2=plt.subplot2grid((4,3),(1,0),rowspan=2,colspan=1)  
    chrt3=plt.subplot2grid((4,3),(1,1),rowspan=3,colspan=2)  
    chrt4=plt.subplot2grid((4,3),(3,0),rowspan=1,colspan=1)  
    
    #เริ่มสั่ง plot data ลงไปจริงๆ
    x = [1,3,4,8]
    y = [7,10,8,9]
    chrt1.plot(x,y)  #สั่ง plot ลงพื้นที่แรก
    
    #เอาข้อมูล DBZ เดิมมาทำต่อ
    chrt2.hist(CharHeight,bins,histtype='bar',rwidth=0.9)
    
    x = [1,3,4,8]
    y = [7,10,8,9]
    x2 = [1,2,6,8]  
    y2 = [3,6,8,10]
    chrt3.bar(x,y,label='Series1') #ใช้ plt.bar สร้างกราฟแท่ง 
    chrt3.bar(x2,y2,label='Series2', color='red') #กำหนดสีได้ 
    chrt3.legend()
    
    chrt4.plot([1,2,3,4],[6,3,5,8])
    
    plt.show()
    หัด Python สำหรับคนเป็น Excel : ตอนที่ 8 – การสร้างกราฟด้วย Matplotlib 192

    ตอนต่อไป Seaborn

    สำหรับเนื้อหาเรื่อง Matplotlib เราจะรู้เท่านี้พอก่อน เพราะเดี๋ยวตอนหน้าเราจะเปลี่ยนไปใช้ Seaborn ซึ่งทำกราฟแปลกๆ ได้สะดวกกว่า Matplotlib มากครับ เราค่อยไปเรียนแบบละเอียดกันในนั้นละกันนะ

    สารบัญ Series Python

    • 2 วิธี คำนวณภาษีแบบขั้นบันได ด้วย Excel (Step Tax Calculation)

      2 วิธี คำนวณภาษีแบบขั้นบันได ด้วย Excel (Step Tax Calculation)

      ในคลิปนี้เราจะมาเรียนรู้วิธีคำนวณภาษีแบบขั้นบันได (Step Tax Calculation) กันครับ ซึ่งมีอยู่ 2 วิธีด้วยกัน คือคำนวณในตาราง กับคำนวณใน 1 บรรทัด ซึ่งผมจะสอนทั้งสองวิธีเลย

      แหล่งเรียนรู้เพิ่มเติม เพื่อให้เข้าใจเรื่องการ Lookup เพื่อ คำนวณ Step Tax

    • แนวทางการใช้ Python ใน Power BI

      แนวทางการใช้ Python ใน Power BI

      จากที่เราได้เรียนรู้การใช้ Python เบื้องต้นกันมาบ้างแล้วในหลายๆ ตอน คราวนี้เราจะมาใช้ Python กันในโปรแกรม Power BI กันบ้าง ซึ่งในบทความนี้เพื่อนๆ จะได้เรียนรู้ว่ามันเอามาใช้ด้วยกันได้ยังไง ในลักษณะไหน ต้องทำอะไรบ้าง? โดยตัวอย่างที่แสดงจะไม่ได้ทำอะไรซับซ้อนเพื่อความเข้าใจง่ายนะครับ (คือเรื่องที่ทำให้ดูใน Python ในบทความนี้ ทำใน Power Query โดยตรงก็ได้ แค่จะแสดงให้เห็น Concept เฉยๆ)

      เตรียมความพร้อม

      ก่อนอื่น เราจะต้อง Download แล้ว Install Python ลงเครื่องคอมพิวเตอร์ของเราก่อน (ใช้แค่ Collab เหมือนเดิมไม่ได้แล้ว) ไม่งั้นมันจะใช้ Python ใน Power BI ไม่ได้นะครับ

      ซึ่งตอน Install ผมแนะนำให้ติ๊กว่าให้เอา Python add เข้า PATH ของเครื่องด้วยนะครับ

      จากนั้น ให้ ทำการ Install Package ที่เกี่ยวข้อง และคิดว่าจะใช้งานใน Power BI ด้วย โดยใส่คำสั่งเหล่านี้ที่ Command Prompt ของ Windows (ไม่ใช่ของ Python นะ)

      pip install pandas 
      pip install matplotlib 
      pip install numpy 
      pip install seaborn

      พอ Install ทุกอย่างที่จำเป็นหมดแล้ว ก็เข้าโปรแกรม Power BI ได้ ซึ่งเมื่อลองเข้าไปใน Option จะเห็นว่า มันมองเห็น Python ที่เรา Install ลงในเครื่องแล้ว

      ส่วนเรื่องของ IDE จะปล่อยเป็นค่า Default ก็ได้ แต่ของผมเลือก Other แล้ว browse ไปที่ Microsoft Visual Studio Code ตามตำแหน่งนี้ C:\Users\ชื่อUser\AppData\Local\Programs\Microsoft VS Code\Code.exe

      แนวทางการใช้ Python ใน Power BI 193

      ใช้ Python ในขั้นตอน Get Data

      เราจะลองใช้ Python ในขั้นตอนของการ Get Data โดยไปที่ Get Data -> More…-> Other -> Python Script

      Concept คือ Power Query จะมองเห็นตัวแปรที่เก็บ DataFrame ของ Python แยกเป็นคนละ Object กัน เช่น ใส่คำสั่งนี้ลงไปใน Script

      import pandas as pd
       TestVar1=pd.read_csv("https://raw.githubusercontent.com/ThepExcel/download/master/ThepExcelsample.csv")
       data = {'แอปเปิ้ล': [1, 3, 6, 8],'มะละกอ': [10, 30, 50, 90]}
       TestVar2=pd.DataFrame(data)

      พอกด ok จะเห็นเป็น 2 Object ดังนี้ (สังเกตว่ามองไม่เห็นตัวแปร data ที่เป็น Dictionary)

      แนวทางการใช้ Python ใน Power BI 194
      แนวทางการใช้ Python ใน Power BI 195

      ให้เลือก TestVar1 แล้วกด Transform เพื่อทำงานต่อ

      สังเกตว่าใน step Source จะมีคำสั่ง = Python.Execute( xxxx ) โผล่มา ซึ่งคำสั่งนี้ใช้ได้ใน Power Query ของ Power BI เท่านั้น ไม่สามารถเอาไปใช้ใน Power Query ของ Excel ได้นะครับ

      ใช้ Python ในขั้นตอน Transform

      พอ Load Data เข้ามาได้แล้ว เราก็สามารถ Transform โน่นนี่นั่นใน Power Query Editor ได้ตามปกติเลย เช่น ในที่นี้ผมจะ Filter ผู้ขายเป็น sales ก เท่านั้น

      จากนั้นเวลาเราจะใช้ Python ทำงานต่อ เราสามารถไปที่ Transform -> Run Python Script ได้

      จากนั้นมันจะมี comment บอกว่า #’dataset’ holds the input data for this script นั่นก็แปลว่าตัวแปรชื่อว่า dataset เป็นตัวเก็บข้อมูลก่อนที่จะ run Script ล่าสุดนี้นั่นเอง

      เช่น ถ้าผมเขียนใน Script ว่า

      #'dataset' holds the input data for this script
      dataset2=dataset.copy()  #ลองสร้าง data เป็นอีกตัวนึง
      dataset2['ยอดขาย']=dataset2['ราคาต่อชิ้น']*dataset2['จำนวนชิ้น']      #สร้างคอลัมน์ยอดขาย

      ถ้ามันขึ้นเตือนเรื่อง Privacy ให้เลือกทุกอันเป็น Public ให้หมดแล้วกด ok

      ก็จะมี Step Run Python script โผล่มา โดยเห็นผลลัพธ์เป็น 2 Object แยกจากกัน ซึ่ง dataset2 จะมีคอลัมน์ยอดขายเพิ่มขึ้นมาด้วย

      แนวทางการใช้ Python ใน Power BI 196

      สมมติว่าเราจะเอา dataset2 นี่แหละไปทำงานต่อ ก็คลิ๊กที่ทำคำว่า table ได้เลย เพื่อ drill down ลงไปใน object นั้น

      จากนั้นกด Close & Apply เพื่อเอา Data เข้าไปใน Data Model ได้เลย

      ใช้ Python ใน Visual

      เราสามารถใช้ Python สร้าง Visual ได้ด้วย ซึ่งผมจะใช้ Matplotlib ในการสร้างแล้วกัน

      ก่อนอื่นให้คลิ๊กที่ Visual ที่มี icon เป็นคำว่า Py ได้เลย (Py=Python)

      แนวทางการใช้ Python ใน Power BI 197

      มันจะบอกว่าให้ลาก Field ลงมาที่ block Values เพื่อเริ่มเขียน Script ได้ งั้นเราก็ลากเลย เอา TXID, ยอดขาย, สินค้า, วิธีชำระเงิน ลงมาแล้วกัน

      สังเกตว่ามันมีการ Comment บอกเราว่า dataset ของเราได้คัดเลือกเอา Field 4 ตัวนั้นลงมาแล้ว และมีการกำจัดข้อมูลที่ซ้ำออกให้ด้วย (นี่คือสาเหตุที่ผมต้องเอา TXID ลงมา ไม่งั้นมันลบข้อมูลหายเหี้ยนแน่)

      จากนั้นใน Script ดังนี้เพื่อลองสร้าง Boxplot ของยอดขายขึ้นมา แล้วกด Run Script

      # Paste or type your script code here:
      import matplotlib.pyplot as plt 
      plt.boxplot(dataset['ยอดขาย'])
      plt.show()
      แนวทางการใช้ Python ใน Power BI 198

      พอได้กราฟออกมา เราสามารถสร้าง Visual ตัวอื่นให้มา Interact กับกราฟที่เกิดจาก Python ได้ด้วย เช่น ผมเอาลูกค้ามาเป็น Slicer มันก็ยังสามารถ Filter ข้อมูลในกราฟของ Python ได้ด้วย

      แนวทางการใช้ Python ใน Power BI 199

      ทีนี้จะทำกราฟได้ดีแค่ไหน ก็ขึ้นกับความสามารถด้าน Python ของเพื่อนๆ แล้วล่ะ

      สรุป

      สรุปแล้ว เราสามารถใช้ Python ได้ตั้งแต่ขั้นตอน Get Data / Transform Data และ การทำ Visual ด้วยเลย ซึ่งหากใช้ Python ได้คล่องๆ ก็จะทำอะไรได้มากกว่าที่ Power BI ปกติทำได้อีกมาก ที่ผมคิดว่าเหมาะ เช่น การทำ Web Scrapping รวมถึงการใช้ Regex แบบซับซ้อน เป็นต้น (แต่ตัวอย่างนี้ยังไม่ได้แสดงถึงจุดนั้น)

      ไว้ผมหัด Python เก่งๆ แล้วจะมาแสดงตัวอย่างเคสที่เหมาะกับการใช้ Python ให้ดูอีกทีนะครับ

      ว่าแล้วผมก็ขอไปหัดใช้ Python ต่อก่อนล่ะครับ^^

    • ทำอย่างไรถึงจะเก่ง Excel?

      ทำอย่างไรถึงจะเก่ง Excel?

      หากมีคนถามผมว่า ทำยังไงถึงจะเก่ง Excel? ต้องเรียนคอมพิวเตอร์มาหรือไม่? ผมก็มักจะตอบโดยการเล่าเรื่องของตัวผมเองว่าทำไมผมจึงพัฒนาทักษะ Excel ได้เก่งขึ้นมาจนถึงระดับที่อยู่ในตอนนี้ จากเดิมตอนที่ทำงานครั้งแรกก็ใช้ Excel ไม่เป็นเหมือนทุกคนนั่นแหละ ใครจะไปเก่งมาแต่เกิด ตอนเรียนมหาวิทยาลัยก็ไม่ได้เรียน ก็เหมือนกับหลายๆ ท่านนั่นแหละ

      ซึ่งจากการตกผลึกแล้ว มันมีปัจจัยใหญ่ๆ อยู่ไม่กี่ข้อ ที่ทำให้ผมเก่ง Excel ได้ ซึ่งเทคนิคเหล่านี้ จริงๆ ก็เอาไปใช้กับการฝึกเรื่องไหนก็ได้นั่นแหละ

      หาวิธีทำงานที่ดีขึ้นไปเรื่อยๆ

      ทำอย่างไรถึงจะเก่ง Excel? 200

      ทุกอย่างเริ่มต้นจากความขี้เกียจ…

      ตัวผมเองนั้นต้องสารภาพตามตรงว่าเป็นคนที่ค่อนข้างขี้เกียจ (แต่ไม่ได้ขี้เกียจไปซะทุกเรื่องนะ 555 เพราะมันมีขี้เกียจแบบดีกับแบบไม่ดี) สิ่งที่ผมขี้เกียจมากที่สุดคือ “ขี้เกียจที่จะทำงานถึกๆ ซ้ำๆ” ซึ่งเป็นการขี้เกียจแบบดีนะ

      ผมจะเป็นคนที่ไม่ยอมนั่งทำงานถึกๆ เหมือนหุ่นยนต์ไปเรื่อยๆ เด็ดขาด ถ้างานไหนที่ทำแล่วรู้สึกว่าเริ่มถึก ผมจะทำทุกวิถีทางที่จะกำจัดมันไปให้เร็วที่สุดเท่าที่ทำได้ (แต่ไม่ได้ปฏิเสธงานนะ เพราะว่าอยากได้ผลงานที่ดีอยู่) ผมจะถามตัวเองเสมอว่า มันมีวิธีทำงานที่ดีกว่าที่ทำอยู่มั้ย? ซึ่งแน่นอนว่า “ส่วนใหญ่แล้วจะมี”

      และเราจะรู้วิธีนั้นได้ยังไง? ถ้าเป็นแต่ก่อนอาจจะต้องหาพี่ที่ทำงานที่เก่งๆ ให้สอนให้ แต่สมัยนี้เราหาทุกอย่างได้จาก internet

      ซึ่งปัญหาที่เราเจออยู่นั้น มันมีคนเคยเจอปัญหานั้นมาแล้วอย่างแน่นอน (และก็มีวิธีแก้ไขแล้วด้วย) แค่เราต้องค้นหาให้เจอ ซึ่ง trick ก็คือ ต้องหาด้วยภาษาอังกฤษ แล้วคุณจะเจอ Forum หรือ บทความ หรือคลิปวีดีโอ ที่จะบอกวิธีแห้ปัญหาที่คุณเจออยู่ได้อย่างแน่นอน

      และพอเริ่มแก้ปัญหาได้ คุณจะมีเวลาเยอะขึ้น แต่ผมก็จะไม่หยุดแค่นั้น ผมจะหาลองหาวิธีที่ดีขึ้นไปอีก ซึ่งเป็นไปได้ว่าวิธีที่ทำอยู่นั้นดีมากแล้ว แต่เมื่อเวลาผ่านไป มีเครื่องมือมากขึ้น ก็อาจมีวิธีใหม่ๆ โผล่ขึ้นมาอีกก็ได้ (เช่น Power Query, Power Pivot, Power BI, Dynamic Array)

      ภาษาอังกฤษสำคัญมาก

      ทำอย่างไรถึงจะเก่ง Excel? 201
      https://unbabel.com/blog/top-languages-of-the-internet/

      ปฏิเสธไม่ได้เลยว่า แหล่งความรู้ที่ยิ่งใหญ่ที่สุดในโลกนี้คือ internet และภาษาที่ใช้บันทึกความรู้เหล่านั้นไว้ ส่วนใหญ่จะเป็นภาษาอังกฤษ ( Content ใน Net เป็นภาษาอังกฤษประมาณ 60% ในขณะที่ภาษาไทยมีไม่ถึง 1%) ดังนั้นถ้าทักษาด้านนภาษาอังกฤษของคุณไม่ดี คุณจะเข้าถึงความรู้เหล่านั้นอย่างที่ผมพูดถึงในหัวข้อที่แล้วไม่ได้เลย (โดยเฉพาะเรื่องการอ่านและการฟัง)

      ตัวผมเองเป็นคนที่ทักษาภาษาอังกฤษค่อนข้างดีอยู่แล้ว (สมัยทำงานใหม่ๆ ผมเคยสอบ TOEIC ได้ 980/990 มั้ง) ซึ่งน่าจะเป็นเพราะผมพยายามให้ชีวิตได้เจอภาษาอังกฤษบ่อยๆ ตลอดเวลา

      ผมเป็นคนที่ชอบเล่นเกม ซึ่งการเล่นเกมของผมจะทำให้มั่นใจได้ว่าจะเจอภาษาอังกฤษวันละ 1-2 ชั่วโมงเป็นอย่างต่ำ โดยเฉพาะเกมแนวที่ต้องอ่านเยอะๆ จะยิ่งมีประโยชน์เพราะจะทำให้ได้เจอคำศัพท์เยอะมากๆ ไปด้วย (ถ้าเล่นเกมที่ไม่ค่อยได้อ่าน ก็จะได้ประโยชน์น้อย)

      แต่ถ้าคุณไม่ได้ชอบเล่นเกม คุณต้องไปหาสิ่งที่คุณชอบ แต่ให้ใช้ภาษาอังกฤษ เช่น ดูหนัง ฟังเพลง หรือค้นหาข้อมูลงานอดิเรกของคุณ ให้เป็นภาษาอังกฤษเข้าไว้ มันช่วยได้จริงๆ นะครับ

      ด้วยการฝึกแบบนี้ ผสมผสานกับการคิดในเชิงระบบ เชิงโครงสร้างมากขึ้น ผมมั่นใจว่าทักษะภาษาอังกฤษของคุณจะต้องดีขึ้นแน่นอน (ใครสนใจให้ผมสอนวิชาภาษาอังกฤษก็บอกได้นะ 555)

      ฝึกฝนการมองทุกอย่างให้เป็นระบบ

      ทำอย่างไรถึงจะเก่ง Excel? 202
      https://medium.com/disruptive-design/tools-for-systems-thinkers-the-6-fundamental-concepts-of-systems-thinking-379cdac3dc6a

      นอกจากความคิดในเชิง Logic ซึ่งเป็นสิ่งหนึ่งที่หลายคนคิดว่าสำคัญแล้ว อีกสิ่งนึงเลยที่ทำให้การใช้ Excel ของหลายๆ คนยังไม่ดีเท่าที่ควร เพราะไม่สามารถมองหรือคิดถึงสิ่งต่างๆ ในเชิงระบบ หรือที่เรียกว่า System Thinking ได้ การคิดเชิงระบบเป็นการมองถึงความเชื่อมโยงของสิ่งที่ต่างๆ ว่าองค์ประกอบของสิ่งต่างๆ มันทำงานสัมพันธ์กันยังไง แล้วสิ่งที่เราสนใจมันเป็นส่วนไหนของระบบที่ใหญ่ขึ้นไปอีก

      วิธีนึงที่ช่วยให้คิดในเชิงระบบได้ดีขึ้นคือการวาดรูป Diagram ที่เชื่อมโยงความสัมพันธ์ของแต่ละส่วนออกมาให้เห็นชัดๆ ครับ

      การมองเห็นความสัมพันธ์ มองทุกอย่างเป็นเชิงระบบ จะช่วยให้เรามีความเข้าใจที่ดีขึ้น พลิกแพลงเรื่องต่างๆ ได้มากขึ้น ซึ่งสิ่งเหล่านี้มันคือพื้นฐานสำคัญของการเขียนสูตร Excel เลยล่ะ เพราะฟังก์ชันใน Excel 1 ตัว มันต้องการ input หลายๆ ตัว เราก็ต้องเข้าใจว่า input แต่ละตัวต้องใส่อะไรเข้าไป และสิ่งที่เราใส่เข้าไปอาจเป็นฟังก์ชันอีกตัวนึงซ้อนลงไปอีกก็ได้ จนเกิดสิ่งที่เรียกว่า “สูตรซ้อนสูตร” เช่น INDEX+MATCH เป็นต้น

      จะมองไปแล้วก็คล้ายกับภาษาอังกฤษ ที่ประโยคอาจประกอบไปด้วยส่วนต่างๆ ทั้ง Subject + Verb + Object ซึ่งแต่ละส่วนอาจมีส่วนประกอบเป็นสิ่งต่างๆ เช่น N +(Adj) หรือ V+(Adv) หรือแม้แต่มีคำเชื่อมเช่นพวก And, then อะไระพวกนี้ซ้อนลงไปอีก

      หากคุณสามารถมองทะลุเห็นความสัมพันธ์ของสิ่งต่างๆ ได้แล้ว คุณก็เรียกได้ว่าบรรลุ รู้แจ้ง เหมือนกับที่ Neo เห็นภาพในเรื่อง Matrix เลยล่ะ

      ทำอย่างไรถึงจะเก่ง Excel? 203

      สอนความรู้ให้คนอื่นต่อให้ได้

      อันนี้เป็นเทคนิคที่ผมใช้บ่อยมากๆ เลย เพราะการที่เราจะต้องเอาความรู้ไปสอนคนอื่นต่อ มันเป็นการบังคับให้เราทำความเข้าใจความรู้นั้นๆ ได้ดีขึ้นมากกว่าการแค่นั่งอ่าน นั่งดู นั่งเรียนเฉยๆ ดั่งเช่นที่แสดงในรูป Learning Pyramid จะพบว่าการสอนคนอื่นต่อ (ล่างสุด จำได้ 90%) ทำให้เราจดจำได้ดีกว่าการฟังเฉยๆ (บนสุด 5%) มากๆ

      ทำอย่างไรถึงจะเก่ง Excel? 204
      https://www.developgoodhabits.com/learning-pyramid/

      ในสมัยก่อน นอกจากผมจะสอนเพื่อนๆ น้องๆ ที่ office แล้ว ผมยังทำเว็บ ทำเพจ Excel เพื่อให้ความ รู้กับคนอื่นด้วย ซึ่งเป็นอีกช่องทางนึงที่ทำให้ผมได้เจอเคสปัญหาแปลกๆ เยอะกว่าที่ทำงานปกติ

      แต่ถ้าคุณอยากเจอปัญหา Excel เยอะๆ ก็ไม่จำเป็นต้องมานั่งทำเพจให้เสียเวลาแล้ว คุณอาจใช้วิธีไปช่วยตอบปัญหาตาม Forum หรือกลุ่ม Line/Facebook ต่างๆ ซึ่งมีเยอะแยะมากๆ ก็จะเป็นวิธีที่ดีมากๆ เช่นกันครับ เรียกได้ว่าบางที “คำถามสำคัญกว่าคำตอบ” ด้วยซ้ำ

      พอเราเจอปัญหาเยอะๆ ที่หลากหลาย แล้วเอาชนะมันให้ได้ ก็เหมือนกับการเอาชนะ Monster ได้แล้ว Level Up เหมือนที่ผมเคยเขียนบทความเรื่อง 10 ข้อคิดจากเกมออนไลน์ ใช้พัฒนาความก้าวหน้าทักษะ Excel ไปแล้วนั่นแหละ

      เพื่อนๆ ล่ะ? มีเทคนิคอะไรบ้าง

      หลักการเหล่านี้คือวิธีที่ผมใช้ในการฝึกฝน Excel แล้วของเพื่อนๆ มีวิธีไหนบ้าง มาแชร์กันนะครับ

    • AGGREGATE, SUBTOTAL, SUM แตกต่างกันอย่างไร?

      AGGREGATE, SUBTOTAL, SUM แตกต่างกันอย่างไร?

      บทความนี้ขอแบบสั้นๆ ได้ใจความนะครับ เป็นการสรุปความแตกต่างของฟังก์ชันที่เอาไว้สรุปข้อมูลอย่าง AGGREGATE, SUBTOTAL, SUM เอาเป็นว่าเรามาเริ่มกันเลยดีกว่า

      สรุปความแตกต่างของ AGGREGATE, SUBTOTAL, SUM

      TopicSUMSUBTOTALAGGREGATE
      คำนวณเฉพาะตัวเลขYYY
      เลือกวิธีการสรุปข้อมูลได้X (ต้องเปลี่ยนฟังก์ชันไปเลย)Y (เลือกได้)Y (เลือกได้)
      คำนวณเฉพาะที่ Filter เห็นXYY (เลือกได้)
      คำนวณเฉพาะที่ มองเห็น (ไม่ Filter ทิ้ง, ไม่ Hide แถว)XY
      (เลือกได้ ถ้าใช้ฟังก์ชันเลข 10x

      จะไม่คำนวณ Hidden Rows)
      Y (เลือกได้)
      สามารถ Ignore ข้อมูลที่มี Error ได้XXY (เลือกได้)

      AGGREGATE เจ๋งสุดอย่างเห็นได้ชัด

      จะเห็นว่า AGGREGATE เจ๋งสุดอย่างเห็นได้ชัด ดังนั้นถ้ามีให้ใช้ก็ใช้แทน SUBTOTAL ไปได้เลยนะครับ

      Function_num ของ AGGREGATE

      AGGREGATE มีฟังก์ชันให้เลือกใช้มากมาย ถ้าเลือกตัวไหนมันก็จะคำนวณสรุปตามวิธีของฟังก์ชันนั้นๆ

      1. AVERAGE
      2. COUNT
      3. COUNTA
      4. MAX
      5. MIN
      6. PRODUCT
      7. STDEV.S
      8. STDEV.P
      9. SUM
      10. VAR.S
      11. VAR.P
      12. MEDIAN
      13. MODE.SNGL
      14. LARGE
      15. SMALL
      16. PERCENTILE.INC
      17. QUARTILE.INC
      18. PERCENTILE.EXC
      19. QUARTILE.EXC

      Tips : โดยที่ function_num หมายเลข 14-19 จะสามารถรองรับสูตรแบบ Array Formula ได้ (ซึ่งใช้ function_num Large, Small แทน function_num Max, Min ได้) และใช้ SUMPRODUCT แทน function_num SUM, COUNT, COUNTA ได้

      Options ของ AGGREGATE

      สิ่งที่โดดเด่นสุดของ AGGREGATE ก็คือ options ที่สามารถ เลือกได้ว่าจะ Ignore ไม่คำนวณอะไรบ้าง เช่น ignore ผลลัพธ์ที่เกิดจาก SUBTOTAL, AGGREGATE ที่ซ้อนอยู่อีกที, ignore hidden rows (แถวที่ซ่อนอยู่) , error

      ถ้าจะ ignore มันทุกอย่างเลย ก็เลือก option ที่เป็นเลข 3 ครับ

      AGGREGATE, SUBTOTAL, SUM แตกต่างกันอย่างไร? 205

      ตัวอย่าง

      AGGREGATE, SUBTOTAL, SUM คำนวณเฉพาะตัวเลข ไม่สนใจ text

      AGGREGATE, SUBTOTAL, SUM แตกต่างกันอย่างไร? 206

      คำนวณเฉพาะที่ Filter เห็น

      AGGREGATE, SUBTOTAL, SUM แตกต่างกันอย่างไร? 207

      AGGREGATE คำนวณเฉพาะที่ มองเห็น (ไม่คำนวณ Hidden Row) ส่วน SUBTOTAL ถ้าเป็นฟังก์ชันเลข 9 จะยังคำนวณ Hidden Rows แต่ถ้าใช้ฟังก์ชันเลข 109 จะไม่คำนวณ

      AGGREGATE, SUBTOTAL, SUM แตกต่างกันอย่างไร? 208

      AGGREGATE สามารถ Ignore ข้อมูลที่มี Error ได้

      aggregate subtotal sum
    • สอนใช้ INDEX + MATCH แบบสั้นๆ เท่าที่จำเป็น (แถม XLOOKUP)

      สอนใช้ INDEX + MATCH แบบสั้นๆ เท่าที่จำเป็น (แถม XLOOKUP)

      ถ้าถามว่าฟังก์ชันในการ Lookup ข้อมูลอันไหนที่ฮิตที่สุด คำตอบก็คงไม่พ้น VLOOKUP แต่ถ้าถามว่าอะไรยืดหยุ่นที่สุดและใช้ได้กับ Excel ทุก Version คำตอบก็คือ INDEX+MATCH นั่นเอง (แต่ถ้าคุณมี Excel 365 ที่มีพวก XLOOKUP กับ XMATCH มันก็จะเจ๋งกว่าอ่ะนะ 555)

      ในบทความนี้ผมจะมาสอนการใช้งานเจ้า INDEX กับ MATCH แบบสั้นๆ ไม่ได้เจาะลึกอะไรมากมาย (ถ้าจะลงลึกเรื่อง INDEX อ่านได้ที่นี่) แต่สามารถเอาไปใช้ได้เลยละกันนะครับ เน้นเอาใจคนมีเวลาน้อย อิอิ

      ทำไม VLOOKUP อย่างเดียวจึงไม่เพียงพอ?

      ผมว่ามันเป็นเพราะ 2 สาเหตุใหญ่ๆ เลย คือ

      1. VLOOKUP ค้นหาแล้ววิ่งไปทางซ้ายไม่ได้
      2. VLOOKUP จะเสี่ยงต่อการสูตรพังเมื่อมีการแทรกคอลัมน์ในตารางอ้างอิง (เพราะระบุ Col_index_num เป็นตัวเลขค่าคงที่ในสูตร)

      ด้วย 2 สาเหตุนี้ คงจะเพียงพอที่จะให้คุณลองอยากจะเรียนรู้ INDEX+MATCH ขึ้นมาบ้างแล้วล่ะ ซึ่งข่าวดีคือ ผมว่ามันใช้ง่ายมากๆ

      หน้าที่ของ INDEX และ MATCH

      • INDEX สามารถ “ดึงข้อมูลในพื้นที่ที่กำหนด โดยเราต้องระบุพิกัดตำแหน่ง” ให้มัน
      • MATCH สามารถ “ค้นหาตำแหน่งของข้อมูล” ใน Range ที่กำหนดได้ (Range มีได้แค่ 1 แถว หรือ 1 คอลัมน์ ห้ามเป็นตาราง)
        ผลลัพธ์จะออกมาเป็นตัวเลขตำแหน่ง (ที่เดี๋ยวเราจะส่งไปให้ INDEX ใช้ต่อ)

      จะเห็นว่า INDEX ดึงข้อมูลได้ แต่ค้นหาข้อมูลเองไม่ได้ ส่วน MATCH ค้นหาข้อมูลได้ ดึงข้อมูลไม่ได้ มันจึงเกิดมาคู่กันนั่นเอง

      สอนใช้ INDEX + MATCH แบบสั้นๆ เท่าที่จำเป็น (แถม XLOOKUP) 209

      วิธีการใช้งาน INDEX + MATCH

      version วีดีโอ

      version บทความ

      สอนใช้ INDEX + MATCH แบบสั้นๆ เท่าที่จำเป็น (แถม XLOOKUP) 210

      สถานการณ์คือ จะหาว่า sales ค ชื่อว่าอะไร แต่ชื่อดันอยู่คอลัมน์ซ้ายมือ เลยใช้ VLOOKUP ไม่ได้

      วิธีแก้ปัญหาคือ เราต้องใช้ MATCH หาให้ได้ก่อนว่า sales ค อยู่ลำดับที่เท่าไหร่ แล้วเราค่อยใช้ INDEX ดึงชื่อลำดับนั้นๆ ออกมา

      การใช้ MATCH มีการใช้งานดังนี้

      =MATCH(lookup_value,lookup_array,match_type)
      โดยที่ match_type แบบ Exact Match คือให้ระบุเป็นเลข 0

      ดังนั้นลำดับตำแหน่งของ sales ค หาได้ดังนี้

      =MATCH(A8,B2:B5,0)
      =3

      จากนั้น ค่อยใช้ INDEX ดึงค่าใน range ที่ระบุ ในตำแหน่งที่ต้องการออกมา

      =INDEX(array,row_num,column_num)
      แต่เราใส่แค่นี้ได้ ถ้าเราเลือกพื้นที่ array แค่มิติเดียว (คอลัมน์เดียว หรือ แถวเดียว)
      =INDEX(array,ลำดับตำแหน่งของตัวที่ต้องการ)
      =INDEX(array,ลำดับตำแหน่งจาก MATCH)

      ดังนั้นชื่อที่เราต้องการ สามารถใช้สูตรได้ดังนี้

      =INDEX(A2:A5,ตำแหน่งที่หาได้จาก MATCH)

      พอผสมกันก็จะเป็นดังนี้

      =INDEX(A2:A5,MATCH(A8,B2:B5,0))

      หรือเขียนในรูปแบบทั่วๆ ไปก็คือ

      =INDEX(return_array,MATCH(lookup_value,lookup_array,0))
      =INDEX(คอลัมน์ผลลัพธ์ที่ต้องการ,MATCH(lookup_value,คอลัมน์ที่เอา lookup_value ไปค้นหา,,0))

      สรุปแล้วผมสามารถเชียนได้ดังนี้

      index match excel

      แค่นี้เพื่อนๆ ก็ใช้ INDEX+MATCH หาข้อมูลที่ต้องการได้แล้วล่ะครับ ซึ่งไม่ต้องกลัวเรื่องวิ่งไปซ้ายไปขวา หรือไม่ต้องกลัวการแทรกคอลัมน์ในตารางอ้างอิงอีกต่อไป เย้ๆ

      แถมเรื่อง XLOOKUP

      ถ้าเรามี XLOOKUP ก็จะเขียนสูตรได้ประมาณนี้ คือเลือก lookup_array,return_array ได้เลย ดังนั้นใครมี XLOOKUP ก็จะง่ายกว่าแหละ แต่ถ้าไม่มีก็ต้องใช้ INDEX+MATCH ไปนะครับ ^^

      =XLOOKUP(lookup_value,lookup_array,return_array,[if_not_found],[match_mode],[search_mode])
      =XLOOKUP(lookup_value,lookup_array,return_array)
      =XLOOKUP(lookup_value,คอลัมน์ที่เอา lookup_value ไปค้นหา,คอลัมน์ผลลัพธ์ที่ต้องการ)
      =XLOOKUP(A8,B2:B5,A2:A5)
      สอนใช้ INDEX + MATCH แบบสั้นๆ เท่าที่จำเป็น (แถม XLOOKUP) 211
    • สอนใช้ฟังก์ชัน IF และผองเพื่อน (IFS, SWITCH)

      สอนใช้ฟังก์ชัน IF และผองเพื่อน (IFS, SWITCH)

      หนึ่งในฟังก์ชันที่ถูกใช้บ่อยที่สุดอันนึงในการเขียนสูตร Excel ก็คือฟังก์ชันที่ชื่อว่า IF ซึ่งมีความสามารถในการเขียนสูตรแบบมีเงื่อนไข ซึ่งเวลาผมสอนมักจะบอกเสมอว่า หากในหัวเรานึกถึงคำว่า “ถ้า” ก็ให้นึกถึง IF ได้เลย ซึ่งนอดีตผมเคยเขียนบทความเกี่ยวกับ IF ไว้แล้ว แต่วันนี้จะมา Refresh ให้ใหม่ พร้อมแนะนำเพื่อนๆ ของมันคือ IFS และ SWITCH ด้วย

      เอาจริงๆ ผมว่าฟังก์ชันนี้เป็นฟังก์ชันที่เข้าใจง่ายมากนะ มันมีความสามารถในการแสดงผลลัพธ์ 2 อย่าง นั่นคือ เราสามารถใช้สูตรแบบนึงถ้าเงื่อนไขเป็นจริง และเราใช้สูตรอีกแบบนึงถ้าเงื่อนไขเป็นเท็จได้

      เช่น สมมติเราจะให้ขนมเป็นของรางวัลเด็ก โดยมีเงื่อนไขว่า จะให้จำนวนขนมตามอายุของเด็ก แต่ถ้าอายุเกิน 10 ปี จะได้ครึ่งนึงของอายุ (เศษปัดทิ้ง) เช่น อายุ 8 ขวบได้ขนม 8 ชิ้น แต่ถ้า 13 ขวบ จะได้ 6 ชิ้น เป็นต้น

      เริ่มจากการคิด Logic ของ Decision Tree

      ปัญหาของการใช้ IF สำหรับคนที่เพิ่งหัดใช้ก็คือ มักจะคิดไม่ออกว่าผลลัพธ์มันมีกรณีไหนบ้าง (ส่วนใหญ่มักจะคิดแค่ฝั่งเดียวว่าถ้าเงื่อนไขจริงแล้วจะทำอะไร แต่ไม่ได้คิดว่าถ้าเงื่อนไขไม่จริงจะทำอะไร) และบางทีก็ไม่ชัดเจนว่าเงื่อนไขที่เป็นตัวแบ่งแต่ละกรณีมันคืออะไรกันแน่ (ทั้งๆ ที่หลายๆ คนตอบปากเปล่าได้แท้ๆ)

      if

      ถ้ามีปัญหาเหล่านี้ สิ่งที่ผมอยากบอกคือ อย่าเพิ่งเขียนสูตร แต่ให้ลองเขียนแผนผังการตัดสินใจแบบ Decision Tree ขึ้นมาก่อน (ถ้าเรายังไม่ค่อยคล่อง) เพื่อให้เราสามารถเข้าใจภาพรวมทั้งหมด และคิดเป็นระบบมากขึ้น โดยตกผลึกความคิดได้อย่างชัดเจนก่อนว่าวิธีคิดคำตอบมันมีกี่กรณี ตัวแบ่งคืออะไร?

      จะเห็นว่าผลลัพธ์ของโจทย์นี้มีอยู่ 2 กรณี คือ

      1. กรณีอายุเกิน 10 ปี : ได้ครึ่งนึงของอายุ (เศษปัดทิ้ง) ซึ่ง สูตรผลลัพธ์คือ INT(เลขอายุ/2)
      2. กรณีอายุไม่เกิน 10 ปี : ได้ตามอายุ ซึ่ง สูตรผลลัพธ์คือ เลขอายุ

      พอเห็นแบบนี้ดังนั้นเงื่อนไขที่เราต้องเช็คก็คือ “อายุเกิน 10 ปีหรือไม่?” นั่นเอง

      ดังนั้นสามารถเขียนสูตรได้แบบนี้

      การเขียนสูตร IF

      สูตร IF 1 ตัว จะแยกผลลัพธ์ได้เป็น 2 แบบ ดังนี้

      =IF(logical_test,value_if_true,value_if_false)
      =IF(เงื่อนไข,ถ้าเงื่อนไขจริงจะทำอะไร,ถ้าเงื่อนไขเป็นเท็จจะทำอะไร)
      
      Tips : ตรงส่วน logical_test นั้นโดยทั่วไปเราจะใส่สูตรเพื่อให้ออกมาเป็นค่า TRUE/FALSE แต่มันยังสามารถรับค่าที่เป็นตัวเลขได้ด้วย (ถ้าเป็นเลข 0 จะเป็น FALSE ส่วนเลขอื่นๆ จะเป็นจริงทั้งหมด)

      ดังนั้นในเคสนี้ สูตรจึงออกมาเป็นแบบนี้

      =IF(อายุ > 10,INT(อายุ/2),อายุ)
      สอนใช้ฟังก์ชัน IF และผองเพื่อน (IFS, SWITCH) 212

      ถ้าปัญหาของคุณคือ คิดและเข้าใจเงื่อนไขทั้งหมด แต่ไม่รู้ว่าจะต้องเขียนสูตรใน input แต่ละตัวของ IF ยังไง ผมจะบอกว่าอย่างนี้ไม่ใช่ปัญหาของการใช้ฟังก์ชัน IF ไม่เป็นแล้วครับ แต่มันเป็นปัญหาของพื้นฐานการเขียนสูตรในเรื่องอื่นๆ ซะมากกว่า เช่น

      ส่วน logical_test

      การจะเขียนสูตรในส่วนของ logical_test ได้ จะต้องเข้าใจเรื่องดังนี้มาก่อน

      • การจะได้ค่า TRUE/FALSE เกิดได้จาก 2 กรณีหลักๆ คือ
        • การใช้เครื่องหมายเปรียบเทียบ เช่น =, >, <, >=, <=, <> (ไม่เท่ากับ) เช่น ในเคสนี้มีการเทียบว่า อายุ >10 หรือไม่?
        • การฟังก์ชันพวกกลุ่ม IS… เช่น ISNUMBER, ISERROR
      • ฟังก์ชันตรรกศาสตร์เพื่อรวบเงื่อนไขหลายๆ อันเข้าด้วยกัน
        • AND เงื่อนไขย่อยๆ ทุกอันต้องเป็นจริงทั้งหมด จึงจะให้ผลลัพธ์เป็นจริง เขียนในรูปแบบ AND(เงื่อนไข1,เงื่อนไข2)
        • OR เงื่อนไขย่อยๆ อย่างน้อยอันใดอันหนึ่งเป็นจริง จึงจะให้ผลลัพธ์เป็นจริง เขียนในรูปแบบ OR(เงื่อนไข1,เงื่อนไข2)
        • NOT กลับจริงเป็นเท็จ เท็จเป็นจริง เขียนในรูปแบบ NOT(เงื่อนไข)

      Tips : ตรงส่วน logical_test นั้นโดยทั่วไปเราจะใส่สูตรเพื่อให้ออกมาเป็นค่า TRUE/FALSE แต่มันยังสามารถรับค่าที่เป็นตัวเลขได้ด้วย (ถ้าเป็นเลข 0 จะเป็น FALSE ส่วนเลขอื่นๆ จะเป็นจริงทั้งหมด) ดังนั้นมันจึงเหมาะกับการใช้ Boolean Logic แทนการใช้ AND, OR ใน Array Formula มากๆ ซึ่งถ้าใครสนใจลองอ่านได้ที่นี่

      ส่วนของ value_if_true, value_if_false

      ถ้าถามว่าสูตรในส่วนนี้เขียนยังไง ผมจะบอกว่าอันนี้เป็นเรื่องอื่นที่ไม่เกี่ยวกับ IF โดยสิ้นเชิงเลย ถ้าคุณไม่มีความรู้เรื่องการเขียนสูตรอื่นๆ ก็จะทำ Part นี้ไม่ได้ครับ ดังนั้นให้ไปฝึกฝนเรื่องอื่นๆ ด้วย เช่น ในตัวอย่างนี้มีการใช้ INT หรือจะใช้ ROUNDDOWN ก็ได้ แต่ถ้าไม่รู้จักเลยก็จะทำโจทย์นี้ไม่ได้นั่นเอง ซึ่งจะเห็นว่าไม่ได้เกี่ยวกับ IF เลยนะครับ

      แล้วถ้าผลลัพธ์มีมากกว่า 2 กรณีล่ะ?

      อย่างที่ผมบอกไปก่อนหน้านี้ว่า IF สามารถแสดงผลลัพธ์ได้ 2 กรณี หลายคนอาจะสงสัยว่า แล้วถ้าผลลัพธ์มีมากกว่า 2 กรณีล่ะ? จะทำไง?

      ผมจะขอแนะนำแบบนี้ครับ

      ถ้าผลลัพธ์ของแต่ละกรณี สามารถใช้การ Lookup ได้ ให้ Lookup

      พูดง่ายๆ มันถ้าสิ่งที่เราต้องการ สามารถใช้การสร้างตารางอ้างอิงแล้วดึงค่ากลับมาได้ เช่น การดึงชื่อพนักงานจากรหัสพนักงาน ประเภทสินค้าจากรหัสสินค้า หรือแม้แต่การตัดเกรดจากคะแนนที่ได้ พวกนี้ควรใช้สูตรพวก Lookup/Reference เช่น VLOOKUP, INDEX+MATCH, XLOOKUP แทนการใช้ IF ครับ เพราะจะเขียนสูตรง่ายกว่า แถมยืดหยุ่นและแก้เงื่อนไขได้ง่ายกว่าการใช้ IF เยอะเลย

      สอนใช้ฟังก์ชัน IF และผองเพื่อน (IFS, SWITCH) 213

      ถ้าผลลัพธ์ของแต่ละกรณี Lookup ไม่ได้

      สอนใช้ฟังก์ชัน IF และผองเพื่อน (IFS, SWITCH) 214

      เช่น จากข้อมูลข้างต้น เรามีเงื่อนไขการลดราคาว่า

      • ถ้าซื้อเกิน 3 ชิ้น ลด 10%
      • ถ้าซื้อตั้งแต่ 5 ชิ้นขึ้นไป และชำระเงินเป็นเงินสด ถึงจะลด 15%

      แบบนี้เราจะใช้พวกสูตรกลุ่ม Lookup ไม่ได้แล้วครับ แต่จะต้องใช้ IF ซ้อนกัน/IFS/SWITCH มาช่วยแทน

      และเราก็ควรคิดให้ดีก่อนว่า ควรพิจารณาเงื่อนไขไหนก่อนดี ซึ่งถ้าไล่ให้ครบจริงๆ ต้องเขียนให้มีผลลัพธ์ 3 แบบดังนี้

      • ถ้าซื้อตั้งแต่ 5 ชิ้นขึ้นไป และชำระเงินเป็นเงินสด ถึงจะลด 15%
        (เราต้องคิดอันนี้ก่อนเรื่องซื้อเกิน 3 ชิ้น ไม่งั้นจะไม่มีทางมาตกเงื่อนไขตัวนี้เลย)
      • ถ้าซื้อเกิน 3 ชิ้น ลด 10%
      • นอกนั้น ลด 0%

      IF ซ้อนกัน

      โดยที่ผมจะขอเริ่มจากตัวที่เป็นพื้นฐานที่ใช้ได้ทุก version นั่นก็คือ IF ซ้อนกัน ซึ่งวิธีทำก็คือใส่ IF ลงไปอีกชุดนึงเลยในส่วนที่เป็น value_if_true หรือ value_if_false ก็ได้ (หรือทั้งคู่ก็ได้)

      สอนใช้ฟังก์ชัน IF และผองเพื่อน (IFS, SWITCH) 215

      ซึ่งถ้าเขียนเป็นโครงสร้างสูตร จะเป็นดังนี้

      =IF(logical_test1,value_if_true1,IF(logical_test2,value_if_true2,value_if_false2))

      ถ้าใช้กับโจทย์ที่ให้ไปก็จะเป็นแบบนี้

      =IF(AND([@จำนวนชิ้น]>=5,[@วิธีการชำระเงิน]="เงินสด"),0.15,IF([@จำนวนชิ้น]>3,0.1,0))

      ซึ่งสูตรข้างบน สามารถใช้ IFS แทนได้ ก็จะไม่ต้องใช้หลายฟังก์ชันซ้อนกัน

      IFS

      สามารถใช้ฟังก์ชัน IFS ตัวเดียว แล้วเขียนเงื่อนไขคู่ไปกับ value_if_true ไปได้เรื่อยๆ ทีละคู่ได้เลย

      ifs
      =IFS(logical_test1,value_if_true1,logical_test2,value_if_true2,...)

      ซึ่งถ้าอยากจะแสดงค่ากรณีที่ไม่ตรงกับเงื่อนไขใดๆ เลย สามารถใช้ TRUE มาช่วยได้ตอนจบดังนี้

      ifs
      =IFS(logical_test1,value_if_true1,logical_test2,value_if_true2,TRUE(),value_else)

      ถ้าใช้กับโจทย์ข้างบนจะเป็นแบบนี้

      =IFS(AND([@จำนวนชิ้น]>=5,[@วิธีการชำระเงิน]="เงินสด"),0.15,[@จำนวนชิ้น]>3,0.1,TRUE,0)

      ลองดูตัวอย่างอื่นๆ ได้จากคลิปนี้

      SWITCH

      ถ้าเราไม่มี IFS ให้ใช้ แต่มี SWITCH ก็สามารถใช้ได้เหมือนกัน (เช่นใน DAX จะ ไม่มี IFS แต่มี SWITCH)

      ตามปกติแล้ว SWITCH คือจะคล้ายๆ กับ CHOOSE คือเลือกว่า ถ้าค่าที่เราสนใจเป็นแบบนี้ๆ จะทำอะไร แต่ SWITCH ดีกว่า CHOOSE ตรงที่ว่าค่าที่สนใจสามารถเป็นอะไรก็ได้ ในขณะที่ CHOOSE ค่าที่สนใจต้องเป็นตัวเลข 1,2,3,4,… ไปเรื่อยๆ เท่านั้น

      switch
      =SWITCH(expression,value1,result1,value2,result2,...,default)

      แต่ถ้าเรานำ SWITCH มาพลิกแพลงโดยใส่ TRUE ลงไปใน expression หรือค่าที่จะเช็ค มันจะทำตัวแบบ IFS ได้เลย เพราะเมื่อไหร่ที่ value เป็นจริง มันจะแสดง result ของ value นั้นทันที ดังนี้

      switch
      =SWITCH(TRUE(),logical_test1,value_if_true1,logical_test2,value_if_true2,value_else)

      ถ้าใช้กับโจทย์ข้างบนจะเป็นแบบนี้

      =SWITCH(TRUE,AND([@จำนวนชิ้น]>=5,[@วิธีการชำระเงิน]="เงินสด"),0.15,[@จำนวนชิ้น]>3,0.1,0)

      จบแล้ว

      เช่นเคย ใครอ่านแล้วสงสัยอะไรตรงไหนก็ถามได้เลยนะครับ หากชอบก็ฝากแชร์ให้เพื่อนๆ ด้วยนะ ^^

    • แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI

      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI

      การที่เราจะคำนวณเรื่องต่างๆ ใน Power BI ให้ได้ดั่งใจนั้น หลายๆ ครั้งเรามักต้องการคำนวณโดยสนใจเฉพาะเงื่อนไขบางอย่าง ซึ่งเราจะต้องเข้าใจ Concept ของการ Filter ข้อมูลให้ได้อย่างลึกซึ้ง และในบทความนี้ผมจะสอนคุณให้เห็นวิธีการคำนวณที่หลากหลาย มาดูกันเลยว่ามีวิธีอะไรบ้างที่เราควรจะรู้จักเพื่อให้สามารถคำนวณค่าตามเงื่อนไขที่เราต้องการได้ ซึ่งหลายๆ เทคนิคในนี้เอาไปใช้กับ Power Pivot ของ Excel ได้เช่นกันครับ

      ไฟล์ตัวอย่าง

      ก่อนอื่น ให้โหลด Data ตัวอย่างได้จากไฟล์นี้ครับ

      เริ่มสร้าง Measure หลัก

      ในนั้นผมมีสร้าง Measure ไว้ตัวนึง เอาไว้ Sum จำนวน Sales Quantity ในตาราง fSales ดังนี้

      TotalQty = SUM(fSales[SalesQuantity])

      มาค่อยๆ ทำความเข้าใจกัน สมมติผมลาก TotalQty เข้า Visual ซักอันนึง มันจะได้ผลลัพธ์เป็น TotalQty รวมทั้งหมดในข้อมูล

      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 216

      ทีนี้เราจะเริ่มทำการ Filter (คัดกรอง) หรือ Slice (หั่น) ข้อมูลให้เหลือเฉพาะสิ่งที่เราต้องการ ซึ่งทำได้หลายวิธีมากๆ เลย

      Filter ผ่านการแบ่ง Row/Column/Category ใน Visual นั้นๆ

      ถ้าผมลาก Field ClassName จาก dProduct ลงมาใน Rows มันก็จะแบ่ง TotalQty ตาม ClassName นั้นๆ เช่น Filter ClassName เป็น Deluxe จะทำให้ TotalQty เหลือแค่ 329,043 ชิ้น ซึ่งนี่คือการ Filter ข้อมูลแบบนึง ซึ่งเป็นการ Filter ที่ทำผ่านการ Slice ข้อมูลตามมิติต่างๆ ผ่าน Relationship ที่มี

      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 217

      การ Filter นี้ทำงานได้แม้ตัว ClassName จะอยู่คนละตารางกัน เป็นเพราะมี Relationship ที่เชื่อมผ่าน ProductKey โดยมีทิศทางการ ไหลของ Filter ที่ยอมให้ Filter จาก dProduct มายัง fSales ได้นั่นเอง (ดูจากหัวลูกศร)

      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 218

      Filter ผ่าน Interaction

      นอกจากที่เราจะ Filter ข้อมูลผ่านการลากลงไปใน Row/Column/Category ในVisual แล้ว เราก็ยังสามารถ Filter ข้อมูลโดยคลิ๊กที่ Visual ตัวอื่น ซึ่งมันจะทำการ Filter ผ่าน Interaction ระหว่าง Visual ทั้งสองตัวได้ด้วย เช่น ผมคลิ๊กที่ Asia ที่กราฟโดนัท ส่งผลให้ตารางถูก Filter ไปด้วย

      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 219

      Filter ผ่าน Filter Pane

      เราสามารถใช้ Filter Pane เพื่อ Filter ข้อมูลเฉพาะ Visual ที่เลือก / Visual เฉพาะ Page นั้นๆ / Visual ทุก Page ได้

      เช่น ถ้าผมเอา BrandName ลากเข้า Filter on This Page แล้วเลือก Contoso ก็จะได้ดังนี้

      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 220

      จะเห็นว่าตอนนี้ ตัวตารางถูก Filter จากทั้ง Interaction ระหว่างกราฟ และ BrandName จาก Filter Pane เลย

      Filter ผ่านฟังก์ชัน CALCULATE แบบเปลี่ยนเงื่อนไข

      วิธี Filter ที่ผ่านมาทั้งหมด สามารถ Filter ได้ย่อยสุดแค่ระดับ Visual เท่านั้น ไม่สามารถ Filter เฉพาะระดับ Measure ที่ต้องการได้ ซึ่งหากเราอยากทำแบบนั้น จะต้องเขียนสูตรเท่านั้น ซึ่งหนึ่งในฟังก์ชันที่ทำได้ค่อนข้างสะดวกก็คือ CALCULATE นั่นเอง

      เช่น ผมอยากจะสร้าง Measure ที่คำนวณ TotalQty ของ ProductCategory Audio เท่านั้น ผมสามารถเขียน Measure ได้ดังนี้ (ณ ตอนนี้ผมเอา Filter จากที่อื่นออกหมดแล้ว)

      TotalQty Audio = CALCULATE([TotalQty],dProduct[ProductCategory]="Audio")
      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 221

      ผลลัพธ์คือ Power BI ทำการ Filter ProductCategory เป็น Audio เฉพาะ Measure นั้นๆ ทำใผ้ผลลัพธ์เหลือน้อยลง

      อย่างไรก็ตาม การที่เขียนเงื่อนไข Filter ใน CALCULATE เป็นเงื่อนไขเชิง Logic เช่น dProduct[ProductCategory]=”Audio” จริงๆ แล้วเป็นการใส่เงื่อนไขเช่นเดียวกับสูตรนี้เป๊ะๆ

      FILTER(ALL(dProduct[ProductCategory]),dProduct[ProductCategory]="Audio")
      // ให้ผลลัพธ์เป็นตารางที่มีคอลัมน์เดียวคือ ProductCategory และมีแถวเดียวคือ Audio
      // สามารถมองได้ว่าจริงๆ แล้วเงื่อนไขในการ Filter ของ CALCULATE นั้นคือ Table แบบนึง

      ดังนั้นหากเราเปลี่ยน Row เป็น ProductCategory จะเห็นผลลัพธ์แบบนี้ ซึ่งได้เลขเดียวกันหมดเท่ากับ Audio เลย (ตรง Category อื่นไม่ใช่ช่องว่าง เพราะไม่ได้เป็นการ Filter ซ้ำ แต่เป็นการเปลี่ยนเงื่อนไขการ Filter เป็นอันใหม่ต่างหาก)

      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 222

      การใช้ CALCULATE แล้วใส่สูตรคำนวณในเงื่อนไขการเปรียบเทียบ

      หากจะเขียนเงื่อนไขใน CALCULATE โดยอ้างอิงเปรียบเทียบค่ากับสิ่งที่ไม่ใช่ค่าคงที่ (เช่น สูตรหรือ Measure) เราจะเขียนสูตรตรงๆ ใน CALCULATE ไม่ได้ แต่จะต้องใช้การประกาศค่าใน VAR ให้หลายเป็นค่าคงที่ไปก่อน แล้วค่อยอ้างอิงค่าจาก VAR มาใช้ต่อใน CALCULATE อีกที เช่น

      ถ้าจะคำนวณยอด TotalQty แต่เอาเฉพาะจากร้านค้าที่มีขนาดมากกว่าค่าเฉลี่ย

      เราจะใส่สูตรแบบนี้ไม่ได้ เพราะมีการเปรียบเทียบกับค่าที่เป็นสูตร AVERAGE(dStores[SellingAreaSize])

      AboveAverageAreaSize = CALCULATE([TotalQty],dStores[SellingAreaSize]>AVERAGE(dStores[SellingAreaSize]))

      เราต้องเลี่ยงไปใช้ VAR แทน แบบนี้ จะไม่มีปัญหา เพราะเปลี่ยนการคำนวณ AVERAGE(dStores[SellingAreaSize]) ไว้ในค่าคงที่ชื่อ AvgArea แล้ว

      AboveAverageAreaSize = 
      VAR AvgArea=AVERAGE(dStores[SellingAreaSize])
      RETURN
      CALCULATE([TotalQty],dStores[SellingAreaSize]>AvgArea)
      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 223

      การปลด Filter ใน CALCULATE

      เราสามารปลดเงื่อนไขการ Filter ได้ด้วยการใช้ ALL หรือ ALLSELECTED ลงไปในเงื่อนไขของ CALCULATE ซึ่ง ALL จะปลดเงื่อนไขการ Filter ทั้งหมดไม่ว่าจะมาจาก Visual ไหนก็ตาม แต่ ALLSELECTED จะปลดแค่จาก Visual ตัวเองเท่านั้น

      AllQty = CALCULATE([TotalQty],ALL(dProduct[ProductSubcategory]))
      AllselectedQty = CALCULATE([TotalQty],ALLSELECTED(dProduct[ProductSubcategory]))
      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 224

      อย่างไรก็ตามเราต้องปลดเงื่อนไขให้ตรง Field ที่มีการ Filter ด้วย เช่น ใน Visual มีการ Filter ด้วย ProductSub ก็ต้องปลดด้วย ProductSub ให้ตรงกัน ดังนั้นถ้าเปลี่ยน Row ใน Visual เป็นอันอื่น เช่น ProductCat สูตรมันจะปลด Filter ไม่ออกเลย

      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 225

      หมายเหตุ : หาก Field ที่เราตั้งใจจะปลด Filter นั้นมีการ Sort by Column อื่นอีก เราก็ต้องปลด Column ที่ไปอ้างอิงการ Sort ด้วยนะ

      Calculate กับเงื่อนไข Filter บน Field Date

      จากที่ผมได้บอกไปก่อนหน้าว่าเวลาจะปลด Filter นั้นจะต้องปลดให้ตรงกับ Field ที่มีการ Filter อยู่ แต่มันมีกรณียกเว้นคือ หากเราไปอ้างอิงคอลัมน์ Date ของตารางวันที่ใน Data Model มันจะเป็นการปลด Filter ออกทั้งตารางวันที่เลย เช่น

      สมมติผมจะสร้าง Measure เพื่อคำนวณ Qty สะสมตั้งแต่มี Data มา ผมจะสามารถเปลี่ยนเงื่อนไข Filter ให้เลือกวันที่ <= วันสุดท้ายของ Filter Context นั้นๆ ได้เลย แม้ Field ที่ Visual จะเป็น YearMonth ก็ตาม

      AccumQty = 
      VAR LastVisibleDay=MAX(dDate[Date])
      RETURN
      CALCULATE([TotalQty],dDate[Date]<=LastVisibleDay)
      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 226

      อย่างไรก็ตามเวลาจะปลด Filter เฉยๆ ด้วย ALL จะใช้ปลดที่ Date เพื่อให้ปลดทั้งตารางไม่ได้ (มันจะเอาไม่ออก) ต้องใช้ FILTER มาช่วย ในการสร้างตารางให้เห็นวันที่ให้ครบดังนี้

      AllDateQty = CALCULATE([TotalQty],FILTER(ALL(dDate[Date]),TRUE()))
      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 227

      Filter ผ่านฟังก์ชัน CALCULATE แบบ Filter เพิ่ม ไม่ปลดเงื่อนไขเดิม

      ถ้าอยากจะคงเงื่อนไข Filter เดิมไว้ โดยไม่ปลด Filter ออกก่อน ก็สามารถทำได้ด้วยการใส่ KEEPFILTER เข้าไปในเงื่อนไขของ CALCULATE ดังนี้

      TotalQty Audio Keep = CALCULATE([TotalQty],KEEPFILTERS(dProduct[ProductCategory]="Audio"))
      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 228

      Filter แบบเปลี่ยนทิศทาง Relationship เป็น 2 ทิศทาง

      หากเราสร้าง Measure ขึ้นมาใหม่เพื่อคำนวณ UnitPrice สูงสุด แล้วเอาใส่ลงไปใน Visual ที่เอา Field มาจากตารางอื่น ผลจะออกมาเป็นเลขเดียวกันทั้งหมดดังนี้

      MaxUnitPrice = MAX(dProduct[UnitPrice])
      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 229

      สาเหตุเป็นเพราะ RegionCountryName ไม่สามารถไหลไป Filter คอลัมน์ UnitPrice ในตาราง dProduct ได้

      วิธีที่ช่วยได้คือ การแก้ทิศทางเส้น Relationship ให้เป็นแบบ Bi-Directional (2 ทิศทาง) ซึ่งผมแนะนำว่าไม่ควรไปแก้ที่ Data Model โดยตรงเพราะมีความเสี่ยงที่ทำให้เกิดความกำกวมของ Model ว่าจะ Filter ตารางจากทิศทางไหนดี

      วิธีที่ผมขอแนะนำคือ ให้เปลี่ยนทิศทาง FILTER ด้วย CALCULATE + CROSSFILTER โดยเลือก Direction เป็น Both ดังนี้

      MaxUnitPrice = CALCULATE(MAX(dProduct[UnitPrice]),
      CROSSFILTER(dProduct[ProductKey],fSales[ProductKey],Both))
      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 230

      Filter แบบเปลี่ยนเส้น Relationship

      ณ ตอนนี้ Data Model ของเรามีการเชื่อมความสัมพันธ์ระหว่างตารางวันที่ กับตารางหลักอยู่ 2 เส้น โดย

      • Active 1 เส้น คือ เชื่อม Date กับ OrderDate
      • ไม่ Active 1 เส้น คือ เชื่อม Date กับ DeliveryDate
      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 231

      แปลว่าเวลาเราลาก Field จากตาราง Date ลงมาใน Visual มันจะเป็นการ Filter ด้วย OrderDate (ตัวที่ Active) ดังนี้

      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 232

      เราสามารถทำให้การ Filter เปลี่ยนไปใช้ DeliveryDate ได้โดยการไปทำให้เส้น OrderDate ไม่ Active ก่อน แล้วสั่งให้ DeliveryDate Active ขึ้นมา แต่นั่นก็ไม่ใช่วิธีที่ผมแนะนำ

      วิธีที่ผมอยากแนะนำคือให้เปลี่ยนเส้น Relationship โดยใช้ CALCULATE+USERELATIONSHIP ดังนี้

      TotalQty DeliveryDate = CALCULATE([TotalQty],USERELATIONSHIP(dDate[Date],fSales[DeliveryDate]))
      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 233

      Filter ด้วย Context Transition

      ตามปกติแล้ว หากเราสร้างคอลัมน์ใหม่ในตาราง dimension เช่น dProduct แล้วเขียนสูตรใน New Column เพื่อคำนวณค่าจากตาราง fact เช่น SUM(fSales[SalesQuantity]) มันจะออกมาได้ค่าเท่ากันหมด เพราะการเขียนสูตรในตารางนั้นมีแต่ Row Context ไม่มี Filter Context ซึ่งผลจะได้ดังนี้

      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 234

      แต่ถ้าเราใส่ CALCULATE ครอบลงไป หรือใช้การอ้างอิงด้วย Measure แทน (หากเขียนสูตรอ้างอิง Measure จะเสมือนว่ามี CALCULATE มาครอบโดยอัตโนมัติ) มันจะเกิด สิ่งที่เรียกว่า Context Transition ขึ้น คือจะเปลี่ยนเงื่อนไขในแต่ละแถว ให้กลายเป็น Filter จริงๆ ดังนี้

      ProductQty = CALCULATE(SUM(fSales[SalesQuantity]))
      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 235

      ซึ่งให้ผลเหมือนกับแบบนี้เป๊ะ

      ProductQty = [TotalQty]
      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 236

      Filter แบบเขียนสูตรเองไม่ง้อ Relationship

      แบบนี้จะซับซ้อนสุด เพราะเราจะเขียนสูตรเพื่อ Filter เอง

      สมมติผมอยากจะสร้าง Slicer ให้เลือกเดือนปีที่สิ้นสุด แล้วจะแสดงกราฟจำนวน Qty ย้อนหลัง 3 เดือนนับจากวันที่สิ้นสุดที่ผมเลือกไป ผมสามารถเอา YearMonth มาเป็น Slicer ตามนี้

      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 237

      จะเห็นว่าพอเลือกเดือนที่คิดว่าจะให้เป็นเดือนสิ้นสุดแล้ว มันดัน Filter Visual เราให้ Row เหลือแค่เดือนนั้นๆ ไปด้วย ซึ่งจะทำให้เราไม่สามารถแสดงข้อมูลของเดือนอื่นได้ ดังนั้นเราจะเปลี่ยนวิธีคือ สร้าง New Table ใหม่ให้มีแต่ค่า YearMonth แต่ไม่ต้องผูก Relationship ดังนี้

      New Table

      YM = ALL(dDate[YearMonth])

      Add Column 2 อัน คือ

      FirstDate = DATE(LEFT(YM[YearMonth],4),RIGHT(YM[YearMonth],2),1)
      LastDate = EOMONTH(YM[FirstDate],0)

      จะได้ผลลัพธ์ตารางใหม่แบบนี้ ซึ่งเราจะไม่เอาไปผูก Relationship ใดๆ ทั้งสิ้น

      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 238

      จากนั้นเราเปลี่ยนไปใช้ Slicer YearMonth จากตารางใหม่ จะพบว่าคราวนี้มันไม่มา Filter ตารางแล้ว (เพราะไม่มี Relationship กับ dDate)

      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 239

      คราวนี้เราจะสร้าง Measure ใหม่ เพื่อที่จะให้แสดงข้อมูลย้อนหลังแค่ 3 เดือนจากวันที่เลือก ดังนั้นเราจะเขียนสูตรแบบนี้

      TotalQtyPrev3M = 
      VAR LastDateSelected=SELECTEDVALUE(YM[LastDate]) //เอาค่าวันที่สุดท้ายจาก Slicer ที่เลือก
      VAR FirstVisibleDate=EDATE(LastDateSelected,-3)+1 // ย้อนกลับไป 3 เดือน เพื่อหาจุดเริ่มต้นที่ต้องการ
      VAR CurrentVisible=MAX(dDate[Date]) // เอาค่าจาก Filter Context ปัจจุบันใน visual
      RETURN IF(AND(CurrentVisible<=LastDateSelected,CurrentVisible>=FirstVisibleDate),[TotalQty],BLANK()) //คัดเลือกช่วงที่ต้องการ
      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 240

      ปกติแล้ว Visual ใน Power BI จะไม่แสดงค่าใน Row mี่มีค่าเป็น Blank ดังนั้นถ้าเราใส่แค่ Measure TotalQtyPrev3M ก็จะได้ผลลัพธ์เหลือแค่ 3 เดือนจริงๆ ดังนี้เลย

      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 241

      Filter โดยอาศัย TREATAS เพื่อเลียนแบบ Date Lineage

      วิธีนี้เป็นวิธีที่ค่อนข้าง Advance นะครับ สมมติว่าผมอยากจะเขียน Measure เพื่อคำนวณยอดจำนวนสินค้าวันสุดท้ายของแต่ละร้านค้า หากเรารู้จัก TREATAS เราจะสามารถใช้มันสร้างตารางจำลองขึ้นมา Filter ข้อมูลตามเงื่อนไขที่ต้องการได้ แม้เราจะเขียนสูตรเพื่อสร้างคอลัมน์ใหม่ในตารางจำลองขึ้นมาก็ตาม

      ปกติถ้าเขียนสูตรสร้างคอลัมน์ขึ้นมาเฉยๆ (ที่ไม่ใช่การใช้ ALL, DISTINCT, VALUES) มันจะไม่มีเรื่องของ Relationship กับตารางอื่น ทำให้ Filter ไม่ได้ แต่ถ้าเราใช้ TREATAS เราจะเลือกได้ว่าจะให้ตารางที่เราสร้างขึ้นมา ทำตัวเหมือนกับคอลัมน์ไหนใน Data Model (ซึ่งมี Relationship)

      TotalQtyLastDayofStore = 
      //สร้างตารางจำลองที่มีรายชื่อร้านค้า และวันสุดท้ายที่มีการขายของ
      VAR MyTable=ADDCOLUMNS(DISTINCT(dStores[StoreKey]),
      "LastDateSales",CALCULATE(MAX(fSales[OrderDate])))
      // ใช้ TREATAS สั่งให้ MyTable (2คอลัมน์) มี Relationship เลียนแบบ dStores[StoreKey],dDate[Date]
      VAR LineageTable=TREATAS(MyTable,dStores[StoreKey],dDate[Date])
      RETURN CALCULATE([TotalQty],LineageTable)
      แนะนำสารพัดวิธี Filter ข้อมูลใน Power BI 242
    • เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ

      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ

      Power Query นั้นมาพร้อมกับเครื่องมือสำเร็จรูปที่ช่วยให้เราจัดการข้อมูลได้ง่ายขึ้นมาก แต่ก็ยังมีอีกหลายสถานการณ์ที่เครื่องมือสำเร็จรูปไม่ตอบโจทย์เรา 100% ซึ่งจะต้องมีการแก้สูตร M Code ให้ทำงานได้ตรงใจเรามากขึ้น (แต่อย่าเพิ่งตกใจ มันไม่ได้ยากขนาดนั้น) และในบทความนี้ผมจะแนะนำ Tips การแก้สูตรเล็กๆ น้อยๆ แต่ช่วยให้งานเราสำเร็จได้ดีขึ้นมหาศาลเลย

      เทคนิคการ Filter แบบไม่สนใจพิมพ์เล็กพิมพ์ใหญ่

      ปกติแล้วการ Filter ใน Power Query จะสนใจพิมพ์เล็กพิมพ์ใหญ่ด้วย (จริงๆ ก็กับทุกฟังก์ชันนั่นใน Power Query นั่นแหละ) ดังนั้นถ้าเราไม่ต้องการให้มันสนใจเรื่องนี้ก็มีทางแก้อยู่ 2 แนวทาง นั่นก็บังคับให้ทุกตัวเป็นตัวพิมพ์แบบเดียวกันก่อน (เช่นทำเป็น lowercase) แล้วค่อย filter ด้วยเงื่อนไขตัวพิมพ์เล็กใน step ถัดไป ซึ่งคงเป็นวิธีที่หลายคนรู้อยู่แล้ว(มั๊ง)

      ในส่วนนี้ผมจะนำเสนออีกวิธีนึง นั่นก็คือการแก้ให้แปลงพิมพ์เล็กเพิมพ์ใหญ่ในเงื่อนไขของการเปรียบเทียบของสูตรไปเลย เช่น

      Filter ปกติจะได้สูตรนี้

      = Table.SelectRows(Source, each ([Data] = "aa"))

      ถ้าเราต้องการ aa แบบไม่สนพิมพ์เล็กพิมพ์ใหญ่ เราสามารถสั่งให้ lowercase ในสูตรไปเลยก็ได้เป็นดังนี้

      = Table.SelectRows(Source, each (Text.Lower([Data]) = "aa"))
      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 243

      ซึ่งมีข้อดีกว่าเดิมคือเราไม่สูญเสียความพิมพ์เล็กพิมพ์ใหญ่ของข้อมูลนั้นๆ ไปนั่นเอง

      เทคนิคการ Remove Duplicates ไม่สนใจพิมพ์เล็กพิมพ์ใหญ่

      ปกติแล้ว Remove Duplicates ใน Power Query จะสนใจพิมพ์เล็กพิมพ์ใหญ่ด้วย เช่น แบบนี้

      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 244

      เราจะแก้ไขสูตร M Code เล็กน้อย จากแบบนี้

      = Table.Distinct(MyData, {"Name"})

      เป็นแบบนี้ นั่นคือเพิ่มเงื่อนไขใน equationCriteria ให้เป็น Comparer.OrdinalIgnoreCase มันจะไม่สนเรื่องพิมพ์เล็กพิมพ์ใหญ่ทันที

      = Table.Distinct(MyData, {"Name",Comparer.OrdinalIgnoreCase})
      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 245

      เทคนิคการ Split ข้อมูลโดยใช้ Delimiter หลายแบบ

      เทคนิคต่อไปเป็นการทำให้การ Split ของเราเจ๋งยิ่งขึ้น จากเดิมที่ Split ได้ด้วย Delimiter แค่ตัวเดียว คราวนี้เราจะสามารถ Split ด้วยทีละหลายๆ Delimiter ได้ด้วยการแก้ M Code เพียงเล็กน้อยเท่านั้น และใช้ได้กับการ Split เป็นหลายคอลัมน์หรือหลาย Row ก็ได้ เช่น

      ข้อมูลผมอยากจะแบ่งด้วย , ; | คำว่า “และ”

      ตอนแรกให้กด Split ตามปกติไปก่อน

      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 246

      แล้วจะได้สูตรประมาณนี้

      = Table.SplitColumn(Source, "ผู้เล่น", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), {"Team.1", "Team.2"})

      ถ้าสูตรมี {“Team.1”, “Team.2”} แปลว่ามันจะ Split ออกมาแค่ 2 คอลัมน์เท่านั้น ถ้าเราไม่ต้องการให้จำกัดแค่ 2 คอลัมน์ ก็ให้ลบ {“Team.1”, “Team.2”} (รวมถึง comma ข้างหน้า) ออกไปเลย เป็นแบบนี้ มันจะ Dynamic ตามจำนวนข้อมูลได้

      = Table.SplitColumn(Source, "ผู้เล่น", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv))

      จากนั้นลบ Changed Type ทิ้งไป เพราะเรายังทำไม่เสร็จ

      ทีนี้มาถึง Step สำคัญ คือ ให้แก้ฟังก์ชันจาก

      SplitTextByDelimiter(",", QuoteStyle.Csv)

      เป็นแบบนี้ โดยใส่ Delimiter เป็น List ของ Delimiter mี่ต้องการได้เลย

      SplitTextByAnyDelimiter({"delimiter1","delimiter2","delimiter3"}, QuoteStyle.Csv)

      เช่นใน Case นี้ใส่ได้ดังนี้

      SplitTextByAnyDelimiter({",",";","|","และ"}, QuoteStyle.Csv)

      สรุปแล้วสูตรเราจะกลายเป็นแบบนี้

      = Table.SplitColumn(Source, "ผู้เล่น", Splitter.SplitTextByAnyDelimiter({",",";","|","และ"}, QuoteStyle.Csv))

      และเราก็จะได้ผลลัพธ์ตามต้องการ

      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 247

      ซึ่งเราก็นำไปใช้กับกรณี Split into Rows ได้เช่นกัน

      จาก Code ที่มัน Gen มาให้แบบนี้ (ซึ่งซับซ้อน ช่างมันไปก่อน) เราจะสนใจแค่การแก้ตรง SplitTextByDelimiter เหมือนเดิม

      = Table.ExpandListColumn(Table.TransformColumns(Source, {{"ผู้เล่น", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), let itemType = (type nullable text) meta [Serialized.Text = true] in type {itemType}}}), "ผู้เล่น")

      สรุปแล้วให้ แก้ Code กลายเป็นแบบนี้

      = Table.ExpandListColumn(Table.TransformColumns(Source, {{"ผู้เล่น", Splitter.SplitTextByAnyDelimiter({",",";","|","และ"}, QuoteStyle.Csv), let itemType = (type nullable text) meta [Serialized.Text = true] in type {itemType}}}), "ผู้เล่น")
      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 248

      เทคนิค Group by แล้วรวมข้อความที่เป็น Text คั่นด้วย Delimiter

      สมมติเรามีข้อมูลดังนี้

      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 249

      เราจะ Group by ตามผู้ขาย แต่อยากได้รายชื่อสินค้าเอามารวมแล้วคั่นด้วยเครื่องหมาย / จะทำยังไง?

      เราสามารถใช้การ Group ที่เรียกว่า All Rows มาช่วยได้ เช่น

      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 250

      จากนั้นจะได้ผลลัพธ์แบบนี้

      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 251

      concept คือเหมือนเดิม ว่า _ คืออ้างอิงตารางทั้งตารางที่ผ่านการ Group มาแล้ว ดังนั้นผมสามารถแก้สูตรให้ย่อๆ เหลือแค่นี้ก็ได้ ซึ่งก็จะได้ผลลัพธ์เหมือนเดิมเลย

      = Table.Group(#"Changed Type", {"ผู้ขาย"}, {"all", each _})
      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 252

      จากนั้นผมจะอ้างอิงไปที่คอลัมน์สินค้า ซึ่งทำได้โดยการเขียนว่า _[ชื่อคอลัมน์] เช่น

      = Table.Group(#"Changed Type", {"ผู้ขาย"}, {"all", each _[สินค้า]})

      ผลลัพธ์จะกลายเป็น List

      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 253

      หากต้องการทำให้ได้ List แบบไม่ซ้ำกัน ก็ใช้ List.Distinct มาช่วย

      = Table.Group(#"Changed Type", {"ผู้ขาย"}, {"all", each List.Distinct(_[สินค้า])})
      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 254

      พอเป็นแบบนี้เราจะสามารถกด Expand Column แล้วเลือก Extract Values ได้เลย ซึ่งมันจะเรียกใช้ฟังก์ชัน Text.Combine เพื่อรวมข้อมูลให้

      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 255

      ผลลัพธ์จะกลายเป็นแบบนี้

      = Table.TransformColumns(#"Grouped Rows", {"all", each Text.Combine(List.Transform(_, Text.From), "/"), type text})
      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 256

      เทคนิคการ Group by แล้วนับค่าในคอลัมน์แบบไม่ซ้ำ

      จาก Data ในเทคนิคที่แล้ว หากเราจะสั่ง Group by ผู้ขาย และจะนับจำนวนลูกค้าแบบไม่ซ้ำกัน เราจะพบว่าไม่สามารถใช้ Count Distinct Rows ใน Group by เพื่อเลือกคอลัมน์ลูกค้าได้สาเหตุเป็นเพราะ Count Distinct Rows ใน Group by เอาไว้นับจำนวนบรรทัดแบบไม่ซ้ำ (โดยดูทั้งบรรทัดเท่านั้น)

      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 257

      แล้วถ้าเราจะนับแบบไม่ซ้ำ โดยนับเฉพาะคอลัมน์ลูกค้าจะทำยังไง?

      ทางแก้ก็ทำได้ 2 แนวทาง

      แนวทางอันแรกคือใช้ All Rows แล้วอ้างอิงไปที่คอลัมน์ที่ต้องการนับ เช่น ลูกค้า แล้วใช้ List.Distinct ครอบแบบตัวอย่างที่แล้วเพื่อให้ได้รายการแบบไม่ซ้ำ แต่ตอนจบให้ครอบด้วย List.Count เพื่อนับจำนวน เช่น

      = Table.Group(#"Changed Type", {"ผู้ขาย"}, {"all", each List.Count(List.Distinct(_[ลูกค้า]))})

      อีกแนวทางคือ เราจะเริ่มจากการใช้ Count Distinct Rows แบบผิดๆ ตาม UI ไปก่อน แล้วจะไปแก้สูตรอีกที ดังนั้น ok ไปเลย จะได้แบบนี้

      = Table.Group(#"Changed Type", {"ผู้ขาย"}, {{"Count", each Table.RowCount(Table.Distinct(_)), Int64.Type}})
      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 258

      ตรงนี้แปลว่าให้นับจำนวนแถว ของตารางที่ถูกทำให้ Distinct ซึ่ง _ คือตารางภายใต้ group ของผู้ขายทั้งตาราง (เหมือนกับตัวอย่างที่แล้ว)

      Table.RowCount(Table.Distinct(_)) 

      เราจะต้องแก้ให้มันมอง item ในคอลัมน์ลูกค้าของตารางนั้นแบบไม่ซ้ำ จึงต้องแก้สูตรเป็น List.Distinct แล้วอ้างอิงไปที่คอลัมน์ลูกค้า โดยใช้ _[ชื่อคอลัมน์] ดังนี้

      Table.RowCount(List.Distinct(_[ลูกค้า]))

      สรุปแล้วแก้สูตรเป็นดังนี้ก็จะใช้ได้แล้ว

      = Table.Group(#"Changed Type", {"ผู้ขาย"}, {{"Count", each Table.RowCount(List.Distinct(_[ลูกค้า])), Int64.Type}})
      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 259

      เทคนิคการ Trim แบบให้ทำให้ช่องว่างตรงกลางเหลือแค่ 1 เคาะ

      หลายคนอาจไม่ได้สังเกต ว่า Trim ใน Power Query นั้น จะตัดข้อมูลได้แค่ด้านหน้ากับด้านหลังเท่านั้น ไม่สามารถจะเอาข้อมูลช่องว่างตรงกลางออกไปได้ (ต่างจาก TRIM ใน Excel)

      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 260

      ดังนั้นถ้าอยากให้ใน Power Query มัน Trim ได้แบบเดียวกับใน Excel จะต้องมีการแก้ Code ดังนี้

      ให้ใส่ Custom Column แล้วใส่สูตรดังนี้

      Text.Combine(List.Select(Text.Split([Original]," "),each _<>"")

      หลักการคือ

      • Text.Split จะแยกข้อมูลออกจากกันด้วย Delimiter ที่กำหนด คือ ” “
      • List.Select ใช้เพื่อคัดเลือกเอาข้อมูลใน List ให้เหลือเฉพาะตัวที่ไม่ใช่ช่องว่าง (ตรง each _<>”” โดยที่ _ คือข้อมูลใน List แต่ละตัว)
      • Text.Combine ใช้เพื่อรวมข้อมูลใน List เข้าเป็นข้อความเดียวกัน คั่นด้วย Delimiter ที่กำหนด (แบบในตัวอย่างเรื่อง Group By)
      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 261

      เทคนิคการแก้ชื่อคอลัมน์แบบอ้างอิงตำแหน่งแทนชื่อ

      สมมติว่าเรามีข้อมูลอยู่ แล้วต้องการจะแก้ชื่อคอลัมน์ใน Power Query

      ปกติแล้วเราจะกด Double Click เพื่อแก้ชื่อไปเลย เช่น ผมแก้คอลัมน์แรก เป็น BillNumber

      = Table.RenameColumns(Source,{{"TXID", "BillNumber"}})
      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 262

      สูตรมันจะบันทุกว่าให้เปลี่ยนชื่อคอลัมน์จาก TXID เป็น BillNumber

      ซึ่งก็ดีนะ แต่จะมีปัญหาทันที ถ้าชื่อคอลัมน์ในต้นฉบับเปลี่ยนไปเป็นอันอื่นที่ไม่ใช่ TXID

      หากเรามั่นใจว่าจะเปลี่ยนชื่อคอลัมน์แรกเสมอ (ให้เป็น TXID) ก็สามารถใช้ฟังก์ชัน Table.ColumnNames มาช่วยได้ ซึ่งมันจะได้ชื่อคอลัมน์ทั้งหมดในตารางที่อ้างอิงออกมาเป็น List เช่น ถ้าอยากได้ชื่อคอลัมน์ของตาราง Source ก็ทำแบบนี้

      = Table.ColumnNames(Source)
      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 263

      ถ้าเราจะอ้างอิงไปที่ item แรกใน List สามารถอ้างอิงด้วยเลข index ในรูปแบบ ชื่อlist{index} โดย index เริ่มที่เลข 0

      แปลว่า item แรกคือ

      = Table.ColumnNames(Source){0}
      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 264

      ดังนั้นเอาไปแทนในสูตรเดิม = Table.RenameColumns(Source,{{“TXID”, “BillNumber”}}) จะได้แบบนี้ ซึ่งจะเปลี่ยนจากการ Hard Code คำว่า TXID ลงไปในสูตร ให้กลายเป็นไปหาชื่อคอลัมน์แรกสุดมาแทนนั่นเอง

      = Table.RenameColumns(Source,{{Table.ColumnNames(Source){0}, "BillNumber"}})
      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 265

      เทคนิครวมข้อมูลทุก Sheet ใน Excel (ข้อมูลไม่เป็น Table)

      การรวมข้อมูลใน Excel หลายๆ ตารางเข้าด้วยกัน หากว่าข้อมูลแต่ละตารางเป็น Table อยู่แล้วจะรวมได้ง่ายมาก ใน Navigation แค่อ้างอิงไปที่ตัวไฟล์ Excel แล้ว Filter ให้เหลือเฉพาะ Table ที่ต้องการแล้วกด Expand Table ออกมาก็จบเลย รายละเอียดลองดูในคลิปนี้

      แต่ถ้าข้อมูลแต่ละตารางไม่ใช่ Table มันจะรวมตรงๆ ไม่ได้ เพราะ Data แต่ละอันยังไม่ได้รับการ Promote หัวตาราง จึงยังค้างเป็นคำว่า Column1, Column2, Column3…

      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 266

      ซึ่งพอสั่ง Expand ออกมาแล้วเอาข้อมูลแต่ละตารางมา Append กัน จะทำให้มีปัญหาหัวตารางกลายเป็น Data ซ้ำไปซ้ำมา ซึ่งต้องมานั่ง Filter ทิ้งอีก (และถ้าแต่ละตารางเรียงคอลัมน์ไม่เหมือนกันก็จะมีปัญหาทันที)

      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 267

      วิธีแก้ง่ายๆ คือ ก่อนจะถึงขั้นตอน Expand ในขั้นตอนแรกสุดที่ใช้ฟังก์ชัน Excel.Workbook อ่านค่าในไฟล์ Excel ให้แก้ input ที่ชื่อว่า useHeaders จาก null เป็น true ซะ เช่น

      = Excel.Workbook(File.Contents("D:\ThepExcel\Fin\Pandora\B\PowerQuery V2\PQ Data Support\MonthlySales2020-sheets-Easy.xlsx"), null, true)

      เป็น

      = Excel.Workbook(File.Contents("D:\ThepExcel\Fin\Pandora\B\PowerQuery V2\PQ Data Support\MonthlySales2020-sheets-Easy.xlsx"), true, true)
      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 268

      เพียงเท่านี้ มันจะทำการ Promote Header แต่ละตารางก่อนแล้ว

      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 269

      ทำให้เวลา Expand ออกมาไม่มีปัญหาแม้ว่าจะเป็น Sheet ครับ

      เทคนิคแก้สูตร M Code ให้ Power Query ทำงานได้ดั่งใจ 270

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

      = Table.ExpandTableColumn(#"Removed Other Columns", "Data", List.Union(List.Transform(#"Removed Other Columns"[Data],each Table.ColumnNames(_))))

      จบแล้ว

      สำหรับเทคนิค Power Query ในบทความนี้ก็ขอจบเพียงเท่านี้ ใครอยากรู้เทคนิคในการทำอะไรอีกก็สามารถบอกได้เลยนะครับ

      ใครที่สนใจเรียนรู้เรื่อง Power Query ผมมีเรื่องนี้ด้วยครับ

      Excel Power Up 2021 : พลังแห่งข้อมูล สร้างได้ด้วย Power Query

    • Power BI Visual : สร้างกราฟ Waterfall ให้ได้ดั่งใจ

      Power BI Visual : สร้างกราฟ Waterfall ให้ได้ดั่งใจ

      ขอเปิดบทความ Series ใหม่นั่นก็คือการเจาะลึกปรับแต่งการทำงานของ Visual ต่างๆ ใน Power BI ให้สร้างผลลัพธ์ให้ได้ดั่งใจเรามากขึ้น ซึ่งขอประเดิมด้วยกราฟ Waterfall ก่อนเลยครับ

      กราฟ Waterfall เป็นกราฟที่เหมาะกับการเอาไว้แสดงองค์ประกอบว่าตัวเลขที่เราสนใจมันมีตัวเลขนั้นได้เพราะมีองค์ประกอบอะไรทำให้เกิดขึ้น (ทั้งทิศทางบวกและลบ) แต่มันอาจมีวิธีการใส่ข้อมูลที่เข้าใจยาก เราจึงต้องมาเจาะลึกกันให้เข้าใจมากขึ้นกันในบทความนี้

      Waterfall แบบไม่มี Breakdown

      ตัวอย่างแบบ Basic ที่สุด ก็คือ เอา TotalRevenue กับ MonthName ลงไปใน Visual นี้ มันก็จะแสดงให้เห็นว่า ยอดขายรวมทั้งหมด (กราฟ Total สีน้ำเงินด้านขวา) นั้นมาจาก เดือนอะไรเท่าไหร่ (ผมเอาปีไปเป็น Slicer/Filter แล้วเลือกปีเดียว)

      เพื่อให้อธิบายง่ายขึ้น ผมจะเลือกให้มันแสดง Data Label ออกมาด้วย

      Power BI Visual : สร้างกราฟ Waterfall ให้ได้ดั่งใจ 271

      Waterfall แบบมี Breakdown

      กราฟ Waterfall นั้นสามารถใส่ Field ลงไปใน Breakdown ได้ด้วย เช่น ผมใส่ StoreType ลงไปด้วย จะพบว่าการทำงานของมันจะเปลี่ยนไปโดยสิ้นเชิง

      Power BI Visual : สร้างกราฟ Waterfall ให้ได้ดั่งใจ 272

      ผลลัพธ์ของมันกลายเป็นการพยายามจะบอกว่า ยอดขายแต่ละเดือนนั้น ถ้าแบ่งตาม StoreType แล้ว มันมีการเปลี่ยนแปลงจากเดือนนึงเทียบกับอีกเดือนนึงยังไง (เอาแท่งขวาลบซ้าย สำหรับ breakdown แต่ละ item) โดยจะไม่มี Total ด้านขวาสุดอีกต่อไป

      เช่น มอง May (23.5 M) เทียบกับ June (22.7 M) จะพบว่า มันเกิดจาก

      • ยอด Online เพิ่มขึ้น 0.7M
      • ยอด Catalog ลดลง 0.1M
      • ยอด Reseller ลดลง 0.4M
      • ยอด Store ลดลง 1.1M

      กรณีที่การ Breakdown มันมีเยอะมาก เช่น ผมเปลี่ยนจาก StoreType เป็น BrandName จะพบว่ามันไม่ได้แสดง BrandName ทั้งหมดออกมา แต่จะมีการ Group เป็น Other ให้ด้วย ซึ่งเรากำหนดได้ว่าจะให้มันแสดง BreakDown สูงสุดกี่ตัว (ไม่รวม Others) ในหัวข้อ Max breakdowns ใน section แปรงทาสี ซึ่งปกติจะเป็น 5 ตัว (ไม่รวม Others)

      Power BI Visual : สร้างกราฟ Waterfall ให้ได้ดั่งใจ 273

      Waterfall Breakdown พลิกแพลง

      เนื้อหาข้างบนทั้งหมดนี้คือกราฟ Waterfall แบบพื้นฐาน ซึ่งหากเราอยากได้ Waterfall ที่แสดงผลลัพธ์แปลกกว่านี้ เช่น อยากให้เทียบว่า จาก Target ที่ตั้งไว้ เมื่อเทียบกับ Actual ที่ได้จริง ส่วนที่มันต่างกัน มันมาจากองค์ประกอบอะไร? ซึ่งมันทำตรงๆ ไม่ได้เพราะ Target กับ Actual เป็นคนละ Measure กันโดยสิ้นเชิง

      เราจะทำยังไงดี? มาดูกัน

      ก่อนอื่นเราจะต้องสร้าง Table ใหม่ขึ้นมาเพื่อตอบโจทย์นี้ โดยสร้าง Field ที่จะระบุ Label ที่เราต้องการ (เพราะใร Visual จะแสดงLabel ตาม item ที่มีอยู่จริง ก็เลยต้องสร้างขึ้นมาจริงๆ) โดยไม่ต้องผูก Relationship อะไรทั้งสิ้น เช่น

      Power BI Visual : สร้างกราฟ Waterfall ให้ได้ดั่งใจ 274

      จากนั้นเราก็สร้าง Measure ใหม่ขึ้นมา โดยเช็คค่า Field Sort ในตารางของเราด้วย SELECTEDVALUE แล้วห้แสดงค่าที่ต้องการดังนี้

      หลักกการคือเช็คว่าถ้าค่าใน Field WaterFallHelp[Sort] เป็น 1 ให้แสดง [TargetFinal] ถ้าเป็น 2 ให้เป็น [TotalRevenue]

      ซึ่งถ้ามั่นใจว่า Label มีแค่ 2 item ก็ใช้ IF ธรรมดาก็ได้

      WaterfallMeasure = 
      IF(SELECTEDVALUE(WaterFallHelp[Sort])=1,[TargetFinal],[TotalRevenue])

      ซึ่งถ้าใช้ SWITCH จะทำ Label หลายแท่งได้สะดวกกว่า

      WaterfallMeasureV2 = 
      SWITCH(SELECTEDVALUE(WaterFallHelp[Sort]),
      1,[TargetFinal],  //แท่งแรกแสดงค่า Target
      2,[TotalRevenue]  //แท่งหลังแสดงค่า Actual
      )

      แล้วเราก็เอา Label จากตารางไปเป็น Category แล้วเอา Measure ตัวใหม่ไปเป็น Value จะได้ดังนี้ ว่ามันแสดงค่าของทั้งคู่ถูกต้อง แต่ดันเอามารวมกันเป็น Total ซึ่งไม่มีความหมาย (กราฟ ณ ตอนนี้ยังไม่ใช่สิ่งที่เราต้องการ)

      Power BI Visual : สร้างกราฟ Waterfall ให้ได้ดั่งใจ 275

      คราวนี้เราจะทำการใส่ breakdown ลงไป เพื่อแสดงการเปลี่ยนแปลง จากจุด Begin (ในที่นี้คือ Target) ไป End (ในที่นี้คือค่า Actual) แล้ว Total ก็จะหายไปเอง

      สมมติผมอยากจะพยายามแจกแจงว่า การที่ค่า Target มันกลายมาเป็น Actual ได้นั้น เพราะ Brand ไหนทำผลงานได้เกินเป้าหรือขาดเป้าเท่าไหร่? เราก็สามารถลาก BrandNameลงมาที่ Breakdown ได้เลย ซึ่งเราก็สามารถปรับจำนวน Breakdown ให้แสดงเยอะๆ ได้เช่นเดิม เช่น ผมปรับเป็น 7

      เลขที่โผล่มาในแต่ละ Brand เกิดจากการเอา แท่งขวา-แท่งซ้าย นั่นคือ Actual-Target สำหรับแต่ละ Brand นั่นเอง

      Power BI Visual : สร้างกราฟ Waterfall ให้ได้ดั่งใจ 276

      ถ้าแท่งไหนเป็นบวก คือแท่งนั้นทำได้เกิน Target ถ้าเป็นลบก็คือทำไม่ถึง Target พอรวมๆ กันทุกตัว ก็จะสามารถแสดงได้ว่า ที่ค่า Actual ถึงหรือไม่ถึง Target นั้นเป็นเพราะ Brand ไหนเป็นหลักนั่นเอง ผมลองพิสูจน์ให้ดูโดยใช้ Measure ที่ชื่อว่า TargetDiff ขึ้นมาอีกตัวจะเห็นว่าเลขตรงกัน

      ด้วยเทคนิคนี้เราจะเอาไปใช้กับอะไรก็ได้ เช่น ถ้าเปลี่ยน Breakdown เป็นเรื่องอื่น เช่น ปี ก็จะรู้ว่าปีไหนทำถึงเป้าไม่ถึงเป้าเป็นต้น (แต่เรื่องที่เอามาลง breakdown ต้องสามารถแสดงค่าด้วย Measure แท่งซ้ายกับขวาได้อย่างถูกต้องทั้งคู่นะครับ)

      ก็จบแล้วสำหรับเทคนิคการปรับแต่งกราฟ Water Fall ยังไงก็ลองนำไปปรับใช้ดูนะครับ ใครทำแล้วติดอะไร หรือสงสัยตรงไหนก็ถามได้เลย

    • ค้นหาข้อความที่มีลักษณะตามต้องการ ด้วย Regular Expression (Regex)เบื้องต้น

      ค้นหาข้อความที่มีลักษณะตามต้องการ ด้วย Regular Expression (Regex)เบื้องต้น

      สิ่งหนึ่งที่เป็นจุดอ่อนของ Excel ในปัจจุบัน ก็คือความสามารถในการหาข้อความที่มี Pattern ตามต้องการ ใน Excel มีแค่ Wildcard (* กับ ?) ซึ่งไม่ค่อยยืดหยุ่นเท่าไหร่ โดยเฉพาะถ้าเอาไปเทียบกับการใช้ Regular Expression (เรียกสั้นๆว่า Regex) ซึ่งเป็นวิธีที่ตอบโจทย์กว่าการใช้สัญลักษณ์ Wildcard ใน Excel อย่างเทียบไม่ติด

      ถ้าเราใช้ Regular Expression เป็น เราก็จะสามารถค้นหาข้อมูลที่มีลักษณะตามรูปแบบ (Pattern) ตามที่เรากำหนดได้ เช่น จะหา email, เบอร์โทรศัพท์, ชื่อ นามสกุล หรืออะไรก็ตามในข้อความ ขอแค่มันมี Pattern ที่แน่นอนก็พอ

      ที่น่าคับแค้นใจคือในโปรแกรมอย่าง Google Sheets หรือ Python สามารถดรียกใช้ Regex ได้ค่อนข้างสะดวก แต่ถ้าจะใช้ Regex ใน Excel เราจะต้อง import Library พิเศษผ่าน VBA ก่อน (ต้อง Add Reference ชื่อ Microsoft VBScript Regular Expressions) ซึ่งเป็นเรื่องที่ค่อนข้างยุ่งยากสำหรับคนทั่วไป ดังนั้นใครอยากให้ Excel มี Regex ในตัวเลยโดยไม่ต้องใช้ VBA สามารถไป Vote ได้ที่นี่

      ในบทความนี้จะเป็นการสอนใช้ Regular Expression เบื้องต้น ซึ่งความรู้นี้สามารถนำไปใช้ได้กับหลายโปรแกรมเลยที่รองรับ Regular Expression ดังนั้นเรียนรู้ไปแล้วคุ้มแน่นอน (เดี๋ยวเราจะมาทำ Regex กันจริงๆ ใน Excel VBA, Google Sheets, Python ในตอนต่อไปนะครับ)

      เริ่มเรียนรู้ Regular Expression

      วิธีการเรียนรู้ Regular Expression ได้จากหลายเว็บ เช่น

      แต่ถ้าใครขี้เกียจอ่านในเว็บอื่น ลองอ่านที่ผมสรุปเบื้องต้นข้างล่างนี้ก็ได้

      พอเรียนแล้ว สามารถลองเอานำคำที่เราต้องการ Match ไปลองใส่ในเว็บ https://regexr.com/ แล้วลองใส่ pattern ต่างๆ ลงไปดูว่ามันเจออะไรบ้าง ข้อดีคือนอกจากมันจะตอบอบ่างรวดเร็วว่าเจออะไรบ้าง ตรงไหน มันยังอธิบาย Pattern ที่เราเขียนให้ด้วยว่าหมายความว่ายังไง

      Syntax พื้นฐาน

      Literals
      =========
      abcกขค…	ตัวหนังสือ(ที่ระบุ)
      123…	ตัวเลข(ที่ระบุ)
      
      Special Characters
      ===================
      .	อักขระอะไรก็ได้ (ยกเว้นขึ้นบรรทัดใหม่)
      ^…	เริ่มด้วย…
      …$	จบด้วย…
      *	มีอย่างน้อย 0 ตัวขึ้นไป
      +	มีอย่างน้อย 1 ตัวขึ้นไป
      ?	มี 0 หรือ 1 ตัว
      \	escape character สำหรับอักขระพิเศษ เช่น \.	ก็จะแปลว่าเครื่องหมายจุด หรือ \* ก็จะแปลว่าเครื่องหมาย *
      
      Character Classes (Alternation ระดับ Character)
      ==================
      [abc]	a, b, หรือ c
      [^abc]	ไม่ใช่ a, b, c
      [a-z]	a ถึง z ตัวไหนก็ได้
      [A-Z]	A ถึง Z ตัวไหนก็ได้
      [0-9]	เลข 0 ถึง 9
      
      Predefined Character Classes
      =======================
      \d	ตัวเลขอะไรก็ได้ เทียบเท่า [0-9]
      \D	อักขระอะไรก็ได้ที่ไม่ใช่ตัวเลข
      \w	อักขระภาษาอังกฤษหรือตัวเลข เทียบเท่า [a-zA-Z0-9_]
      \W	ไม่ใช่อักขระภาษาอังกฤษหรือตัวเลข
      \s	whitespace character (space, tab, newline)
      \S	อะไรก็ได้ที่ไม่ใช่ whitespace character
      
      Quantifiers
      ========================
      *	มีอย่างน้อย 0 ตัวขึ้นไป
      +	มีอย่างน้อย 1 ตัวขึ้นไป
      ?	มี 0 หรือ 1 ตัว
      {n}	มีจำนวน n ครั้ง
      {n,}	มีจำนวน n ครั้งขึ้นไป
      {n,m}	มีจำนวน n-m ครั้ง
      
      Grouping and Capturing
      ========================
      (…)	capturing group
      (?:…)	non-capturing group
      
      Anchors
      ================
      ^…	เริ่มด้วย…
      …$	จบด้วย…
      \b	word boundary
      \B	non-word boundary
      
      | หรือ (Alternation ระดับ Pattern) 
      ============
      (abc|def)	หา abc หรือ def
      a(|b)c		หาเจอทั้ง ac หรือ abc เลย
      
      Flags พิเศษ
      =======
      i	ไม่สนใจพิมพ์เล็กพิมพ์ใหญ่
      g	global search (หาทุกตัว ไม่ใช่แค่ตัวแรก).
      m 	multiline matching เช่น ทำให้ ^ and $ เจอทั้ง start และ end of a line ไม่ใช่ข้อความรวมกันทั้งหมด

      ตัวอย่าง Pattern และความหมาย

      • thep = มีคำว่า thep ตรงไหนก็ได้ในข้อความ
      • ^thep = ขึ้นต้นด้วย thep (คำว่า thep ต้องอยู่หน้าสุด)
      • thep$ = จบด้วยคำว่า thep (คำว่า thep ต้องอยู่หลังสุด)
      • ^thep$ = เป็นคำว่า thep เป๊ะๆ ห้ามมีคำอื่น
      • [thep] = มีตัว t h e หรือ p
      • thep[1-5] = มีคำว่า thep ตามด้วยเลข 1-5 (ตัวเดียว)
      • thep\d = มีคำว่า thep ตามด้วยเลข 0-9 (ตัวเดียว)
      • thep\d{5} = มีคำว่า thep ตามด้วยเลข 0-9 (5 digit)
      • thep\d{5,7} = มีคำว่า thep ตามด้วยเลข 0-9 (5-7 digit)
      • thep\d{5,} = มีคำว่า thep ตามด้วยเลข 0-9 (5 digit ขึ้นไป)
      • thep\D = มีคำว่า thep ตามด้วยอะไรก็ได้ที่ไม่ใช่ตัวเลข 1 ตัว
      • thep. = มี thep ตามด้วยตัวอะไรก็ได้ 1 ตัว
      • thep\. = มีคำว่า thep. (thepตามด้วยจุด) อยู่ในข้อความ
      • th.p = มี th ตามด้วยตัวอะไรก็ได้ 1 ตัว แล้วตามด้วย p
      • th.+p = มี th ตามด้วยตัวอะไรก็ได้อย่างน้อย 1 ตัว แล้วตามด้วย p
      • th.?p = มี th ตามด้วยตัวอะไรก็ได้ 0 หรือ 1 ตัว (มีหรือไม่มีก็ได้) แล้วตามด้วย p
      • th.*p = มี th ตามด้วยตัวอะไรก็ได้กี่ตัวก็ได้ (มีหรือไม่มีก็ได้) แล้วตามด้วย p
      • thep? = มีคำว่า the ตามด้วย p หรือไม่ก็ได้
      • thep+ = มีคำว่า the ตามด้วย p อย่างน้อย 1 ตัว
      • th(ep)+ = มีคำว่า th ตามด้วย ep อย่างน้อย 1 ชุด
      • (thep|inw)excel = มีคำว่า thepexcel หรือ inwexcel
      • \bthep\b = เจอ thep เมื่อไม่ได้ติดกับคำอื่นเท่านั้น แต่ดีกว่า \sthep\s เพราะ \bthep\b จะเจอ thep ตอนขึ้นต้นประโยคเลยด้วย

      รูปแบบที่ซับซ้อนขึ้น

      สมมติข้อความที่ผมสนใจคืออันนี้ และผมต้องการดึงเฉพาะส่วนที่เป็น email ออกมา ดูสิว่าจะทำยังไง?

      สวัสดี ผมชื่อ นายศิระ เอกบุตร ชื่อเล่น ระ อายุ 37 ปี สูง 170 cm มี email คือ thepexcel@gmail.com ชอบการ์ตูนเรื่อง Hunter x Hunter, Attack on Titan, Evangelion ชอบหนังเรื่อง The Matrix, Inception ชอบเล่นเกม ROV, Valorant, StarCraft2 ลืมบอกไปว่าผมเป็นคนทำเว็บ www.thepexcel.com เพื่อแบ่งปันความรู้เรื่อง Excel & Power BI  ยินดีที่ได้รู้จักครับ

      การจะเลือกเอาสิ่งที่ต้องการ เราก็ต้องถามตัวเองว่า ถ้าเรามองด้วยตาเปล่า เรารู้ได้ยังไงว่าส่วนไหนของ email?

      ถ้าถามผม มันต้องเป็นประมาณนี้

      มีอักขระจำนวนนึง ตามด้วยเครื่องหมาย @ แล้วต่อด้วยอักขระอักจำนวนนึง ตามด้วยจุด แล้วตามอักขระอีกจำนวนนึง โดยต้องมีเครื่องหมายเว้นวรรคมาครอบทั้งหน้าหลังด้วย

      เครื่องหมายที่เกี่ยวข้อง เพื่อที่อยากจะได้ email ตั้งแต่ @ จนถึง .

      @.+\.
      • @ คือ ตัว @ (เราอยากจะหาตัวอะไรก็พิมพ์ตัวนั้น ยกเว้นจะไปซ้ำกับสัญลักษณ์พิเศษ ซึ่งต้องใส่ \ นำหน้าจะได้รู้ว่าเป็นอักขระธรรมดา)
      • .+ คืออักขระอะไรก็ได้อย่างน้อย 1 ตัว
        • . แทนอักขระอะไรก็ได้ (ที่ไม่ใช่ขึ้นบรรทัดใหม่)
        • + คือมีอย่างน้อย 1 ตัว
      • \. แทนจุด (\ คือ ใส่ไปให้รู้ว่าต้องการ . ธรรมดา ไม่ใช่สัญลักษณ์พิเศษ)

      ปรากฏว่ามัน Match ข้อมูลเยอะมาก เพราะเราดันบอกว่าให้เอาตั้งแต่เครื่องหมาย @ แล้วตามด้วยตัวอะไรก็ได้อย่างน้อย 1 ตัว (เพราะใช้+) แล้วก็ตามด้วยด้วยจุด มันก็เล่น Match ให้เยอะที่สุดเท่าที่จะ Match ได้เลย อันนี้คือธรรมชาติของมันที่เรียกว่า Greedy Match (Match แบบตะกละ)

      ค้นหาข้อความที่มีลักษณะตามต้องการ ด้วย Regular Expression (Regex)เบื้องต้น 277

      ถ้าเราต้องการให้มันหาให้น้อยที่สุดเท่าที่จำเป็น เราสามารถใส่เครื่องหมาย ? ต่อท้าย + เข้าไป (เราใส่ ? ต่อท้ายพวก * + ? ได้ เพื่อให้มันทำการหาแบบ Non Greedy )ซึ่งจะได้ผลว่าเจอถึงจุดตัวแรกที่ต่อจากเครื่องหมาย @ เท่านั้น (เพราะหาแบบไม่ตะกละแล้ว)

      @.+?\.
      ค้นหาข้อความที่มีลักษณะตามต้องการ ด้วย Regular Expression (Regex)เบื้องต้น 278

      อย่างไรก็ตามเราสามารถใช้เทคนิคอื่นได้ เช่น

      • \s คือ เว้นวรรค
      • \S คือ ทุกอย่างที่ไม่ใช่เว้นวรรค

      ดังนั้นผมสามารถแก้ Pattern เป็นแบบนี้ได้ โดยที่ไม่ต้องใช้ ? เลย เพราะผมไม่เอาเว้นวรรค มันเลยไม่ข้ามไปที่คำอื่น(ข้ามไม่ได้เพราะมีเว้นวรรคคั่นอยู่)

      @\S+\.
      ค้นหาข้อความที่มีลักษณะตามต้องการ ด้วย Regular Expression (Regex)เบื้องต้น 279

      พอรู้แบบนี้ก็จะสามารถใช้ Pattern นี้เพื่อเอา Email ทั้งอันได้

      \S+@\S+\.\S+
      ค้นหาข้อความที่มีลักษณะตามต้องการ ด้วย Regular Expression (Regex)เบื้องต้น 280

      ถ้าในข้อความมี email หลายที่มันก็จะสามารถหาเจอได้ เช่น ข้อความกลายเป็นแบบนี้ ก็ไม่มีปัญหา

      xyz@gmail.com สวัสดี ผมชื่อ นายศิระ เอกบุตร ชื่อเล่น ระ อายุ 37 ปี สูง 170 cm  abc@outlook.com เป็นคนทำเว็บ www.thepexcel.com เพื่อแบ่งปันความรู้เรื่อง Excel & Power BI มี email คือ thepexcel@gmail.com ชอบการ์ตูนเรื่อง Hunter x Hunter, Attack on Titan, Evangelion xxxx@aaa.co.th ชอบหนังเรื่อง The Matrix, Inception ชอบเล่นเกม ROV, Valorant, StarCraft2 ยินดีที่ได้รู้จักครับ thepexceltraining@gmail.com
      ค้นหาข้อความที่มีลักษณะตามต้องการ ด้วย Regular Expression (Regex)เบื้องต้น 281

      ถ้าหากเราอยากจะได้ส่วนข้างหน้า @ และหลัง @ แยกกัน เราสามารถใส่วงเล็บเข้าไปแบ่ง Group ผลลัพธ์ได้ ดังนี้

      (\S+)@(\S+\.\S+)
      ค้นหาข้อความที่มีลักษณะตามต้องการ ด้วย Regular Expression (Regex)เบื้องต้น 282

      หรือจะใส่วงเล็บใหญ่ครอบไปอีกที เพื่อเอาทั้ง email เป็นอีก Group ด้วยก็ได้ดังนี้

      ((\S+)@(\S+\.\S+))
      regular expression regex
    • ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก

      ตอนนี้ผมคิดว่าเพื่อนๆ หลายคนคงเริ่มใช้ Power Query กันบ้างแล้วใช่ไหม? ผมเลยอยากเขียนบทความนี้เพื่อสรุปกระบวนท่าพื้นฐานในการจัดการข้อมูลด้วย Power Query มาให้เพื่อนๆ ได้ทบทวนกันครับ และยังเป็นการชวนให้คนที่ยังไม่เคยใช้ได้ลองมาสนุกไปด้วยกันนะ!

      ถ้าเพื่อนๆ ชอบอ่านการ์ตูนคงเคยได้ยินเรื่องดาบพิฆาตอสูรใช่ไหมครับ? พระเอกที่ชื่อทันจิโร่มีท่าไม้ตาย “ปราณวารี” เราในฐานะผู้ใช้ Power Query ใน Excel/Power BI จะเรียกท่าไม้ตายของเราว่า “ปราณคิวรี่” กันบ้างดีไหมล่ะ 555

      เอาล่ะ เพื่อไม่ให้เสียเวลา มาดูกันว่า Power Query มีกระบวนท่าจัดการข้อมูลยังไงบ้าง? บทความนี้ผมจะขอนำเสนอเรื่องพื้นฐานก่อนน้า ส่วนกระบวนท่าขั้น Advance เดี๋ยวจะมีในบทความต่อๆ ไป

      เตรียมสูดลมหายใจลึกๆ แล้วไปพบกับปราณคิวรี่พื้นฐานทั้ง 10 รูปแบบกันเลยดีกว่า!

      Version คลิปวีดีโอ

      ปราณคิวรี่ รูปแบบที่ 1 : Fill Down

      ท่านี้เจ๋งมากครับ! เพราะมันช่วยเติมช่องว่างด้วยข้อมูลด้านบนได้ ซึ่งเหมาะมากกับรายงานที่ข้อมูลชอบเว้นว่างไว้ เช่น ในตารางของเรา คอลัมน์ผลไม้อาจถูกเว้นว่างแบบที่มนุษย์เข้าใจ (แต่คอมพิวเตอร์เข้าใจว่ามันว่างจริงๆ)

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 283

      ซึ่งเราสามารถแก้ไขช่องว่างที่เป็น null แบบง่ายๆ ด้วยวิธีนี้

      • เลือกคอลัมน์ที่ต้องการ -> คลิ๊กขวา -> Fill -> Down หรือ
      • เลือกคอลัมน์ที่ต้องการ -> Transform -> Fill -> Down
      Power Query
      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 284
      จะเห็นว่าช่องว่างๆ ได้ถูกถมด้วยค่าข้างบนเรียบร้อยแล้ว

      ปราณคิวรี่ รูปแบบที่ 2 : Replace

      กระบวนท่านี้ยังมีความสามารถเปลี่ยนค่า Error เป็นค่าอื่นด้วย Replace Error หรือจะเปลี่ยนค่านึงเป็นอีกค่านึงด้วย Replace Values ก็ได้ แต่มันมีจุดต้องระวังนิดนึงครับ! ถ้าเราใช้มันกับข้อความ บางครั้งมันจะแทนที่ข้อความแค่บางส่วน เช่นถ้าเปลี่ยน “ส้ม” เป็น “มะนาว” มันก็จะเปลี่ยน “ส้ม”โอ เป็น “มะนาว”โอ ไปด้วยนะครับ

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 285
      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 286
      ส้ม กลายเป็นมะนาว
      ส้มโอ กลายเป็น มะนาวโอ!

      ทางแก้คือ ตอนใช้ Replace Value เพื่อนๆ ควรเลือก Advance แล้วติ๊ก Match Entire Cell Content ด้วย จะได้เป๊ะ!

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 287

      ปราณคิวรี่ รูปแบบที่ 3 : Column From Example

      กระบวนท่านี้เหมือนเป็นท่าไม้ตายที่อัจฉริยะ มันเลียนแบบกระบวนท่าอื่นๆ ได้เพียงใส่ผลลัพธ์ที่ต้องการให้ดูตัวอย่าง เหมือน Flash Fill ใน Excel ยังไงยังงั้นเลยครับ มันก็จะเลือกสูตรหรือคำสั่งที่เหมาะสมให้เราได้คอลัมน์ใหม่ตามที่ต้องการ

      ตัวอย่างเช่น เราอาจจะแยกบางส่วนของคำ, เปลี่ยนตัวอักษรเป็นพิมพ์เล็กพิมพ์ใหญ่, เติม 0 หน้าตัวเลข, เขียนเงื่อนไข IF อะไรพวกนี้ เครื่องมือนี้ทำได้หมดเลยครับ!

      เอาล่ะ ผมจะทำให้ดูเป็นตัวอย่างนะครับ

      Power Query ให้ความสำคัญเรื่องตัวพิมพ์เล็กพิมพ์ใหญ่เสมอ หมายความว่ามันแยกแยะตัวอักษรที่พิมพ์ต่างกันได้หมด ดังนั้นเราควรทำตัวพิมพ์ให้ตรงกันทั้งหมดก่อนนะ เพื่อนๆ สามารถใช้คำสั่งใน Format ช่วยได้ มีทั้ง lowercase, UPPERCASE, Capitalize Each Word สบายใจได้เลยครับ

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 288
      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 289

      แต่ถ้าเพื่อนๆ ยังไม่รู้จักคำสั่งพวกนี้ดีพอ ก็ใช้ Column From Example ช่วยได้เหมือนกัน เรียกใช้งานแล้วใส่ตัวอย่างผลลัพธ์ที่ต้องการไว้ในคอลัมน์ด้านขวา มันจะคิดสูตรให้เหมือน Flash Fill แต่เจ๋งกว่าตรงที่ Power Query มัน Refresh ได้ด้วยนั่นแหละ

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 290
      แค่ใส่ตัวอย่างผลลัพธ์ที่ต้องการ ก็ได้คำตอบมาอย่างชิลๆ

      ปราณคิวรี่ รูปแบบที่ 4 : Filter

      กระบวนท่า Filter คือการคัดเลือกข้อมูลเฉพาะที่เราต้องการ ฟังดูอาจจะง่ายๆ แต่จริงๆ มันละเอียดอ่อนมากครับ มีหลายจุดที่ต้องระวังดังนี้

      • ถ้าในคอลัมน์มีข้อมูล Error อยู่มันจะติด Error มาด้วย ต้องจัดการ Error ให้หายไปก่อน (เช่นใช้กระบวนท่า Replace Error)
      • ทุกคำสั่งใน Power Query ให้ความสำคัญเรื่องตัวพิมพ์เล็กพิมพ์ใหญ่ด้วย Filter ก็เช่นกัน ดังนั้นอย่าลืมคิดถึงประเด็นนี้ด้วย
      • ที่สำคัญสุดคือ การติ๊กเลือก item ใน filter ให้สังเกตสูตรที่ออกมาด้วยว่าตรงตามที่ต้องการมั้ย?

      ยกตัวอย่างให้เห็นชัดๆ

      มีผลไม้ 5 แบบ ผมกดเลือกเอาออก 2 อัน เหลือ 3 อัน สูตรที่บันทึกจะบอกว่า ไม่เอา 2 อัน ซึ่งก็คือกล้วยกับมะนาว

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 291
      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 292

      แต่ถ้าผมกดเลือกเอาออก 3 อัน เหลือ 2 อัน สูตรที่บันทึกจะกลายเป็น เอา 2 อัน คือส้มโอกับแอปเปิ้ล

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 293
      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 294

      เพราะฉะนั้น วิธีบันทึกสูตรจะไม่เหมือนกัน ต้องตรวจสอบให้แน่ใจว่าเราทำตามที่คิดว่าจะได้ผลจริงๆ รึเปล่าด้วยนะครับ!

      ปราณคิวรี่ รูปแบบที่ 5 : Split

      กระบวนท่าแยกข้อมูลจาก 1 ช่องให้กลายเป็นหลายๆ ช่องได้ คล้าย Text to Column ใน Excel มากๆ เพียงแต่เทคนิคการแบ่งมีหลากหลายกว่า เช่น ใช้ตัวคั่น (Delimiter), จำนวนอักษร (Number of Character), หรือแบ่งตามตำแหน่งอักษรก็ยังได้

      และที่เด็ดกว่า Excel ก็คือสามารถเลือกแบ่งทีเดียวจากทางซ้าย ทางขวา หรือทุกครั้งที่เจอตัวคั่นตามที่ต้องการได้เลย

      นอกจากนั้นยังมีความสามารถ แบ่งเป็นหลายๆ แถว ได้ด้วยนะครับ เพื่อนๆ ซึ่งเหมาะมากกับกรณีที่จำนวนข้อมูลที่จะถูกแบ่งมีไม่แน่นอน

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 295
      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 296

      ปราณคิวรี่ รูปแบบที่ 6 : Group By

      กระบวนท่า Group By จะรวบข้อมูลที่ซ้ำเข้าด้วยกันเป็นบรรทัดเดียว (คล้าย Remove Duplicates) แต่ที่เจ๋งกว่าคือมันสามารถสรุปข้อมูลไปพร้อมกันได้ด้วย เช่น Sum, Count, Average และอื่นๆ

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 297
      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 298

      ถ้าสังเกตดูจะเห็นว่าจำนวนแถวลดลง คอลัมน์จะเหลือแค่ตัวที่ Group ไว้ และคอลัมน์สรุป คอลัมน์ที่เหลือหายไปหมด

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 299
      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 300

      จริงๆ แล้ว Group By เป็นกำลังหลักที่จะพัฒนาไปใช้กับท่าแบบ Advance ที่เรียกว่า All Rows ในตอนต่อไป ซึ่งผมจะอธิบายให้ฟังอย่างละเอียดนะครับ

      ปราณคิวรี่ รูปแบบที่ 7 : Pivot

      กระบวนท่านี้เปลี่ยนข้อมูลหลาย Item ในคอลัมน์เดียวให้กลายเป็นหัวตารางหลายคอลัมน์ และสามารถกำหนดตัวเลขสรุปในคอลัมน์ได้ด้วย เอาล่ะ!

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 301
      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 302
      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 303

      ปราณคิวรี่ รูปแบบที่ 8 : Unpivot

      กระบวนท่านี้ทำตรงข้ามกับ Pivot เปลี่ยนหัวตารางหลายๆ คอลัมน์ ให้กลายมาเป็น Item ในคอลัมน์เดียว ชื่อว่า Attribute แถมตัวเลขที่อยู่ในคอลัมน์เดิมจะมาอยู่ในคอลัมน์ Value อีกด้วย

      ในชีวิตจริง เรามักจะเจอสถานการณ์ที่ต้องใช้กระบวนท่า Unpivot บ่อยมากๆ (เพราะคนชอบส่งข้อมูลเชิง Report มาให้เรา ไม่ใช่ส่งข้อมูลเชิง Database) ดังนั้นฝึกใช้ให้ช่ำชองล่ะ

      จากตัวอย่าง คอลัมน์พนักงานขาย sales ก-ง กระจายอยู่คนละคอลัมน์ ทั้งที่จริงควรรวมลงในคอลัมน์เดียวกัน ซึ่งการเลือกคอลัมน์ที่อยู่กับที่ (สินค้า กับ วิธีการชำระเงิน) แล้วคลิกขวา -> Unpivot Other Columns เป็นวิธีที่ดีที่สุดครับ

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 304

      จะสังเกตได้ว่าสูตรจะบันทึกว่าพลิกคอลัมน์อื่นๆ ที่ไม่ใช่สินค้าและวิธีการชำระเงินลงมาให้หมด

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 305
      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 306

      Tips: ถ้ามั่นใจว่าจะพลิกแค่ sales ก-ง ให้เลือกคอลัมน์นี้แล้วใช้ Unpivot Only Selected Columns แทนนะครับ

      ปราณคิวรี่ รูปแบบที่ 9 : Append Query

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

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 307

      หลังจาก Append จะเป็นแบบนี้ สังเกตว่าระบบยึดคอลัมน์ตารางแรกเป็นหลักก่อน แล้วถ้ามีคอลัมน์เพิ่มเติมในตารางที่สองก็จะมาเพิ่มต่อท้าย ตารางไหนที่ไม่มีคอลัมน์นั้นก็จะเป็น null ว่างๆ ครับ

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 308
      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 309

      ปราณคิวรี่ รูปแบบที่ 10 : Merge Query

      กระบวนท่านี้คล้ายการใช้ VLOOKUP ใน Excel แต่ดีกว่าตรงที่ Merge Query สามารถได้ผลลัพธ์ทุก Row ในขณะที่ VLOOKUP ได้แค่เพียง Item แรก อีกทั้งยังมีฟีเจอร์ที่เรียกว่า Fuzzy Merge ที่อนุญาตให้เชื่อมข้อมูลผิดพลาดเล็กน้อยได้ด้วย

      สมมุติว่าใช้ตารางที่ Append แล้วด้านบนมา Merge กับตารางในรูป โดยระบุการเชื่อมที่คอลัมน์ใด (เลือกได้หลายคอลัมน์) จะได้ผลดังนี้

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 310

      จากนั้นสามารถกด Expand Column ที่ต้องการได้

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 311

      ผลลัพธ์จะออกมาแบบนี้ครับ

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 312

      สังเกตได้ว่าเราจะได้ข้อมูลกลับมาทุกบรรทัด ทำให้จำนวนแถวเพิ่มขึ้น ส่วนอะไรที่หาไม่เจอจะได้ null กลับมาแทนครับ

      ปราณคิวรี่ พื้นฐาน 10 รูปแบบ : รวมกระบวนท่า Power Query พื้นฐานที่คุณควรรู้จัก 313

    • อธิบายการทำงาน DATEDIF ใน Excel และแนวทางแก้ไขให้ได้ผลลัพธ์ดั่งใจ

      อธิบายการทำงาน DATEDIF ใน Excel และแนวทางแก้ไขให้ได้ผลลัพธ์ดั่งใจ

      หนึ่งในฟังก์ชันที่ลึกลับที่สุดใน Excel สำหรับผมคือฟังก์ชันที่ชื่อว่า DATEDIF ครับ มันคือฟังก์ชันที่สามารถคำนวณระยะห่างระหว่างวันที่สองวันที่กำหนดได้ โดยสามารถแสดงผลลัพธ์เป็นระยะห่างได้หลายรูปแบบมากๆ เช่น ห่างเต็มวัน เต็มเดือน เต็มปี หรือแบบแปลกๆ เช่น นับวันแบบไม่สนใจเดือน และแบบอื่นที่แปลกๆ อีกมากมาย แต่มันดันกลายเป็นฟังก์ชันลึกลับที่ทาง Microsoft ไม่ค่อยอยากให้คุณใช้? ทำไมถึงเป็นแบบนั้น? และเราจะแก้ไขผลลัพธ์แปลกๆ จาก DATEDIF ยังไง มาดูกันครับ (Edit : มีสรุปสูตรให้ท้ายบทความ)

      หมายเหตุ: บอกไว้ก่อนว่า DATEDIF ใน DAX ของ Power BI ไม่ได้ทำงานแบบเดียวกับฟังก์ชันใน Excel นะ มันเป็นอีกแบบโดยสิ้นเชิงเลย ในบทความนี้จะเป็นการพูดถึง DATEDIF ใน Excel นะครับ

      ฟังก์ชันลึกลับ?

      ที่ผมบอกว่ามันลึกลับเพราะว่ามันเป็นฟังก์ชันที่ไม่ขึ้นใน List ของฟังก์ชันใน Excel ด้วยซ้ำ

      เวลาพิมพ์ =DATE เพื่อดูว่ามีฟังก์ชันอะไรบ้าง? ก็หาเจ้าตัวนี้ไม่เจอ!

      อธิบายการทำงาน DATEDIF ใน Excel และแนวทางแก้ไขให้ได้ผลลัพธ์ดั่งใจ 314

      แต่ถ้าพิมพ์จนครบแล้วเปิดวงเล็บ จะพบว่ามันมีตัวตนอยู่จริงๆ (แต่ก็ไม่ได้แสดง Tool Tips อะไรออกมาเลย 555)

      อธิบายการทำงาน DATEDIF ใน Excel และแนวทางแก้ไขให้ได้ผลลัพธ์ดั่งใจ 315

      วิธีการใช้งานของ DATEDIF

      DATEDIF( start_date, end_date, interval )

      โดยที่ interval เป็นการเลือก Mode ของการแสดงผลลัพธ์ ซึ่งมีหลายแบบ ดังนี้

      โหมดการทำงานของ DATEDIF

      • : จำนวน ปีเต็ม ระหว่าง start_date และ end_date
      • m : จำนวน เดือนเต็ม ระหว่าง start_date และ end_date
      • : จำนวน วันทั้งหมด ระหว่าง start_date และ end_date
      • md : จำนวน วันที่เหลือ หลังจากนับเดือนเต็มจาก start_date ถึง end_date (เหมือนคิด m แล้วค่อย d)
      • ym : จำนวน เดือนที่เหลือ หลังจากนับปีเต็มจาก start_date ถึง end_date (เหมือนคิด y แล้วค่อย m)
      • yd : จำนวน วันที่เหลือ หลังจากนับปีเต็ม จาก start_date ถึง end_date (เหมือนคิด y แล้วค่อย d)

      ตัวอย่างการใช้งานดังรูป

      อธิบายการทำงาน DATEDIF ใน Excel และแนวทางแก้ไขให้ได้ผลลัพธ์ดั่งใจ 316

      พอเห็นแบบนี้แล้วหลายคนคงสงสัยว่า ทำไมถึงต้องเอาฟังก์ชันที่เจ๋งขนาดนี้ไปซ่อนให้ลึกลับด้วยล่ะ?

      สาเหตุเพราะฟังก์ชันนี้มันมีพฤติกรรมแปลกๆ หลายอย่างเลย ทาง Microsoft ถึงกับเขียนไว้ใน support document เลยนะ ว่ามันน่ากลัวมาก 555 ลองไปอ่านดูได้

      อธิบายการทำงาน DATEDIF ใน Excel และแนวทางแก้ไขให้ได้ผลลัพธ์ดั่งใจ 317

      อาการแปลกๆ ของ DATEDIF

      ซึ่งเอาจริงๆ แล้วอาการแปลกๆ ของ DATEDIF จะเกิดขึ้นถ้าเราเริ่มต้นในช่วงปลายเดือนครับ เพราะมัน ต้องพยายามจบเดือนในเลขวันเดียวกับวันเริ่มต้น แต่บางทีมันก็เป็นไปไม่ได้!

      อาการนับจำนวนติดลบหากวันเริ่มอยู่ในช่วงปลายเดือน

      ถ้าเริ่มวันที่ 31 แล้วจบแถวๆ สิ้นเดือนที่มี 31 วัน ก็จะดูไม่มีปัญหาอะไร ทุกอย่างดูดี โปรแกรมมองว่าครบวันพอดีที่วันที่ 31

      อธิบายการทำงาน DATEDIF ใน Excel และแนวทางแก้ไขให้ได้ผลลัพธ์ดั่งใจ 318

      ถ้าเริ่มวันที่ 31 แล้วจบแถวๆ สิ้นเดือนที่มี 30 วัน สังเกตว่ามันจะมองว่าครบเดือนเต็มๆ ในวันที่ 1 ของเดือนถัดไป (จินตนาการว่าถ้าเดือนเมษามี 31 วันจะจบวันนั้นแหละ)

      สาเหตุเพราะว่ามันพยายามมองว่าการจบเดือน เปรียบเสมือนต้องจบเดือนในเลขวันเดียวกับวันเริ่มต้นนั่นเอง

      อธิบายการทำงาน DATEDIF ใน Excel และแนวทางแก้ไขให้ได้ผลลัพธ์ดั่งใจ 319

      ถ้าเริ่มวันที่ 31 แล้วจบแถวๆ สิ้นเดือน กพ. มันจะมองว่าครบเดือนเต็มๆ เลยไปอีก (จินตนาการว่าถ้าเดือน กพ. มี 31 วันจะจบวันนั้นแหละ) ส่งผลให้การนับจำนวนวันติดลบได้

      และถ้ายิ่งปีที่กพ. มี 28 วัน (ก็ปีปกติแหละ) ยิ่งแปลกหนัก คือติดลบ 2 เลยทีเดียว เพราะมันจะมองว่าครบเดือนเต็มๆ ในวันที่ 3 (จินตนาการว่าถ้าเดือนกพ. มี 31 วันจะจบวันนั้นแหละ)

      อธิบายการทำงาน DATEDIF ใน Excel และแนวทางแก้ไขให้ได้ผลลัพธ์ดั่งใจ 320

      อาการแปลกๆ อันอื่น

      ผมมองว่าอาการแปลกอื่นๆ เป็นเรื่องของความต้องการที่เจาะจงของแต่ละคน ซึ่งอาจจะต้องการไม่เหมือนกัน

      เช่น บางครั้งเวลาผมไปสอนลูกค้า เค้าก็บอกว่าอยากให้เมื่อเริ่มสิ้นเดือน จบสิ้นเดือน (แม้เลขจะน้อยกว่า) เช่น เริ่ม 31 มค. จบ 30 เมษา แบบนี้ให้ถือว่าครบเต็มเดือนเดือน ณ วัน สิ้นเดือนนั้นๆ ไปเลย ซึ่งจะเห็นว่า DATEDIF จะยังไม่ได้มองว่าครบเดือน (แต่จะมาครบในวันที่ 1)

      ถ้าคุณมีความต้องการแบบเดียวกับลูกค้าของผม มันก็ต้องมีการ Adjust สูตรให้มันทำงานให้ได้ดั่งใจ ซึ่งมีแนวทางดังนี้

      แนวทางการปรับสูตร DATEDIF ให้ทำงานดั่งใจ

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

      จะเห็นว่าเราสามารถทำให้ถือว่าครบเดือนในวันสิ้นเดือนได้ ซึ่งเอาไว้ใช้ adj แบบ m และ ym ได้ทั้งคู่เลย

      อธิบายการทำงาน DATEDIF ใน Excel และแนวทางแก้ไขให้ได้ผลลัพธ์ดั่งใจ 321

      เริ่มวันที่ 30 ก็ใช้ได้

      อธิบายการทำงาน DATEDIF ใน Excel และแนวทางแก้ไขให้ได้ผลลัพธ์ดั่งใจ 322

      ถ้าวันเริ่ม <=28 มันก็จะไม่มีการ adjust เพราะเลขวันเริ่มไม่ได้มากกว่าวันจบ (มันถูกต้องอยู่แล้ว)

      อธิบายการทำงาน DATEDIF ใน Excel และแนวทางแก้ไขให้ได้ผลลัพธ์ดั่งใจ 323

      การ adjust เรื่อง md ที่มีติดลบ

      เราต้องถามตัวเองแหละว่าต้องการผลลัพธ์แบบไหนถึงเรียกว่าถูกใจเรา?

      ผมคิดว่าถ้าเลขวันเริ่ม <=28 เราทุกคนไม่น่ามีปัญหากับผลลัพธ์ของ DATEDIF ดังนั้นมันจะเริ่มมีปัญหากับการเริ่มด้วยวันที่ 29,30,31 เท่านั้น

      แต่เราลองมาดูก่อนว่า ถ้าเริ่มวันที่ 28 มันให้ผลลัพธ์แบบไหน ซึ่งจะพบว่าถ้าจบวันที่ 28 จะถือว่า md เป็น 0 แล้ววันถัดไปเป็น 1,2,3… ไปเรื่อยๆ

      อธิบายการทำงาน DATEDIF ใน Excel และแนวทางแก้ไขให้ได้ผลลัพธ์ดั่งใจ 324

      ดังนั้นถ้าเริ่มวันที่ 29 เราก็น่าจะอยากให้ถ้ามันจบวันที่ 29 ก็เป็น 0 แล้วไล่ไปเรื่อยๆ แต่ปรากฏว่ามันไม่ได้ทำงานแบบนั้น โดยเฉพาะหากเดือนก่อนหน้ามีไม่ถึงวันที่ 29

      อธิบายการทำงาน DATEDIF ใน Excel และแนวทางแก้ไขให้ได้ผลลัพธ์ดั่งใจ 325

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

      อธิบายการทำงาน DATEDIF ใน Excel และแนวทางแก้ไขให้ได้ผลลัพธ์ดั่งใจ 326

      ซึ่งจะเห็นว่าผลลัพธ์ได้ดั่งใจแล้ว

      อธิบายการทำงาน DATEDIF ใน Excel และแนวทางแก้ไขให้ได้ผลลัพธ์ดั่งใจ 327

      ลองเปลี่ยนเลขไปเริ่ม 31 ว่า work มั้ย ก็พบว่าน่าจะได้ดั่งใจแล้วนะ

      อธิบายการทำงาน DATEDIF ใน Excel และแนวทางแก้ไขให้ได้ผลลัพธ์ดั่งใจ 328

      ลองเลขน้อยๆ ก็ดู ok ไม่ได้มีการ adjust อะไร

      อธิบายการทำงาน DATEDIF ใน Excel และแนวทางแก้ไขให้ได้ผลลัพธ์ดั่งใจ 329

      แต่ถ้าเรา adjust เรื่องเดือนตอนสิ้นเดือนไปแล้ว การนับวันก็ควรเป็น 0 วันด้วย ดังนั้นจะต้องปรับสูตรนับวันให้สอดคล้องใหม่อีกที ซึ่งผมได้แสดงวิธีแก้ไขให้ใน section สรุปสูตรข้างล่างนี้แล้วครับ

      สรุปสูตรทั้งหมด

      คำนวณปี

      =DATEDIF(วันเริ่ม,วันจบ,"y")

      คำนวณเดือน

      =IF(AND(DAY(วันเริ่ม)>DAY(วันจบ),วันจบ=EOMONTH(วันจบ,0)),
      DATEDIF(วันเริ่ม,วันจบ,"ym")+1,DATEDIF(วันเริ่ม,วันจบ,"ym"))

      คำนวณวัน

      =IF(DAY(วันเริ่ม)>DAY(วันจบ),IF(วันจบ=EOMONTH(วันจบ,0),0,
      IF(DAY(EOMONTH(วันจบ,-1))<DAY(วันเริ่ม),DAY(วันจบ),DATEDIF(วันเริ่ม,วันจบ,"md"))))

      ตัวอย่างการคำนวณ

      ลองคำนวณ อายุงาน เป็นจำนวน ปี เดือนวัน ด้วยสูตรใหม่ดูได้ดังนี้

      อธิบายการทำงาน DATEDIF ใน Excel และแนวทางแก้ไขให้ได้ผลลัพธ์ดั่งใจ 330

      ผมสามารถแก้สูตร DATEDIF ให้ได้ผลลัพธ์ดั่งใจ(ผม)แล้ว แต่จะให้ได้ดั่งใจคุณรึเปล่าไม่รู้นะครับ เพราะแต่ละคนชอบไม่เหมือนกัน อาจต้องหา Logic มาปรับให้ตรงใจคุณอีกทีนะ ^^