Author: Sira Ekabut

  • 13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข)

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข)

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

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

    เอาล่ะ เพื่อไม่ให้เสียเวลา มาดูกันเลยดีกว่าว่ามีกับดักอะไรบ้าง?

    กับดัก 1 : ทำให้เพื่อนเขียนสูตรไม่ติด

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

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 1

    ซึ่งหลังจากปรับ Format เป็น Text แล้วจะทำให้เมื่อพิมพ์อะไรลงไปใน Cell ก็ตาม Excel จะมองว่าข้อมูลนั้นเป็น Text ทั้งหมดเลย โดยไม่ต้องใส่เครื่องหมาย ‘ นำหน้าด้วยซ้ำ (แต่ต้องปรับเป็น Text ก่อนพิมพ์นะ)

    ซึ่งการทำให้เป็น Text นั้น Excel ก็จะมองว่าการเขียนสูตร ก็จะกลายเป็น Text ธรรมดาๆ ไปด้วย ทำให้เขียนสูตรไม่ติดนั่นเอง

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 2

    วิธีแก้ไข

    ต้องปรับ Format ให้กลับมาเป็น General หรือ Clear Format ทิ้งก็ได้ จากนั้นให้กระตุ้นให้มันคิดว่ามีการพิมพ์ข้อมูลใหม่ ซึ่งเราจะสามารถกระตุ้นให้สูตรกลับมาทำงานอีกครั้งได้ด้วยการ Replace (Ctrl+H) โดยแทนเครื่องหมาย = ด้วย = นั่นเอง

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 3

    พอแก้ไขแล้วสูตรก็จะกลับมาทำงานอีกครั้งนึง

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 4

    กับดัก 2 : ทำให้สูตรไม่อัปเดทด้วย Manual Calculation

    วิธีนี้เป็นวิธีที่โคตรเลวร้าย เพราะขณะที่เพื่อนเขียนสูตร สูตรมันจะทำงานอยู่ แต่ว่าถ้า input เปลี่ยนไป แทนที่ผลลัพธ์ของสูตรจะอัปเดท มันกลับไม่อัปเดท

    วิธีทำคือให้เลือก Formula -> Calculation Options ->Manual

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 5

    ทีนี้ตอนเขียนสูตรตอนแรกมันจะทำงานได้

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 6

    แต่พอไปแก้ input ต้นทาง ผลลัพธ์ของสูตรจะไม่อัปเดท

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 7

    วิธีสังเกตคือ Status Var ด้านซ้ายจะมีคำว่า Calculate ค้างอยู่ แปลว่ามันยังไม่ได้คำนวณอะไรบางอย่าง

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 8

    ทดสอบได้ว่า ถ้าลองกดปุ่ม F9 เพื่อบังคับให้มันคำนวณใหม่ คำว่า Calculate จะหายไป และผลลัพธ์การคำนวณจะถูกต้อง

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 9

    ความเลวร้ายของมันไม่ได้มีแค่นี้ เพราะถ้าเรา Save ไฟล์ที่ปรับแบบ Manual Calculation เอาไว้ แล้วเอาไปให้คนอื่นเปิด เพื่อนของเราก็จะติดอาการ Manual Calculate จากไฟล์นี้ไปด้วยเช่นกัน !

    วิธีแก้ไข

    ก็ให้ไปเลือก Calculation Options ให้เป็น Automatic ซะก็จบแล้ว

    กับดัก 3 : ทำให้มองไม่เห็นข้อมูลด้วยการถม Font สีเดียวกับพื้นหลัง

    วิธีแกล้งเพื่อนแบบง่ายๆ อีกอันก็คือ เราไปเปลี่ยน Font ของสีตัวอักษรให้มีสีเดียวกับ Background ซะเลย (ซึ่งมักจะเป็นสีขาว) เพียงเท่านี้เพื่อนก็จะมองไม่เห็นข้อความทีมีอยู่แล้วล่ะ เกรียนแบบทำง่ายมากๆ เลยอันนี้

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 10

    วิธีแก้ไข

    การสร้างกับดักอันนี้ง่ายมาก วิธีแก้ไขก็ง่ายมากเช่นกัน แค่เปลี่ยนสี Font เป็นสีอื่น เช่น Automatic หรือสีดำก็หายแล้ว

    กับดัก 4 : ทำให้มองไม่เห็นข้อมูลด้วย Custom Number Format

    ถ้าใครคิดว่าการใส่ Font สีขาวมัน Basic เกินไป มาดูการแกล้งด้วย Number Format แบบ Advance โดยให้เลือกข้อมูลแล้วใส่ Custom Format เป็น code ดังนี้

    ;;;
    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 11

    พอกด ok แล้ว ก็จะมองไม่เห็นข้อมูลทันที แต่ข้อมูลไม่ได้หายไปจริงๆนะ แค่มองไม่เห็นเฉยๆ สังเกตได้จากรูปข้างล่าง ตรง Formula Bar ยังมีคำว่า cat อยู่เลย แต่เรามองไม่เห็น

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 12

    การที่ Custom Format นี้ทำให้ข้อมูลหายไปได้เป็นเพราะว่า Custom Format แบบเต็มยศสามารถระบุได้ดังนี้

    Formatเลขบวก ; Formatเลขลบ ; Formatเลขศูนย์ ; Formatตัวหนังสือ

    แต่เราใส่แต่ ; ซึ่งเป็นตัวคั่นอย่างเดียว โดยไม่ใส่ code รูปแบบอะไรเลย ทำให้มองไม่เห็นข้อมูลเลยนั่นเองครับ

    ใครสงสัยเรื่อง Custom Number Format สามารถไปอ่านรายละเอียดได้ที่นี่เลย

    วิธีแก้ไข

    วิธีแก้ก็ให้ปรับ Format เป็น General หรือ Clear Format ทิ้งเช่นเดิมครับ

    กับดัก 5 : ถมดำพื้นหลังด้วย Conditional Format

    ปกติแล้วเครื่องมือ Conditional Format จะสามารถกำหนดได้ว่า หากข้อมูลใน Cell ตรงกับเงื่อนไขที่กำหนด ให้ใส่ Format ตามต้องการได้

    ถ้าจะแกล้งเพื่อนเราสามารถเลือกข้อมูลแล้วใส่เงื่อนไขประหลาดๆ เข้าไป เพื่อให้มันถมสีดำทั้ง Font และ Background แค่นี้ใครเจอก็เซ็งแล้วล่ะ เช่น ให้เลือก Highlight Cell Rules แบบ Greater Than

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 13

    จากนั้นใส่เลขติดลบเยอะๆ ไปเลย เช่น -1000000 แล้วเลือก Custom Format Fill สีดำซะ (สาเหตุที่ใส่เลขติดลบแล้วมันใช้งานได้ เพราะว่า Excel จะมองว่าข้อความจะมีค่ามากกว่าตัวเลขและตัวเลขปกติเราจะไม่ใส่ติดลบ แถมช่องว่าง Excel ก็จะมองว่าเป็นเลข 0 อีก มันจึงตรงเงื่อนไขหมดเลย)

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 14

    แค่นี้ฉากหลังจะหลายเป็นสีดำทันที แล้วถมสีแก้ไม่ได้ด้วย (เช่นในรูปผมกดถมสีเหลืองแล้ว มันก็ไม่เหลือง)

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 15

    วิธีแก้ไข

    ต้องเอา Conditional Format ออก ซึ่งเราอาจจะลบออกเฉพาะ Cell ที่เลือก หรือจะเอาออกทั้ง Sheet เลยก็ย่อมได้ (แต่ถ้าจะเลือกแบบละเอียด ให้ไปที่ Manage Rules แทน)

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 16

    กับดัก 6 : ซ่อนคอลัมน์แรกๆ ให้หายไปซะ

    อันนี้จริงๆ เป็นวิธีแกล้งที่เห็นง่าย แก้ง่าย แต่หลายคนแก้ไม่เป็น เช่น หากเราเลือกคอลัมน์แรกๆ แล้วคลิ๊กขวา Hide ซะ แค่นี้คอลัมน์ก็จะถูกซ่อนไป

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 17

    เนี่ย หายไปละ…

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 18

    วิธีแก้ไข

    เราจะเลือกคอลัมน์ที่มองเห็นอยู่ตามปกติแล้ว Unhide ธรรมดาๆ ไม่ได้ วิธีที่ถูกต้องคือ ต้องเลือกคอลัมน์แรกที่ยังมองเห็นอยู่แล้วลากไปทางซ้าย แล้วค่อนกดคลิ๊กขวา Unhide จึงจะได้

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 19

    กับดัก 7 : ทำให้เลื่อน Scroll หน้าจอไม่ได้ด้วยการ Freeze Pane

    ปกติแล้วเราจะสามารถ Lock หน้าจอบางส่วนให้ตรึงอยู่กับที่ แม้ว่าจะกด Scroll หน้าจอลงไปข้างล่างหรือไปทางขวาได้ วิธีการทำคือให้เลือกช่องแรกที่จะไม่ Lock แล้วกด View-> Freeze Pane

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 20

    จะพบว่าคอลัมน์ทางซ้าย และแถวข้างบนของ cell ที่เราเลือก (คอลัมน์ A-B และ Row 1) จะถูก Lock ให้อยู่กับที่ไว้ เมื่อทำการเลื่อนหน้าจอไปมา นี่คือการ Freeze Pane ที่ถูกต้อง

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 21

    แต่จะเกิดอะไรขึ้น ถ้าเราดันไป Freeze Pane ที่ Cell ขวาล่างมากๆ จนเกือบจะล้นหน้าจอ เช่น R22

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 22

    เพื่อนจะเลื่อนหน้าจอแทบไม่ไปเลย งงแน่นอน เกรียนสุดๆ

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 23

    กับดัก 8 : เปลี่ยน Format วันที่และเวลาให้เป็น General

    Excel นั้นมองวันที่และเวลาเป็นแค่ตัวเลขธรรมดาๆ ตัวนึง ดังนั้นหากเราเลือกข้อมูลที่เป็นวันที่ แล้วลองไปเปลี่ยน Number Format ให้เป็น General ดู พวกวันที่จะกลายเป็นเลข 4 หมื่นกว่าๆ ส่วนเวลาจะกลายเป็นทศนิยมไปเลย ดูแล้วปวดหัวมากมาย

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 24

    วิธีแก้ไข

    แค่เลือก Number Format กลับมาให้เป็นวันที่ก็จบแล้วครับ

    กับดัก 9 : เปลี่ยนความกว้างคอลัมน์ให้เหลือนิดเดียว

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

    เราสามารถเปลี่ยนความกว้างคอลัมน์พร้อมกันหลายๆ คอลัมน์ได้เลย โดยเลือกหลายๆ คอลัมน์แล้วลากเปลี่ยนความกว้างทีเดียว

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 25

    วิธีแก้ไข

    วิธีแก้ไขก็ง่ายมาก แค่ปรับความกว้างคอลัมน์ให้เพียงพอก็จบแล้วครับ อาจใช้การดับเบิ้ลคลิ๊กที่ช่องแบ่งคอลัมน์ก็ได้

    กับดัก 10 : ทำให้พิมพ์อะไรไม่ได้เลยด้วย Data Validation

    ปติแล้วเครื่องมือ Data Validation จะสามารถช่วยให้เราสามารถกำหนดได้ว่าแต่ละ Cell จะยอมให้พิมพ์ข้อมูลแบบไหนลงไปได้บ้าง ซึ่งถ้าพิมพ์ผิดมันจะไม่ยอม

    วิธีแกล้งเพื่อน เราก็แค่เลือกพื้นที่แล้วใส่ Data Validation ที่เพื่อนไม่มีทางจะกรอกถูก เช่น ให้เลือกเป็น List แล้วใส่คำแปลกๆ ลงไป แต่ที่สำคัญให้เอา in-cell Dropdown ออก เพื่อนจะได้ไม่รู้ว่าต้องกรอกอะไร

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 26

    แค่นี้เพื่อนก็จะกรอกอะไรไม่ได้เลย

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 27

    วิธีแก้ไข

    แค่เลือกพื้นที่แล้วเลือก Data Validation แบบ Any Value (กรอกอะไรก็ได้) ก็จบเลยครับ

    กับดัก 11 : Protect Sheet แบบไม่ต้องใส่ Password

    วิธีอันนี้จะทำให้พิมพ์ข้อมูลไม่ได้ในช่องที่ทำการ Lock เอาไว้ ซึ่งตามปกติแล้วทุก Cell ใน Excel จะถูก Lockไว้ตั้งแต่ต้นอยู่แล้ว ดังนั้นเมื่อไหร่ที่ทำการ Activate การ Protect Sheet ขึ้นมาจริงๆ เราจะไม่สามารถแก้ไขอะไรใน Cell ได้เลย

    ดังนั้นวิธีการทำกับดัก ก็แค่ไปที่ Review -> Protect Sheet -> ok จบเลย

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 28

    แค่นี้เพื่อนก็จะไม่สามารถพิมพ์หรือแก้อะไรได้เลย

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 29

    วิธีแก้ไข

    แค่ไปที่ Review -> Unprotect Sheet ก็หายเลยครับ

    Tips : การ Protect sheet ในชีวิตจริง เราจะต้องมาเลือกบาง cell ที่ยอมให้เพื่อนกรอกได้ แล้วเอาการ Lock Cell ออกซะ ก่อนที่จะทำการ Protect Sheet จริงๆ

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 30

    กับดัก 12 : ทำให้แทรกคอลัมน์ แทรกแถวไม่ได้ด้วย Array Formula

    การเขียนสูตรแบบ Array Formula นั้น หากเราเขียนสูตรให้ผลลัพธ์แสดงออกมาหลายช่อง เวลาจะแก้ไขจะไม่สามารถแก้ช่องใดช่องหนึ่งได้ จะต้องแก้ไขโดยเลือกทั้ง Array แล้วแก้ไขเท่านั้น

    เช่น หากเราลองเลือกพื้นที่แล้วใส่สูตรว่า =1 แล้วกด Ctrl+Shift+Enter เพื่อเรียกใช้สูตรแบบ Array

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 31

    พอกด Ctrl+Shift+Enter แล้วจะมีเครื่องหมายปีกกามาครอบสูตรของเราเอง

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 32

    ซึ่งหากเราลองเลือกแค่บางส่วนของสูตร Array แล้วกด ปุ่ม del บน Keyboard เพื่อลบข้อมูล มันจะไม่ยอม โดยจะบอกว่าเราไม่สามารถแก้ไขบางส่วนของ Array ได้

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 33

    ซึ่งก็จะไม่สามารถแทรกแถว หรือ ลบแถว หรือคอลัมน์ เช่นกัน ยกเว้นว่าจะเลือกข้อมูลสูตร Array ทั้งหมดก่อนแล้วกดปุ่ม del บน Keyboard จึงจะลบได้

    ความเลวร้ายคือ หากเราใส่สูตรว่า =”” แล้วกด Ctrl+Shift+Enter เพื่อนจะมองไม่เห็นผลลัพธ์เพราะมันเป็น Array ของ Blank Text

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 34

    เพื่อนจะงงทันทีว่าทำไมเค้าถึงแทรกคอลัมน์ไม่ได้!

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 35

    วิธีแก้ไข

    ให้หา Array ว่างเปล่านั้นให้เจอแล้วลบทิ้งซะ ซึ่งการหา Array ให้เจอมันมีเทคนิคอยู่คือ ให้เลือกทั้งคอลัมน์(ที่เราลองแทรกแล้วไม่ได้) แล้วให้ใช้ Go to Special (Ctrl+g) –> Special ในการหาช่องที่เป็นสูตรก่อน

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 36

    มันจะเด้งมาเลือกช่องนึงที่มีสูตร Array อยู่

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 37

    ให้เรา Go to Special อีกทีแล้วเลือก Current Array (หรือกด Ctrl+/) มันจะเลือกพื้นที่ Array นั้นทั้งหมดให้เลย

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 38

    คราวนี้เราก็สามารถกดปุ่ม del บน Keyboard เพื่อลบ Array นั้นทิ้งได้แล้ว

    กับดัก 13 : ซ่อน Sheet แบบ Very Hidden

    ปกติแล้วเราจะสามารถซ่อน Sheet ใดๆ ที่ต้องการได้โดยกดคลิ๊กขวาที่ tab sheet แล้วเลือก Hide เพื่อซ่อน sheet ที่ต้องการได้เลย แต่วิธีนี้มันก็สามารถ Unhide ได้ง่ายๆ โดยกดคลิ๊กขวา Unhide ได้เลย

    วิธีที่แสบกว่าคือ กด Alt+F11 เพื่อเปิด Visual Basic Editor แล้วซ่อน Sheet แบบ Very Hidden ซะ ดังนี้

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 39

    จากนั้นก็กดปิดเจ้า Visual Basic Editor ซะ

    พอเราคลิ๊กขวาที่ sheet จะพบว่ามันไม่มีอะไรให้ Unhide แล้ว และเพื่อนก็งงทันที!

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 40

    วิธีแก้ไข

    วิธีแก้ก็ต้องกด Alt+F11 เข้าไปยัง Visual Basic Editor แล้วแก้กลับมาเป็น Visible เหมือนเดิม

    13 กับดักสุดเกรียนใน Excel ที่ใครโดนต้องกุมขมับ (พร้อมวิธีแก้ไข) 41

    จบแล้ว

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

  • วิธีเช็คว่าเลขแต่ละหลักเรียงจากน้อยไปมากหรือยัง

    วิธีเช็คว่าเลขแต่ละหลักเรียงจากน้อยไปมากหรือยัง

    อาทิตย์ก่อนหน้ามีแฟนเพจ inbox ถามมาว่า มีวิธีตรวจสอบอย่างไรว่าตัวเลข 5 หลักที่กรอกใน Cell นั้นเรียงจากน้อยไปมากแล้วหรือยัง? ผมคิดว่าเป็นเรื่องที่น่าสนใจ ดังนั้นมาดูวิธีทำกันครับ

    สมมติตัวอย่างเป็นแบบนี้

    วิธีเช็คว่าเลขแต่ละหลักเรียงจากน้อยไปมากหรือยัง 42

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

    ถ้าใช้ Excel 365

    ขั้นตอนแรกคือดึงข้อมูลแต่ละตัวมาพิจารณาด้วย MID เช่น

    =MID(A2,SEQUENCE(LEN(A2)),1)
    วิธีเช็คว่าเลขแต่ละหลักเรียงจากน้อยไปมากหรือยัง 43

    จากนั้นก็ลอง Sort ข้อมูลใหม่ ด้วย SORT

    =SORT(MID(A2,SEQUENCE(LEN(A2)),1))
    วิธีเช็คว่าเลขแต่ละหลักเรียงจากน้อยไปมากหรือยัง 44

    แล้วใช้ CONCAT หรือ TEXTJOIN รวมข้อความอีกที

    =CONCAT(SORT(MID(A2,SEQUENCE(LEN(A2)),1)))
    วิธีเช็คว่าเลขแต่ละหลักเรียงจากน้อยไปมากหรือยัง 45

    CONCAT แล้วจะเป็น Text ยังไงก็ไม่เท่าเลขเดิม ดังนั้นเราบังคับ Text ให้เป็น Number ด้วยการใส่ –นำหน้า แล้วค่อยเอามาเทียบกัน

    =--CONCAT(SORT(MID(A2,SEQUENCE(LEN(A2)),1)))=A2
    วิธีเช็คว่าเลขแต่ละหลักเรียงจากน้อยไปมากหรือยัง 46

    ตัวไหนที่เป็น TRUE คือตัวที่เรียงจากน้อยไปมากแล้วนั่นเอง

    ถ้าใช้ Excel version เก่ากว่า Excel 365

    ถ้าใช้ Excel version เก่า จะไม่มีฟังก์ชันเจ๋งๆ อย่าง SEQUENCE, SORT และ CONCAT ให้ใช้เลย ดังนั้นเราจะใช้แนวทาง คือ ดึงแต่ละคู่มาเทียบกันตรงๆ เลยน่าจะง่ายที่สุด เช่น

    =MID($A5,B$2,1)<=MID($A5,B$3,1)

    จากนั้น copy paste ทั้งตารางได้

    วิธีเช็คว่าเลขแต่ละหลักเรียงจากน้อยไปมากหรือยัง 47

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

    วิธีเช็คว่าเลขแต่ละหลักเรียงจากน้อยไปมากหรือยัง 48

    ตัวที่เป็น TRUE ก็คือมีการเรียงแล้วนั่นเอง

    ชอบวิธีแบบไหนกัน?

    ทีนี้หลายคนอาจคิดว่าวิธีการของ Excel 365 ดูเหมือนจะยากกว่าซะงั้น จริงๆ เป็นเพราะว่ามันยืดหยุ่นมากกว่า เนื่องจากตัวเลขจะมีกี่หลักก็ได้ ในขณะที่วิธีแบบ Excel version เก่านี้ เหมาะกับจำนวนหลักที่แน่นอนมากกว่า

    ที่จริงแล้ว Excel version เก่าก็เขียนสูตรแบบ Array Formula เพื่อให้จำนวนหลักมัน Dynamic ได้แบบเดียวกับ Excel 365 ก็ได้ แต่สูตรที่เขียนจะซับซ้อนขึ้นมากเลยครับ ใครอยากลองฝึกของโหดก็ลองดูได้นะ ^^

  • Excel Array Formula ตอนที่ 2 : การใช้ Array Formula แบบมีเงื่อนไขด้วย IF

    Excel Array Formula ตอนที่ 2 : การใช้ Array Formula แบบมีเงื่อนไขด้วย IF

    ในตอนที่แล้ว เราได้เรียนพื้นฐานของการใช้ Array Formula กันไปแล้ว ในตอนนี้ผมจะใช้ IF และ Boolean Logic มาช่วยสร้างสูตร Array Formula แบบมีเงื่อนไขกันครับ

    ใช้ความเป็น FALSE ของ IF

    วิธีนี้เราจะใช้ IF เช็คเงื่อนไข ถ้ากรณีเป็นจริงจะทำตามที่กำหนด กรณีเป็นเท็จจะปล่อยให้เป็น FALSE ไปเพื่อ Ignore การคำนวณนั้นๆ เช่น กรณีสนใจแค่เพศหญิง ก็ใช้สูตรแบบนี้ได้ (สังเกตว่าเราจะไม่ใส่ value_if_false )

    =IF(C2:C16=E2,B2:B16)
    Excel Array Formula ตอนที่ 2 : การใช้ Array Formula แบบมีเงื่อนไขด้วย IF 49

    ถ้าหากอยากได้ค่าน้อยสุดก็เอา MIN ไปครอบซะ เช่น

    =MIN(IF(C2:C16=E2,B2:B16))

    แค่นี้เราก็สามารถเลียนแบบฟังก์ชัน MINIFS ได้แล้ว แต่มันเจ๋งกว่านั้น เพราะเราใช้ฟังก์ชันอะไรก็ได้

    เราจะใช้ MEDIAN ก็ยังได้ เช่น กรณีสนใจค่า MEDIAN กรณีเป็นผู้ชายก็เขียนสูตรดังนี้ได้

    =MEDIAN(IF(C2:C16=E2,B2:B16))
    Excel Array Formula ตอนที่ 2 : การใช้ Array Formula แบบมีเงื่อนไขด้วย IF 50

    กรณีมีหลายเงื่อนไขแบบ AND

    ใน Array Formula เราจะใช้ฟังก์ชัน AND ตรงๆ ไม่ได้ เพราะมันจะรวบเงื่อนไขทุกตัวเข้าด้วยกันแบบไม่แยก item พิจารณา ถ้ามีตัวใดตัวหนึ่งเป็น FALSE มันจะ FALSE ทันที และให้ผลออกมาค่าเดียวเลย

    เช่น ให้เงื่อนไขคือ เป็นผู้ชาย ที่สูงน้อยกว่า 160 ถ้าใช้ AND จะเป็นดังนี้

    =AND(C2:C16=E2,B2:B16<E5)
    Excel Array Formula ตอนที่ 2 : การใช้ Array Formula แบบมีเงื่อนไขด้วย IF 51

    ถ้าจะใช้เงื่อนไขแบบ AND เราจะใช้ Boolean Logic ด้วยหลักการคูณ ที่ว่า ถ้าตัวใดตัวหนึ่งเป็น FALSE มันจะคูณได้ 0 ทันที การจะออกมาเป็น 1 ได้จะต้องเป็น TRUE ทุกตัวเท่านั้น

    ดังนั้นเราจะเปลี่ยนเงื่อนไขเป็นดังนี้ได้

    =(C2:C16=E2)*(B2:B16<160)
    Excel Array Formula ตอนที่ 2 : การใช้ Array Formula แบบมีเงื่อนไขด้วย IF 52

    จากนั้นก็เอา IF ไปครอบได้ ซึ่งปกติแล้วตรง logical_test ของ IF สามารถเปลี่ยนเลข 0 เป็น FALSE และเลขอื่นเป็น TRUE ได้

    =IF((C2:C16=E2)*(B2:B16<E5),B2:B16)
    array formula condition if

    ที่นี้ถ้าอยากได้การสรุปแบบไหนก็ครอบลงไปอีกทีได้ เช่น หาค่า MEDIAN อีกก็ได้

    =MEDIAN(IF((C2:C16=E2)*(B2:B16<E5),B2:B16))
    Excel Array Formula ตอนที่ 2 : การใช้ Array Formula แบบมีเงื่อนไขด้วย IF 53

    กรณีมีหลายเงื่อนไขแบบ OR

    กรณีเป็นเงื่อนไขแบบ OR ถ้าหากเป็น Array Formula เราก็จะใช้ OR ไม่ได้เช่นกัน ด้วยเหตุผลเดียวกับ AND ว่ามันจะรวบให้เหลือตัวเดียว ดังนั้นเราจะใช้ Boolean Logic แบบบวก (ถ้ามีตัวใดตัวหนึ่งเป็น TRUE บวกกันแล้วจะต้องมากกว่า 0 แน่นอน) เช่น

    เป็นหญิง หรือ สูงน้อยกว่า 160

    =(C2:C16=E2)+(B2:B16<E5) 
    Excel Array Formula ตอนที่ 2 : การใช้ Array Formula แบบมีเงื่อนไขด้วย IF 54

    ทีนี้เราก็เอา IF มาใส่ได้ละ เลข 0 จะเป็น FALSE ส่วนเลขอื่่นจะเป็น TRUE ทั้งหมดเลย

    =IF((C2:C16=E2)+(B2:B16<E5),B2:B16)
    Excel Array Formula ตอนที่ 2 : การใช้ Array Formula แบบมีเงื่อนไขด้วย IF 55

    ทีนี้ถ้าจะหาค่า MEDIAN ก็ครอบลงไปอีกที

    =MEDIAN(IF((C2:C16=E2)+(B2:B16<E5),B2:B16))
    Excel Array Formula ตอนที่ 2 : การใช้ Array Formula แบบมีเงื่อนไขด้วย IF 56

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

  • การใช้ Excel Power Pivot ตอนที่ 5 : การทำรายงาน Actual vs Target

    การใช้ Excel Power Pivot ตอนที่ 5 : การทำรายงาน Actual vs Target

    การใช้ Pivot Table แบบปกตินั้นเวลาเราจะทำรายงานยอดขาย Actual vs Target เราจะทำต้องทำตาราง Pivot แยกกัน 2 อัน แล้วค่อยเอามาเทียบกันด้วยวิธีอะไรบางอย่าง ไม่ว่าจะ Copy Paste หรือ VLOOKUP มาอยู่ข้างๆ กัน แต่ถ้าหากเราใช้ Concept ของ Data Model เราจะสามารถทำรายงาน Actual vs Target ในตาราง Pivot เดียวได้เลย

    โหลดไฟล์ Target

    โหลดไฟล์ Target ได้ที่นี่

    วิธีการทำรายงาน Actual vs Target

    จากหลักการของ Data Model ที่เราเรียนมาในตอนที่แล้ว จะช่วยให้เราสามารถทำรายงาน Actual vs Target ได้โดยง่าย แค่หา Dimension Table ที่ Common กัน ระหว่าง Fact Table ที่เป็น Actual กับค่าตัวเลขของตาราง Target เราก็จะสามารถ Filter ข้อมูลจาก Field ที่อยู่ในตาราง Dimension ที่ Common กันนั้น แล้วส่งผลผ่าน Relationship ไปหาทั้งตาราง Actual และ Target พร้อมๆ กันนั่นเอง

    เช่นข้อมูลในตาราง Target ผมเป็นแบบนี้

    การใช้ Excel Power Pivot ตอนที่ 5 : การทำรายงาน Actual vs Target 57

    จะเห็นว่าข้อมูลที่พอจะนำไปเชื่อมกับ Dimension ที่ Common กับตาราง Actual ได้ก็คือ สินค้า กับเรื่องของวันที่นั่นเอง

    ตอนนี้เรามีตารางสินค้าแล้ว ดังนั้นสิ่งที่เราควรจะทำคือ สร้างตารางวันที่ขึ้นมา

    ตารางวันที่

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

    ซึ่งถ้าเอาละเอียดก็ควรเป็นแบบที่ 1 บรรทัดมี 1 วัน ซึ่งจะสร้างตารางวันที่ใน Excel แล้ว Import เข้า Data Model หรือจะใช้ Power Query สร้างแบบ Dynamic ขึ้นมาก็ได้ (แต่ถ้าใช้ Power BI จะสร้างมารถใช้ DAX แบบ New Table สร้างได้ซึ่งเป็นวิธีที่ง่ายที่สุด)

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

    แต่เพื่อความง่าย ในบทความนี้เราจะทำตารางวันที่ในระดับเดือนละกัน (สมมติว่าในรายงานของเราจะทำสรุปแค่ระดับเดือน)

    ดังนั้นเดี๋ยวผมจะเอาข้อมูลวันที่จาก Target ไปทำเป็นตารางวันที่ซะเลย โดยเดี๋ยวเราจะเปิดไฟล์หลัก (DataModel) แล้วทำการ Get Data จากไฟล์ Target แค่ปีกับเดือน แล้วแยกไปเป็น Query ใหม่ชื่อ DateTable ดังนี้

    มาถึง คอลัมน์ปีมันเว้นว่างไว้ ก็สั่ง คลิ๊กขวา -> Fill Down ซะ แล้ว Remove Other Columns

    การใช้ Excel Power Pivot ตอนที่ 5 : การทำรายงาน Actual vs Target 58

    จากนั้นก็ Add Column -> Column from Example แล้วสร้าง Field ที่เชื่อมปีกับเดือนซะ แบบนี้ ซึ่งมันจะสร้างสูตรให้ว่า

    Text.Combine({Text.From([ปี], "th-TH"), Text.PadStart(Text.From([เดือน], "th-TH"), 2, "0")})
    การใช้ Excel Power Pivot ตอนที่ 5 : การทำรายงาน Actual vs Target 59

    ผมตั้งชื่อคอลัมน์ใหม่นี้ว่า DateKey เป็นอันจบ

    การใช้ Excel Power Pivot ตอนที่ 5 : การทำรายงาน Actual vs Target 60

    จากนั้นก็กด Close&Load to… แบบ Connection Only แต่ให้ติ๊ก Load เข้า Data Model ซะ

    การใช้ Excel Power Pivot ตอนที่ 5 : การทำรายงาน Actual vs Target 61

    จัดการกับ Table Target

    ต่อไปเราจัดการกับไฟล์ Target ให้กลายเป็นข้อมูลเชิง Database ที่เรียบร้อยขึ้นด้วยการ Get Data ใหม่อีกที จากนั้น Fill Down ปี แล้ว Unpivot สินค้าลงมาให้หมด ได้ดังนี้

    การใช้ Excel Power Pivot ตอนที่ 5 : การทำรายงาน Actual vs Target 62

    คราวนี้เราจะไปทำ DateKey ใน Data Model บ้าง ขี้เกียจใช้ Column From Example เหมือนเดิมละ (เปลี่ยนวิธีบ้าง จะได้เห็นวิธีทำหลายๆ แบบเนอะ) ดังนั้นเรา Load Data นี้เข้า Data Model ไปเลย

    การใช้ Excel Power Pivot ตอนที่ 5 : การทำรายงาน Actual vs Target 63

    จากนั้นเราเข้าไปดู Target ใน Power Pivot จะเห็นแบบนี้ (ซึ่งเป็นผลลัพธ์ของ Power Query)

    การใช้ Excel Power Pivot ตอนที่ 5 : การทำรายงาน Actual vs Target 64

    ต่อไปเราจะสร้างคอลัมน์ใหม่ให้เป็น DateKey ด้วย DAX ดังนี้

    DateKey:=Target[ปี]&FORMAT(Target[เดือน],"00")
    • ซึ่งเราจะอ้างอิงคอลัมน์ด้วย ชื่อตาราง[ชื่อคอลัมน์]
    • ฟังก์ชัน FORMAT จะเหมือนกับฟังก์ชัน TEXT ของ Excel มีความสามารถในการแปลง Value ตัวเลขให้เป็น Text ที่มีหน้าตาตาม Custom Number Format ที่กำหนดได้ (ซึ่งผมกำหนดให้เป็นเลข 2 หลัก ด้วย 00)
    • จากนั้นเอามาเชื่อมกันด้วย &
    การใช้ Excel Power Pivot ตอนที่ 5 : การทำรายงาน Actual vs Target 65

    เราทำแบบนี้กับตารางหลัก ซึ่งก็คือ TXDate เช่นกัน

    DateKey:=TXData[ปี]&FORMAT(TXData[เดือน],"00")
    การใช้ Excel Power Pivot ตอนที่ 5 : การทำรายงาน Actual vs Target 66

    จากนั้นมาดู Data Model ที่ Diagram View

    การใช้ Excel Power Pivot ตอนที่ 5 : การทำรายงาน Actual vs Target 67

    0ากนั้นให้ทำการผูก Relationship เพิ่มเติมซะ

    การใช้ Excel Power Pivot ตอนที่ 5 : การทำรายงาน Actual vs Target 68

    จากนั้น Add Measure Total Target เข้าไปในตาราง Target ซะ

    การใช้ Excel Power Pivot ตอนที่ 5 : การทำรายงาน Actual vs Target 69

    แค่นี้เราก็พร้อมจะทำรายงาน Actual vs Target แล้ว

    แค่ต้องลาก Field จากตาราง Dimension ที่ Common กันระหว่างตาราง Actual กัย Target แค่นี้ก็ดูข้อมูลเทียบกันได้แล้ว

    การใช้ Excel Power Pivot ตอนที่ 5 : การทำรายงาน Actual vs Target 70

    ถ้าอยากรู้ว่า Actual ทำได้กี่ % เมื่อเทียบกับ Target ก็สร้าง Measure เพื่อจับหารกันได้ แต่การหารแบบดัก Error ให้เป็น Blank ได้สามารถใช้ฟังก์ชัน DIVIDE ใน DAX มาช่วยได้เลยดังนี้

    =DIVIDE([TotalSales],[TotalTarget])
    การใช้ Excel Power Pivot ตอนที่ 5 : การทำรายงาน Actual vs Target 71

    แค่นี้ก็สามารถแสดง %Achievement ได้แล้ว ไม่ต้อง Copy Paste, ไม่ต้อง VLOOKUP อะไรทั้งสิ้น

    รายงาน actual vs target report

    และนี่ก็คือตัวอย่างการทำรายงานแบบ Actual vs Target ด้วย Power Pivot ครับใครทำตามแล้วสงสัยอะไรก็สามารถ Comment ถามได้นะครับ

    ศึกษา Power Query เพิ่มเติมได้ที่ไหน?

    ในบทความนี้มีการใช้ Power Query มาช่วยจัดการข้อมูลพอสมควร ใครเห็นแล้วสนใจ อยากจะศึกษาให้ลึกซึ้งกว่านี้ สามารถศึกษาได้จาก (เข้าไปดูเนื้อหาบางส่วนได้ฟรี)

    หรือถ้าชอบแบบอ่านหนังสือ ก็ศึกษาได้จาก หนังสือ Excel Power Upได้เลยครับ (สามารถอ่านเนื้อหาฟรีๆ บางส่วนได้ที่นี่)

    สารบัญซีรีส์ Power Pivot

    • การใช้ Excel Power Pivot ตอนที่ 4 : Data Model ทำงานอย่างไร

      การใช้ Excel Power Pivot ตอนที่ 4 : Data Model ทำงานอย่างไร

      ก่อนที่เราจะทำรายงาน Actual vs Target ได้นั้นเราจะต้องมีความเข้าใจเรื่องของ Data Model ซะก่อนว่ามันทำงานยังไง ซึ่งในตอนที่แล้วผมแค่ทำการสร้าง Relationship แล้วทำรายงานให้ดูเฉยๆ แต่ยังไม่ได้อธิบายการทำงานของมันเลย จึงคิดว่าเพื่อเป็นพื้นฐานที่ดี เราควรจะเข้าใจการทำงานของมันอย่างลึกซึ้งยิ่งขึ้นซะก่อน

      สาเหตุที่วิเคราะห์ข้อมูลข้ามตารางได้

      การที่เราสามารถลากข้อมูลจากคนละตารางมาวิเคราะห์ร่วมกันได้ เพราะมันมีการ Filter ข้อมูลข้ามตาราง ผ่านทิศทางของเส้น Relationship ซึ่งสังเกตว่ามันจะวิ่งจาก Dimension Table (ตารางอ้างอิง) ไป Fact Table (ตารางหลัก)

      data model

      เช่น ที่เราลากประเทศลงมา แล้วตัวเลขต่างๆ ใน Pivot สามารถแสดงออกมาได้ถูกต้องตามรูปนี้ มันมีหลักการดังนี้

      การใช้ Excel Power Pivot ตอนที่ 4 : Data Model ทำงานอย่างไร 72

      สมมติเราดูที่ประเทศลาว : การที่ได้เลข TotalSales 24,231 และ Count of TXID 49 มันมาจากอะไร?

      เราต้องอย่าลืม Concept ที่สำคัญที่สุดของการคำนวณทุกอย่างใน Pivot Table นั่นก็คือ

      ข้อมูลแต่ละช่องใน Pivot Table แท้จริงนั้นคำนวณมาจากการ Filter ข้อมูลตามสิ่งที่ระบุใน Rows Label, Column Label, และหัว Filter รวมถึง Slicer (เราเรียกบริบทการ Filter ทั้งหมดที่แต่ละช่องในรายงาน Pivot ต้องเจอว่า Filter Context) จากนั้นค่อยทำการคำนวณตามวิธีที่ระบุในช่อง Values (ซึ่งถ้าเป็น Power Pivot ก็สามารถคำนวณด้วยสูตรใน Measure)

      เทพเอ็กเซลพยายามเน้นเรื่องนี้ตลอดนะ สำคัญมากๆ

      ดังนั้นใน Row Label ที่เป็นของประเทศลาว จึงเปรียบเสมือนว่าเรา Filter ตาราง CustomerCountry ที่คอลัมน์ประเทศ ด้วยค่า “ลาว” ซึ่งจะทำให้เหลือ customer id แค่เบอร์ C00008, C00009, และ C00010 ดังนี้

      การใช้ Excel Power Pivot ตอนที่ 4 : Data Model ทำงานอย่างไร 73

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

      การใช้ Excel Power Pivot ตอนที่ 4 : Data Model ทำงานอย่างไร 74

      จะเห็นว่าเลขที่คำนวณได้จาก Row ที่เหลือจากการ Filter นั้นตรงกับค่าใน Pivot เลย และนี่ก็คือที่มาที่ไปของเลขนั้น

      และถ้าใน Pivot เราลากสินค้า (จากตาราง ProductCost) ลงมาอีก เช่น

      การใช้ Excel Power Pivot ตอนที่ 4 : Data Model ทำงานอย่างไร 75

      หากดูที่ ประเทศลาว สินค้าเป็น dvd หนัง : จะเหลือ TotalSales 8,681 และ Count of TXID 10

      มันก็เปรียบเสมือนมีการ Filter สินค้า ในตาราง ProductCost ให้เป็น dvd หนัง แล้วมันก็จะส่งผลให้ไป Filter ตารางหลักให้เป็น dvd หนังไปด้วยนั่นเอง (เรียกได้ว่ามีการรุมกัน Filter จากทั้ง CustomerCountry และ ProductCost เลยล่ะ)

      การใช้ Excel Power Pivot ตอนที่ 4 : Data Model ทำงานอย่างไร 76

      Field สินค้ามี 2 ที่ ควรลากจากตารางไหน?

      Field สินค้านั้นมีอยู่ทั้งในตาราง ProductCost (Dimension Table) และ TXData (Fact Table) ซึ่งจริงๆ ก็เป็นงี้กับทุกตารางนั่นแหละ

      การจะลาก Field สินค้าจากตาราง ProductCost หรือลาก Field สินค้าจาก TXData ลงมาวิเคราะห์ ณ ตอนนี้จะมีค่าเท่ากัน… เพราะว่ามีการขายสินค้าใน ProductCost ทุกอย่างครบในตาราง TXData จริงๆ

      แต่ถ้าหากว่าในตาราง ProductCost (Dimension Table) มีประเภท Product เยอะกว่า เช่น มี Product บางตัวของบริษัทที่ยังขายไม่ออก (จึงยังไม่มีในตาราง TXData) แบบนี้ผลลัพธ์จะไม่เหมือนกันได้ การจะเห็นภาพชัดกว่าก็ควรลากจากตาราง Dimension มากกว่าที่จะลากจาก Fact Table

      เช่น เราไปเพิ่มสินค้าใน Product Cost ของ sheet Excel แล้ว Refresh ใน Data Model ดังนี้

      การใช้ Excel Power Pivot ตอนที่ 4 : Data Model ทำงานอย่างไร 77
      อันนี้เพิ่มใน Sheet Excel

      จากนั้นไปกด Data -> Refresh All เพื่อให้ Data Model มีการอัปเดท

      ทีนี้หากเราลองไปที่Pivot แล้ว ใส่สินค้าจากตาราง ProductCostไปที่ Row อย่างเดียว (อย่าเพิ่งใส่ Value) จะเห็น item เกมด้วย (ถ้าลากสินค้าจาก TXData จะไม่มีเกม)

      การใช้ Excel Power Pivot ตอนที่ 4 : Data Model ทำงานอย่างไร 78

      แต่พอเราลาก TotalSales ลงมา เกมจะหายไป เพราะปกติแล้วหากค่า Value เป็น Blank มันจะไม่แสดงออกมา

      การใช้ Excel Power Pivot ตอนที่ 4 : Data Model ทำงานอย่างไร 79

      หากเป็น Pivot Table ปกติ เราจะสามารถตั้งค่าให้แสดงแบบ Show item with no data ได้ แต่ใน Power Pivot มันจะติ๊ก option นี้ไม่ได้

      การใช้ Excel Power Pivot ตอนที่ 4 : Data Model ทำงานอย่างไร 80

      ทางนึงที่พอจะแก้ได้คือ ให้เราแก้สูตรใน Measure ให้มันไม่มีทางเป็น Blank ซะเลย เช่น จับบวกเลข 0 ลงไป แค่นี้ก็ไม่มีทาง Blank แล้ว

      ซึ่งเราสามารถไป Edit Measure ที่สร้างไว้แล้วใน Ribbon Power pivot ได้ โดยไปที่ Power Pivot -> Measures -> Manage Measures -> Edit แล้วแก้สูตรโดยบวก 0 เข้าไปซะ

      การใช้ Excel Power Pivot ตอนที่ 4 : Data Model ทำงานอย่างไร 81

      แค่นี้เราก็สามารถแสดงค่า 0 ออกมาได้สบายๆ แล้ว

      การใช้ Excel Power Pivot ตอนที่ 4 : Data Model ทำงานอย่างไร 82

      นอกจากนี้ บางทีเราต้องการจะนับ item แบบไม่ซ้ำด้วย DISTINCTCOUNT เราก็ต้องเลือกให้เหมาะสม

      • ถ้าจะนับสินค้าทุกอย่างที่มีให้ขายก็ควรจะนับจาก Dimension Table
        • =DISTINCTCOUNT(ProductCost[สินค้า])
      • ถ้าจะนับสินค้าที่มีให้ขายแล้วจริงก็ควรจะนับจาก Fact Table
        • =DISTINCTCOUNT(TXData[สินค้า])

      เช่นแบบนี้

      การใช้ Excel Power Pivot ตอนที่ 4 : Data Model ทำงานอย่างไร 83

      หวังว่าเพื่อนๆ จะพอเข้าใจหลักการทำงานของ Data Model มากขึ้นนะครับ ใครไม่เข้าใจตรงไหนก็ comment ถามได้นะ แต่อย่างที่บอกไปหลายครั้งว่า Concept ของ Power Pivot นั้นเหมือนกับ Power BI มาก ใครอยากเจาะลึกก็แนะนำ

      ตอนต่อไป

      ตอนต่อไป เราจะมาเรียนรู้เรื่องการทำรายงาน Actual vs Target กันจริงๆ ละ 555

      สารบัญซีรีส์ Power Pivot

      • ซีรีส์สอนวิธีใช้ Pivot Table ใน 5 นาที

        ซีรีส์สอนวิธีใช้ Pivot Table ใน 5 นาที

        คลิปนี้ผมจะมาสอนการใช้เครื่องมือสรุปผลข้อมูลที่เจ๋งที่สุดใน Excel อย่าง Pivot Table ให้เพื่อนๆ ที่ยังไม่เคยใช้มาก่อนได้รู้จักและใช้มันเป็นภายใน 5 นาทีครับ (ซึ่งน่าจะมีหลายตอนเลยล่ะ ติดตามกันไปยาวๆ นะ)

        สามารถโหลดไฟล์ประกอบได้ที่นี่ : https://github.com/ThepExcel/download… แล้วคลิ๊กคำว่า Download นะ

      • การใช้ Excel Power Pivot ตอนที่ 3 : ลาก่อน VLOOKUP สวัสดี Data Model

        การใช้ Excel Power Pivot ตอนที่ 3 : ลาก่อน VLOOKUP สวัสดี Data Model

        ในตอนนี้เราจะมาเรียนรู้เรื่องของการผูก Data Model ซึ่งก็คือการทำให้ข้อมูลหลายๆ ตารางมาผูกความสัมพันธ์กัน (Relationship) รวมกันเป็นสิ่งที่เรียกว่า Data Model ซึ่งจะช่วยให้เราสามารถดึงข้อมูลจากตารางอื่นมาใช้ Pivot ร่วมกับตารางหลักได้อย่างสบายๆ ไม่ต้องใช้ VLOOKUP อีกต่อไป

        เอาข้อมูลแต่ละตารางเข้าสู่ Data Model

        แนวทางที่ผมอยากแนะนำคือ ให้แปลงข้อมูลเป็น Table ก่อน แล้วตั้งชื่อ Table ซะ แล้วค่อย Add เข้า Data Model ครับ เราจะมาทำทีละตารางกัน (ตารางหลักเราทำไปแล้ว)

        เริ่มจากการ Convert เป็น Table (Ctrl+T) และ ตั้งชื่อ Table ซึ่งผมตั้งว่า SalesBio

        การใช้ Excel Power Pivot ตอนที่ 3 : ลาก่อน VLOOKUP สวัสดี Data Model 84

        Convert และตั้งชื่อให้ครบทุกตารางเลยนะครับ (ยกเว้นตาราง Commission ซึ่งยังยากไปขอข้ามไปก่อน) ตารางอื่นๆ ผมตั้งชื่อดังนี้

        • CustomerCountry
        • ProductCost

        พอตั้งชื่อครบทุกตารางแล้ว ก็ไปที่ Ribbon PowerPivot แล้วกด Add to Data Model ซะ

        การใช้ Excel Power Pivot ตอนที่ 3 : ลาก่อน VLOOKUP สวัสดี Data Model 85

        มันจะเปิดหน้าต่าง PowePivot ขึ้นมา และทำการ Add ตารางที่เราเลือกเข้าไป (ในขณะที่ตาราง TXData อยู่อีก tab นึงทางด้านซ้าย)

        การใช้ Excel Power Pivot ตอนที่ 3 : ลาก่อน VLOOKUP สวัสดี Data Model 86

        ให้เรากดปุ่มรูป Excel เพื่อ Switch to Workbook กลับมายัง Excel ปกติ

        การใช้ Excel Power Pivot ตอนที่ 3 : ลาก่อน VLOOKUP สวัสดี Data Model 87

        จากนั้นก็มา Add ตารางอื่นต่อจนครบ

        การใช้ Excel Power Pivot ตอนที่ 3 : ลาก่อน VLOOKUP สวัสดี Data Model 88

        Tips : จริงๆ แล้วเราสามารถ Add ตารางเข้า Data Model ผ่าน Power Query ก็ได้นะ (ตอน Close & Load to… จะมีให้ติ๊ก) ซึ่งการเอาข้อมูลเข้า Data Model จะไม่ได้ถูกจำกัดจำนวนแถวที่ล้านกว่าแถวเหมือน Excel นะ (เช่น Get Data มาจาก Source อื่นที่มีหลายล้านบรรทัด) แต่เผื่อบางคนยังไม่รู้จัก Power Query ผมยังไม่พูดถึงรายละเอียดละกัน

        สรุปว่าตอนนี้ผมมี 4 ตารางครบแล้วนะ

        การใช้ Excel Power Pivot ตอนที่ 3 : ลาก่อน VLOOKUP สวัสดี Data Model 89

        ผูก Relationship ให้ Data Model

        เมื่อเอาข้อมูลเข้าไปครบแล้ว เราจะไปผูก Relationship ให้กับ Data Model กัน โดยไปที่ Home -> Diagram View

        การใช้ Excel Power Pivot ตอนที่ 3 : ลาก่อน VLOOKUP สวัสดี Data Model 90

        จากนั้นให้เราจัดเรียงตารางหลักให้อยู่ตรงกลาง (จะได้ดูง่ายๆ) แล้วลากความสัมพันธ์เชื่อมแต่ละตารางเข้าด้วยกัน ผ่าน Field ที่เป็นตัวเชื่อม เช่น TXData กับ SalesBio จะเชื่อมกันด้วย “ผู้ขาย” (จะเริ่มการลากจากตารางไหนก็ได้)

        การใช้ Excel Power Pivot ตอนที่ 3 : ลาก่อน VLOOKUP สวัสดี Data Model 91

        จะได้ผลลัพธ์ดังนี้ ซึ่งมีเลข 1 กับ * โผล่มาที่เส้นของ Relationship

        การใช้ Excel Power Pivot ตอนที่ 3 : ลาก่อน VLOOKUP สวัสดี Data Model 92
        • เลข 1 (one) หมายถึง Field ตัวเชื่อมในฝั่งตารางนั้น มีค่าไม่ซ้ำกัน (แต่ละค่ามีตัวเดียว)
          • เราจะเรียกตารางฝั่งที่เป็นเลข 1 ว่าตาราง Dimension Table (หรือตารางอ้างอิง)
        • สัญลักษณ์ * (many) หมายถึง Field ตัวเชื่อมในฝั่งตารางนั้น มีค่าซ้ำกันได้ (แต่ละค่ามีหลายตัว)
          • เราจะเรียกตารางฝั่งที่เป็นเลข 1 ว่าตาราง Fact Table (หรือตารางหลัก ที่เก็บ Transaction จริงๆ ไว้)

        ดังนั้นความสัมพันธ์ระหว่าง SalesBio กับ TXData ก็จะเรียกว่า One-to-Many นั่นเองครับ (ถ้ามองอีกทิศก็เป็น Many-to-One)

        หมายเหตุ : Data Model ของ Excel จะไม่รองรับแบบ Many-to-Many นะครับ (จะต้องสร้าง Table มาเชื่อมตรงกลางอีกที ถึงจะใช้ได้) แนวทางการทำประมาณนี้

        ทีนี้เราก็ลากเชื่อมตารางอ้างอิงทุกอันเข้ากับตารางหลัก ได้ดังนี้

        • ผู้ขาย vs ผู้ขาย
        • สินค้า vs สินค้า
        • ลูกค้า vs customer id (สังเกตว่าชื่อ Field ไม่เหมือนกันก็ได้)
        การใช้ Excel Power Pivot ตอนที่ 3 : ลาก่อน VLOOKUP สวัสดี Data Model 93

        พอลากเชื่อมหมดแล้ว เราสามารถ Switch กลับไปที่ Excel ของเราที่ทำตาราง Pivot เอาไว้แล้ว และไปดูที่ All เพื่อให้มองเห็นทุกตารางได้

        การใช้ Excel Power Pivot ตอนที่ 3 : ลาก่อน VLOOKUP สวัสดี Data Model 94

        สมมติผมจะเอาประเทศลูกค้าลงมาวิเคราะห์ร่วมกันกับตารางหลัก ก็สามารถลากลงมาได้เลย โดยไม่ต้อง VLOOKUP มารวมในตารางเดียวกันเหมือนสมัยโบราณอีกต่อไป (เพราะเราเชื่อมความสัมพันธ์ผ่าน Relationship ของ Data Model แล้ว)

        การใช้ Excel Power Pivot ตอนที่ 3 : ลาก่อน VLOOKUP สวัสดี Data Model 95

        และนี่คือประโยชน์ของการใช้ Data Model ครับ ซึ่งจะช่วยเอาข้อมูลจากหลายๆ ตารางมาวิเคราะห์ร่วมกันได้ ซึ่งคำนวณได้รวดเร็วกว่า VLOOKUP เยอะมาก และรองรับข้อมูลจำนวนมหาศาลได้ด้วย ซึ่ง Concept ของ Data Model ก็แทบจะเหมือนกับใน Power BI เลยล่ะ (แต่ Power BI มีความสามารถมากกว่านิดหน่อย) ใครอยากลงลึกเรื่องนี้ก็ลองไปเล่นใน Power BI ได้นะครับ

        ตอนต่อไป

        ในบทความนี้จะเป็นแค่ Data Model พื้นฐานเท่านั้น ในตอนต่อไปจะเป็นการอธิบายการทำงานของ Data Model อย่างละเอียดมากขึ้นครับ

        สารบัญซีรีส์ Power Pivot

        • การใช้ Excel Power Pivot ตอนที่ 2 : ทำผลสรุป Value ให้เป็นข้อความด้วย DAX

          การใช้ Excel Power Pivot ตอนที่ 2 : ทำผลสรุป Value ให้เป็นข้อความด้วย DAX

          ตามปกติแล้ว ในช่อง Values ของ Pivot Table จะแสดงข้อมูลออกมาได้แค่ตัวเลขเท่านั้นไม่สามารถทำเป็นข้อความได้ ที่เป็นแบบนั้นเพราะมันถูกสรุปด้วยการ Sum, Count, Average, Max, Min ปกติไงล่ะ… แต่ใน Power Pivot เราสามารถเขียน Measure ได้ด้วยฟังก์ชัน DAX อะไรก็ได้ ดังนั้นเราก็สามารถสรุปผลลัพธ์ที่เป็น Text ได้แล้วล่ะ และในบทความนี้ก็จะสอนวิธีทำให้ครับ

          Warning : บทความนี้เริ่มมีความซับซ้อน

          ในบทความนี้อาจมีสูตรหลายตัวที่ค่อนข้างมีความซับซ้อน เพราะเกี่ยวข้องกับ Concept หลายๆ อย่างของ DAX ที่ใน Excel ไม่มี เช่นเรื่องของ Table Function หรือสูตรที่ให้ผลลัพธ์ออกมาเป็นตาราง รวมถึง Concept ของการคำนวณ ซ้ำๆ แต่ละแถวของตารางด้วย Expression ที่กำหนด (เรียกว่า Iterate) ซึ่งค่อนข้างใช้จินตนาการสูงพอควร

          การจะเข้าใจอย่างลึกซึ้งว่ามันทำงานยังไง คุณอาจต้องศึกษาการทำงานของ DAX เพิ่มเติมด้วยนะครับ เพราะมันอธิบายสั้นๆ ได้ยากพอควร

          ซึ่ง Tips ที่ผมอยากแนะนำ คือ เรียน DAX ผ่าน Power BI จะง่ายกว่า Excel เพราะใน Power BI มีตัวช่วยเยอะกว่า ซึ่งเรียนใน Power BI แล้วสุดท้ายก็เอามาใช้ใน Excel ได้อยู่ดี (ผมเองก็เรียน DAX จาก Power BI เหมือนกัน แล้วตอนนี้ผมก็เอามาใช้ใน Excel ได้)

          หากใครสนใจ ใครสนใจก็ลองไปดูได้ครับ (ตอนนี้กำลังลดราคาพิเศษอยู่ด้วย จาก 2290 เหลือ 1790 บาท หมดเขต 29 กค. 63)

          เอาล่ะ หมดช่วงขายของแล้ว มาเริ่มสิ่งที่น่าสนใจกันจริงๆ ดีกว่า 555

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

          เอา Transaction ID ล่าสุดมาแสดง

          เราสามารถใช้ฟังก์ชัน LASTNONBLANK มาช่วยในกรณีนี้ได้ครับ

          LASTNONBLANK ( <ColumnName>, <Expression> )

          LASTNONBLANK จะทำงานแบบ Iterator เช่นเดียวกับพวก SUMX แต่มีความสามารถในการเช็ค Expression สำหรับแต่ละแถวของ <ColumnName> โดยเรียงตาม Sort Order ของ Column นั้นๆ แล้วเอาค่าสุดท้ายที่ <ColumnName> และ <Expression> ไม่ Blank กลับมา ซึ่งผลลัพธ์จะกลับมาเป็นตารางที่มี 1 แถว 1 คอลัมน์

          Tips : เมื่อ DAX ให้ผลลัพธ์เป็นตารางที่มี 1 แถว 1 คอลัมน์ มันสามารถถูกมองให้เป็นผลลัพธ์เป็น Scalar Value หรือค่าตามปกติได้ด้วย แปลว่าผมสามารถแสดงผลลัพธ์ด้วยค่านี้ได้เลย

          แปลว่าผมสามารถให้มันเอาเลข TXID ล่าสุดมาได้เพราะว่า TXID เราเรียงเป็นเลข Running อยู่แล้วจึงใช้ได้

          =LASTNONBLANK(TXData[TXID], TXData[TXID])

          หรือจะใส่ <Expression> เป็นเลข 1 ไปเลยก็ยังได้ครับ เพื่อให้มันเช็คแค่ TXData[TXID] อย่างเดียว

          =LASTNONBLANK(TXData[TXID],1)

          แค่นี้เราก็จะได้ Transaction ID ล่าสุดแล้วล่ะ 555

          การใช้ Excel Power Pivot ตอนที่ 2 : ทำผลสรุป Value ให้เป็นข้อความด้วย DAX 96

          ถ้าเกิดใครอยากได้ Transaction ID แรกสุด ก็จะมีตัวคล้ายๆ กันให้ใช้ นั่นก็คือ FIRSTNONBLANK ( <ColumnName>, <Expression> ) นั่นเองครับ

          เอา Product ล่าสุดมาแสดง

          สำหรับ “ชื่อProduct” เราไม่สามารถใช้ LASTNONBLANK มาช่วยได้ เพราะ คอลัมน์ “ชื่อProduct” มันเรียงตาม A-Z (เมื่อคอลัมน์นี้ไม่ได้เรียงตามเวลา คำว่า LAST เมื่อใช้กับชื่อProduct มันจึงไม่มี concept ของคำว่า “ล่าสุด” ) แต่เราจะเอาเจ้า [TXID ล่าสุด] ที่ได้จากข้อที่แล้วมาช่วยทำงานต่อไปด้วยการใช้ LOOKUPVALUE แบบนี้

          LOOKUPVALUE ( <Result_ColumnName>, <Search_ColumnName>, <Search_Value>)

          LOOKUPVALUE สามารถเอาผลลัพธ์ในคอลัมน์ <Result_ColumnName> ที่ต้องการกลับมา โดยค้นหาข้อมูล <Search_Value> ในคอลัมน์ <Search_ColumnName> นั่นเอง

          ซึ่งจะเห็นว่า Concept การเขียนสูตรคล้ายๆ ฟังก์ชัน LOOKUP ใน Excel เลย แต่ LOOKUPVALUE มันต้องเจอผลลัพธ์แบบเป๊ะๆ เท่านั้น ต่างจาก LOOKUP ใน Excel ที่ทำการค้นหาแบบ Approximate Match นะ

          สรุปแล้ว ใน เคสนี้เราเขียนได้ว่า

          =LOOKUPVALUE(TXData[สินค้า],TXData[TXID],[TXID ล่าสุด])

          แปลว่าให้เอา [TXID ล่าสุด]ไปหาในคอลัมน์ TXData[TXID] จากนั้นให้เอาค่า TXData[สินค้า] ในแถวเดียวกันกลับมา

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

          สรุป Value ข้อความ Text

          เอาชื่อลูกค้าทุกคนมารวมกันแยกด้วยตัวคั่น

          เราสามารถใช้ฟังก์ชัน CONCATENATEX มาช่วยรวมข้อมูล Text แล้วใส่ Delimiter เป็น ได้ ซึ่งมันจะทำงานคล้ายๆ SUMX แต่ต่างกันที่ตอนจบ ตรงที่ SUMX เอาข้อมูลใน Expression ทุกตัวมา SUM กัน แต่เจ้า CONCATENATEX นั้นเอา Expression ทุกตัวมาเชื่อมเป็นข้อความเดียวกันแล้วคั่นด้วย Delimiter ซึ่งสามารถเรียงลำดับการเชื่อมได้ด้วยนะ

          CONCATENATEX ( <Table>, <Expression>, [<Delimiter>] , [<OrderBy_Expression>] , [<Order>] )
          • ฟังก์ชันนี้จะทำการ Iterate แต่ละแถวของ <table> ด้วยการเอา <expression> มาเชื่อมกันด้วย [delimiter]
          • สำหรับ <table> นั้นเราใช้อีกฟังก์ชัน นั่นคือ DISTINCT มาช่วย ซึ่งมีความสามารถทำให้เหลือเฉพาะ item ที่ไม่ซ้ำกันเท่านั้นแล้วคืนค่ากลับมาเป็นตาราง (เรียกว่า Table Function ซึ่งใน DAX มีหลายตัวมากๆ)
          • โดยในที่นี้ใส่เป็น DISTINCT(TXData[ลูกค้า]) เพื่อให้ได้รายชื่อลูกค้าแบบไม่ซ้ำกันนั่นเอง

          สรุปแล้ว เราจะเขียนสูตรแบบนี้

          =CONCATENATEX(DISTINCT(TXData[ลูกค้า]),[ลูกค้า],"/")
          การใช้ Excel Power Pivot ตอนที่ 2 : ทำผลสรุป Value ให้เป็นข้อความด้วย DAX 97

          ถ้าอยากให้เรียงตามคอลัมน์ลูกค้าเอง (ซึ่งก็เรียงตาม A-Z) ก็สามารถระบุคอลัมน์ที่ใช้ Sort ได้ และวิธีการ Sort ได้

          =CONCATENATEX(DISTINCT(TXData[ลูกค้า]),[ลูกค้า],"/",[ลูกค้า],ASC)
          การใช้ Excel Power Pivot ตอนที่ 2 : ทำผลสรุป Value ให้เป็นข้อความด้วย DAX 98

          List ชื่อลูกค้าที่สร้างยอดขายมากสุด Top3

          เราสามารถใช้ TOPN มาช่วยสร้างผลลัพธ์เป็น Table ที่ Filter ให้เหลือผลลัพธ์ N ตัวเรียงตาม <OrderBy_Expression> ได้ดังนี้

          TOPN ( <N_Value>, <Table> , [<OrderBy_Expression>] , [<Order>] )

          จากนั้นเอาไปใช้ในส่วนของ <table> ของ CONCATENATEX

          =CONCATENATEX(TOPN(3,DISTINCT(TXData[ลูกค้า]),[TotalSales],DESC),[ลูกค้า],"/",[TotalSales],DESC)

          และเราสามารถรวมยอดขายเฉพาะ TopN Customer ได้ด้วยการใช้ SUMX มาช่วยดังนี้

          =SUMX(TOPN(3,DISTINCT(TXData[ลูกค้า]),[TotalSales],DESC),[TotalSales])

          ตัว [TotalSales] จะถูกคิดสำหรับข้อมูลแต่ละแถวของ TOPN ซึ่งจะเกิด Effect ที่เรียกว่า Context Transition ที่จะช่วยให้คิดข้อมูลเป้นยอดขายของลูกค้าแต่ละคนนั้นๆ ได้

          สรุปออกมาได้ดังนี้

          การใช้ Excel Power Pivot ตอนที่ 2 : ทำผลสรุป Value ให้เป็นข้อความด้วย DAX 99

          อย่างไรก็ตามคำสั่ง TOPN ถ้าเกิดมีลูกค้ายอดขายเท่ากันเป๊ะ มันอาจจะออกมามากกว่า N ที่เรากำหนดก็ได้ เช่น

          Sales ค ขายของเล่น มีลูกค้าที่มียอดเท่ากันดังรูป

          การใช้ Excel Power Pivot ตอนที่ 2 : ทำผลสรุป Value ให้เป็นข้อความด้วย DAX 100

          ทำให้ Sales ค ขายของเล่น มัน List ออกมา 4 คน คือ C00004, C00011, C00012, C00013 และได้ยอดรวม TOPN 3,150 บาท

          ถ้าเราอยากได้ TOP3 แบบที่ได้ 3 จริงๆ ไม่ให้เกินมา

          จะต้องมีการจัดการเรื่องค่าซ้ำ เช่น วิธีที่ง่ายที่สุดคืออาจจะบวกค่า Random ที่น้อยมากๆ เข้าไปเพื่อให้ไม่มีเลขที่เท่ากันเป๊ะๆ เช่น

          Listลูกค้าTop3 (แบบได้ 3 จริงๆ)

          =CONCATENATEX(TOPN(3,DISTINCT(TXData[ลูกค้า]),[TotalSales]+RAND()/1000,DESC),[ลูกค้า],"/",[TotalSales],DESC)

          Top3CustSales (แบบมาจาก 3 คนจริงๆ)

          =SUMX(TOPN(3,DISTINCT(TXData[ลูกค้า]),[TotalSales]+RAND()/1000,DESC),[TotalSales])

          สรุปแล้วจะได้แบบนี้

          การใช้ Excel Power Pivot ตอนที่ 2 : ทำผลสรุป Value ให้เป็นข้อความด้วย DAX 101

          Sales ค ขายของเล่น จะได้แค่ 3 คน คือ C00004, C00011, C00012 (ซึ่งจะได้ 12 หรือ 13 มันสุ่มเอานะ…)

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

          ตอนต่อไป

          ในตอนต่อไปเริ่มจะเริ่มทำงานกับตารางที่มากกว่า 1 อัน โดยที่ตารางหลายๆ อันนั้นจะมีการเชื่อมความสัมพันธ์กันเป็นสิ่งที่เรียกว่า Data Model นั่นเอง ใช่แล้วล่ะ เรากำลังจะได้เรียนสิ่งที่เป็น Data Model กันจริงๆ ซักที แล้วคุณจะได้เห็นพลังที่แท้จริงของสิ่งที่เรียกว่า Data Model ว่ามันเจ๋งแค่ไหนครับ

          สารบัญซีรีส์ Power Pivot

          • การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน

            คงปฏิเสธไม่ได้ว่า Pivot Table นั้นเป็นเครื่องมือสรุปข้อมูลที่ใช้ง่ายที่สุดของ Excel (จริงๆ ผมว่าถ้าเทียบกับโปรแกรมอื่น Pivot ก็ยังง่ายและเจ๋งกว่าอยู่ดี) ซึ่งการใช้ Pivot Table แบบทั่วๆ ไปก็สามารถตอบโจทย์การทำงานได้มหาศาลแล้ว อย่างไรก็ตาม ก็ยังมีงานบางอย่าง ที่ Pivot Table ธรรมดายังตอบโจทย์ไม่ได้ แต่ต้องใช้ Power Pivot แทน เช่น

            1. การนับข้อมูลแบบไม่ซ้ำ เช่น นับจำนวนลูกค้า, จำนวนวันที่ที่ขายของ, จำนวน sales, จำนวนประเภทสินค้า
            2. การทำ Calculated Field ที่ไม่ใช่การ SUM
            3. การแสดงข้อมูลสรุปในช่อง Value ออกมาเป็น Text เช่น แสดงชื่อลูกค้าคนล่าสุด แสดงรายการสินค้าออกมาคั่นด้วย comma แสดงสินค้าขายดี Top3
            4. การวิเคราะห์ข้อมูลเทียบกับช่วงเวลาก่อนหน้า
            5. การวิเคราะห์ข้อมูลจากหลายตาราง เช่น การเอาค่าจากอีกตารางมาโดยไม่ต้อง VLOOKUP, การคำนวณ Actual vs Target

            นี่คือตัวอย่างของสิ่งที่Pivot ธรรมดาๆ ทำไม่ได้…

            แต่ว่าไม่ต้องเสียใจไป เพราะจริงๆ แล้วถ้าเราใช้ Pivot Table อีกโหมดนึงที่เรียกว่าโหมด Data Model ซึ่งจะทำให้ Pivot Table ธรรมดากลายเป็น Power Pivot ซึ่งจะมีความสามารถเพิ่มขึ้นมหาศาลใกล้เคียงกับความสามารถของ Power BI เลยล่ะ

            อย่างไรก็ตาม Excel ที่จะใช้ Data Model และ Power Pivot ได้จะต้องเป็น Excel 2010 ขึ้นไปเท่านั้นนะครับ เก่ากว่านี้หมดสิทธิ์ ซึ่งถ้าเป็น 2013 ขึ้นไปจะมีโหมด Data Model ให้ใช้ในตัว แต่ถ้าเป็น Excel 2010 จำเป็นต้องโหลด Add-in Power Pivot มาใช้ซะก่อน

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

            เตรียมความพร้อม Data Model / Power Pivot

            คนที่ใช้ Excel 2010 ให้ไปโหลด Add-in Power Pivot นี่แล้ว Install ซะ มันจะมี Ribbon Power Pivot โผล่ออกมาให้ใช้ครับ

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 102

            คนที่ Version ใหม่กว่า 2010 ก็ให้ไป Enable Power Pivot add-in ซะก่อน โดยไปที่ File -> Options -> Add-in -> Com Add-ins -> Go

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 103

            จากนั้นก็เลือก Power Pivot ซะ

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 104

            หลังจาก ok ไปจนครบ ก็จะมี Ribbon Power Pivot มาให้ใช้แล้ว

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 105

            โหลดไฟล์ประกอบได้ที่นี่

            โหลดผ่าน GitHub

            ก่อนอื่นเรามาดูวิธีเรียกใช้ Pivot Table โหมด Data Model กันครับ

            วิธีเรียกใช้ Pivot Table โหมด Data Model

            การเอาข้อมูลเข้าสู่โหมด Data Model นั้นทำได้ 3 วิธี นั่นคือ

            1. เอาเข้าด้วย Pivot Table (ผ่านการติ๊กเลือก Option ล่างสุดตอนสร้าง Pivot)
            2. นำเข้าผ่านเครื่องมือ Power Pivot ในคำสั่ง Add to Data Model
            3. นำเข้าผ่าน Power Query โดย Load To.. Connection Only แล้วติ๊ก Add to Data Model
            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 106

            หากใช้ข้อมูลเพียงตารางเดียวจากชีท TXData การเอาเข้าผ่าน Pivot Table ไปเลยจะง่ายที่สุดเลย

            Tips : ก่อนจะเอาข้อมูลเข้าไปวิเคราะห์ใน Pivot Table เพื่อให้ในอนาคตชีวิตสบายขึ้น ควรแปลงข้อมูลนั้นให้เป็น Table ก่อน ด้วยการกด Insert -> Table เพื่อให้ตัว PivotTable สามารถอ้างอิงข้อมูลจาก Data Source ที่ขยายอาณาเขตตัวเองตามข้อมูลใหม่ที่ใส่เพิ่มได้โดยอัตโนมัติ ซึ่งผมตั้งชื่อ Table นี้ว่า TXData ละกัน (แต่ขั้นตอนนี้ไม่ได้จำเป็นกับการทำ Data Model นะ)

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 107

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

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 108

            พอแปลงเป็น Table แล้วให้เลือกข้อมูลที่จะเอาเข้า Pivot Table แล้วกด Insert -> Pivot Table ตามปกติ แต่ให้ติ๊ก Add this Data to the Data Model ด้วย (สำคัญมากกกกกก)

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 109

            พอกด ok เราจะได้ PivotTable โหมดพิเศษที่เป็น Mode Data Model ขึ้นมาแล้ว ซึ่งหน้าตาแทบจะเหมือน Pivot Table ธรรมดาๆ เลย แต่มีความต่างตรงที่ผมตีกรอบให้ดู

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 110

            เอาล่ะเรามาเริ่มทำอะไรเจ๋งๆ ที่ Pivot Table ปกติทำไม่ได้กัน

            ความเจ๋ง 1 : นับข้อมูลแบบไม่ซ้ำ

            ปกติแล้วเวลาเราลากข้อมูลเข้ามา Count ใน Pivot มันก็จะรับแค่ว่าคอลัมน์ที่เราเลือกมีข้อมูลอยู่กี่ตัว ไม่ได้สนว่าซ้ำรึเปล่า (ซึ่งส่วนใหญ่จะซ้ำกระจาย) เช่น ลากลูกค้าลงมาดูคู่กับสินค้าและผู้ขาย เพื่อดูว่ามีลูกค้ากี่คนที่ซื้อสินค้านั้นๆ โดยผู้ขายคนนั้นๆ (ผมกดเปลี่ยน Report Layout เป็น Tabular Form จะได้เห็นชื่อ Field ชัดๆ)

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 111

            จะเห็นว่าตรงช่องที่ผมทาสีเหลือง มัน Count ลูกค้าได้ 27 แบบนี้ หลายคนอาจตีความว่า มีลูกค้า 27 คนที่ซื้อของเล่นที่ขายโดย sales ง รึเปล่า?

            ถ้าเราดับเบิ้ลคลิ๊กที่เลข 27 จะเห็นชัดเลย ว่าลูกค้าที่มันเอามานับนั้นซ้ำกระจาย (แค่เบอร์ 14 ก็ซ้ำไป 3 รอบแล้ว)

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 112

            และถ้าเราอยากจะนับแบบไม่ซ้ำจะทำยังไงล่ะ?

            คำตอบง่ายมาก แค่กลับไปที่ Pivot แล้วเปลี่ยนวิธีสรุปข้อมูลจาก Count ธรรมดาๆ เป็น Distinct Count ก็จบเลย (แต่มันอยู่ใน More Options… นะ)

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 113
            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 114

            ซึ่งพอกด ok เราก็จะได้จำนวนลูกค้าแบบไม่ซ้ำกันแล้ว ซึ่ง PivotTable โหมดปกติจะทำอะไรแบบนี้ไม่ได้เลยนะ

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 115

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

            เช่นในปี 2020 หนังสือมีการขายแค่ 11 เดือน ในขณะที่ตัวอื่นขายครบ 12 เดือน

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 116

            ความเจ๋ง 2 : การทำ Calculated Field ที่ไม่ใช่การ SUM ด้วย Measure

            ปกติแล้วเวลาเราใช้ Calculated Field ใน Pivot Table นั้น สูตรที่เราเขียน มันจะใช้การสรุปผลด้วยการ Sum เท่านั้น ไม่สามารถเปลี่ยนเป็น Count, Max, Min อะไรได้เลย

            แต่ถ้าเราใช้ Mode Data Model แล้ว Calculated Field จะง่อยกว่าเดิม! เพราะมันใช้ไม่ได้เลยเนื่องจากหลายเป็นสีเทาไปแล้ว…

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 117

            แต่ไม่ต้องเสียใจไป ที่มันเป็นสีเทาเพราะมันมีตัวที่เจ๋งกว่าให้ใช้ นั่นก็คือ Measure นั่นเอง (ซึ่งคือตัวเดียวกับ Power BI)

            วิธีการเรียกใช้ Measure ให้คลิ๊กขวาที่ชื่อตารางใน Pivot Field List แล้วกด +Add Measure… (ถ้าคลิ๊กขวาแล้วไม่มีก็ไปเลือกใน Ribbon Power Pivot ตามวิธีถัดไป)

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 118

            นอกจากการกด +Add Measure เราจะไปกดใน Ribbon Power Pivot ก็ได้นะครับ (เมนูจะเจ๋งกว่าด้วย เพราะมีสีสวยงามตอนเขียนสูตร)

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 119

            ในที่นี้ผมจะกดสร้าง Measure ผ่านเมนูของ Power Pivot ละกันนะครับ เพราะมีตัวช่วยเยอะกว่า

            พอกดสร้าง Measure ปุ๊ป จะเห็นช่องให้ใส่สูตร ถ้าเรากดปุ่ม fx มันจะ List ฟังก์ชันที่ใช้ได้ขึ้นมาเพียบเลย ซึ่งไม่ได้มีแค่ SUM แล้วเนอะ

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 120

            ฟังก์ชันที่ใช้ได้นี้เป็นสูตรเฉพาะที่เรียกว่า DAX (Data Analysis eXpression) ซึ่งเป็นภาษาที่ใช้ใน PowerPivot กับ Power BI และพวก Analysis Service ต่างๆ ซึ่งมีความคล้ายกับฟังก์ชันใน Excel ของเรามากเลย หลายๆ ฟังก์ชันที่เรารู้จักใน Excel ก็สามารถนำมาใช้ในนี้ได้ และก็มีหลายๆ ฟังก์ชันถูกใส่เข้ามามากกว่าใน Excel ปกติ เพื่อใช้ในการวิเคราะห์ข้อมูลโดยเฉพาะ

            ยกตัวอย่างเช่น การนับลูกค้าแบบไม่ซ้ำ นอกจากใช้คำสั่ง Distinct Count ใน Summarize Value By… เราก็ยังสามารถใช้ฟังก์ชัน DISTINCTCOUNT ใน DAX มาช่วยได้

            วิธีเขียนสูตรคือ ให้พิมพ์ชื่อฟังก์ชันแล้วกด Tab เลือกเอา มันจะมีตัวช่วยขึ้นมาว่าจะ DISTINCTCOUNT คอลัมน์ไหน

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 121

            เราก็เลือกว่า DISTINCTCOUNT(TXData[ลูกค้า] แล้วอย่าลืมพิมพ์วงเล็บปิดด้วย สรุปได้สูตรนี้

            =DISTINCTCOUNT(TXData[ลูกค้า])

            พอกด ok มันก็จะสร้าง Measure ขึ้นมาใหม่ และ add เข้า Pivot ให้เราเลย (ถ้ามันยังไม่ add ให้ก็ลากมาใส่เองได้)

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 122

            นอกจากการ DistinctCount แล้ว มันยังทำเรื่องต่างๆ ได้อีกมากมาย เช่น เราจะสร้างยอดขายรวมขึ้นมาโดยไม่ต้องมีคอลัมน์ยอดขายในตารางจริง แต่จะใช้คอลัมน์จำนวนชิ้น * ราคาต่อชิ้น แล้ว SUM ด้วย SUMX

            เรียนรู้ SUMX

            SUMX(<table>, <expression>)

            SUMX จะใช้สูตร <expression> ที่ระบุลงไปในแต่ละแถวของตาราง <table> (เรียกว่า Iterate) แล้วสุดท้ายค่อย SUM ซึ่งจะคล้ายๆกับสูตร SUMPRODUCT ใน Excel แต่ยืดหยุ่นกว่ามากๆ

            เราจะให้ <table> เป็นตาราง TXData ของเรานี่แหละ ส่วน <expression> เราจะเอา จำนวนชิ้น * ราคาต่อชิ้น

            ดังนั้นสูตรออกมาจะเป็นดังนี้

            =SUMX(TXData,TXData[ราคาต่อชิ้น]*TXData[จำนวนชิ้น])

            ซึ่งเราสามารถเลือก Number Format ให้ Measure นั้นๆ ได้เลยด้วย

            Power Pivot

            แค่นี้เราก็จะได้ยอดขายรวมแล้ว

            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 123

            หายอดขายเฉลี่ยต่อลูกค้า

            ยกตัวอย่างเช่น หากเราต้องการจะแสดงยอดขายเฉลี่ยต่อลูกค้า 1 คน เราก็สามารถเขียนสูตรโดยเอาเลขสรุป 2 ค่ามาหารกัน

            • ให้ตัวเศษ = ยอดขายรวม
            • ตัวส่วน = จำนวนลูกค้า(แบบไม่ซ้ำ)

            ซึ่งความเจ๋งของ Measure คือ มันอ้างอิง Measure ที่มีอยู่แล้วได้ ด้วยการใส่ [ชื่อMeasure]

            ดังนั้นเราจะเขียนสูตรแบบนี้ได้เลย

            =[TotalSales] / [จำนวนลูกค้าแบบไม่ซ้ำ]
            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 124
            การใช้ Excel Power Pivot ตอนที่ 1 : การใช้งานพื้นฐาน 125

            และนี่ก็คือตัวอย่างของการเริ่มหัดใช้ Power Pivot แบบง่ายๆ เดี๋ยวตอนต่อไปจะเริ่มซับซ้อนขึ้นแล้ว

            ถ้าอยากปูพื้นฐานก่อน…

            ถ้าใครอ่านบทความนี้แล้วรู้สึกว่าอยากจะมีความรู้ PivotTable ให้ดีกว่านี้ เพราะยังไม่เข้าใจบางจุด ก็สามารถไปศึกษาคอร์สออนไลน์ของผมได้นะครับ ซึ่งดูตอนไหนก็ได้ กี่รอบก็ได้ ไม่มีหมดอายุ แถมยังอัปเดทเนื้อหาให้เรื่อยๆ อีก (ขอโฆษณาซะหน่อย 555)

            ตอนต่อไป

            จะมาดูวิธีทำให้ช่อง Value ของ Pivot สามารถแสดงข้อความได้กันครับ

            สารบัญซีรีส์ Power Pivot

            • เรียน Calculus ด้วย Excel ตอนที่ 3 : Optimization หาจุดสูงสุด จุดต่ำสุด

              เรียน Calculus ด้วย Excel ตอนที่ 3 : Optimization หาจุดสูงสุด จุดต่ำสุด

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

              การทำ Optimization ด้วยการหาอนุพันธ์

              เวลาเรามีฟังก์ชันอะไรซักอย่าง แล้วอยากจะหาว่าจุดสูงสุดหรือจุดต่ำสุดในช่วงที่สนใจอยู่ที่ตำแหน่งไหน? เราจะทำยังไงกับมันได้บ้าง?

              ก่อนจะไปหาค่าที่ทำให้เกิด “จุดสูงสุด” หรือ “จุดต่ำสุด” เราไปรู้จักอีกคำนึงก่อน นั่นก็คือ Critical Value หรือ ค่า x ที่ทำให้เกิดจุดวกกลับ (Extreme Point) ของเส้นกราฟซะก่อน

              optimization maximize minimize

              ซึ่งจุดวกกลับก็จะมี 2 ลักษณะอีกคือ

              • ถ้าความชันของกราฟเปลี่ยนจากบวก ไป0 แล้ว ไปลบ แสดงว่าจุดวกกลับนั้นเป็นแบบตัว A ซึ่งก็น่าจะทำให้เกิดจุดต่ำสูงสุด
              • ถ้าความชันของกราฟเปลี่ยนจากลบ ไป0 แล้ว ไปบวก แสดงว่าจุดวกกลับนั้นเป็นแบบตัว U ซึ่งก็น่าจะทำให้เกิดจุดต่ำสุด

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

              จาก y=x^3-10x^2

              เมื่อ Diff แล้วจะได้แบบนี้

              y'=3x^2-20x

              เดี๋ยวผมลอง Plot กราฟดู

              เรียน Calculus ด้วย Excel ตอนที่ 3 : Optimization หาจุดสูงสุด จุดต่ำสุด 126

              จะเห็นชัดเลยว่าจุดวกกลับนั้นมีค่า y’ เป็น 0 จริงๆ

              ดังนั้นเราเอา 3x^2-20x=0 แล้วแก้สมการ

              แยกตัวประกอบเทียบกับ 0

              x(3x-20)=0

              จะได้ว่า

              • x=0 หรือ
              • 3x-20=0 ซึ่ง x=20/3 = 6.667 นั่นเอง

              ทีนี้ถ้าเราอยากจะ Test ว่า จุดที่เราแก้สมการมาได้ เช่น x=0, x= 6.6667 นั้น จุดไหนเป็นประเภทจุดวกกลับแบบไหน เป็นแบบจุดสูงสุด หรือ ต่ำสุด โดยไม่อยาก Plot กราฟออกมา หรือไม่อยากจะมานั่งดูค่าบริเวณใกล้เคียง เราก็สามารถทดสอบได้จากการหาค่า y” ที่จุด x นั้นๆ นั่นเอง

              เรียน Calculus ด้วย Excel ตอนที่ 3 : Optimization หาจุดสูงสุด จุดต่ำสุด 127
              • ถ้าค่า y” ที่ x นั้นๆ มากกว่า 0 =ความชัน (y’) มีอัตราการเปลี่ยนแปลงเป็นบวก (แปลว่า ความชันเพิ่มจาก – 0 + ) แสดงว่าเป็นจุดวกกลับแบบต่ำสุด (ชันจาก – 0 + คล้าย กับว่าถึงเวลาที่เป็นขาขึ้นแล้วนั่นเอง )
              • ถ้าค่า y” ที่ x นั้นๆ น้อยกว่า 0 =ความชัน (y’) มีอัตราการเปลี่ยนแปลงเป็นลบ (แปลว่า ความชันเพิ่มจาก + 0 – ) แสดงว่าเป็นจุดวกกลับแบบสูงสุด

              ในกรณีตัวอย่างของเรา ที่จุดที่แก้สมการมาได้ 2 ตัว

              • ที่จุด x=0 , y” =-20 ซึ่งเป็นลบ แสดงว่าเป็นจุดวกกลับแบบจุดสูงสุด
              • ที่จุด x=6.667, y”=20 ซึ่งเป็นบวก แสดงว่าเป็นจุดวกกลับแบบจุดต่ำสุด

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

              • จุดวกกลับที่เป็นประเภทสูงสุดทั้งหมด เรียกว่าเป็น จุดสูงสุดสัมพัทธ์ (Relative Maximum หรือ Local Maximum)
                • ในกราฟ y คือจุดที่ x=0,y=0
                • ในกราฟ y’ ไม่มี เพราะไม่มีจุกวกกลับรูปตัว A เลย
              • จุดวกกลับที่เป็นประเภทต่ำสุดทั้งหมด เรียกว่าเป็น จุดต่ำสุดสัมพัทธ์ (Relative Minimum หรือ Local Minimum)
                • ในกราฟ y คือ จุดที่ x=6.667, y=-148.148
                • ในกราฟ y’ คือ จุด x=3.333, y’= -33.33
              • คำว่าสัมพัทธ์ พูดง่ายๆ ก็คือ เมื่อลองเทียบกับบริเวณข้างๆ แล้วเป็นยังไง

              ทีนี้มาดูแบบสัมบูรณ์กันบ้าง

              • แต่ถ้าจุดใดที่ฟังก์ชันมีค่ามากที่สุดจริงๆ เมื่อเทียบกับทุกจุด แบบนี้เรียกว่า จุดสูงสุดสัมบูรณ์ (Absolute Maximum หรือ Global Maximum)
                • ในกราฟ y ไม่มี เพราะ x เพิ่มขึ้นเรื่อยๆ แล้ว y ก็เพิ่มขึ้นไปจนถึง infinity
              • แต่ถ้าจุดใดที่ฟังก์ชันมีค่าน้อยที่สุดจริงๆ เมื่อเทียบกับทุกจุด แบบนี้เรียกว่า จุดต่ำสุดสัมบูรณ์ (Absolute Minimum หรือ Global Minimum)
                • ในกราฟ y ไม่มี เพราะ x ลดลงเรื่อยๆ แล้ว y ก็ลดลงไปจนถึง -infinity
                • ในกราฟ y’ คือ จุด x=3.333, y’= -33.33
                • จะเห็นว่าจุดที่เป็น Absolute Max/Min ก็จะเป็น Relative Max/min ด้วยเสมอ แต่ในทางกลับกันไม่ใช่นะ

              นอกจากวิธีนี้แล้ว การหาค่าจุดสูงสุดต่ำสุดด้วยเครื่องมืออื่นๆ ก็มีดังนี้

              หาค่าจุดสูงสุดต่ำสุดด้วยเครื่องมืออื่นๆ

              ใช้ Excel Solver

              หากจะใช้ Excel ทำ Optimization เราจะใช้ Solver Add-in มาทำ เพราะมันเป็นเครื่องมือที่มีมากับ Excel อยู่แล้ว และเก่งกว่า Goal Seek ตรงที่หาค่า Min, Max ได้ และใส่ข้อจำกัดหรือ Constrain ได้ด้วย

              วิธีการเรียกใช้ Solver ให้ไปที่ File -> Excel Options -> Add-in -> Go… -> ติ๊ก Solver Addin

              เรียน Calculus ด้วย Excel ตอนที่ 3 : Optimization หาจุดสูงสุด จุดต่ำสุด 129

              เช่น เราสามารถให้ Solver ทำการ

              • Set Objective : หาค่า y (B3) น้อยสุด (Min)
              • By Changing Variable Cell : โดยที่ให้เปลี่ยนค่า x (A3) ไปเรื่อยๆ
              • Subject to the Constraints : โดยมีข้อจำกัดคือ x>=0
              เรียน Calculus ด้วย Excel ตอนที่ 3 : Optimization หาจุดสูงสุด จุดต่ำสุด 130

              Solving Method ให้เลือก GRG Nonlinear เพราะเราก็ได้เห็นแล้วว่าสมการระหว่างค่า x กับ y นั้นเป็นเส้นโค้ง ไม่ใช่เส้นตรง

              พอกด Solve : จะได้ว่า Solver ก็สามารถหาค่า x ที่ทำให้ y ต่ำสุดได้ 6.667 เช่นกัน

              เรียน Calculus ด้วย Excel ตอนที่ 3 : Optimization หาจุดสูงสุด จุดต่ำสุด 131

              หรือจะทำอีกแบบนึงคือ Solve หาค่า x ที่ทำให้ y’ เป็น 0 (Value of : 0) โดยที่ x>=0.1 ก็ได้เช่นกัน พอ Solve ก็จะได้คำตอบเดียวกัน

              เรียน Calculus ด้วย Excel ตอนที่ 3 : Optimization หาจุดสูงสุด จุดต่ำสุด 132
              เรียน Calculus ด้วย Excel ตอนที่ 3 : Optimization หาจุดสูงสุด จุดต่ำสุด 133

              ใช้เว็บ Wolfram Alpha

              เขียนสิ่งที่ต้องการรู้ในเว็บ Wolfram Alpha ซึ่งเป็นเว็บด้านการคำนวณทางคณิตศาสตร์โดยเฉพาะ บอกเลยว่าโคตรโกง!! เพียงแค่ใส่สมการแล้วมันแก้ให้เลยแบบนี้ก็ได้

              3x^2-20x=0

              เรียน Calculus ด้วย Excel ตอนที่ 3 : Optimization หาจุดสูงสุด จุดต่ำสุด 134

              เอาจริงๆ ใส่สมการดังเดิมแบบนี้ไปเลยยังได้ minimize maximize y=x^3-10x^2

              เรียน Calculus ด้วย Excel ตอนที่ 3 : Optimization หาจุดสูงสุด จุดต่ำสุด 135

              ตัวอย่างเชิงประยุกต์ : ออกแบบภาชนะที่ต้นทุนต่ำสุด

              ถ้าต้องทำทรงกระบอกบรรจุน้ำปริมาตร 1 ลิตรพอดี (แบบมีฝาปิดด้วย) ควรจะทำทรงกระบอกรัศมี (r) เท่าไหร่ สูง (h) เท่าไร่ จึงจะประหยัดวัตถุดิบที่ใช้ผลิตมากที่สุด

              เรียน Calculus ด้วย Excel ตอนที่ 3 : Optimization หาจุดสูงสุด จุดต่ำสุด 136

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

              พื้นที่ผิว

              ซึ่งพื้นที่ผิวคิดจาก พื้นที่ฝาและก้น รวมกับพื้นที่ผิวทรงกระบอกด้านข้าง

              พื้นที่ฝาและก้น : เป็นพื้นที่วงกลม 2 อัน ฝาปิดบนกับฐานข้างล่าง

              = PI()*r^2 * 2 อัน

              พื้นที่ผิวรอบๆ : มาจากทรงกระบอกด้านข้าง = เส้นสอบรูปวงกลม *ความสูง

              =2*PI()*r*h
              พื้นที่ผิวรวม A(r,h) = 2* PI()*r^2 + 2*PI()*r*h

              ปริมาตร

              ปริมาตร V = PI()*r^2 *h

              ย้ายข้างให้เหลือ h ตัวเดียว

              h = V/(PI()*r^2)

              เราเอา h ที่เป็นข้อจำกัดนี่ เข้าไปแทนในสมการพื้นที่ A ซะ เพื่อให้ฟังก์ชันของพื้นที่เขียนอยู่ในรูปแบบของ r ตัวเดียว

              พื้นที่ผิวรวม A(r) = 2* PI()*r^2 + 2*PI()*r* V/(PI()*r^2)

              ตัดไปตัดมา จะได้ว่า

              A(r) = 2* PI()*r^2 + 2V/r

              หากเรา diff หา A’ จะได้ว่า

              A'(r) = 4* PI()*r - 2V/r^2

              ถ้าเรา Solve หา r ที่ทำให้ A'(r) เป็น 0 จะได้ว่า

              4* PI()*r = 2V/r^2
              V = 2 * PI()* r^3
              r = (V / 2 * PI() )^(1/3)

              V ในที่นี้ที่เราต้องการปริมาตรคือ 1000 cm3 ก็แทนค่าเลย

              r  = (1000 / (2 * PI()))^(1/3) = 5.419261 m นั่นเอง

              ส่วนความสูง h เรารู้ความสัมพันธ์ของมันอยู่แล้ว ก็แทนค่าตัวแปรเลย

              h = V/(PI()*r^2) = 1000/(PI()*5.419261^2) = 10.83852 cm

              หากเราลอง Plot กราฟด้วย Excel ที่ V=1000 จะได้เห็นภาพ ดังนี้

              เรียน Calculus ด้วย Excel ตอนที่ 3 : Optimization หาจุดสูงสุด จุดต่ำสุด 137

              ที่ r ประมาณ 5.4 ทำให้ Aต่ำสุดจริงๆ เพราะว่า

              A’ อยู่ที่ประมาณ 0 ส่วน A” มีค่าเป็น + แสดงว่า A’กำลังชันขึ้น แสดงว่าเป็นจุดวกกลับแบบต่ำสุดนั่นเอง

              สารบัญ Calculus

              • สารพัดวิธี Lookup หาค่าตัวสุดท้าย

                สารพัดวิธี Lookup หาค่าตัวสุดท้าย

                หลายๆ คนคงรู้จักการใช้พวก VLOOKUP หรือ MATCH เพื่อหาข้อมูลที่ต้องการแบบ Exact Match กันอยู่แล้ว ซึ่งมันจะได้ค่าของ lookup_value ตัวแรกที่เจอ (นับจากข้างบนลงล่าง) แต่ก็มีหลายสถานการณ์ที่เราอยาก Lookup หาค่าตัวสุดท้ายมากกว่า

                โดยเฉพาะเวลาที่ฐานข้อมูลเรียงตามวันที่/เวลาจากเก่าไปใหม่ เราย่อมอยากได้ข้อมูลที่อัปเดทล่าสุดมากกว่าอยากได้บรรทัดแรกจริงมั้ย? เช่นข้อมูลเป็นแบบนี้

                สารพัดวิธี Lookup หาค่าตัวสุดท้าย 138

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

                กรณีที่ 1 : กรณียอมให้เรียง Data ใหม่ได้ทั้งหมด

                ถ้าแบบนี้ก็ง่ายสุด ให้เรากด sort ใหม่ ให้เอาวันเวลาใหม่สุดมาอยู่ข้างบน

                สารพัดวิธี Lookup หาค่าตัวสุดท้าย 139

                แบบี้เราจะ VLOOKUP แบบ Exact Match ได้เลย

                =VLOOKUP(G2,C:D,2,FALSE)
                สารพัดวิธี Lookup หาค่าตัวสุดท้าย 140

                กรณีที่ 2 : กรณียอมให้เรียง Product ใหม่ได้ แต่ใน Product เดียวกันวันเวลาต้องเรียงจากเก่าไปใหม่

                สมมติเรียงแบบนี้ได้

                สารพัดวิธี Lookup หาค่าตัวสุดท้าย 141

                แบบนี้เราจะใช้ VLOOKUP Approximate Match ได้เลย เพราะแบบ Approximate Match จะได้ตัวสุดท้ายอยู่แล้ว

                =VLOOKUP(G2,C:D,2,TRUE)
                สารพัดวิธี Lookup หาค่าตัวสุดท้าย 142

                แต่สูตรข้างบนนี้จะใช้ได้ ต้องมั่นใจว่ามี lookup_value ที่หาใน database นะ เพราะไม่งั้นมันอาจจะผิดได้
                เช่น แม้ว่า lookup_value เป็นคำว่า “cนี้ไม่มีซะหน่อย” ซึ่งควรจะได้ #N/A ก็ดันเจออยู่ดี
                (แบบ Approximate Match มันจะเอาตัวสุดท้ายที่น้อยกว่าหรือเท่ากับค่า lookup_value มาให้เรา)

                ดังนั้นถ้าจะให้ชัวร์ ต้องลองดึงค่าคอลัมน์แรกกลับมาแล้วใช้ IF เช็คอีกที (คล้ายเทคนิค VLOOKUP เร็ว 100 เท่า) เช่น

                =IF(VLOOKUP(G2,C:D,1,TRUE)=G2,VLOOKUP(G2,C:D,2,TRUE),NA())
                สารพัดวิธี Lookup หาค่าตัวสุดท้าย 143

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

                ถ้าเป็น Excel Version เก่า (กว่า Excel 365)

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

                =LOOKUP(lookup_value,lookup_vector,[result_vector])
                =LOOKUP(2,1/(เงื่อนไข),$D$2:$D$11)
                =LOOKUP(2,1/($C$2:$C$11=G2),$D$2:$D$11)

                LOOKUP นั้นจะทำงานแบบ Approximate Match เสมอ ซึ่งเรา Lookup ค่าเลข 2
                จากตาราง lookup_vector ที่เราสร้างให้ได้เลข 1 กับ Error จากการเขียนเงื่อนไขแบบนี้

                =1/($C$2:$C$11=G2)   
                ซึ่ง 1/TRUE ได้ 1, 1/FALSE ได้ Error
                สารพัดวิธี Lookup หาค่าตัวสุดท้าย 144

                พอเรา lookup ด้วย 2 ก็จะได้บรรทัดที่มี 1 ตัวสุดท้ายอยู่ แล้วเราค่อยสั่งเอาผลลัพธ์ในคอลัมน์ D กลับมา (LOOKUP ดีตรงที่ว่า แยก Lookup_vector กับ Result_vector ออกจากกันได้)

                สารพัดวิธี Lookup หาค่าตัวสุดท้าย 145

                ถ้ามี Excel 365

                ใช้ XLOOKUP ตัว LOOKUP สุดโกง

                =XLOOKUP(lookup_value,lookup_array,return_array,[if_not_found],[match_mode],[search_mode])

                match_mode

                • 0 – Exact match. If none found, return #N/A. This is the default.
                • -1 – Exact match. If none found, return the next smaller item.
                • 1 – Exact match. If none found, return the next larger item.
                • 2 – A wildcard match where *, ?, and ~ have special meaning.

                search_mode

                • 1 – Perform a search starting at the first item. This is the default.
                • -1 – Perform a reverse search starting at the last item.
                • 2 – Perform a binary search that relies on lookup_array being sorted in ascending order. If not sorted, invalid results will be returned.
                • -2 – Perform a binary search that relies on lookup_array being sorted in descending order. If not sorted, invalid results will be returned.

                ดังนั้นเราจะใช้แบบนี้

                =XLOOKUP(G2,$C$2:$C$11,$D$2:$D$11,"-",0,-1) จบเลย
                สารพัดวิธี Lookup หาค่าตัวสุดท้าย 146

                ใช้ FILTER

                นอกจากนี้ใน Excel 365 เรายังใช้ FILTER มาช่วยก็ได้นะ โดย FILTER OrderID เฉพาะที่ product เป็น a ออกมาหลายๆ รายการเลย (เรียกว่า Spill Array)

                =FILTER(D2:D11,C2:C11=G2)
                สารพัดวิธี Lookup หาค่าตัวสุดท้าย 147

                ซึ่งวิธีนี้ดีกว่าวิธีอื่นตรงที่เรากำหนดได้เลยว่าจะเอา item ลำดับที่เท่าไหร่กลับมาก็ได้ ด้วยสูตรนี้

                =INDEX(FILTER($D$2:$D$11,$C$2:$C$11=G2),เลขลำดับ)

                ถ้าอยากได้อันสุดท้ายอันเดียว ก็ใช้ INDEX มาช่วยก็ได้ แล้วใช้ COUNTA นับว่า Filter มาเหลือกี่ตัว (ใช้ COUNTIFS ก็ได้แล้วแต่ชอบ) แล้วเอาใช้ในเลขลำดับ

                =INDEX(FILTER($D$2:$D$11,$C$2:$C$11=G2),COUNTA(FILTER($D$2:$D$11,$C$2:$C$11=G2)))
                สารพัดวิธี Lookup หาค่าตัวสุดท้าย 148

                หรือ

                INDEX(FILTER($D$2:$D$11,$C$2:$C$11=G2),COUNTIFS($C$2:$C$11,G2))
                สารพัดวิธี Lookup หาค่าตัวสุดท้าย 149

                error #CALC คือมัน Filter แล้วไม่มีผลลัพธ์ออกมา ถ้าอยากให้ไม่ขึ้น Error ก็ใช้ IFERROR ดักไปก็ได้ เช่น

                =IFERROR(INDEX(FILTER($D$2:$D$11,$C$2:$C$11=G2),COUNTIFS($C$2:$C$11,G2)),"-")
                สารพัดวิธี Lookup หาค่าตัวสุดท้าย 150

                ใช้ Power Query

                เราเอา transaction table เข้าไป แล้ว เรียงใหม่ใน power queryจะได้แบบนี้ (กดเรียงวันที่ก่อน และกดเรียงเวลา)

                สารพัดวิธี Lookup หาค่าตัวสุดท้าย 151

                จากนั้นให้ add index column ก่อนจะ remove duplicates ไม่งั้นมันจะมี bug ไปใช้ลำดับก่อนจะ sort ในการเก็บตัวบนสุด

                สารพัดวิธี Lookup หาค่าตัวสุดท้าย 152

                จากนั้นก็ remove duplicates ที่คอลัมน์ product ซะก็จะได้ตัวล่าสุด จบเลย

                สารพัดวิธี Lookup หาค่าตัวสุดท้าย 153

                พอได้ตารางนี้แล้ว เราจะเอาไป Merge กับตารางอื่นยังไงก็ได้แล้ว ไม่ขอทำให้ดูละกันนะครับ

                สรุปแล้วคุณชอบแบบไหนครับ?

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

              • เรียน Calculus ด้วย Excel ตอนที่ 2 : Integrate กับพื้นที่ใต้กราฟพิศวง

                เรียน Calculus ด้วย Excel ตอนที่ 2 : Integrate กับพื้นที่ใต้กราฟพิศวง

                ในตอนที่แล้วเราได้เรียนเรื่องพื้นฐาน Calculus และเรื่องการหา Derivative กันไปแล้ว ในตอนนี้เราจะมาเรียนอีกเรื่องนึงที่สำคัญมากๆ นั่นก็คือการ Integrate นั่นเองครับ

                ซึ่งเจ้า Integration หรือ การอินทิเกรต คือ กระบวนการที่ตรงข้ามกับการหาอนุพันธ์ หรือ Derivative นั่นเอง

                Integrate นั้นตรงข้ามกับ Differentiate

                รูปแบบทั่วไปคือ ถ้าสมมติ diff ฟังก์กัน F(x) แล้วได้ฟังก์ชัน f(x)

                \frac{d}{dx} F(x)= f(x)

                หาเรา integrate f(x) จะได้ F(x) + c

                \int f(x) dx = F(x) + c

                โดยที่

                • เครื่องหมาย ∫ คือเครื่องหมาย Integral
                • dx คือ ตัวที่บอกว่ามันย้อนการ diff ที่เทียบกับ dx มา
                • c คือค่าคงที่ (Constant) ซึ่งเดี๋ยวอ่านต่อข้างล่างจะรู้ว่าทำไมต้องใส่ +c ด้วย

                เช่น ตอนเรียนเรื่อง Derivative เราเรียนรู้ไปว่า

                \frac{d}{dx} x^n= nx^{n-1}

                ดังนั้น ตอน Integrate จะกลับกันเป็นแบบนี้

                \int nx^{n-1} dx = x^n + c

                เช่น หากถามว่า integrate 3x^2 จะได้เท่าใหร่ ต้องบอกว่า ได้ x^3 +c เพราะสามารถเป็นไปได้หลายแบบเช่น

                • x^3 เฉยๆ
                • x^3 +5 ก็ได้
                • x^3 – 2 ก็ได้
                • จะเห็นว่า c จะเป็นค่าคงที่อะไรก็ได้นั่นเอง

                ดังนั้นนี่คือสาเหตุที่เราต้องใส่ +c ไว้ในรูปสมการทั่วไปด้วย ซึ่งหลายๆ คนจะลืม +c ตลอด ถึงขนาดมีการทำ meme มาล้อประจำ

                เรียน Calculus ด้วย Excel ตอนที่ 2 : Integrate กับพื้นที่ใต้กราฟพิศวง 154
                อย่าลืม +c ด้วยนะ แงๆๆๆ
                เรียน Calculus ด้วย Excel ตอนที่ 2 : Integrate กับพื้นที่ใต้กราฟพิศวง 155
                meme อันนี้อย่างเท่เลย

                ความหมายที่แท้จริงของการ Integrate

                หากการหาอนุพันธ์ได้อัตราการเปลี่ยนแปลง ของกราฟ เช่น

                หากเรา Diff เทียบต่อเวลา เราจะแปลงระยะทาง เป็นความเร็ว เป็นความเร่ง ได้

                ระยะทาง --> ความเร็ว --> ความเร่ง

                ดังนั้นถ้าเรา Integrate เทียบกับเวลา เราก็สามารถย้อนกลับได้เช่นกัน

                ความเร่ง --> ความเร็ว --> ระยะทาง

                สมมติว่าเรารู้ฟังก์ชันของความเร็วของ รถวิเศษที่เรานั่ง ณ เวลาต่างๆ เป็นดังนี้

                เรียน Calculus ด้วย Excel ตอนที่ 2 : Integrate กับพื้นที่ใต้กราฟพิศวง 156

                หาถามว่าเมื่อเวลาผ่านไป 10 วินาที รถวิเศษวิ่งไปได้ระยะทางไกลกี่เมตร? เราจะหาคำตอบยังไง??

                แน่นอนว่าถ้าเราวิ่งด้วยความเร็วคงที่ตลอดที่ 5 m/s ถ้าวิ่งแบบนี้ไป 10 วินาที ก็คือ 5 m/s *10 s = 50 m จริงมั้ยครับ ซึ่งเอาจริงๆ มันก็คือการหาพื้นที่ใต้กราฟนั่นเอง

                ถ้าเราถามว่า ระหว่างวินาทีที่ 2 ถึง 8 วิ่งได้ระยะทางเท่าไหร่ เราก็หาพื้นที่ใต้กราฟเฉพาะวินาทีที่ 2-8

                เรียน Calculus ด้วย Excel ตอนที่ 2 : Integrate กับพื้นที่ใต้กราฟพิศวง 157

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

                สมมติฟังก์ชันของความเร็วเป็น v= 3t^2+5 เราจะหาพื้นที่ใต้กราฟของเส้นโค้งนี่ได้ยังไง???

                เรียน Calculus ด้วย Excel ตอนที่ 2 : Integrate กับพื้นที่ใต้กราฟพิศวง 158

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

                เรียน Calculus ด้วย Excel ตอนที่ 2 : Integrate กับพื้นที่ใต้กราฟพิศวง 159

                หลักการ คือ ถ้าเราแบ่งสี่เหลี่ยมให้แคบๆ มากๆๆๆๆ (เรียกว่า dt ละกัน) การหาพื้นที่ย่อยๆ (ds) จะได้ว่า

                พื้นที่ย่อยสี่เหลี่ยมผืนผ้า ds = สูง*กว้าง = v(t)*dt

                ส่วน พื้นที่รวม เราจะใช้การ integreate มาช่วย เพราะเป็นการรวมแบบที่ dt เล็กมากๆๆ เข้าใกล้ 0 นั่นเอง

                Total Area = \int v(t)dt

                อย่าลืมว่า integrate ความเร็ว จะได้ ระยะทาง ซึ่งเราคิดไว้แล้วว่าพื้นที่ใต้กราฟของความเร็วคือระยะทาง นั่นแปลว่า integrate ก็คือพื้นที่ใต้กราฟนั่นเอง! (แต่พื้นที่ใต้กราฟสามารถมีส่วนเหนือแกน x เป็น +, ใต้แกน x เป็น – ได้ด้วยนะ ซึ่ง integrate แล้วจะ net หักกัน)

                สรุปแนวคิด

                หากเราจะเปรียบเทียบความหมายของการหาอนุพันธ์ vs การอินทิเกรต จะเป็นแบบนี้ครับ

                • การหาอนุพันธ์ นั้น เราจะได้อัตราการเปลี่ยนแปลง หรือ ความชันของกราฟ ของจุดที่สนใจ
                • การอินทิเกรต นั้น เราจะได้พื้นที่ใต้กราฟ (แบบ net กัน ระหว่างพื้นที่บน กับ ล่าง)

                การคำนวณหาระยะทางด้วยความรู้ Integrate

                สมมติ v(t)= 3t^2+5

                แบบนี้ระยะทาง s ก็คือ

                s(t) = \int v(t)dt = \int (3t^2+5 )dt

                จะได้ว่า ระยะทาง s ณ วินาที่ที่ t คือแบบนี้

                s(t) = t^3+5t+c

                ถ้าจะหาระยะทางตั้งแต่วินาทีที่ 2-8 ให้ใส่ t เป็น 8 จะได้ระยะทาง ณ วินาทีที่ 8, และใส่ t เป็น 2 ได้ระยะทางวินาทีที่ 2

                จากนั้นเอามาลบกัน

                • ระยะทาง วินาทีที่ 8 =8^3 + 5*8 + c
                • ระยะทาง วินาทีที่ 2 =2^3 + 5*2 + c
                • ระยะทาง วินาทีที่ 2 ถึง 8 =(8^3 + 5*8 + c) – (2^3 + 5*2 + c)
                • ซึ่ง +c จะตัดกันเสมอ
                • = 534 นั่นเอง

                แปลว่า ระยะทาง หลังวิ่งไป 10 วินาที ก็จะได้เป็น ระยะทาง วินาทีที่ 10 – ระยะทาง วินาทีที่ 0

                • ระยะทาง วินาทีที่ 10 =10^3 + 5*10 + c
                • ระยะทาง วินาทีที่ 0 =0^3 + 5*0 + c
                • ระยะทาง วินาทีที่ 0 ถึง 10 =(10^3 + 5*10 + c) – (0^3 + 5*0 + c) ซึ่ง +c จะตัดกันเสมอเช่นกัน
                • แปลว่าเราใช้ระยะทางวินาทีที่ 10 ได้เลย แบบไม่ต้องมี + c เนอะ
                • = 10^3 + 5*10 = 1050 m นั่นเอง

                การคำนวณหาระยะทางด้วยความรู้ Excel

                ถ้าใช้ Excel เราแค่แบ่งระยะเวลาให้ย่อยมากๆ จนได้ dt เล็กๆๆๆๆ แล้วเอาไปคูณความเร็วของแต่ละ dt นั้นๆ ก็จะได้พื้นที่สี่เหลี่ยมผืนผ้าเล็กๆ จากนั้นเอาสี่เหลี่ยมผืนผ้าเล็กๆ มารวมกันก็จะได้พื้นที่ใต้กราฟ เช่น

                เรียน Calculus ด้วย Excel ตอนที่ 2 : Integrate กับพื้นที่ใต้กราฟพิศวง 160

                ซึ่งจะได้ 1050.0155 ซึ่งใกล้เคียงกับ 1050 แต่ไม่เป๊ะหรอกนะ เพราะ dt เราไม่ได้เล็กพอ (แค่นี้ก็อัดไปแสนบรรทัดแล้ว)

                และนี่ก็คือ Concept ของการ Integrate ครับ หวังว่าเพื่อนๆ จะพอเห็นภาพนะ

                ความรู้แถม : ถ้าไม่อยากเสียพื้นที่ Excel ในการทำตาราง

                ถ้าเราไม่อยากมานั่งทดบรรทัดเยอะๆ แบบตารางข้างบนนี้ (เป็นแสนเป็นล้านบรรทัด แถมช้าอีก) ก็ใช้ความรู้ Array Formula หรือ Power Query มาช่วยก็ได้ (อันนี้ค่อนข้าง Advance นะ ใครไม่รู้เรื่องไม่เป็นไรครับ) เช่น

                ใช้ความรู้ Array Formula ของ Excel 365

                อยากหาระยะทาง ณ เวลา 2 วินาที

                ใช้ SEQUENCE สร้างเลข Running ระยะเวลา เช่น

                =SEQUENCE(rows,columns,start,step)
                =SEQUENCE(A2/E1+1,1,0,E1)
                เรียน Calculus ด้วย Excel ตอนที่ 2 : Integrate กับพื้นที่ใต้กราฟพิศวง 161

                ต่อไปก็คำนวณ v ออกมาจาก v(t)= 3t^2+5 ได้

                =3*SEQUENCE(A2/E1+1,1,0,E1)^2+5
                เรียน Calculus ด้วย Excel ตอนที่ 2 : Integrate กับพื้นที่ใต้กราฟพิศวง 162

                ต่อไปเอาไปคูณกับ dt 0.0001 แล้วหาผลรวม

                =SUM((3 * SEQUENCE(A2/E1+1,1,0,E1)^2+5) * E1)

                lock $ เล็กน้อย ให้ copy สูตรได้

                =SUM((3 * SEQUENCE(A2/$E$1+1,1,0,$E$1)^2+5) * $E$1)
                เรียน Calculus ด้วย Excel ตอนที่ 2 : Integrate กับพื้นที่ใต้กราฟพิศวง 163

                ใช้ Array Formula ของ Excel verison เก่า

                Excel เก่าไม่มี SEQUENCE สามารถใช้ ROW+INDIRECT มาพลิกแพลงเอา เช่น

                =(ROW(INDIRECT("1:"&A2/E1+1))-1)*E1

                version เก่าจะไม่มี effect spill แบบนี้ แต่ไม่เป็นไร เดี๋ยวจะทำ step ต่อไปได้อยู่ดี

                เรียน Calculus ด้วย Excel ตอนที่ 2 : Integrate กับพื้นที่ใต้กราฟพิศวง 164

                Tips : การใช้ฟังก์ชัน INDIRECT นั้นเป็น Volatile ฟังก์ชัน ถ้าเลี่ยงได้ก็ควรจะเลี่ยง ดังนั้นเราสามารถใช้ฟังก์ชัน INDEX มาช่วยสร้าง Dynamic Range แทนได้ แล้วค่อยใช้ ROW ครอบ เช่น

                =(ROW(A1:INDEX(A:A,A2/E1+1))-1)*E1
                เรียน Calculus ด้วย Excel ตอนที่ 2 : Integrate กับพื้นที่ใต้กราฟพิศวง 165

                จากนั้น lock $ ซะหน่อยเป็นแบบนี้

                =(ROW($A$1:INDEX($A:$A,A2/$E$1+1))-1)*$E$1

                สุดท้ายก็เหมือนกัน แต่ใช้ SUMPRODUCT มารวมเลยดีกว่า จะไม่ได้ต้องกด Ctrl+Shift+Enter

                =SUMPRODUCT((3 * ((ROW($A$1:INDEX($A:$A,A2/$E$1+1))-1)*$E$1)^2+5) * $E$1)
                เรียน Calculus ด้วย Excel ตอนที่ 2 : Integrate กับพื้นที่ใต้กราฟพิศวง 166

                ใช้ความรู้ Power Query มาสร้างฟังก์ชัน

                สร้าง Parameter secPara ว่าจะเอา ณ เวลาวินาทีที่เท่าไหร่

                จากนั้นสร้าง Query MyArea มาคำนวณพื้นที่รวม โดยอ้างอิงถึง Parameter secPara ที่สร้างไว้

                let
                    dt=0.0001,
                    NumItem = secPara/dt+1,
                    Source = List.Numbers(0, NumItem,  dt), //สร้าง Sequence ด้วย List.Number
                    ConvertTable = Table.FromList(Source, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
                    RenameColumns = Table.RenameColumns(ConvertTable,{{"Column1", "MyTime"}}),
                    AddVel = Table.AddColumn(RenameColumns, "MyVel", each 3*Number.Power([MyTime],2)+5),
                    AddArea = Table.AddColumn(AddVel, "SmallArea", each [MyVel]*dt),
                    SumArea = List.Sum(AddArea[SmallArea])
                in
                    SumArea

                แล้วเอา Query นี้แปลงเป็นฟังก์ชันโดยคลิ๊กขวา Create Function แล้วใช้ชื่อ MyAreaFx ซึ่งรับ input คือ secPara ว่าจะคำนวณระยะทาง ณ วินาทีที่เท่าไหร่

                จากนั้นเราก็เอา Table ที่ต้องการหาระยะทาง ณ เวลาต่างๆ เข้าไป แล้วเรียกใช้ฟังก์ชัน MyAreaFx ที่สร้างไว้ ก็จบเลย

                เรียน Calculus ด้วย Excel ตอนที่ 2 : Integrate กับพื้นที่ใต้กราฟพิศวง 167
                เรียน Calculus ด้วย Excel ตอนที่ 2 : Integrate กับพื้นที่ใต้กราฟพิศวง 168

                ตอนต่อไป

                เดี๋ยวตอนหน้าจะเป็นการประยุกต์มากขึ้นอีกหน่อยนะ เช่น คำนวณหาจุดสูงสุดต่ำสุดด้วยการใช้ Diff หรือคำนวณหาปริมาตร ด้วยการ Integrate เป็นต้น

                สารบัญ Calculus

                • เรียน Calculus ด้วย Excel ตอนที่ 1 : พื้นฐานแคลคูลัส

                  เรียน Calculus ด้วย Excel ตอนที่ 1 : พื้นฐานแคลคูลัส

                  วันก่อนผมได้ถามแฟนเพจว่าอยากให้สอนเรื่องอะไรเป็นพิเศษ มีคำตอบนึงทำให้ผมสนใจมาก นั่นคือ อยากให้สอนพื้นฐาน​ Calculus แบบใช้​ Excel​ มาช่วยคำนวณ ตั้งแต่​ Limit, Differential, Integral etc.

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

                  เอาล่ะ เรามาเริ่มกันเลยดีกว่าว่า Calculus คืออะไร ความหมายของการ Diff จริงๆ คืออะไร แล้วใช้ใน Excel ยังไง?

                  Calculus คืออะไร?

                  มันคือหลักการทางคณิตศาสตร์ที่ใช้ศึกษา “อัตราการเปลี่ยนแปลง” ซึ่ง ไอแซค นิวตัน ได้คิดต้นขึ้นเพื่อใช้อธิบายปรากฏการณ์ทางฟิสิกส์ต่างๆ เช่น กฎการเคลื่อนที่ กฎแห่งแรงโน้มถ่วง ที่คณิตศาสตร์สมัยนั้นอธิบายไม่ได้ (จริงๆ มีอีอกคนนึงก็คิดค้น Calculus ในแง่สัญลักษณ์ที่พวกเราใช้กันเหมือนกัน แต่ดันไม่ดังเท่านิวตัน)

                  ตามปกติแล้ว หากความสัมพันธ์ระหว่างค่า x กับ y เป็นเส้นตรง เราจะสามารถหาอัตราการเปลี่ยนแปลงของ y เทียบกับ x (หรือ ความชัน) ได้ง่ายๆ แบบนี้

                  ความชัน = การเปลี่ยนแปลงของ y / การเปลี่ยนแปลงของ x = ∆y /∆x = (y2-y1) / (x2-x1)

                  ซึ่งไม่ว่าคิดที่ตรงจุดไหน ความชันก็เท่ากันทั้งเส้น

                  เรียน Calculus ด้วย Excel ตอนที่ 1 : พื้นฐานแคลคูลัส 169

                  แต่ถ้าความสัมพันธ์ระหว่าง x กับ y ดันไม่ใช่เส้นตรง แปลว่าแต่ละจุดของเส้นนั้นอาจมีความชันไม่เท่ากันก็ได้ ดังนี้

                  เรียน Calculus ด้วย Excel ตอนที่ 1 : พื้นฐานแคลคูลัส 170

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

                  ทีนี้ Concept ของมันคือ เราจะหาความชันของจุดที่เส้นความชันมีการสัมผัสกับเส้นโค้งเป๊ะๆ เลยก็ไม่ได้อีก เพราะว่าที่จุดสัมผัสนั้นไม่มีความยาว ไอ้ความชัน ∆y /∆x เดี๋ยวตัวส่วน ∆x เป็น 0 แล้วจะได้ infinity คำนวณไม่ได้

                  เค้าก็เลยคิด Concept อันนึงขึ้นมาเรียกว่า Limits เพื่อคำนวณสิ่งที่เข้าใกล้ค่าที่กำหนด เช่น แทนที่จะหาความชันของจุดเป๊ะๆ ก็ไปหาความชันของรูปสามเหลี่ยมเล็กๆ แถวๆ จุดนั้นแทน โดยใช้สัญลักษณ์ x แทนจุดเริ่มของ x และเพิ่มระยะไป h จะได้ x+h (บางตำราก็ใช้ ∆x แทน h ซึ่งก็คือสิ่งเดียวกัน)

                  ทำให้ความชันของสามเหลี่ยม = ∆y /∆x = f(x+h)-f(x) / h
                  calculus excel

                  คราวนี้ค่า h มันก็อาจจะเยอะหรือน้อย ขึ้นอยู่กับสามเปลี่ยมใหญ่แค่ไหน ถ้าเราอยากได้สามเหลี่ยมเล็กๆๆๆ เพื่อให้เราสามารถหาความชันของจุดที่เราต้องการที่จุด x ได้พอดี เราก็ต้องทำให้ระยะ h นั้นสั้นๆๆๆๆ ที่สุดเท่าที่จะทำได้ แต่ห้ามเป็น 0 เราก็จะเรียกว่า limit เมื่อ h เข้าใกล้ 0

                  เราเรียกการเปลี่ยนแปลงแบบน้อยมากๆๆๆๆๆ ว่า Differentials เช่นเจ้า ∆x เล็กๆ หรือ h ของเราเนี่ย

                  • เช่น เรียกการเปลี่ยนแปลง x น้อยๆๆ ว่า Differentials ของ x หรือ dx นั่นเอง
                  • เรียกการเปลี่ยนแปลงของ y น้อยๆ ว่า Differentials ของ y หรือ dy

                  เราเรียกอัตราการเปลี่ยนแปลงของ dy เทียบกับ dx เล็กๆ ที่เปลี่ยนไป ว่า การหา Derivative (อนุพันธ์) ของ y เทียบกับ x หรือชื่ออื่นๆว่า

                  • dy/dx (ซึ่งแน่ล่ะ เพราะมันเอาค่า y เล็กๆ หาร x เล็กๆ ไง)
                  • y’
                  • f'(x)

                  ซึ่งมีสูตรคือ

                  \frac{dy}{dx} = lim_{h \to 0} \frac{f(x+h) – f(x)}{h}

                  ลองหาอนุพันธ์ของสมการ y=x^2 + 10

                  สมมติว่าสมการ y ของเรา หรือ f(x) คือ y=x^2 + 10 จะได้ว่า

                  \frac{dy}{dx} = lim_{h \to 0} \frac{ ((x+h)^2+10 )- (x^2+10)}{h}

                  กระจายตัวยกกำลังสองออกมา ด้วยสูตร (a+b)^2 = a^2+2ab+b^2

                  \frac{dy}{dx} = lim_{h \to 0} \frac{ (x^2+2xh+h^2+10 )- (x^2+10)}{h}

                  x2 +10 เหมือนกันตัดกัน แล้ว ดึง h ออกมานอกวงเล็บ

                  \frac{dy}{dx} = lim_{h \to 0} \frac{ (2x+h )h}{h}

                  h เศษกับส่วนตัดกันได้ เพราะว่า h ไม่ใช่ 0 แน่ๆ พอ h เข้าใกล้ 0 ทำให้ 2x+h เข้าใกล้ 2x เฉยๆ

                  \frac{dy}{dx} = lim_{h \to 0} (2x+h ) = 2x

                  สรุป เมื่อ y=x^2 + 10 แล้ว dy/dx คือ 2x นั่นเอง

                  แปลว่า เมื่อ y=x^2 + 10 แล้ว
                  สมการของการเปลี่ยนแปลงของ y เทียบกับ x หรือ dy/dx หรือ Derivative ของ y เทียบกับ x จะได้ 2x นั่นเอง

                  หากเราเอา x กับ y’ มา Plot กราฟ จะได้เส้นสีส้มแบบนี้ ซึ่งค่า y’ คือความชัน ณ จุดที่ x มีค่าต่างๆ กัน เช่น

                  • ที่ x =-5, y’ =-10 คือความชันเป็น -10 (ลบเยอะ)
                  • ที่ x =0, y’ =0 คือความชันเป็น 0 (ศูนย์)
                  • ที่ x =5, y’ =10 คือความชันเป็น 10 (บวกเยอะ)

                  ซึ่งจะเห็นว่าตรงกับที่เราวาดรูปวิเคราะห์ไว้เลย

                  เรียน Calculus ด้วย Excel ตอนที่ 1 : พื้นฐานแคลคูลัส 171

                  มาลองพิสูจน์กันว่า หากเราทำให้ ∆x น้อยลงแล้วหาความชันจะได้เหมือนกัน limits มั้ย?

                  ทดสอบเรื่อง Limits เมื่อ ∆x เข้าใกล้ 0 ด้วย Excel

                  ถ้าเราใช้สมการลองทำให้ ∆x มันถี่ๆ มากๆ หน่อย ก็จะยังได้กราฟเส้นเดิมเนอะ ซึ่งเราจะมีค่า y’ เฉลยเอาไว้เทียบกับสิ่งที่เราจะทดสอบ

                  เรียน Calculus ด้วย Excel ตอนที่ 1 : พื้นฐานแคลคูลัส 172

                  คราวนี้เราจะลองมาหา y’ โดยใช้วิธีการคำนวณความชันระหว่าง ∆x ที่มีค่าต่างๆ กัน

                  เริ่มที่ ∆x เป็น 1

                  จะเห็นว่าค่า y’ ยังต่างจาก y’=2x พอสมควร ลอง plot trend line ออกมาได้ y’=2x+1 เฉยเลย (เพราะว่าค่า h หรือ ∆x ยังมากอยู่ ซึ่งยังไม่ถือว่าเข้าใกล้ 0)

                  เรียน Calculus ด้วย Excel ตอนที่ 1 : พื้นฐานแคลคูลัส 173

                  คราวนี้ลอง ∆x เป็น 0.1

                  จะเห็นว่าค่าเริ่มใกล้เคียง y’=2x ขึ้น โดยเพี้ยนแค่ 0.1 แทนที่จะเพี้ยน 1 เหมือนเดิม 555

                  เรียน Calculus ด้วย Excel ตอนที่ 1 : พื้นฐานแคลคูลัส 174

                  คราวนี้ลอง ∆x เป็น 0.0001

                  ยิ่งถ้า ∆x =0.0001 ยิ่งใกล้ๆๆๆ กับ 2x เข้าไปอีก

                  เรียน Calculus ด้วย Excel ตอนที่ 1 : พื้นฐานแคลคูลัส 175

                  นี่แหละความหมายของ dy/dx ล่ะครับ ยิ่ง ∆x มันเข้าใกล้ 0 มันก็จะให้ค่าที่เป็นความชัน หรืออัตราการเปลี่ยนแปลง ณ จุดนั้นๆ ให้เราเลย ซึ่งในทางคณิตศาสตร์เค้าก็พยายามหาความสัมพันธ์สำเร็จรูปออกมาให้พวกเราได้ใช้แบบไม่ต้องไปใช้ limits อีกต่อไป

                  สรุปสูตรของเรื่องการหา Derivative หรือ อนุพันธ์

                  สูตรหลักที่ 1 : การ diff x^n

                  \frac{d}{dx} x^n= nx^{n-1}

                  สูตรนี้สูตรเดียวใช้ได้หลายเรื่องมาก เช่น

                  หาก diff ค่าคงที่ c ก็จะเปรียบเหมือนลองมองสูตรบนสุดให้ n เป็น 0 : จะทำให้ 0*X^(0-1) = 0 ไปด้วย

                  \frac{d}{dx}c = 0

                  หาก diff x ก็จะเปรียบเหมือนมองสูตรบนสุดให้ n เป็น 1 : จะทำให้ 1*X^(1-1) = 1 นั่นเอง

                  \frac{d}{dx}x = 1

                  สูตรหลักที่ 2 : กระจายการบวกลบได้ตรงๆ

                  \frac{d}{dx} [f(x) \pm g(x)]= f'(x) \pm g'(x)

                  จากสูตรนี้ทำให้เรารู้ว่า เราสามารถดึงค่าคงที่ออกมาได้

                  \frac{d}{dx} cf(x) = c \frac{d}{dx}f(x)

                  สาเหตุเพราะว่า

                  cf(x) = f(x)+f(x)+f(x)+… c รอบ

                  สูตรหลักที่ 3 : กระจายการคูณ = หน้า diff หลัง + หลัง diff หน้า

                  \frac{d}{dx} [f(x) \cdot g(x)]= f(x) \cdot g'(x) + g(x) \cdot f'(x)

                  สูตรหลักที่ 4 : กระจายการหาร = (ล่าง diff บน – บน diff ล่าง) / ล่าง^2

                  \frac{d}{dx} [\frac {f(x)} {g(x)}]= \frac{g(x)f'(x)-f(x)g'(x)}{[g(x)]^2}

                  Higher-order Derivatives (อนุพันธ์อันดับสูง)

                  หาก y=f(x)

                  อนพันธ์ปกติ หรือ อันดับ 1 คือ diff ไป 1 รอบ

                  \frac{dy}{dx} = y’ = f'(x)

                  อนพันธ์อันดับ 2 คือ diff y ไป 2 รอบ

                  \frac{d^2y}{dx^2} = y” = f”(x) = f^{(2)}(x)

                  อนพันธ์อันดับ n คือ diff y ไป n รอบ

                  \frac{d^ny}{dx^n} = f^{(n)}(x)

                  Calculus กับโจทย์การคำนวณเรื่องการเคลื่อนที่

                  หากเราสามารถ Plot ความสัมพันธ์ระหว่างระยะทาง (s) กับ เวลา (t) ได้ด้วยฟังก์ชัน s = f(t)

                  เราจะสามารถคำนวณอัตราการเปลี่ยนแปลงของระยะทาง เทียบกับ เวลา หรือ “ความเร็ว (v) “ ว่า

                  v = \frac{ds}{dt}

                  เราจะสามารถคำนวณอัตราการเปลี่ยนแปลงของความเร็ว เทียบกับ เวลา หรือ “ความเร่ง (a) “ ว่า

                  a = \frac{dv}{dt}

                  เช่น สมมติว่าเราสามารถคำนวณตำแหน่งของการเคลื่อนที่ได้จากฟังก์ชันนี้ (assume ว่า ความเร่ง a คงที่)

                  s(t) = s_0+v_0t+\frac{1}{2}at^2
                  • s(t) = ระยะทาง ณ เวลาที่ t
                  • s0 = ระยะทางจุดเริ่มต้น
                  • v0 = ความเร็วจุดเริ่มต้น
                  • t = เวลาที่ผ่านไป
                  • a = ความเร่ง

                  จากกฎ Calculus เราจะคำนวณหาฟังก์ชันของความเร็วกับเวลา คือ v หรือ s'(t) ได้จากกฎการกระจายการบวก

                  v=s'(t) = v_0+at

                  เพราะว่า

                  \frac{d}{dt}s_0 = 0 \spaceและ\space \frac{d}{dt}v_0t = v_0 \spaceและ \frac{d}{dt}\frac{1}{2}at^2 = 2*\frac{1}{2}at

                  คำนวณหาฟังก์ชันของความเร่งกับเวลา คือ a หรือ s”(t) หรือ v'(t)

                  a=v'(t) = a

                  ซึ่งก็ถูกต้องเพราะเคสนี้ สมการการเคลื่อนที่ที่ผมใช้ ต้องใช้กับกรณีที่มีค่า a คงที่นั่นเอง

                  สูตรพวกนี้ คือสูตรฟิสิกส์ที่เรียนกันใน ม.ปลาย ซึ่งจริงๆ ก็เป็นการหา Derivative มาให้แล้วแบบสำเร็จรูปนั่นเองล่ะครับ

                  เช่น กรณีที่เราปล่อยลูกบอกจากตึกที่สูง 200m ถามว่า ถ้าผ่านไป 3 วินาที บอลจะมีความเร็วเท่าไหร่

                  จากสูตรนี้

                  v=s'(t) = v_0+at
                  • v0= ความเร็วเริ่มต้น = 0 m/s
                  • a = ความเร่ง = แรงดึงดูดของโลก = 9.81 m/s^2
                  • t = 3 วินาที

                  ดังนั้นความเร็วที่วินาทีที่ 3 หลังจากปล่อย คือ =0+9.81*(3) = 29.4300 m/s

                  หากเราลองทำใน Excel ดูแบบไม่พึ่งพา Calculus แต่ใช้การเปลี่ยน t ที่ละ 0.0001 แทน ก็จะเป็นแบบนี้

                  เรียน Calculus ด้วย Excel ตอนที่ 1 : พื้นฐานแคลคูลัส 176

                  จะเห็นว่าได้ค่าใกล้เคียงกับการใช้ Calculus มากๆ เลย และนี่แหละคือหลักการของการคำนวณ Change แบบเล็กๆ ของ Calculus ครับ

                  แปลว่าถ้าถามว่าวินาทีที่ 4 ความเร็วเป็นเท่าไหร่ ผมก็เอาระยะทางที่วินาทีที่ 4 กับวินาทีที่ 4.000001 ลบกัน หารด้วย 0.000001 ก็จบเหมือนกัน เช่น

                  v วินาทีที่ 4 =( 1/2*9.81*4.000001^2  -  1/2*9.81*4^2 )/0.000001 = 39.240005 
                  ซึ่งถ้าคิดจาก Calculus จะได้ v วินาทีที่ 4 =9.81*4 = 39.240 ซึ่งก็ถือว่า Excel ก็คำนวณได้ใกล้เคียงล่ะ 555

                  ตอนต่อไป

                  ตอนต่อไปจะมาดูเรื่องที่ตรงข้ามกับ Derivatives นั่นก็คือการ Integrate นั่นเอง

                  สารบัญ Calculus

                  • Power BI ตอนที่ 20 : การคำนวณต้นทุนแบบ FIFO ด้วย DAX

                    Power BI ตอนที่ 20 : การคำนวณต้นทุนแบบ FIFO ด้วย DAX

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

                    ( Edit 30/6/2020 14:20 : ผมมีแก้ Code ที่ Error เรื่องเครื่องหมาย & ให้แล้วนะครับ รบกวนลอง refresh หน้าเว็บด้วย)

                    FIFO คืออะไร?

                    FIFO หรือ First In, First Out คือวิธีการทางบัญชี ที่จะใช้ต้นทุนสินค้าชิ้นที่ซื้อเอาไว้เก่าที่สุดก่อนแล้วค่อยไล่ไปชิ้นใหม่ขึ้นเรื่อยๆ ซึ่งผลของมันจะเห็นได้ชัดเลยกับสินค้าที่มีราคาซื้อเปลี่ยนแปลงไปเยอะๆ

                    เช่น เราซื้อสินค้าไป 3 รอบ จากเก่าไปใหม่ คือ

                    • 2 ชิ้น @ 4บาท/ชิ้น
                    • 5 ชิ้น @ 7 บาท/ชิ้น
                    • 3 ชิ้น @5 บาท/ชิ้น

                    ถามว่าถ้าเราขายสินค้าไป 2 รอบ คือ

                    • ขายรอบแรก : 4 ชิ้น @ 6 บาท/ชิ้น
                    • ขายรอบสอง : 5 ชิ้น @ 8 บาท/ชิ้น

                    แต่ละรอบจะได้กำไรเท่าไหร่?

                    การขายรอบแรก 4 ชิ้น

                    • ต้นทุนจะใช้ของสินค้า 2 ชิ้น @ 4บาท/ชิ้น + 2 ชิ้น @ 7 บาท/ชิ้น (เพราะขายทั้งหมดแค่ 4) = 8+14 = 22 บาท
                    • แปลว่ากำไร 4*6 – 22 = 2 บาท

                    การขายรอบสอง 5 ชิ้น

                    • ต้นทุนจะใช้ของสินค้า 3 ชิ้น @ 7บาท/ชิ้น (เพราะราคา 7 บาทเหลือแค่ 3 ชิ้น) + 2 ชิ้น @ 5 บาท/ชิ้น = 21+10 = 31 บาท
                    • แปลว่ากำไร 5*8 – 31 = 9 บาท

                    จะเห็นว่าวิธีการคำนวณนั้นยุ่งยากมาก เพราะต้องนั่งไล่ดูว่าใช้สินค้าเดิมไปถึงตัวไหนแล้ว จะได้เอาราคามาถูกอัน และถ้าสินค้ามีหลายชนิดอีก ยิ่งยากเข้าไปใหญ่เลย!!

                    เดี๋ยวทั้งหมดนี้เราจะมาทำด้วย Power BI กันนะครับ แต่สำหรับคนที่อยากใช้ Excel สามารถไปดูที่ Link เหล่านี้ได้

                    วิธีคำนวณ FIFO ด้วย Excel

                    มีหลายท่านที่ได้ทำวิธีการคำนวณ FICO ด้วย Excel ไปแล้ว ผมจึงไม่ขอทำซ้ำอีก แต่ละแบบก็มีข้อดีข้อเสียต่างกันไป

                    • QQ15 Calculate FIFO cost (สูตรโดย Excel Wizard) : อันนี้เป็นวิธีใช้สูตรกรณีเป็นสินค้าเดียว
                    • วิธีใช้สูตรแบบสินค้าหลายตัว (สูตรโดย Excel Wizard) เป็น post ในกลุ่ม Excel Super Fan ที่ถามมาโดยคุณ Nattaporn Chamwong : สามารถคำนวณได้จากสินค้าหลายตัว และดูผลลัพธ์พร้อมกันได้ทุกตัว [แต่บอกไว้ก่อนว่าซับซ้อนมากๆ]
                    • FIFO Costing with Excel Data Table using inward and outward table (อ. สมเกียรติ ฟุ้งเกียรติ แห่ง Excel Expert Training) : ใช้ concept ของ Data Table คำนวณได้จากสินค้าหลายตัว แต่ดูผลลัพธ์ได้ทีละตัว [วิธีนี้ผมชอบตรง concept ไม่ซับซ้อนดี และตรวจสอบผลลัพธ์ได้ง่าย]

                    วิธีคำนวณ FIFO ด้วย DAX ของผม

                    สำหรับวิธี DAX ของผม จะสามารถคำนวณได้จากสินค้าหลายตัว และแสดงผลลัพธ์ได้พร้อมกันทั้งหมด แถมเอาไปหมุนดูในมุมไหนก็ได้ (เพราะเอาไปสร้าง DAX Measure ได้) ดังนั้นมันจะยืดหยุ่นสุดๆ ไปเลยครับ โดยที่ผมประยุกต์เอา concept แนวคิด วิธีตาราง Data Table ของ อ. สมเกียรติ มาดัดแปลงให้ดีขึ้น โดยใช้ความสามารถของเครื่องมือยุคใหม่อย่าง DAX

                    ซึ่งผมใช้ concept ของ การสร้างตารางจำลองด้วย FILTER ผสมผสานกับการใช้ Iterator อย่าง SUMX ทำให้สามารถสร้างตารางจำลองในอากาศได้เลย ทำให้มันเป็นวิธีที่ทรงพลังมากๆ

                    ถ้าใครงงกับคำศัพท์เหล่านี้ก็ไปอ่านบทเก่าๆ เรื่อง SUMX กับ FILTER ได้นะครับ ส่วนใครไม่เคยเห็น VAR กับ RETURN ก็ไปอ่านได้ที่นี่

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

                    สรุปแล้ว Data มีดังนี้

                    Power BI ตอนที่ 20 : การคำนวณต้นทุนแบบ FIFO ด้วย DAX 177

                    ก่อนอื่นผมเอาตารางการซื้อขายเข้าสู่ Power BI ก่อนแบบ Get Data จาก Excel ที่ผมเตรียมไว้ต่างหากอย่างตรงไปตรงมา ดังนี้

                    Power BI ตอนที่ 20 : การคำนวณต้นทุนแบบ FIFO ด้วย DAX 178

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

                    สิ่งแรกเพื่อให้การคำนวณ FIFO ง่ายขึ้น จะต้องมีจำนวน Unit ที่ซื้อ และขาย แบบสะสมซะก่อน ซึ่งสามารถใช้คำสั่ง SUMX + FILTER มาช่วย จะเห็นว่า DAX ใช้การอ้างอิงแบบ Cell Reference ของ Excel ไม่ได้ การเขียนเพื่ออ้างบรรทัดก่อนหน้าแบบสะสมก็จะยากกว่า Excel พอสมควรเนอะ

                    กด New Column แล้วใส่สูตรของแต่ละตัว โดยที่ผมมี comment อธิบายการทำงานให้ในสูตรด้วย // นะครับ

                    AccumBuy = ยอดซื้อสะสม

                    AccumBuy = 
                    VAR CurrentProductID = TXData[ProductID]
                    VAR CurrentNum = TXData[Num]
                    //ใช้ VAR เก็บค่าของข้อมูล ProductID กับ Num ของตาราง TXData 
                    //เอาไว้ใช้อ้างอิงอีกทีภายใน SUMX (ซึ่งมีการเปลี่ยนตาราง)
                    RETURN
                    // ใช้ SUMX เพื่อรวมค่าจากตารางจำลองที่สร้างขึ้นมา
                    // ใช้ Filter สร้างตารางในแถวก่อนหน้าทั้งหมดเฉพาะ ProductID ปัจจุบัน
                        SUMX (
                            FILTER (
                                TXData,
                                TXData[ProductID] = CurrentProductID
                                    && TXData[Num] <= CurrentNum
                            ),  
                            TXData[UnitBuy]
                        ) 
                    

                    AccumSell = ยอดขายสะสม

                    AccumSell = 
                    // หลักการเดียวกับ AccumBuy แค่เปลี่ยนเป็นการขาย
                    VAR CurrentProductID = TXData[ProductID]
                    VAR CurrentNum = TXData[Num]
                    RETURN
                        SUMX (
                            FILTER (
                                TXData,
                                TXData[ProductID] = CurrentProductID
                                    && TXData[Num] <= CurrentNum
                            ),
                            TXData[UnitSell]
                        )

                    แค่มี 2 ตัวนี้ จริงๆ เราก็สามารถคำนวณจำนวน Unit Balance ณ แต่ละขณะได้แล้ว ดังนี้

                    UnitBalance = TXData[AccumBuy]-TXData[AccumSell]

                    สรุปได้ข้อมูลทั้ง 3 คอลัมน์ดังนี้

                    Power BI ตอนที่ 20 : การคำนวณต้นทุนแบบ FIFO ด้วย DAX 179

                    Concept การคำนวณเรื่อง FIFO ในไฟล์ของ อ. สมเกียรติ

                    ทีนี้ Concept การคำนวณเรื่อง FIFO ในไฟล์ของ อ. สมเกียรติ คือ เอาจำนวนขายที่มีค่อยๆ มาหักลบจำนวนซื้อไล่จากเก่าไปใหม่ โดยเทียบเอาตัวต่ำกว่าระหว่างจำนวนซื้อแต่ละครั้งนั้นๆ กับจำนวนขายที่ยังค้างอยู่ ซึ่งจะได้จำนวนขายที่มาจับคู่กับจำนวนซื้อจริงๆ

                    เช่น ในรูปนี้ จะเห็นว่ามีจำนวนขาย 150,000 ชิ้น มันก็จะค่อยๆ เอามาหักลบ 50,000 10,000 70,000 และสุดท้ายเหลือ จับคู่กับตัวที่ซื้อ 100,000 ชิ้นแค่ 20,000 เท่านั้น

                    จากนั้นก็เอาจำนวนชิ้นที่คำนวณได้ไปคูณ UnitCost เพื่อให้ออกมาเป็น Cost of Goods Sold (ผมจะเรียกย่อๆ ว่า COGS) ของการซื้อแต่ละครั้งที่จับคู่กับจำนวนขายจริง (ในช่อง K6:K24)

                    จากนั้นเอา COGS ของการขายทุกครั้งมารวมกัน ได้ช่อง K25 ตัวล่างสุดของตารางกลาง

                    ทีนี้เอาค่า K25 ที่ได้จากตารางกลางไปโปรยในตารางขวาในคอลัมน์ Q ด้วย Data Table ในฐานะของ Cost of Goods Sold รวมของแต่ละ Transaction ที่มีการขายจริง

                    เช่น

                    • ขายสะสม 30,000 ชิ้น มี COGS 300,000
                    • ขายสะสม 70,000 ชิ้น มี COGS 750,000
                    • แปลว่าที่ขายเพิ่มมา 40,000 ชิ้น ต้องมี COGS 750,000-300,000 คือ 450,000 นั่นเอง

                    นี่คือ Concept วิธีคิด FIFO ของ อ. สมเกียรติ ซึ่งคุณควรทำความเข้าใจ Concept นี้ใน Excel ให้เข้าใจก่อน จึงจะสามารถเข้าใจสิ่งที่ผมจะทำด้วย DAX แทนได้ครับ ใครอยากอ่านวิธีคิดแบบละเอียดไปดูได้ที่นี่

                    Power BI ตอนที่ 20 : การคำนวณต้นทุนแบบ FIFO ด้วย DAX 180

                    คำนวณด้วย DAX (ตรงนี้ค่อนข้างซับซ้อนเลยล่ะ)

                    ทีนี้เพื่อให้คำนวณ COGS สะสมได้ เพื่อให้ง่าย เราจะคำนวณจำนวนซื้อสะสมในบรรทัดก่อนหน้าซะก่อน ดังนี้

                    PrevAccumBuy = 
                    VAR CurrentProductID = TXData[ProductID]
                    VAR CurrentNum = TXData[Num]
                    // เอาค่า AccumBuy ใน Transaction ก่อนหน้า เฉพาะของ ProductID ปัจจุบันมา
                    // ใช้ MAXX เพื่อเอาค่ามากสุดจากตารางจำลองที่สร้างขึ้นมา (ก็จะได้ตัวสะสมอันล่าสุด)
                    // ใช้ Filter สร้างตารางในแถวก่อนหน้าทั้งหมดเฉพาะ ProductID ปัจจุบัน
                    VAR MyResult =
                        MAXX (
                            FILTER (
                                TXData,
                                TXData[Num] < CurrentNum
                                    && TXData[ProductID] = CurrentProductID
                            ),
                            TXData[AccumBuy]
                        )
                    RETURN
                    // ให้แสดงค่าเฉพาะบรรทัดที่เป็นการซื้อเท่านั้น นอกนั้นเป็น 0 ไป
                        IF ( TXData[UnitBuy] > 0, MyResult ) + 0

                    จะได้ตารางหน้าตาแบบนี้ ซึ่งผมจะเอา PrevAccumBuy นี้ไว้ใช้หักลบออกจาก AccumSell เพื่อที่จะได้รู้ว่า ยังมีจำนวนขายให้มาเทียบกับจำนวนซื้อได้อีกกี่ตัว

                    ซึ่ง PrevAccumBuy ของผมจะคล้ายกับส่วนนี้ในสูตรใน Excel เลย (สมมติดูในช่อง J10)

                    IF(AND(@Id=IdKey,@Date>=From,E10>0),MIN(E10,TotalUnit-SUM($J$5:J9)),0)
                    Power BI ตอนที่ 20 : การคำนวณต้นทุนแบบ FIFO ด้วย DAX 181

                    ทีนี้เราจะสามารถใช้สูตรนี้เพื่อคำนวณ COGS สะสมได้

                    CostFIFOAccum = 
                    VAR CurrentNum = TXData[Num]
                    VAR CurrentProductID = TXData[ProductID]
                    VAR AccumSell = TXData[AccumSell]
                    VAR PrevAccumBuy = TXData[PrevAccumBuy]
                    VAR FIFOBuytable =
                    //สร้างตารางจำลอง โดยคัดมาแต่รายการก่อนหน้าที่เป็นการซื้อเท่านั้น
                        FILTER (
                            TXData,
                            TXData[UnitBuy] > 0
                                && TXData[Num] < CurrentNum
                                && TXData[ProductID] = CurrentProductID
                        )
                    VAR FIFOBuytableAdd =
                    // สร้างคอลัมน์ "ActualDeduct" เพิ่มใน FIFOBuytable เพื่อให้รู้ว่าแต่ละจำนวนซื้อนั้นๆ มีจำนวนขายให้หักจริงเท่าไหร่
                    // เพื่อสร้างคอลัมน์ J ในตารางกลางของไฟล์ Excel
                        ADDCOLUMNS (
                            FIFOBuytable,
                            "ActualDeduct", MIN ( TXData[UnitBuy], MAX ( AccumSell - TXData[PrevAccumBuy], 0 ) )
                        )
                    VAR CalCost =
                    // เอาจำนวน unit ที่หักจริงสำหรับ Transaction นั้นๆ * ราคาซื้อ แล้ว SUM (ตรงนี้จะเหมือนคอลัมน์ K ในตารางกลางของไฟล์ Excel)
                        SUMX ( FIFOBuytableAdd, [ActualDeduct] * TXData[UnitPrice] )
                    VAR CostFIFOAccum =
                    // เอาค่า COGS สะสมมาแสดงเฉพาะรายการที่เป็นการขาย ตรงนี้จะเหมือนคอลัมน์ Q ในตารางขวาของไฟล์ Excel
                        IF ( TXData[UnitSell] > 0, CalCost )
                    RETURN
                        CostFIFOAccum

                    จะเห้นว่าส่วนของ “ActualDeduct” ที่มีสูตร

                    MIN ( TXData[UnitBuy], MAX ( AccumSell - TXData[PrevAccumBuy], 0 ) )

                    นั้นจะใช้หลักการของสูตรใน Excel อันนี้เลย

                    IF(AND(@Id=IdKey,@Date>=From,E10>0),MIN(E10,TotalUnit-SUM($J$5:J9)),0)

                    ตอนนี้ผมก็ได้คอลัมน์ Q ของ ไฟล์ Excel แล้ว แต่ของผมดีกว่าตรงที่ออกมาพร้อมกันทุก Product เลย!!

                    Power BI ตอนที่ 20 : การคำนวณต้นทุนแบบ FIFO ด้วย DAX 182

                    ต่อไปก็คำนวณยอด COGS ของแต่ละรายการจริงๆ โดยเอายอดสะสมปัจจุบันหักด้วยยอดสะสมก่อนหน้า

                    CostFIFO = 
                    VAR CurrentNum = TXData[Num]
                    VAR CurrentProductID = TXData[ProductID]
                    VAR PrevFICOAccum =
                    // คำนวณยอด COGS สะสมของ Transaction ก่อนหน้า เฉพาะของ ProductID ปัจจุบัน
                        MAXX (
                            FILTER (
                                TXData,
                                TXData[Num] < CurrentNum
                                    && TXData[ProductID] = CurrentProductID
                            ),
                            TXData[CostFIFOAccum]
                        )
                    VAR CurrentFIFOCost = TXData[CostFIFOAccum] - PrevFICOAccum
                    // เอาที่สะสมปัจจุบัน - สะสมก่อนหน้า = ได้ยอด COGS ปัจจุบัน
                    RETURN
                    // ให้แสดงค่า COGS เฉพาะรายการที่เป็นการขายเท่านั้น
                        IF ( TXData[UnitSell] > 0, CurrentFIFOCost )

                    เท่านี้ผมก็ได้คอลัมน์ R ของไฟล์ Excel แล้ว (แต่ของผมออกมาพร้อมกันทุก Product เลยเช่นเคย)

                    Power BI ตอนที่ 20 : การคำนวณต้นทุนแบบ FIFO ด้วย DAX 183

                    หลังจากนี้ง่ายมากๆ แล้ว

                    หลังจากนี้ก็คำนวณ Revenue กับ Profit ได้ง่ายๆ ดังนี้

                    Revenue = TXData[UnitPrice]*TXData[UnitSell]
                    ProfitFIFO = TXData[Revenue]-TXData[CostFIFO]
                    Power BI ตอนที่ 20 : การคำนวณต้นทุนแบบ FIFO ด้วย DAX 184

                    พอได้พวกนี้ครบแล้ว ก็สามารถสร้าง DAX Measure ที่ต้องการเช่น TotalUnitBuy, TotalUnitSell, ToTotalRevenue, TotalCost, TotalProfit ได้แบบง่ายๆ ด้วย SUM ได้เลย

                    TotalUnitBuy = SUM(TXData[UnitBuy])
                    TotalUnitSell = SUM(TXData[UnitSell])
                    TotalRevenue = SUM(TXData[Revenue])
                    TotalCost = SUM(TXData[CostFIFO])
                    TotalProfit = SUM(TXData[ProfitFIFO])

                    จากนั้นเราก็สามารถเอาไปสร้าง Report ยังไงก็ได้แล้วล่ะ ตรงนี้ไม่มีอะไรยากแล้ว อยากดูรวมทุก Product หรือดูทีละอัน Power BI ทำได้หมด และทำให้ Interactive กันได้ด้วย

                    Power BI ตอนที่ 20 : การคำนวณต้นทุนแบบ FIFO ด้วย DAX 185

                    จบแล้ว

                    ใครทำตามแล้วสงสัยอะไรตรงไหนก็สามารถ comment ถามได้นะครับ บอกเลยว่าวิธีนี้มันทรงพลังมากๆ เพราะเราอยากดูมุมไหน อยาก Filter อะไรก็สามารถทำได้หมด

                    สารบัญ Series Power BI

                    ใครสนใจอยากเรียนเป็นคลิปวีดีโอ ผมมี

                  • Power BI ตอนที่ 19 : การปรับ Cross Filter Direction เพื่อคำนวณค่าในตาราง Dimension

                    Power BI ตอนที่ 19 : การปรับ Cross Filter Direction เพื่อคำนวณค่าในตาราง Dimension

                    บทความนี้จะสอนเรื่องการปรับค่า Cross Filter เพื่อให้สามารถคำนวณข้อมูลที่อยู่ในตาราง Dimension จากตารางอื่นได้ แต่ก่อนจะไปดูเรื่องนั้น มาทวนเรื่องการคำนวณกรณีที่ Measure หลักอยู่ใน Fact Table กันซะก่อนครับ

                    เมื่อ Measure หลัก คำนวณจากข้อมูลใน Fact Table

                    ในตอนที่ 14 เรื่องของ Context Transition ผมมีเขียนสูตรอธิบายการใช้ CALCULATE ผสมกับพวก SUMX AVERAGEX MAXX (เรียกว่า Iterator) ซึ่งจะสามารถเพิ่มการคำนวณมุมมองใหม่ๆ ให้กับ Measure หลัก ซึ่งคำนวณจากข้อมูลในตาราง Fact ผ่านมุมมองต่างๆ ของตาราง Dimension เช่น

                    Power BI ตอนที่ 19 : การปรับ Cross Filter Direction เพื่อคำนวณค่าในตาราง Dimension 186
                    TotalRevenue = 
                    SUMX(fSales,fSales[SalesQuantity]*RELATED(dProduct[UnitPrice])) 

                    จะเห็นว่า TotalRevenue คำนวณจากตาราง fSales ดังนั้นจึงสามารถ Filter จากตารางอื่นได้เมื่อเราใช้ พวก SUMX AVERAGEX MAXX สร้างตารางจำลองขึ้นมา แล้วเกิด Context Transition ขึ้น

                    TotalRevenue เฉลี่ยรายร้านค้า

                    AverageStoreRevenue = 
                    AVERAGEX(DISTINCT(dStores[StoreKey]),[TotalRevenue])

                    TotalRevenue เฉลี่ยราย Category สินค้า

                    AvgProductCategoryRevenue = 
                    AVERAGEX( DISTINCT(dProduct[ProductCategory]) , [TotalRevenue] )

                    TotalProfit ที่มากสุดรายสินค้า

                    MaxProductCategoryProfit = 
                    MAXX( DISTINCT(dProduct[ProductCategory]) ,[TotalGrossProfit] )

                    ซึ่งจะเห็นว่าเราสามารถสร้างมุมมองต่างๆ เพิ่มได้ไม่จำกัด หาก Measure หลักนั้นคำนวณจากข้อมูลซึ่งอยู่ที่ Fact Table แต่ถ้า Measure หลักไม่ได้คำนวณจากคอลัมน์ใน Fact Table ล่ะ? ในบทความนี้เราจะมาดูวิธีจัดการกันครับ

                    เมื่อ Measure หลัก คำนวณจากข้อมูลใน Dimension Table

                    ใน Data Model ด้านบน สมมติผมต้องการคำนวณ Max UnitPrice ก็เลยสร้าง Measure ขึ้นมาว่า

                    MaxUnitPrice = MAX(dProduct[UnitPrice])

                    ซึ่งจะเห็นว่ามันคำนวณจากข้อมูลในตาราง dProduct เต็มๆ เลย

                    ดังนั้นมันจึงไม่สามารถถูก Filter ได้ด้วยตารางอื่นเลยนอกจาก dProduct ตัวเดียวเท่านั้น (ทั้งนี้เพราะว่าทิศทางของ Relationship มันย้อนศรไม่ได้)

                    เวลาเราเอา Measure นี้ไปใช้ใน Visual mี่มีการ Filter จากตารางอื่น (เช่น dDate) ผลลัพธ์ก็จะผิดทันที ซึ่งจะเห็นชัดว่า ค่าทุกตัวเท่ากันหมดเพราะว่าไม่ได้มีการ Filter เกิดขึ้นเลย นั่นเอง

                    Power BI ตอนที่ 19 : การปรับ Cross Filter Direction เพื่อคำนวณค่าในตาราง Dimension 187

                    แนวทางแก้ไขมีอยู่ 2 วิธี คือ

                    1. ปรับทิศทาง Cross Filter ในเส้น Relationship ของ Data Model เป็น Both Direction เสมอ (ไม่แนะนำ)
                    2. ใช้ฟังก์ชัน CROSSFILTER มาช่วยใน CALCULATE เพื่อปรับเป็น Both เฉพาะการคำนวณ Measure นั้นๆ (แนะนำ)

                    ปรับทิศทาง Cross Filter ในเส้น Relationship ของ Data Model เป็น Both Direction

                    วิธีนี้ไม่ต้องเขียนสูตรอะไรทั้งสิ้น เพราะเป็นการไปปรับที่เส้น Relationship ใน Data Model เองเลย โดยให้ดับเบิ้ลคลิ๊กที่เส้นตัวเจ้าปัญหา

                    Power BI ตอนที่ 19 : การปรับ Cross Filter Direction เพื่อคำนวณค่าในตาราง Dimension 188

                    จากนั้นเลือก Cross Filter Direction เป็น Both เพื่อให้มันสามารถ Filter ได้ทั้ง 2 ทิศทาง

                    Cross Filter Direction

                    พอปรับเป็น both แล้ว ลูกศรก็จะหันไปทั้ง 2 ทิศทาง แปลว่ามันยอมให้เรา Filter จากตารางอื่นได้แล้ว

                    Power BI ตอนที่ 19 : การปรับ Cross Filter Direction เพื่อคำนวณค่าในตาราง Dimension 189

                    หากไปดูผลลัพธ์ใน Visual ก็จะถูกต้องแล้ว

                    Power BI ตอนที่ 19 : การปรับ Cross Filter Direction เพื่อคำนวณค่าในตาราง Dimension 190

                    อย่างไรก็ตามผมไม่แนะนำวิธีนี้ เนื่องจาก Data Model อาจเกิดความกำกวมได้ ว่าจะให้ Filter จากทิศไหนไปไหนกันแน่ ดังนั้นเรามาดูอีกวิธีกัน

                    ใช้ฟังก์ชัน CROSSFILTER มาช่วยใน CALCULATE เพื่อปรับเป็น Both เฉพาะการคำนวณ Measure นั้นๆ

                    วิธีนี้ ใน Data Model เราจะยังคงเป็นทิศทางเดียว คือ Single อยู่ แต่คราวนี้เราจะเขียน Measure ตัวใหม่ ให้รองรับการ Filter แบบ 2 ทิศทางได้ โดยใช้ CALCULATE+CROSSFILTER

                    CROSSFILTER ( <LeftColumnName>, <RightColumnName>, <CrossFilterType> )

                    โดยที่ CROSSFILTER มีความสามารถในการเปลี่ยนรูปแบบการ Cross Filter หรือ <CrossFilterType> จาก Relationship ที่มีอยู่แล้วให้เป็น Both, None, OneWay ได้ ซึ่งจะต้องใช้ฟังก์ชันนี้คู่กับ CALCULATE ในฐานะของ Filter เช่น

                    MaxUnitPriceV2 = 
                    CALCULATE(MAX(dProduct[UnitPrice]),
                            CROSSFILTER(dProduct[ProductKey],fSales[ProductKey],Both)
                            )

                    ซึ่งแม้ว่าใน Data Model เส้น Relationship จะยังเป็น Single อยู่ แต่ใน Measure MaxUnitPriceV2 นี้จะสามารถใช้ Relationship แบบ Both ได้ แบบนี้จะไม่ทำให้ตัว Model เสีย และยังสามารถคำนวณได้ถูกต้องอีกด้วย แบบนี้สิ แนะนำเลย!

                    Power BI ตอนที่ 19 : การปรับ Cross Filter Direction เพื่อคำนวณค่าในตาราง Dimension 191

                    สารบัญ Series Power BI

                    ใครสนใจอยากเรียนเป็นคลิปวีดีโอ ผมมี

                  • Power Query Speed Up Tips : รวมเทคนิคแก้ปัญหา Power Query ช้า ให้ทำงานเร็วขึ้น

                    Power Query Speed Up Tips : รวมเทคนิคแก้ปัญหา Power Query ช้า ให้ทำงานเร็วขึ้น

                    ในบทความนี้จะเป็นการรวบรวมเทคนิคและความรู้ความเข้าใจในการที่จะแก้ปัญหา Power Query ช้า ให้ทำงานเร็วขึ้น เพราะหากคุณเริ่มใช้ Power Query เป็น คุณจะเริ่มใช้มันกับทุกสถานการณ์ หากคุณเริ่มทำมันเยอะพอ คุณคงต้องเคยเจอปัญหาว่าบางทีมันทำงานช้ามากตอนที่กด Refresh All เพื่ออัปเดทข้อมูล ไม่ว่าจะเป็นใน Excel หรือ Power BI ก็ตาม เพื่อไม่ให้เสียเวลา เรามาเริ่มกันเลยครับ

                    ตั้งค่า Data Load ให้เหมาะสม

                    ปกติแล้วเวลาเราทำงานกับ Power Query เรามักจะสร้าง Query Step ย่อยๆ ขึ้นมาระหว่างทาง แล้วสุดท้ายก็เอามาใช้จริงแค่บาง Query เท่านั้น นอกนั้นเป็นตัวทด ซึ่งตัวทดควรจะ Load ออกมาแบบ Connection Only จริงมั้ยครับ?

                    ทีนี้ถ้าเราต้องมานั่งกด Close & Load to… Connection Only ทุกอันก็คงเสียเวลาแย่เลย ดังนั้นเราสามารถตั้งค่า Default การ Load เอาไว้ให้เป็น Connection Only ไว้ก่อน โดยไปที่ File –>Option & Settings –> Query Options –> Data Load

                    ตรงนี้มีจุดที่ปรับได้ 3อันคือ

                    Power Query Speed Up Tips : รวมเทคนิคแก้ปัญหา Power Query ช้า ให้ทำงานเร็วขึ้น 192

                    1.Default Load ซึ่งผมแนะนำให้กดแบบ Specific custom default แล้วเอาติ๊กออกไปให้หมด เพื่อให้มันออกมาเป็น Connection Only นั่นเอง (ถ้าอยากจะ Load Query ไหนออกมาเป็นอย่างอื่น ก็กดคลิ๊กขวาที่ Query แล้วกด Load to… ได้)

                    2. โหมด Fast Data Load : ถ้าติ๊กอันนี้ ไอ้เครื่องหมาย i เค้าบอกว่า Query จะ Load ผลลัพธ์ออกไปใช้งานเร็วขึ้น แต่ระหว่างโหลดเครื่องอาจจะนิ่งๆ แฮงๆ ไปชั่วครู่ (เพราะว่ามันทุ่มเทพลังทั้งหมดไปที่การ Load ละมั้ง) แต่ที่ผมเคยลองผลลัพธ์ก็ไม่เห็นจะต่างกันเท่าไหร่เลยครับ 555

                    3. ตั้งค่า Cache : ตัวนี้จริงๆ ไม่ควรเกี่ยวกับการ Load โดยตรง แต่เกี่ยวกับการ Preview Data ให้ดูใน Query Editor มากกว่า (เพราะการ Preview มันเอามาจาก Data ที่เก็บใน Cache) แต่ตรงนี้ผมลองตั้งเยอะๆ แล้วทำให้เร็วขึ้นเล็กน้อยเฉยเลย… ดังนั้นใครมี Hdd เหลือก็ตั้งเยอะหน่อยก็ได้ครับ ไม่เสียหาย

                    ตั้งค่า Allow data preview to download in the background ให้เหมาะสม

                    คำสั่ง Allow data preview to download in the background นี้อยู่ใน Query Option -> Data Load

                    Power Query Speed Up Tips : รวมเทคนิคแก้ปัญหา Power Query ช้า ให้ทำงานเร็วขึ้น 193

                    คำสั่งนี้เอาไว้ทำอะไร?

                    ปกติแล้วเวลา Power Query Get Data มาเตรียมให้เรา Transform เล่น ใน Power Query Editor มันจะเอาข้อมูลมา 1000 แถว ให้เราเห็นภาพผลลัพธ์ก่อน อันนี้แหละที่เรียกว่า Data Preview (ที่เอาจากข้อมูล Cache ที่เก็บในข้อที่แล้ว)

                    หากเราติั๊ก Allow data preview to download in the background เอาไว้ มันจะเป็นการบอกให้ Power Query คอย Update ตัว Preview สำหรับทุกๆ Query และที่สำคัญเวลาที่เรากด Refresh All มันก็จะ Load Preview สำหรับทุก Query ใหม่ด้วย!! ซึ่งตรงนี้แหละที่มันเสียเวลา

                    ข้อสรุปคือ

                    • หากคุณมี Query เยอะๆ โดยเฉพาะ Query ที่ไม่ได้ Load Data ออกมาจริงๆ การไม่ติ๊กจะทำให้ Load เร็วกว่า
                    • อย่างไรก็ตาม ข้อเสียของการเอาออก คือ เวลากดเปลี่ยน Step หรือกดไปดู Query ตัวอื่นใน Query Editor เจ้า Data Preview จะโหลดช้ากว่าเดิม

                    รายละเอียดเคสที่ disable option นี้ช่วยได้ สามารถอ่านได้ในนี้

                    ใช้ Power Query ใน Power BI แทน Excel !

                    ไม่รู้เหมือนกันว่าทำไม เหมือน 2 ตัวนี้มันจะทำงานไม่เหมือนกัน 100% ถ้าใช้ Power Query ใน Power BI มันจะ Load เร็วกว่า Excel นิดหน่อย

                    ซึ่งถ้าเราเคยทำงานใน Excel อยู่แล้ว ไม่จำเป็นต้องไปสร้าง Query ใน Power BI ใหม่ทั้งหมดนะ เราสามารถคลิ๊กขวา Copy Query จาก Excel ไป Power BI ได้เลย

                    Power Query Speed Up Tips : รวมเทคนิคแก้ปัญหา Power Query ช้า ให้ทำงานเร็วขึ้น 194

                    จากนั้นไป Paste ใน Power Query Editor ของ Power BI

                    Power Query Speed Up Tips : รวมเทคนิคแก้ปัญหา Power Query ช้า ให้ทำงานเร็วขึ้น 195

                    ผลลัพธ์ : เคสผมลองแล้วเร็วขึ้น 10% ครับ

                    อย่างไรก็ตาม หาก Query มีการดึงไฟล์จาก Workbook ตัวเองไว้ มันจะเอามาลง Power BI ตรงๆ ไม่ได้ เพราะใน Power BI มันไม่มี Excel.CurrentWorkbook ครับ มีแต่ Excel.Workbook

                    เข้าใจหลักการของการ Reference / Duplicate Table

                    หลายๆ คนอาจจะคิดว่า หากเราเขียน Query1 ไว้แล้ว จากนั้นทำการ Reference Query1 ไปใช้ใน Query2,3,4,… อีกหลายๆ อัน แล้วต้องการ Load ผลลัพธ์ออกหมดทุกอัน มันจะคำนวณ Query1 แค่ครั้งเดียวตอนแรก หลังจากนั้นไม่ต้องคำนวณอีกแล้ว อันนี้เป็นความเข้าใจที่ผิดนะครับ

                    เพราะการ Reference Query จริงๆ มันก็คือเหมือนเอา Code ของ Query1 มาใส่ใน Query อื่นๆ ที่อ้างอิงมันไปด้วยอยู่ดี แต่เหมือนเป็น Let…in… ซ้อนใน Let…in… ของ Query อื่น เช่น

                    Query1 ผมเขียนว่า

                    let
                        Step1 = 3+2,
                        Step2 = Step1*100
                    in
                        Step2

                    จากนั้นผมสร้าง Query 2 แล้ว Reference ข้อมูลจาก Query1 จะได้สูตรใน Query2 ว่า

                    let
                        Source = Query1
                    in
                        Source

                    จากนั้นผมก็ทำนู่นนี่ใน Query 2 ไปอีก เช่น

                    let
                        Source = Query1,
                        Step1 = Source+55,
                        Step2 = Step1/10
                    in
                        Step2

                    แบบนี้เวลามันทำงานจริง มันจะเหมือนว่า Copy Code ใน Query1 มาใส่ใน Query 2 ก่อนจะทำงาน เช่น

                    let
                        Source = 
                            let
                                Step1 = 3+2,
                                Step2 = Step1*100
                            in
                                Step2  
                        ,
                        Step1 = Source+55,
                        Step2 = Step1/10
                    in
                        Step2

                    ซึ่งเวลามันทำงานก็จะประมาณนี้

                    Power Query ช้า

                    ดังนั้นมันก็จะคำนวณทุกสิ่งทุกอย่างใน Query1 ใหม่อยู่ดี (ยกเว้นว่า Query1 ไม่ต้อง Load ออกมา คือเป็นตัวทดเฉยๆ มันก็จะรันแค่ที่ Query2 นี่แหละ)

                    ดังนั้นประโยชน์ของ Reference Query ก็แค่ว่า หากเราไปแก้ Query1 แล้ว ตัวต้นทางของ Query2 จะเปลี่ยนตามอัตโนมัติ ซึ่งต่างจาก Duplicate ซึ่งหากเราไปแก้ Query1 แล้ว ตัว Code ใน Query2 จะไม่ได้เปลี่ยนตามนั่นเอง

                    ใช้ Table.Buffer อย่างเหมาะสม

                    คำสั่ง Table.Buffer มีความสามารถในการเก็บข้อมูลในตารางเข้าสู่ Memory (คนละอันกับ Cache ที่จะเก็บบน HDD) เพื่อที่เวลามีการเรียกใช้อีก มันจะได้ไม่ต้องไปเอาข้อมูลจาก Data Source ใหม่ทุกครั้ง

                    Table.Buffer(table as table) as table

                    เคสที่ผมเคยใช้ ผมใช้มันกับ Table ที่ต้องมีการอ้างถึงหลายรอบใน Query เดียวกัน (ที่อ้างถึงเพราะเป็นการ Filter ช้อมูลจาก Table นั้นคล้ายๆ Vlookup Approximate Match) ซึ่งมีการอ้างถึง Table นั้นเท่ากับจำนวน Row ใน Table หลัก ซึ่งมีหลายพันครั้ง

                    Code ก่อน buffer

                    let
                        //Source เป็นการดึงผลลัพธ์จากอีก Table นึงมาทำงานต่อ
                        Source=SystemEmployee,
                        
                        #"Added Custom" = Table.AddColumn(Source, "Custom", 
                                (main)=>Table.SelectRows(Source,
                                        (sub)=>sub[EnNo]=main[EnNo] and (sub[DateonlyNum]=main[DateonlyNum] or (sub[DateonlyNum]=(main[DateonlyNum]+1) and sub[Mode]=6 )))),
                        
                        ....

                    พบว่าไฟล์ที่เป็นต้นทางจริงๆ ขนาดแค่ 209K แต่ Power Query ดันขึ้นว่า Read Data ไป 900 MB++ (เพราะมันอ่านจาก Source ใหม่ไม่รู้กี่รอบ)

                    Code หลัง buffer

                    let
                        //เพิ่มการ Buffer ให้ Source เพราะว่ามีการเรียกใช้ Source หลายรอบด้วย Table.SelectRows ใน Step ถัดไป
                        Source=Table.Buffer(SystemEmployee),
                        
                        #"Added Custom" = Table.AddColumn(Source, "Custom", 
                                (main)=>Table.SelectRows(Source,
                                        (sub)=>sub[EnNo]=main[EnNo] and (sub[DateonlyNum]=main[DateonlyNum] or (sub[DateonlyNum]=(main[DateonlyNum]+1) and sub[Mode]=6 )))),
                        
                        ....
                        

                    หลังจากใช้เทคนิคTable.Buffer แล้ว ในเคสของผมก็ช่วยลดเวลา Load ไปได้ประมาณ 10-15% (ควรลองทดสอบด้วยนะ เพราะบางเคสทำแล้วอาจจะแย่ลงได้ เนื่องจาก Table.Buffer มันจะทำการอ่านข้อมูลเข้า Ram ทั้งหมดตอนที่ Buffer เลย)

                    อีกทั้งเลขที่ขึ้นว่า Load ข้อมูลจาก Data เท่าไหร่แล้ว มีขนาดใกล้เคียงกับ Data จริงคือ 209kb ไม่ใช่ 900MB++ เหมือนตอนที่ไม่ได้ Buffer (เห็นแล้วตกใจมาก!!)

                    แปลว่าในตัวอย่างที่แล้วเรื่อง Reference/Duplicate Query สมมติเราไปสร้าง Query ซักตัวมาใช้ Table.Buffer Query1 ไว้ จากนั้นให้ Table อื่นอ้างอิง Query นั้นไปใช้ มันก็ไม่ช่วยอะไรอยู่ดี เพราะจะกลายเป็นทุก Query จะต้อง Buffer ใหม่ตลอดเวลานั่นเอง

                    สรุปแล้ว Table.Buffer จะมีประโยชน์ก็ต่อเมื่อ ใช้กับ Query ที่มีการเรียก Table นั้นๆ หลายรอบใน Query เดียวกันเท่านั้น

                    พยายามทำให้ข้อมูลให้เหลือน้อยก่อนทำ Operation อื่น

                    สมมติการ Transform ข้อมูลเรามี 2 เรื่องที่ต้องทำ คือ Add Column คำนวณบางอย่าง กับ Filter ให้เหลือข้อมูลบรรทัดที่ต้องการ

                    ถ้าเป็นไปได้เราควรจะ Filter ก่อน Add Column เพื่อที่ว่า Power Query จะได้คำนวณน้อยลงเท่าที่จำเป็นจริงๆ ไม่ใช่คำนวณทั้งหมดแล้วดันไป Filter ทิ้งทีหลัง แบบนั้นเสีย Resource เปล่าๆ (ยกเว้นว่า ไอ้ Column ที่ add มาคือเงื่อนไขของการ Filter ถ้างั้นเราก็จำเป็นต้อง Add ก่อน จริงมะ?)

                    นอกจากนั้น ก่อนจะใช้ Table.Buffer ในตัวอย่างที่แล้ว หากเราเลือกให้เหลือเฉพาะข้อมูลที่จำเป็นก่อนจะทำการ Buffer มันก็น่าจะช่วยให้ Load Query เร็วขึ้นเช่นกัน ซึ่งผมลองปรับ Query แล้วปรากฏว่าเร็วขึ้น 30%

                    let
                      Source = SystemEmployee,
                      MyBufferTable = Table.Buffer(
                        Table.SelectColumns(Source, {"EnNo", "Mode", "DateonlyNum", "DateTime"})  ),
                      #"Added Custom" = Table.AddColumn(
                        Source, "Custom", 
                        (main) => Table.SelectRows(
                          MyBufferTable, 
                          (sub) => sub[EnNo] = main[EnNo] and (sub[DateonlyNum] = main[DateonlyNum]
                            or (sub[DateonlyNum] = (main[DateonlyNum] + 1) and sub[Mode] = 6))
                        )
                      ),
                    ...

                    พยายามทำให้ Step เหลือน้อยๆ

                    เราสามารถแก้ Code ให้มีจำนวน Step น้อยลงได้ ซึ่งเท่าที่ทดสอบดู Query ก็จะเร็วขึ้นเล็กน้อยด้วย

                    แต่การทำแบบนี้ได้ ต้องเข้าใจโครงสร้างของ M Code ที่อ้างอิง Step ก่อนหน้ามาทำงานต่อ

                    เช่น แทนที่จะเขียนแบบนี้

                    let
                        Source = Query1,
                        Step1 = Source+55,
                        Step2 = Step1/10
                    in
                        Step2

                    การเขียนแบบนี้จะเร็วกว่าเล็กน้อย

                    let
                        Step2 = (Query1+55)/10,
                    in
                        Step2

                    รวมถึงการกำจัด Step ที่ไม่จำเป็น เช่น Add Custom Column ไปแล้ว มาเปลี่ยนชื่อทีหลัง หากเราเปลี่ยนชื่อไปเลยใน Step Add Custom Column ก็จะเร็วกว่า เป็นต้น

                    คลิปทดสอบการแก้ปัญหา Power Query ช้า

                    รายละเอียดของเทคนิคในคลิปนี้ค่อนข้างซับซ้อน ใครสนใจสามารถดูได้ที่นี่ ซึ่งรวมหลายเทคนิคด้วยกันคือ

                    • การยกเลิก Allow data preview to download in the background
                    • ใช้ Table.View มาช่วยบอกให้ Power Query รู้ลักษณะ Structure ของ Data Source โดยไม่ต้องไปลองดึงมาจริงๆ
                    • ยกเลิกการเช็ค Data Privacy
                    • ยกเลิก Parallel Load กรณีที่เอา Data เดิมหลายรอบ

                    เทคนิคอื่นๆ

                    ใครมีเทคนิคอื่นๆ ก็อย่าลืมมาแชร์กันด้วยนะครับ

                  • คัมภีร์สรุป M Code ใน Power Query ตอนที่ 4:  เทคนิค M Code ที่ใช้บ่อย

                    คัมภีร์สรุป M Code ใน Power Query ตอนที่ 4: เทคนิค M Code ที่ใช้บ่อย

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

                    เทคนิค M Code #1: อยากเก็บ Text ไว้เฉพาะอักขระที่กำหนด

                    วิธีนึงที่ใช้ได้ดีคือใช้ฟังก์ชัน Text.Select มาช่วย ซึ่งมีวิธีการใช้งานดังนี้

                    Text.Select(text as nullable text, selectChars as any) as nullable text
                    • text คือ ข้อความ Original
                    • selectChars สามารถใส่เป็น text ธรรมดาได้ แต่ปกติเราจะใส่เป็น List ที่มีอักขระที่อยากจะเอาไว้ซะมากกว่า

                    ยกตัวอย่างเช่น ข้อความของผมเป็นรายชื่อหนังดังนี้ แล้วผมใช้ Text.Select ให้เก็บเฉพาะตัว “a” ไว้

                    ผมสามารถกด Add Custom Column แล้วใส่สูตรดังนี้

                    =Text.Select([Movie Name],"a")
                    คัมภีร์สรุป M Code ใน Power Query ตอนที่ 4: เทคนิค M Code ที่ใช้บ่อย 196

                    อย่าลืมว่าทุกอย่างใน Power Query เป็น Case-Sensitive ทั้งหมด ถ้าอยากได้ “A” ด้วย ผมสามารถใส่เป็น List ได้ดังนี้

                    =Text.Select([Movie Name],{"a","A"})
                    คัมภีร์สรุป M Code ใน Power Query ตอนที่ 4: เทคนิค M Code ที่ใช้บ่อย 197

                    หรือจะใช้วิธีแปลงข้อมูลให้เป็น Lower Case ก่อนส่งค่าไปให้กับ Text.Select ทำงานต่อก็ได้ เช่น

                    Text.Select(Text.Lower([Movie Name]),{"a"})
                    คัมภีร์สรุป M Code ใน Power Query ตอนที่ 4: เทคนิค M Code ที่ใช้บ่อย 198

                    ถ้าเราอยากให้เหลือเฉพาะตัวอักษร a-z หรือ A-Z หรือ space ก็สามารถทำแบบนี้ได้

                    = Text.Select([Movie Name],{"a".."z"}&{"A".."Z"}&{" "})
                    เทคนิค M Code ที่ใช้บ่อย

                    แต่ถ้าจะเอาตัวเลขด้วยเราเขียนตรงๆ ด้วยการเพิ่ม {0..9}ไม่ได้ มันจะขึ้น Error มาเตือนว่า Expression.Error: We cannot convert the value 0 to type Text. (เพราะเราจะเชื่อมด้วย & ซึ่งต้องเป็น Text)

                    งั้นเราก็ใส่ {“0”..”9″} แทนก็ได้ 555

                    = Text.Select([Movie Name],{"a".."z"}&{"A".."Z"}&{" "}&{"0".."9"})

                    ดังนั้นจะเห็นว่าอักขระนอกเหนือจากที่เรากำหนด มันจะหายไปหมดเลย

                    สรุป M Code

                    let
                        Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
                        #"Changed Type" = Table.TransformColumnTypes(Source,{{"Rank", Int64.Type}, {"Movie Name", type text}}),
                        #"Added Custom" = Table.AddColumn(#"Changed Type", "Custom", each Text.Select([Movie Name],{"a".."z"}&{"A".."Z"}&{" "}&{"0".."9"}))
                    in
                        #"Added Custom"

                    เทคนิค M Code #2: กำจัดช่องว่างส่วนเกินระหว่างคำ

                    จะเห็นว่าการเปลี่ยน Star Wars: Episode VII – The Force Awakens ไปเป็น Star Wars: Episode VII The Force Awakens นั้น ระหว่าง VII กับ The มี space 2 ที ซึ่งมันอาจจะมี Space มากกว่านี้ในคำอื่นอีกก็ได้ ดังนั้นเราจะ replace คำธรรมดาๆ ไม่ได้ และเราก็ตัด space ทั้งหมดทิ้งไม่ได้ด้วยเช่นกัน

                    หลายๆ คนอาจจะนึกถึงฟังก์ชัน Trim แต่สำหรับใน Power Query แล้ว Trim จะตัดแค่ช่องว่างหัวท้ายเท่านั้น ไม่ตัดตรงกลางเหมือนกับ TRIM ใน Excel

                    ดังนั้นก็ถึงเวลาประยุกต์ใช้ความรู้หลายๆ อันมารวมกันแล้ว นั่นคือ

                    1. เราจะ Split ข้อความออกจากกันด้วย Space ให้ออกมาเป็น List
                    2. เราจะกำจัด item ที่เป็นช่องว่างออก
                    3. เราจะ Combine item กลับมารวมกันใหม่ด้วย delimiter ที่เป็นช่องว่างอีกที

                    ขั้นตอนที่ 1: Split ข้อความออกจากกันด้วย Space ให้ออกมาเป็น List ด้วย Text.Split

                    Text.Split( [Custom] ," ")
                    คัมภีร์สรุป M Code ใน Power Query ตอนที่ 4: เทคนิค M Code ที่ใช้บ่อย 199

                    ขั้นตอนที่ 2 : กำจัด item ที่เป็นช่องว่างออก โดยใช้ List.Select มาช่วย

                    List.Select(  Text.Split([Custom]," ")  , each _ <>"")
                    คัมภีร์สรุป M Code ใน Power Query ตอนที่ 4: เทคนิค M Code ที่ใช้บ่อย 200

                    ขั้นตอนที่ 3 : Combine item กลับมารวมกันใหม่ด้วย delimiter ที่เป็นช่องว่าง ด้วย Text.Combine

                    Text.Combine( List.Select(Text.Split([Custom]," "), each _ <>"") ," ")
                    คัมภีร์สรุป M Code ใน Power Query ตอนที่ 4: เทคนิค M Code ที่ใช้บ่อย 201

                    เท่านี้เราก็จะได้ผลลัพธ์เหมือนกันใช้ TRIM ใน Excel แล้ว

                    ซึ่งแน่นอนว่าเราสามารถเอาไปสร้างเป็นฟังก์ชันไว้ใช้ได้ด้วย เผื่อใช้ในที่อื่นอีก

                    เช่น สร้าง Blank Query แล้วใส่ Code นี้ลงไป จากนั้นตั้งชื่อว่า CustomTrimFX

                    (txt as text) as text =>
                    Text.Combine( List.Select(Text.Split(txt," "), each _ <>"") ," ")

                    คราวนี้เราก็จะเรียกใช้ได้ง่ายๆ เลย เช่น เอาไปใช้ผ่าน Invoke Custom Function หรือ จะเรียกใน Custom Column หรือ จะพิมพ์สูตรเองก็ยังได้

                    = Table.AddColumn(#"Added Custom", "CustomTrim", each CustomTrimFX([Custom]) )

                    ก็จะได้ผลลัพธ์เหมือนกับที่ทำข้างบนทั้งหมด

                    สรุป M Code

                    let
                        Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
                        #"Changed Type" = Table.TransformColumnTypes(Source,{{"Rank", Int64.Type}, {"Movie Name", type text}}),
                        #"Added Custom" = Table.AddColumn(#"Changed Type", "Custom", each Text.Select([Movie Name],{"a".."z"}&{"A".."Z"}&{" "}&{"0".."9"})),
                        #"Added Custom1" = Table.AddColumn(#"Added Custom", "CustomTrim", each  CustomTrimFX([Custom]) )
                    in
                        #"Added Custom1"

                    เทคนิค M Code #3: ทำให้ Table เหลือ Column เฉพาะที่มีข้อความตรงกับเงื่อนไขที่กำหนด

                    สมมติผมมี Data ที่มีหัวตารางเป็น Actual กับ Target แต่ละเดือนแบบนี้

                    คัมภีร์สรุป M Code ใน Power Query ตอนที่ 4: เทคนิค M Code ที่ใช้บ่อย 202

                    เราต้องการให้เหลือแค่คอลัมน์ที่เป็น Actual เท่านั้น ซึ่งถ้านั่งเลือกเองก็จะยุ่งยาก และไม่ Dynamic (เผื่อมีอีกหลายตารางที่ต้องทำแบบนี้)

                    คัดเลือกคอลัมน์ที่ต้องการด้วย Table.SelectColumns

                    ดังนั้นเราจะใช้ Concept ของ List มาช่วย โดยเราสามารถคัดเลือกคอลัมน์ที่ต้องการด้วยวิธีแบบนี้ได้

                    Table.SelectColumns(table as table, columns as any, optional missingField as nullable number) as table

                    เช่นถ้าจะเอาให้เหลือแค่ Actual-202001 กับ Actual-202002 ก็สามารถเขียนได้ว่า

                    =Table.SelectColumns(Source, {"Actual-202001","Actual-202002"} )

                    แปลว่าถ้าเราสร้าง List ที่เป็นชื่อคอลัมน์ที่ต้องการได้ก็จะจบ

                    สร้าง List ชื่อคอลัมน์ที่ต้องการ

                    ซึ่งเราสามารถทำได้โดยการใช้ Table.ColumnNames ดึงหัวตารางออกมา เช่น

                    Table.ColumnNames(table as table) as list
                    =Table.ColumnNames(Source)

                    แล้วเอา List.FindText มาช่วยคัดกรอง เช่น ตั้งชื่อตัวแปร MyHeader ด้วยสูตรนี้

                    MyHeader= List.FindText(Table.ColumnNames(Source),"Actual")

                    จะแปลว่าเอาคอลัมน์ที่มีคำว่า Actual อยู่ ไม่ว่าจะตรงไหนก็ตาม

                    คัมภีร์สรุป M Code ใน Power Query ตอนที่ 4: เทคนิค M Code ที่ใช้บ่อย 203

                    หรือจะเจาะจงว่าชื่อคอลัมน์ต้องขึ้นต้นด้วย Actual ก็ต้องใช้ List.Select มาช่วย คู่กับ Text.StartsWith แบบนี้

                    MyHeader= List.Select(Table.ColumnNames(Source),each Text.StartsWith(_,"Actual") )

                    พอเราได้ MyHeader แล้วก็เอาไปใส่ใน Table.SelectColumns ได้

                    =Table.SelectColumns(Source, MyHeader )

                    แต่ถ้าทำแค่นี้มันก็จะไม่มีคอลัมน์ Product ออกมาด้วย งั้นอย่าลืมใส่เพิ่มลงไป เช่น

                    =Table.SelectColumns(Source, {"Product"} & MyHeader )

                    หรือจะให้เอาคอลัมน์แรกมาแบบจะเป็นชื่ออะไรก็ได้

                    ก็ใช้ Table.ColumnNames(Source){0} เพื่อเอา item แรกมา

                    สรุปก็เลยเขียนแบบนี้แทน

                    = Table.SelectColumns(Source, {Table.ColumnNames(Source){0}} & MyHeader )

                    สรุป M Code

                    let
                        Source = Excel.CurrentWorkbook(){[Name="Table5"]}[Content],
                        MyHeader = List.Select(Table.ColumnNames(Source),each Text.StartsWith(_,"Actual") ),
                        Result = Table.SelectColumns(Source, {Table.ColumnNames(Source){0}} & MyHeader )
                    in
                        Result

                    เทคนิค M Code #4: แก้ Data Type ของแต่ละคอลัมน์แบบ Dynamic

                    หากเราลองเลือก 2 คอลัมน์แรกของตาราง แล้วกด Detect Data Type ดู จะเห็น Code แบบนี้

                    = Table.TransformColumnTypes(Result,{{"Productxxx", type text}, {"Actual-202001", Int64.Type}})

                    แสดงว่าเราสามารถใช้ฟังก์ชัน Table.TransformColumnTypes มาช่วยจัดการประเภทข้อมูลในตารางได้

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

                    จากการเทียบ code แสดงว่า เจ้า typeTransformations เนี่ย จะต้องใส่เป็น List แบบเดียวกับที่ผมทำสีแดงไว้ นั่นคือเป็น List ซ้อนอยู่ใน List อีกที โดยที่ List ข้างใน เป็น List ของแต่ละคอลัมน์ที่ต้องการ Transform คู่กับ type ที่ต้องการจะแปลง

                    {  {"Productxxx", type text}  ,  {"Actual-202001", Int64.Type}  }

                    วิธีที่ 1 : ใช้ List.Zip มาช่วย

                    ซึ่งวิธีนึงที่ทำได้และเราได้เรียนรู้ฟังก์ชันนั้นไปแล้วในบทที่แล้วก็คือ ใช้ List.Zip มาช่วยนั่นเอง

                    List.Zip(lists as list) as list
                     
                    ซึ่งในที่นี้ lists ต้องใส่เป็น {     ListColumnName , ListDataType      }  เพื่อให้เหมือนกับสิ่งที่อยากได้ข้างบน

                    เรามาสร้างทีละตัวละกัน

                    ListColumnName={Table.ColumnNames(Source){0}} & MyHeader
                    // ตัวนี้ง่ายๆ ตรงไปตรงมาเนอะ
                    ListDataType = {type text} & List.Repeat( {Int64.Type}, List.Count(ListColumnName)-1 )
                    // ตัวนี้บังคับให้คอลัมน์แรกเป็น text เสมอ นอกนั้นให้สร้าง List ของ Int64.Type ขึ้นมาเท่ากับจำนวนคอลัมน์ที่เหลือ ด้วยการ Repeat item ใน List เป็นจำนวน ListColumnName -1 ครั้ง

                    ซึ่งพอมาใช้ใน List.Zip จะเป็นแบบนี้

                    List.Zip({ ListColumnName,ListDataType } )

                    เอาไปใส่ใน Table.TransformColumnTypes อีกที

                    = Table.TransformColumnTypes(Result, List.Zip({ ListColumnName,ListDataType })  )

                    สรุป M Code

                    let
                        Source = Excel.CurrentWorkbook(){[Name="Table5"]}[Content],
                        MyHeader = List.Select(Table.ColumnNames(Source),each Text.StartsWith(_,"Actual") ),
                        Result = Table.SelectColumns(Source, {Table.ColumnNames(Source){0}} & MyHeader ),
                        ListColumnName={Table.ColumnNames(Source){0}} & MyHeader,
                        
                        // ตัวนี้บังคับให้คอลัมน์แรกเป็น text เสมอ นอกนั้นให้สร้าง List ของ Int64.Type ขึ้นมาเท่ากับจำนวน ListColumnName -1
                        ListDataType = {type text} & List.Repeat( {Int64.Type}, List.Count(ListColumnName)-1 ),
                        FinalResult= Table.TransformColumnTypes(Result,List.Zip({ ListColumnName,ListDataType } ))
                    in
                        FinalResult
                    คัมภีร์สรุป M Code ใน Power Query ตอนที่ 4: เทคนิค M Code ที่ใช้บ่อย 204

                    วิธีที่ 2 : ใช้ List.Transform มาช่วย

                    ส่วนของ typeTransformations นั้น นอกจากใช้ List.Zip มาช่วยแล้ว ยังใช้อีก List.Transform มาช่วยได้ด้วย ซึ่งตัว List.Transform นั้นจริงๆ เป็นตัวที่ยืดหยุ่นสุดๆ เลย เพราะ transform สามารถใส่เป็นฟังก์ชันได้ ดังนี้ (เรายังใช้ ListColumnName มาเก็บชื่อคอลัมน์อยู่นะ)

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

                    ถ้าจะบังคับให้ทุกคอลัมน์เป็น text จะง่ายสุดเลยกับวิธีนี้

                    List.Transform(ListColumnName, each {_, type text} )
                    // แปลว่า ให้แปลง list แต่ละตัวเป็น list ที่คู่กับคำว่า type text โดยเอา item ไปใส่แทนคำว่า _

                    จากนั้นเราเอาไปใส่ใน Table.TransformColumnTypes ดังนี้

                    Table.TransformColumnTypes(Result, List.Transform(ListColumnName, each {_, type text} ) )

                    ถ้าจะบังคับคอลัมน์ที่อยู่ใน MyHeader เป็น Int64.Type นอกนั้นเป็น Text

                    List คอลัมน์ที่ตรงกับ MyHeader นั้นก็คือ MyHeader ได้เลย อันนี้ไม่ยาก…

                    ส่วน List ที่ไม่ตรงกับ MyHeader อันนี้เราใช้ List.Difference มาช่วยได้ เช่น

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

                    เช่น

                    NotActualHeader = List.Difference(ListColumnName, MyHeader)

                    จากนั้นเราก็เรียกใช้ Table.TransformColumnTypes 2 รอบ สำหรับทั้ง 2 กรณี ก็จบแล้ว

                    สรุป M Code

                    let
                        Source = Excel.CurrentWorkbook(){[Name="Table5"]}[Content],
                        MyHeader = List.Select(Table.ColumnNames(Source),each Text.StartsWith(_,"Actual") ),
                        Result = Table.SelectColumns(Source, {Table.ColumnNames(Source){0}} & MyHeader ),
                        ListColumnName={Table.ColumnNames(Source){0}} & MyHeader,
                        //list ตัวที่หัวตารางที่ไม่ได้ขึ้นต้นด้วยคำว่า actual
                        NotActualHeader = List.Difference(ListColumnName, MyHeader),
                        //transform หัวตารางที่ไม่ได้ขึ้นต้นด้วยคำว่า actual เป็น text
                        Header1= Table.TransformColumnTypes(Result,List.Transform(NotActualHeader, each {_, type text} ) ),
                        //transform หัวตารางที่ขึ้นต้นด้วยคำว่า actual เป็น Int64.Type
                        Header2= Table.TransformColumnTypes(Header1,List.Transform(MyHeader, each {_, Int64.Type} ) )
                    in
                        Header2

                    หรือจะใช้ if … then … else … มาช่วยเขียนรวบไปเลยแบบนี้ก็ยังได้

                    let
                        Source = Excel.CurrentWorkbook(){[Name="Table5"]}[Content],
                        MyHeader = List.Select(Table.ColumnNames(Source),each Text.StartsWith(_,"Actual") ),
                        Result = Table.SelectColumns(Source, {Table.ColumnNames(Source){0}} & MyHeader ),
                        ListColumnName={Table.ColumnNames(Source){0}} & MyHeader,
                        //transform หัวตารางที่ขึ้นต้นด้วยคำว่า actual เป็น Int64.Type นอกนั้นเป็น Text ด้วย if...then...else
                        Header= Table.TransformColumnTypes(Result,
                            List.Transform(ListColumnName, each 
                                {_, if Text.StartsWith(_,"Actual") then Int64.Type else type text} ) )
                    in
                        Header

                    ทีนี้ไม่ว่าเราจะเปลี่ยนชื่อคอลัมน์ที่ต้นฉบับยังไง Query ก็ไม่พังแล้ว

                    นี่ต้นฉบับ

                    คัมภีร์สรุป M Code ใน Power Query ตอนที่ 4: เทคนิค M Code ที่ใช้บ่อย 205

                    นี่ผลลัพธ์

                    คัมภีร์สรุป M Code ใน Power Query ตอนที่ 4: เทคนิค M Code ที่ใช้บ่อย 206

                    เทคนิค M Code #5: Expand คอลัมน์จากทุก Table ให้มารวมกันแบบ Dynamic

                    จะ Expand แบบ Dynamic ได้ เราต้องสร้าง List ของคอลัมน์ที่ต้องการ Expand ให้ได้ เพื่อเอาไปใส่ใน Table.ExpandTableColumn

                    = Table.ExpandTableColumn(#"Removed Other Columns", "Data", List ของชื่อคอลัมน์)

                    หลักการคือ เราจะใช้สูตร List.Transform โดยใช้ Table.ColumnNames(_) กับทุกๆ Table เพื่อให้แต่ละ Table คืนค่ามาเป็น List ของหัวตารางใน Table นั้นๆ จากนั้นใช้ List.Union มารวม item ทุกตัวเข้าด้วยกัน ซึ่งสามารถเขียนสูตรได้ว่า

                    List.Union(List.Transform(#"Removed Other Columns"[Data],each Table.ColumnNames(_)))

                    สรุปแล้วสูตรโดยรวมเป็นดังนี้

                    = Table.ExpandTableColumn(#"Removed Other Columns", "Data", List.Union(List.Transform(#"Removed Other Columns"[Data],each Table.ColumnNames(_)))   )

                    เรื่องนี้ผมเคยเขียนบทความไว้โดยละเอียดแล้ว ลองไปอ่านได้ใน

                    ตอนนี้เพื่อนๆ ก็น่าจะได้เทคนิคการใช้ M Code จัดการปัญหาที่น่าปวดหัวไปได้หลายอันแล้ว ยังไงก็ลองเอาไปใช้ดูได้นะครับ ใช้ได้ผลเป็นยังไงก็บอกกันบ้างล่ะ

                    ตอนต่อไป

                    ตอนต่อไปจะเป็นเรื่องวิธีการทำให้ Power Query มันรันเร็วขึ้น ขอตัวไปศึกษาใน blog ของผู้เชี่ยวชาญ Power Query อย่าง Chris Webb ก่อน นะครับ ใครอยากรู้วิธีทำอะไรด้วย Power Query สามารถ comment บอกได้เลยนะครับ ^^

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

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

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

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

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

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

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

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

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

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

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

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

                      Table.ColumnNames(table as table) as list

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

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

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

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

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

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

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

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

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

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

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

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

                      {"A".."z"} // สร้าง List A-z แต่ได้อักขระ 6 ตัวที่อยู่ระหว่าง Z กับ a มาด้วย ซึ่งตัวพิมพ์ใหญ่มาก่อนพิมพ์เล็กนะ
                      คัมภีร์สรุป M Code ใน Power Query ตอนที่ 3: เจาะลึกเรื่องของ List 207

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

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

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

                      = {"a".."d"}&{1..5}&{"Sira","Ekabut"}
                      คัมภีร์สรุป M Code ใน Power Query ตอนที่ 3: เจาะลึกเรื่องของ List 209

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

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

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

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

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

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

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

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

                      นอกจากคำสั่งพื้นฐานเหล่านี้แล้ว Power Query ก็มีฟังก์ชันเกี่ยวกับ Listให้เลือกอีกมหาศาลเลย แต่ตัวที่ผมคิดว่าสำคัญมีดังนี้

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

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

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

                      List.Sort(list as list, optional comparisonCriteria as any) as list
                      
                      //comparisonCriteria สามารถใส่เป็น Order.DescendingOrder.Ascending ได้ 
                      //ถ้าไม่ใส่คือ ascending คือเรียงน้อยไปมาก
                      
                      = List.Sort({1,2,-5,8,4,2,"a","b","A"}) // ได้ {-5,1,2,2,4,8,"A","a","b"}
                      = List.Sort({1,2,-5,8,4,2,"a","b","A"},Order.Descending) // ได้ {"b","a","A",8,4,2,2,1,-5}

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

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

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

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

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

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

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

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

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

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

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

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

                      List.Intersect(lists as list, optional equationCriteria as any) as list
                      // lists ต้องใส่ List ใน List อีกชั้นนึง
                      
                      =List.Intersect({ {1,2,-5,8,4,2,"a","b","A"} , {1..9}   })   // ได้ {1,2,8,4}
                      =List.Intersect({ {1,2,-5,8,4,2,"a","b","A"} , {1..9},{3..15}  }) // ได้ {8,4}
                      =List.Intersect({ {1,2,-5,8,4,2,"a","b","A"} , {"a".."z"} }) // ได้ {"a","b"}
                      =List.Intersect({ {1,2,-5,8,4,2,"a","b","A"} , {"A".."Z"} }) // ได้ {"A"}
                      =List.Intersect({ {1,2,-5,8,4,2,"a","b","A"} , {"A".."Z"} },Comparer.OrdinalIgnoreCase) // ได้ {"a","b"}

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

                      List.Union(lists as list, optional equationCriteria as any) as list
                      // lists ต้องใส่ List ใน List อีกชั้นนึง
                      
                      =List.Union({ {1,2,-5,8,4,2,"a","b","A"} , {1..9} })   // ได้ {1,2,-5,8,4,2,"a","b","A",3,5,6,7,9}

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

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

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

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

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

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

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

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

                      List.PositionOfAny(list as list, values as list, optional occurrence as nullable number, optional equationCriteria as any) as any
                      
                      =List.PositionOfAny({1,2,-5,8,4,2,"a","b","A"},{99,8,"b"})  //ได้ 3 เพราะเจอ 8 ที่ index 3

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

                      List.ContainsAny(list as list, values as list, optional equationCriteria as any) as logical
                      
                      =List.ContainsAny({1,2,-5,8,4,2,"a","b","A"}, {4})   // ได้ true
                      =List.ContainsAny({1,2,-5,8,4,2,"a","b","A"}, {6})   // ได้ false
                      =List.ContainsAny({1,2,-5,8,4,2,"a","b","A"}, {6,4})  // ได้ true

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

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

                      List.Repeat(list as list, count as number) as list
                      
                      =List.Repeat({"a","b","A"} , 2)  // ได้ {"a","b","A","a","b","A"}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                      { 6, 15, 20 }

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

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

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

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

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

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

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

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

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

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

                      List.Accumulate(list as list, seed as any, accumulator as function) as any
                      • list คือ list ซึ่งมีข้อมูลที่เราต้องการจะทำการสะสมค่า (Accumulate)
                      • seed คือ ค่าตั้งต้น
                      • accumulator คือ ฟังก์ชันที่จะใช้กับการสะสมค่า
                      =List.Accumulate({1, 2, 3, 4}, 0, (state, current) => state + current)

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

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

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

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

                      ต่อไป…

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

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

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

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

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

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

                      ตอนต่อไป

                      ต่อไปจะเป็นการรวมเทคนิค M Code ที่ใช้บ่อย โดยจะมีการประยุกต์ใช้ฟังก์ชันเจ๋งๆ ในการจัดการเรื่องต่างๆ เช่น คัดเลือกอักขระที่ต้องการ การจัดการหัวตารางแบบ Dynamic เป็นต้น

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

                      • คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each

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

                        เมื่อคุณใช้งาน Power Query ไปเรื่อยๆ จุดที่บ่งบอกว่า คุณกำลังจะก้าวไปสู่ความสามารถอีกขึ้นหนึ่งของ Power Query ก็คือ ความสามารถในการใช้งาน Custom Function นี่แหละครับ ซึ่งหากใช้เป็น คุณจะสามารถแก้ไขปัญหาที่ซับซ้อนได้มากขึ้นกว่าการใช้เครื่องมือมาตรฐานมากมายหลายเท่าเลย

                        Function คือ ขุมพลังที่แท้จริงของ M Code

                        Function (ฟังก์ชัน) คือ สิ่งที่สามารถรับค่า input เข้ามาคำนวณประมวลผล แล้วส่งผลลัพธ์ output ออกมาได้

                        รูปแบบ

                        (input1,input2,...) => expression วิธีคำนวณหรือสูตรของฟังก์ชันนั้นๆ

                        เช่น จะสร้างฟังก์ชันของตัวเองขึ้นมา (เรียกว่า Custom Function) เอาไว้หาพื้นที่สามเหลี่ยม

                        (ฐาน,สูง) => 0.5*ฐาน*สูง   //เราตั้งชื่อ input เป็นภาษาไทยก็ได้นะ แต่ผมแนะนำให้ตั้งเป็น eng แหละดีแล้ว

                        การจะเข้าใจเรื่องนี้ได้ดีขึ้น ผมอยากให้นึกถึงฟังก์ชันของ Excel เป็นตัวเปรียบเทียบครับ ยกตัวอย่างเช่น ฟังก์ชัน LEFT ใน Excel มีรูปแบบดังนี้

                        =LEFT(text,num_chars) //จะเห็นว่ามี input 2 ตัวคือ text และ num_chars

                        ซึ่งถ้าเราใส่ input 2 ตัวนี้เข้าไป LEFT ก็จะทำการดึงบางส่วนของข้อความ text ออกมาจากทางซ้าย ด้วยจำนวนตัวอักษระที่ระบุใน num_chars เช่น =LEFT(“abcde”,2) จะได้ผลลัพธ์เป็น 2 ตัวซ้าย นั่นคือ “ab” เป็นต้น

                        หน้าที่ของฟังก์ชัน

                        รับค่า input →  เอาไปทำอะไรซักอย่าง (processing) → แล้วคายค่าผลลัพธ์ output ออกมา

                        สามารถระบุประเภท Data Type ได้

                        (input1 as text ,input2 as number) as text => expression

                        สามารถกำหนด input เป็น optional ได้

                        (input1 as text ,optional input2 as number) as text => expression 

                        ซึ่งตัวที่เป็น optional หากไม่ใส่ค่ามาจะมีค่าเป็น null ดังนั้นเราอาจต้องกำหนดว่า ถ้าค่า input2 เป็น null จะให้ทำอะไรแทน เป็นต้น

                        การเรียกใช้ Custom Function

                        สมมติว่าเราสร้าง Query ชื่อ TriangleArea ขึ้นมาด้วย M Code ว่า

                        (ฐาน,สูง) => 0.5*ฐาน*สูง
                        Power Query M Custom Function

                        เวลาเราจะใช้งาน ก็สามารถเรียกใช้ได้ใน M Code ได้เลย เช่น ให้สร้าง Blank Query อีกอันนึงในไฟล์เดิม แล้วใส่ M Code ว่า

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 211
                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 212
                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 213

                        หรือจะใช้ผ่าน Invoke Custom Function ก็ได้ เช่น

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 214

                        ซึ่งมันก็จะออกมาเป็นแบบนี้

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 215

                        การใช้ each หรือ ฟังก์ชันแบบย่อๆ

                        เคยเห็น each ที่โผล่มาตอนเรียกคำสั่งต่างๆ มั้ย?

                        หลายๆ ครั้งเวลาที่เรากดคำสั่งเมนูมาตรฐานมันก็จะใส่ each ให้เราเอง เช่น ในตัวอย่างข้างบนก็มี each หรือว่าหากกด Add Column → Custom Column ก็จะมี each ซึ่งผมจะอธิบายโดยละเอียดให้เห็นชัดๆ ดังนี้ว่าจริงๆ แล้วมันคืออะไรกันแน่ครับ

                        เช่น สมมติเรามีข้อมูล ราคาสินค้า และจำนวนอยู่ แล้วอยากจะหายอดขาย

                        ปกติแล้วเราก็จะ Add Custom Column ได้แบบนี้

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 216

                        ซึ่งสูตรจะออกมาเป็น = Table.AddColumn(#”Changed Type”, “ยอดขาย”, each [ราคา]*[จำนวน])

                        แล้วเจ้า each มันคืออะไรล่ะ? เดี๋ยวผมจะอธิบายให้ฟัง

                        each คือการย่อวิธีเขียนฟังก์ชัน

                        จากที่เรารู้แล้วว่าเราสามารถใช้ฟังก์ชันลักษณะนี้ได้

                        (x) => x+1

                        ดังนั้นเราสามารถเปลี่ยนชื่อตัวแปรจาก x เป็น _ ได้ จะได้ว่า

                        (_) => _+1

                        ซึ่งหากใช้ชื่อตัวแปรเป็น _ เราจะสามารถย่อ Code ส่วน (_) => ได้เป็น each ดังนี้

                        each _+1

                        และถ้ามีการอ้างควบคู่กับ [ ] ที่เป็น Record lookup operator เช่น จริงๆ แล้ว _  ที่กำลังอ้างถึง คือตัว table หรือ record จะสามารถละตัว _ ทิ้งไปได้เลย เพื่อให้อ่านสูตรแล้วดูง่ายขึ้น เช่น

                        Table.SelectRows ( Source, (_) => _[Qty] > 100 )

                        จะย่อได้เป็น

                        Table.SelectRows ( Source, each _[Qty] > 100 )

                        และย่อได้อีกว่า

                        Table.SelectRows ( Source, each [Qty] > 100 )

                        each ที่โผล่มาเมื่อกด Custom Column

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

                        ก่อนอื่น ให้เราลองเปลี่ยนสูตรใน Custom Column ให้เหลือแค่ _ จะเห็นภาพชัดขึ้นครับ

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 217

                        ซึ่งสูตรจะออกมาเป็น

                        = Table.AddColumn(#"Changed Type", "ยอดขาย", each _ )

                        แต่จะเห็นว่าในคอลัมน์ยอดขายจะได้ผลลัพธ์ออกมาเป็น Record ในบรรทัดนั้นๆ ซึ่งประกอบไปด้วย Field ทุกอันในตารางเดิมใน Step #”Changed Type”

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 218

                        นั่นแปลว่า _ ใน Step การ AddColumn จะแทน Record ของแต่ละบรรทัดนั่นเอง
                        และการอ้างอิงแต่ละ Field ของ Record จึงทำด้วยวิธี _[ชื่อ Field]

                        และการที่เราใช้ _ เป็นชื่อของ input ทำให้สามารถละ _ ตอนอ้างอิงชื่อ Field ได้ ทำให้แทนที่จะเขียนเต็มๆ ว่า _[ชื่อ Field] จึงสามารถเขียนแค่ [ชื่อ Field] ได้เลย

                        แปลว่า ถ้าเราไม่ย่ออะไรเลย สูตรเต็มๆ จะเป็นแบบนี้ครับ

                        = Table.AddColumn(#"Changed Type", "ยอดขาย", (_)=>_[ราคา]*_[จำนวน]) 

                        โดยที่ _ ที่เป็น Input ของฟังก์ชันก็คือ Record ในแต่ละบรรทัดนั่นเอง

                        พอย่อ (_)=> เป็น each จะได้แบบนี้

                        = Table.AddColumn(#"Changed Type", "ยอดขาย", each _[ราคา]*_[จำนวน]) 

                        แต่พอเขียนแบบย่อสุดๆ โดยละ _ หน้า [ ] ทิ้ง เราเลยเขียนสูตรได้ว่า

                        = Table.AddColumn(#"Changed Type", "ยอดขาย", each [ราคา]*[จำนวน])

                        สรุปวิธีการอ้างอิง Record (แถว), List (ข้อมูลในคอลัมน์) และ Table (ตาราง)

                        ถ้าจะอ้างอิง Record ปัจจุบันที่เลือกอยู่ เรารู้แล้วว่าสามารถใส่ _ หลัง each ได้เลย

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 219

                        ทีนี้ถ้าเราอยากอ้างถึงอย่างอื่นบ้างล่ะ เช่น จะอ้างถึง Table ทั้งอันเลย คอลัมน์ที่ต้องการ หรือ Record ก่อนหน้า จะทำยังไง? เรามาดูทีละอันครับ

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

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 220

                        Tips : ถ้าอยากได้ Step อื่นก็ใส่ชื่อ Step นั้นๆ ลงไป ถ้าอยากได้ตารางอื่นก็ใส่ชื่อตัวแปรที่เป็นตารางอื่น หรือชื่อ query อื่นลงไป

                        ถ้าจะอ้างอิงคอลัมน์ที่ต้องการทั้งคอลัมน์ ก็ใส่ชื่อ Table ตามด้วย [ชื่อคอลัมน์] เช่น ใส่ว่า Source[ผลไม้] ผลลัพธ์ก็จะออกมาเป็น List

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 221

                        ถ้าจะอ้างอิงถึงแถวก่อนหน้า แปลว่าเราต้องรู้แถวปัจจุบันของตัวเองก่อนถึงจะง่าย ซึ่งวิธีที่ง่ายที่สุดคือใส่ index column ให้เริ่มตั้งแต่เลข 0 เอาไว้ เช่น

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 222

                        แล้วเราค่อยอ้างอิง Table แล้วใส่ row index ที่ต้องการ (index 0 คือ แถวแรกนะ อย่าลืม)

                        ดังนั้นเราจะใส่ใน Custom Column ว่า =Source{[Index]-1} แบบนี้ได้ครับ

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 223

                        ทีนี้แถวแรกมัน Error เราจะจัดการยังไงดี?

                        การจัดการ Error ด้วย try…otherwise…

                        หากเราอยากจะจัดการ Error ไม่ให้แสดงออกมา เราสามารถใช้คำสั่ง

                        try...x... otherwise ...y... 

                        มาช่วยได้ครับ

                        คำสั่งนี้มีวิธีทำงาน คือ หาก try x แล้วสำเร็จก็จะทำ x ไป แต่ถ้าลอง x แล้ว Error ก็จะทำ y แทน ซึ่งเราอาจจะทำให้ y เป็นอะไรก็ได้ เช่น 0 หรือปล่อยเป็น null ก็นิยมครับ

                        เช่น ใน Custom Column เราเพิ่มสูตรส่วนของ try และ otherwise ว่า 

                        =try [ราคา]*[จำนวน] otherwise 0

                        แบบนี้มันจะเอาคอลัมน์ [ราคา]*[จำนวน] หาก error ให้แสดงค่า 0 แทน

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 224

                        รวมถึงการอ้างอิงแถวก่อนหน้าที่ Error ในแถวแรกสุด (เพราะไม่มีแถวก่อนหน้า) เราอาจจะให้เป็น null ก็ได้ เช่น

                        try Source{[Index]-1} otherwise null

                        แค่นี้ก็จัดการ error ที่ไม่ต้องการได้แล้วครับ

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 225

                        การเขียนเงื่อนไขด้วย if

                        สำหรับการเขียนเงื่อนไขใน M Code เราก็ใช้ if…then…else… ประกอบกับการใช้ and or not ก็ได้ครับ

                        อย่างตอนเขียนสูตรเพื่ออ้างอิงแถวก่อนหน้า ถ้าไม่ใช้ try…otherwise… เราจะใช้ if ก็ได้ ก็จะให้ผลลัพธ์แบบเดียวกัน

                        if [Index]=0 then null else Source{[Index]-1}
                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 226

                        เจาะลึก each ด้วยการใช้ M Code เลียนแบบ VLOOKUP Approximate Match

                        สมมติผมมีข้อมูลคะแนนสอบอยู่แล้วต้องการจะตัดเกรด ดังนี้
                        ผมเอาตารางซ้ายเข้าเป็น Query ชื่อ TestResult ส่วนตารางขวาชื่อ RefGrade

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 227

                        ใน Query Test Result นั้นผมสร้าง Custom Column ด้วยสูตรว่า =RefGrade ก็จะได้ผลลัพธ์แบบนี้ ว่าในแต่ละบรรทัดของคะแนนสอบ เราได้ตาราง RefGrade กลับมาทั้งตารางเลย (ซึ่งเยอะไป!)

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 228

                        สิ่งที่เราต้องการจริงๆ คือ อยากดูว่าคะแนนที่ได้นั้นอยู่ในช่วงไหน ซึ่ง logic ที่ใช้ได้คือ ต้องทำการเลือก RefGradeมาเฉพาะบรรทัดที่คะแนนต่ำสุด น้อยกว่าหรือเท่ากับ คะแนนสอบที่ได้ในแต่ละบรรทัดเท่านั้น และค่อนเลือกเอาบรรทัดสุดท้ายมาฃ

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

                        Table.SelectRows(table as table, condition as function) as table

                        จะเห็นว่า input ที่มันต้องการมี 2 ตัว คือ table ต้นฉบับ และ เงื่อนไข ซึ่ง table ต้นฉบับนี่ง่ายมาก ก็คือ RefGrade นั่นแหละ
                        แต่ที่ยากก็คือเจ้า condition ที่ดันต้องใส่เป็นฟังก์ชันด้วยสิ

                        เพื่อที่จะให้เข้าใจว่าปกติมันทำงานยังไง เราจะไปดู Query RefGrade แล้วไปลอง Filter มันเล่นๆ ดูก่อน ด้วยเงื่อนไขว่า คะแนนต่ำสุด <= 69 จะได้แบบนี้

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 229

                        ซึ่งเราจะเห็นฟังก์ชัน Table.SelectRows ทำงานให้เราดูเลยว่าต้องเขียนยังไง

                        = Table.SelectRows(#"Changed Type", each [คะแนนต่ำสุด] <= 69)

                        เราก็เลยคิดว่าจะเอาคำสั่งนี้กลับไปเขียนใน TestResult ที่เราค้างไว้ได้ ซึ่งมันก็ใช้ได้จริงๆ (แค่เปลี่ยนชื่อ table จาก “Changed Type” เป็น RefGrade)

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 230

                        และถ้าเราไม่อยากจะ hardcode เลข 69 ล่ะ?

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

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 231

                        ทำไมถึงหาไม่เจอ? ก็เป็นเพราะภายใต้ each อันที่สอง มันกำลังมอง Record ของตาราง RefGrade อยู่น่ะสิ ซึ่งมันไม่มีคะแนนไง เพราะคะแนนอยู่ในตาราง TestResult ต่างหาก!!

                        แล้วเราจะไปอ้างอิง Field ที่อยู่ใน Current Record ของ TestResult ได้ยังไง? คราวนี้แหละเราจะไม่ใช้การย่อด้วย each แล้วเพราะมันทำให้เกิดการอ้างอิงที่ซ้ำกันแล้วโปรแกรมมันก็งง เราจะตั้งชื่อ input ด้วยตัวเราเองให้ชัดเจนไปเลยจะได้ไม่งง โดย Current Record ของ TestResult ผมจะตั้งชื่อว่า main และแต่ละ row ของ RefGrade ผมจะตั้งชื่อว่า sub ซึ่งจะแปลงสูตรได้ดังนี้

                        จากเดิมที่เขียนแล้วไม่ชัดเจน จึงมีปัญหา

                        = Table.AddColumn(#"Changed Type", "Custom", each Table.SelectRows(RefGrade, each [คะแนนต่ำสุด] <= [คะแนน]))

                        เปลี่ยนใหม่ ให้ชัดเจนขึ้นว่าอ้างถึง Field ของ Record ไหน

                        = Table.AddColumn(#"Changed Type", "Custom",  (main) => Table.SelectRows(RefGrade, (sub)=> sub[คะแนนต่ำสุด] <= main[คะแนน]))

                        คราวนี้ผลลัพธ์ไม่ Error แล้ว

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 232

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

                        = Table.AddColumn(#"Changed Type", "Custom", (main) => Table.Last(Table.SelectRows(RefGrade, (sub)=> sub[คะแนนต่ำสุด] <= main[คะแนน])))
                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 233

                        ผลลัพธ์ออกมาเป็น Record เดียวแล้ว ก็กด expand ที่มุมขวาบนของ Field ได้เลย จะได้ผลลัพธ์สุดท้ายที่สมบูรณ์ดังรูป

                        คัมภีร์สรุป M Code ใน Power Query ตอนที่ 2 : Function และ each 234

                        ตอนต่อไป

                        ตอนนี้เราก็ได้เรียนรู้การใช้ฟังก์ชันเบื้องต้นกันไปแล้ว เดี๋ยวในตอนต่อไปจะป็นเรื่องของ List แบบลึกซึ้งขึ้น ซึ่งมีประโยชน์มากด้วยแน่นอนครับ ติดตามต่อได้เลย

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

                        • คัมภีร์สรุป M Code ใน Power Query ตอนที่ 1

                          คัมภีร์สรุป M Code ใน Power Query ตอนที่ 1

                          ซีรีส์นี้จะเป็นการเอาเนื้อหา M Code Language ของ Power Query บางส่วนในหนังสือ Excel Power Up และการเรียนรู้เพิ่มเติมของผมหลังจากนั้นมาผสมผสานกัน เนื้อหาจึงมีทั้งส่วนที่เหมือนและแตกต่างกับในหนังสือด้วยนะครับ อีกอย่างในหนังสืออาจ Copy Code ลำบาก ผมเลยเขียนเป็นบทความไว้ให้เลยดีกว่า จะได้ลอง Copy Paste สูตรไปเล่นได้ง่ายๆ ด้วย

                          เอาเป็นว่าใครอยากจะลงลึกเรื่อง M Code ก็อ่านซีรีส์นี้ได้เลย เพราะผมอยากให้มีคนไทยใช้เครื่องมือนี้เป็นเยอะๆ ครับ อีกอย่างมันใช้ได้ทั้งใน Excel และ Power BI เลย จึงมีประโยชน์มากๆ

                          และที่สำคัญ ในซีรีส์นี้ผมจะมาอัปเดทเนื้อหาเพิ่มให้เรื่อยๆ ด้วยนะ ติดตามไปกันได้ยาวๆ เลยครับ

                          M Language คืออะไร?

                          M Language เป็นภาษาในรูปแบบฟังก์ชัน (Functional Language ตรงข้ามกับอีก concept คือ Object-oriented Programming) ที่ออกแบบมาเพื่อจัดการและดัดแปลงข้อมูลซึ่งเป็นภาษาของ Power Query โดยเฉพาะ ซึ่งปกติเราจะใช้เครื่องมือมาตรฐานใน Power Query Editor สร้าง M Code ออกมาให้เรา แล้วเราค่อยดัดแปลงมันอีกที แต่มาถึงตอนนี้ เราจะมาทำความเข้าใจ M Code ให้ลึกซึ้งมากขึ้นเพื่อที่ให้สามารถใช้มันจัดการปัญหาที่ซับซ้อนมากขึ้นได้ โดยเฉพาะการเขียน Custom Function ที่ทรงพลังมากๆ

                          เราจะค่อยๆ ทำความเข้าใจทีละส่วน เริ่มจากพื้นฐานกันครับ

                          ก่อนอื่นคงต้องทบทวนความจำซักนิดนะครับ ว่า M Language เป็นภาษาที่สนใจเรื่องตัวพิมพ์เล็กพิมพ์ใหญ่ หรือที่เรียกว่า่ Case Sensitive พูดง่ายๆ คือ ถ้าเขียนชื่อฟังก์ชันอะไรผิดแค่เรื่องตัวพิมพ์เล็กพิมพ์ใหญ่ มันก็จะ Error ทันทีเลย (แม้แต่คำว่า let กับ in ก็ต้องตัวพิมพ์เล็กให้ถูกต้อง)

                          Tips : เพื่อให้การเขียน Code ของเราสะดวกสบายที่สุด ผมแนะนำว่าให้คุณฝึกใน Excel365 หรือ Power BI ครับ เพราะมันจะมี Intellisence มาช่วย Guide การเขียนให้เราด้วย

                          Let Expression

                          เวลาเราใช้เครื่องมือมาตรฐานสั่งคำสั่งต่างๆ มันจะมีคำว่า let … in… โผล่มาโดยอัตโนมัติ ในรูปแบบ คือ

                          let
                          	ชื่อตัวแปร1=expression1(สูตร),
                          	ชื่อตัวแปร2=expression2(สูตร),
                          	ชื่อตัวแปร3=expression3(สูตร)
                          in
                          	ชื่อตัวแปรที่ต้องการแสดงผลลัพธ์

                          ยกตัวอย่างเช่น

                          let
                          	Step1=1+2,
                          	Step2=Step1*2
                          in
                          	Step2
                          //แบบนี้ผลลัพธ์จะได้ 6

                          ภายใน Let คือ การตั้งชื่อตัวแปรให้สูตร (Expression) โดยที่เราสามารถตั้งชื่อตัวแปร (Variable) กี่ตัวก็ได้ตามต้องการ โดยคั่นด้วยเครื่องหมาย comma เช่นในตัวข้างบน จริงๆ ก็คือเขียนในบรรทัดเดียวกันก็ได้แบบนี้ (และนี่คือสาเหตุว่าทำไมหลัง let ตัวสุดท้ายไม่มี comma เพราะมันใช้คั่นการตั้งชื่อตัวแปร)

                          let   ตัวแปร1=สูตร1,   ตัวแปร2=สูตร2,   ตัวแปร3=สูตร3

                          และชื่อตัวแปรแต่ละอันก็จะไปโผล่เป็นชื่อ Step ใน Power Query Editor ด้วยนะ

                          หลัง in คือ สิ่งที่มันจะทำการคำนวณเพื่อแสดงเป็นผลลัพธ์ เวลามันทำงานมันจะดูว่า “หลัง in เราต้องการผลลัพธ์อะไร” มันจะดูเองว่าจะเอาค่ามาจากไหน

                          • ในตัวอย่างข้างบน มันจะรู้ว่าเราต้องการค่าในตัวแปร Step2
                          • มันก็จะไปดูว่า Step2 ต้องใช้ค่าจากตัวแปร Step1 ไปคูณ2
                          • จากนั้นมันก็จะไปดูว่า Step1 เกิดจากเอาค่า 1+2 ได้ 3
                          • แล้ว Step2 จะเอา 3*2 ได้ 6

                          Variable และ Expression

                          จากในรูปแบบของ M Code จะพบว่า

                          • สิ่งที่พิมพ์อยู่ก่อนเครื่องหมาย = คือ Variable หรือ ชื่อตัวแปร
                          • สิ่งที่เราพิมพ์หลังเครื่องหมาย = คือ Expression หรือ สูตร

                          ซึ่ง Expression จะถูกคำนวณออกมาได้สิ่งที่เรียกว่า Value หรือ ค่าผลลัพธ์ ซึ่งมีได้หลายประเภท

                          เรามาลงรายละเอียดแต่ละตัวกันครับ

                          Variable (ชื่อตัวแปร)

                          ถ้าจะใช้ชื่อตัวแปรแบบอ่านง่ายที่สุด ต้องมีลักษณะดังนี้

                          1. ต้องขึ้นต้นด้วยตัวอักษร หรือ _
                          2. ห้ามมีช่องว่างเว้นวรรค คีย์เวิร์ดที่สงวนไว้ หรือ สัญลักษณ์ประหลาด

                          ถ้าจะผิดกฎดังกล่าว ต้องใส่ชื่อตัวแปรแบบนี้  #”ชื่อตัวแปรนั่นคือ ใส่ชื่อไว้ในเครื่องหมายคำพูด แล้วขึ้นต้นด้วย Hashtag (ถ้าสังเกตเวลาใช้เครื่องมือ UI มาตรฐาน มันจะตั้งชื่อตัวแปรให้เราแบบนี้แหละ)

                          let
                          	Step1=1+2,
                          	#"Step 2"=Step1 *2,
                          	Step3=#"Step 2" /3
                          in
                          	Step3

                          ดังนั้น ถ้าไม่อยากให้ชื่อตัวแปรใน M Code ของเรามี # ประหลาดๆ แบบนี้ ก็ให้ตั้งชื่อแบบไม่ต้องเว้นวรรคนะครับ

                          Expression (สูตร)

                          คล้ายๆ การเขียนสูตรใน Excel ที่สามารถเป็นส่วนผสมกันระหว่าง Value ประเภทต่างๆ, Operator รวมถึง ฟังก์ชันต่างๆ ทั้ง Standard Function ที่มีมาให้อยู่แล้ว และ Custom Function ที่เราเขียนขึ้นเองได้ด้วย

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

                           ประเภทของ Value (ผลลัพธ์)

                          ประเภทของ Value ใน Power Query มีดังนี้

                          ประเภทรูปแบบ
                          (ระวังตัวพิมพ์เล็กพิมพ์ใหญ่)
                          ตัวอย่าง
                          Null (ค่าว่าง)nullnull
                          Logical (ตรรกะ)true falsetrue false
                          Number (ตัวเลข)ตัวเลข0 1 -3 8.5 4.9e-5
                          Time (เวลา)#time(hour, minute, second)#time(06,15,00)
                          Date (วันที่)#date(year, month, day)#date(2019,07,21)
                          DateTime (วันที่คู่กับเวลา)#datetime(year, month, day, hour, minute, second)#datetime(2019,07,21, 06,15,00)
                          DateTimeZone (วันที่คู่กับเวลา แบบมี TimeZone)#datetimezone( year, month, day, hour, minute, second, offset-hours, offset-minutes)#datetimezone(2019,07,21, 06,15,00, 07,00)
                          Duration (ระยะเวลา)#duration(day,hour,minute,second)#duration(1,2,30,0)
                          Text (ข้อความ)“ข้อความในคำพูด”“hello” “สวัสดี”
                          Binary ไฟล์/ข้อมูล Binary#binary(“AQID”)
                          List (รายการข้อมูล
                          มักใช้กับข้อมูล 1 คอลัมน์)
                          {value1,value2,value3}{1, 2, 3}
                          Record (ข้อมูล 1 แถว)[field1=value1,field2=value2][ A = 1, B = 2 ]
                          Table#table( List ของชื่อหัวตาราง , List ของข้อมูล)
                          โดยข้อมูลแต่ละแถวเป็น List อีกทีนึง
                          #table({“A”,”B”},{{1,2},{3,4}})
                          Function(input1,input2,…) => expression ของฟังก์ชันนั้นๆ(x) => x + 1
                          Type type { number }
                          type table [ A = any, B = text ]

                          เดี๋ยวเราจะมาลงรายละเอียดข้อมูลแต่ละประเภทอีกทีครับ

                          Operator ต่างๆ ที่ใช้บ่อยๆ

                          ใน Power Query นั้น Operator ต่างๆ จะทำงานได้เฉพาะกับ Data Type ที่เหมาะสมเท่านั้น เช่น เราไม่สามารถเอาข้อความที่มีหน้าตาเหมือนตัวเลขไปทำการบวกลบกันได้ ซึ่งต่างจาก Excel และ DAX ที่จะพยายาม Convert ประเภทข้อมูลให้เราโดยอัตโนมัติ

                          ประเภทเครื่องหมายความหมายตัวอย่าง
                          คำนวณ+บวก3+2
                           ลบ3-2
                           *คูณ3*2
                           /หาร3/2
                          ตัวเชื่อม( )ให้คำนวณในวงเล็บก่อน(3+2)*5
                           &เชื่อมข้อมูล“Big”&”Cat”
                          เปรียบเทียบ=เท่ากับ3=2
                           <> ไม่เท่ากับ3<>2
                           มากกว่า3>2
                           น้อยกว่า3<2
                           >=มากกว่าหรือเท่ากับ3>=2
                           <=น้อยกว่าหรือเท่ากับ3<=2
                          ตรรกะandและx>3 and x<=10
                           orหรือx<3 or x>10
                           notกลับจริงเป็นเท็จ
                          เท็จเป็นจริง
                          not (x>3)

                          เรื่องที่ควรรู้ของ M Code

                          Comment

                          //ถ้าจะ Comment บรรทัดเดียว ทำแบบนี้ (ใส่เครื่องหมาย // นำหน้า)
                          /*
                          ถ้าจะ Comment 
                          หลายบรรทัด
                          ทำแบบนี้ (ใส่ใน /* ….. */ )
                          */

                          Code จะเรียงยังไงก็ได้!!

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

                          let
                          	Step2=Step1*2,
                          Step1=1+2
                          	
                          in
                          	Step2

                          Return ค่าอะไรออกมาก็ได้

                          ซึ่งเราจะ Return ค่าอะไรออกมาหลัง In ก็ได้ เช่น ถึงจะเขียน Step2 มาแล้ว แต่เรา Return ค่า Step1 ก็ได้

                          let
                          	Step1=1+2,
                          	Step2=Step1*2
                          in
                          	Step1

                          โดยที่หากเราเขียนแบบนี้ Power Query จะหาทางเองว่าต้องใช้ตัวไหนบ้างในการรัน แล้วมันจะไม่รันตัวที่ไม่จำเป็นด้วย! ซึ่งในตัวอย่างข้างบนมันจะดูว่า สุดท้ายแล้วต้องการผลลัพธ์จากตัวแปร Step1 ซึ่งคำนวณจาก เอาค่า 1+2 ดังนั้นมันจะไม่เสียเวลาไปคำนวณ Step2 เลยครับ หรือถ้าเอาแบบเห็นชัดๆ เลย คือ

                          let
                          	Step1=1+2,
                          	Step2=Step1*2
                          in
                          	4+5

                          แบบนี้ผลลัพธ์จะได้ 9 ซึ่งเกิดจาก 4+5 เลย โดยไม่เกี่ยวกับ Step1 และ Step2 ด้วยซ้ำครับ !!

                          let in ซ้อน let in ได้อีก

                          let
                          	Step1=1+2,
                          	Step2=Step1+3
                          	Step3=
                          		let
                          			Step1 = 100
                          			Step2 = Step1*2
                          		in
                          			Step2
                          in
                          	Step3

                          แบบนี้จะได้ผลลัพธ์ออกมาเป็น 200 เนื่องจาก Step3 สุดท้ายจะไปอ่านค่า Step2 ที่อยู่ใน Let ชั้นในว่า

                          Step2 = Step1*2 // ซึ่งจะได้ Step2 = 100*2 ซึ่งจะได้ 200

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

                          ค่า Value ที่เป็น Output ของ Expression

                          ใน Power Query มีได้หลายแบบ ทั้งที่ให้ค่าเดี่ยวๆ และ ค่าเป็นโครงสร้าง ดังนี้

                          Primitive Value : ข้อมูลพื้นฐานตัวเดียวเดี่ยวๆ

                          พวกนี้เราได้เรียนรู้กันไปแล้วในตารางข้างบนเนอะ

                          • Null (ค่าว่าง)
                          • Logical (ตรรกะ)
                          • Number (ตัวเลข)
                          • Time (เวลา)
                          • Date (วันที่)
                          • DateTime (วันที่คู่กับเวลา)
                          • DateTimeZone (วันที่คู่กับเวลา แบบมี TimeZone)
                          • Duration (ระยะเวลา)
                          • Text (ข้อความ)

                          Structured Values : ข้อมูลที่ประกอบกันเป็นโครงสร้าง

                          List : รายการข้อมูล

                          เป็นการเอาข้อมูล Primitive มาเรียงกัน อยู่ในเครื่องหมาย { } คั่นด้วย comma

                          มักถูกใช้เป็นข้อมูล 1 คอลัมน์ใน Table ที่มีหลายๆ ค่า

                          รูปแบบ

                          {value1, value2, value3 }

                          ตัวอย่าง

                          • {1, 2, 3} // list ตัวเลข 1 2 และ 3
                          • { 1..5 } // มีค่าเท่ากับ { 1, 2, 3, 4, 5 }
                          • {“d”..”g”} // มีค่าเท่ากับ { “d”, “e”, “f”, “g”}
                          • {“D”..”G”} // มีค่าเท่ากับ { “D”, “E”, “F”, “G”}
                          • {100, true, “A”}
                          คัมภีร์สรุป M Code ใน Power Query ตอนที่ 1 235

                          รวม List ได้ด้วย &

                          { 1, 2 } & {3, 4 } // { 1, 2, 3, 4 }
                           { 1, 2 } & { 3, 2} // { 1, 2, 3, 2 }
                          คัมภีร์สรุป M Code ใน Power Query ตอนที่ 1 236

                          อ้างอิงข้อมูลใน List ด้วย {เลข index}

                          โดยที่ เลข index จะเริ่มต้นด้วยเลข 0 (itemแรก คือลำดับที่ 0 นะ ระวังให้ดี!!)

                          SampleList = { 10, 20, 30 }
                          คัมภีร์สรุป M Code ใน Power Query ตอนที่ 1 237

                          ลองคลิ๊กขวาแล้ว Drill Down ที่ 20 ดู จะได้ออกมาเป็น

                          SampleList{1} // จะได้ 20  และสังเกตว่าถ้าจะอ้างอิง item ลำดับที่ 2 เลข index จะเป็นเลข 1 นะ
                          คัมภีร์สรุป M Code ใน Power Query ตอนที่ 1 238

                          Record : เป็นกลุ่มของ Field

                          คำว่า Field หมายถึงข้อมูลที่เป็นคู่กันระหว่าง name และ value

                          มักถูกใช้เป็นข้อมูล 1 แถวใน Table ที่มีหลายๆ คอลัมน์

                          รูปแบบ

                          [ FieldName1=value1, FieldName2=value2, FieldName3=value3 ]

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

                          ตัวอย่าง

                          [ A = 100, B = 200, C = 300 ]
                          คัมภีร์สรุป M Code ใน Power Query ตอนที่ 1 239

                          รวม Record ได้ด้วย &

                          [ A = 1 ] & [ B = 2 ] // [ A = 1, B = 2]

                          ถ้าชื่อ field ซ้ำ จะยึดตัวหลังสุด

                          [ A = 1, B=2 ] & [ A = 10 ] // [ A = 10, B=2 ]
                          คัมภีร์สรุป M Code ใน Power Query ตอนที่ 1 240

                          การอ้างอิงข้อมูลใน Record ด้วย [ชื่อ Field]

                          SampleRecord = [ First Name = "Sira", Last Name = "Ekabut", Height = 172, Weight = 67 ]
                          คัมภีร์สรุป M Code ใน Power Query ตอนที่ 1 241

                          ลองคลิ๊กขวาแล้ว Drill Down ที่คำว่า Sira ใน First Name ดู จะออกมาเป็น

                          SampleRecord[First Name]    // จะได้ "Sira"
                          คัมภีร์สรุป M Code ใน Power Query ตอนที่ 1 242

                          Table : ตาราง

                          คือข้อมูลที่ถูกจัดให้สามารถมีหลายคอลัมน์ และสามารถมีหลายแถวได้ โดยแต่ละคอลัมน์จะสามารถอ้างอิงได้ด้วยชื่อคอลัมน์

                          รูปแบบ (แบบพื้นฐาน)

                          #table( set ของชื่อหัวตาราง , set ของข้อมูลแต่ละแถวอยู่ภายใน  { } คั่นด้วย comma )
                          #table( {"col1","col2"} , { { r1c1value, r1c2value} , { r2c1value, r2c2value},...   } )

                          ตัวอย่าง

                          SampleTable = #table( {"A", "B"}, { {1, 2}, {3, 4}, {5, 6} } )

                          หรือจะเขียนเป็นแบบนี้ก็จะดูคล้ายตารางมากขึ้น

                          SampleTable = #table( 
                          {"A", "B"}, 
                          { 
                          {1, 2}, 
                          {3, 4}, 
                          {5, 6} 
                          } )

                          ซึ่งจะได้ผลลัพธ์แบบนี้ครับ

                          คัมภีร์สรุป M Code ใน Power Query ตอนที่ 1 243

                          การอ้างอิงข้อมูลใน Table

                          ถ้าอ้างอิงด้วย table[ ชื่อ Field ] (แบบไม่ต้องมีเครื่องหมายคำพูด)  จะได้ผลลัพธ์เป็น List ที่เป็นรายการของ Field นั้นๆ (มักใช้กับการอ้างอิงข้อมูลใน 1 คอลัมน์ในตาราง) เช่น =SampleTable[B] จะได้ List ข้อมูลในคอลัมน์ B ออกมา

                          คัมภีร์สรุป M Code ใน Power Query ตอนที่ 1 244

                          ถ้าอ้างอิงด้วย table{เลข index} จะได้ผลลัพธ์ออกมาเป็น Record ซึ่งเป็นข้อมูลใน 1 แถวของตาราง เช่น =SampleTable{1} จะได้ Record แถวที่ 2 ของ Table ออกมา (อย่าลืมว่า Index แถวแรก เริ่มที่เลข 0)

                          คัมภีร์สรุป M Code ใน Power Query ตอนที่ 1 245

                          ถ้าอ้างอิงด้วยทั้ง {index} และ [ชื่อ Field] ซ้อนกัน ก็จะได้ Item นั้นๆ ออกมาเลย (เพราะระบุทั้งแถวทั้งคอลัมน์แล้ว) เช่น ลองกด Drill Down ดูที่เลข 4 จากตอนที่เป็น Table จะได้แบบนี้

                          = SampleTable{1}[B] // หมายถึงเอาแถวที่สอง (index1 คือแถว 2) และ เอา Field ชื่อ B
                          คัมภีร์สรุป M Code ใน Power Query ตอนที่ 1 246

                          ซึ่งเราสามารถอ้างอิง Field ก่อนแถวก็ได้เช่นกัน เช่น = SampleTable[B]{1}

                          คัมภีร์สรุป M Code ใน Power Query ตอนที่ 1 247

                          นอกจากนี้เรายังสามารถอ้างอิงจาก Value ใน Field ที่กำหนด เพื่อให้ได้ Record ออกมาได้ด้วย
                          ด้วยรูปแบบ {[ชื่อ Field = ค่าที่ต้องการ]} เช่น

                          = SampleTable{[A=3]}

                          จะได้ Record ที่ Field A มีค่าเท่ากับเลข 3

                          คัมภีร์สรุป M Code ใน Power Query ตอนที่ 1 248

                          อย่างไรก็ตาม วิธีอ้างอิงจาก Value จะใช้ได้ก็ต่อเมื่อมี Value นั้นๆ แค่ตัวเดียวใน Table เท่านั้น หากมีค่าซ้ำกันมันจะให้ผลเป็น Error ทันที

                          Tips : หากเรากด Drill Down ลงไปในช่องที่อยู่ในคอลัมน์ที่เคยสั่ง Remove Duplicates เอาไว้ก่อน จะทำให้ Power Query รู้ว่า Field นั้นมีค่าไม่ซ้ำกันแน่นอน สูตรที่ออกมาจะเป็นลักษณะของการอ้างอิงจาก Value ใน Field ที่กำหนด ได้โดยอัตโนมัติ

                          เช่น ตารางของผมเคยกด Remove Duplicates คอลัมน์ TXID มาก่อน จากนั้น ผมกด Drill Down ไปที่ Field ราคาต่อชิ้น ในแถวเดียวกับ TXID ที่มีค่าเป็น TX00004 จะได้ผลลัพธ์ออกมาดังนี้

                          คัมภีร์สรุป M Code ใน Power Query ตอนที่ 1 249

                          การ Convert ประเภทข้อมูลที่ใช้บ่อย

                          อย่างที่บอกไปแล้วว่า เวลาจะใช้ Operator หรือฟังก์ชันต่างๆ ใน M Code เรื่องของ Data Type เป็นเรื่องที่ค่อนข้างซีเรียส ดังนั้นเราจะต้องมีการ Convert ประเภทข้อมูลให้ถูกต้องก่อนที่จะทำการคำนวณด้วย

                          ซึ่งการ Convert ประเภทข้อมูลใน M Code เราจะใช้ฟังก์ชันมาช่วยครับ วิธีการจำทั่วไป คือ จะแปลงเป็นอะไรให้ขึ้นต้นด้วยประเภทนั้น แล้วตามด้วย .From ได้เลย

                          จากเป็นวิธีการตัวอย่าง
                          ใดๆNumberNumber.From(value as any) as number=Number.From(“0123”)
                          =123

                          =Number.From(#date(1900,01,01)) =2
                          สังเกต : วันแรกที่ Power Query แทนด้วยเลข 1 คือวันที่ 31 Dec ค.ศ.1899 นะครับ ซึ่งไม่ตรงกับ Excel ซึ่งเลข 1 คือวันที่ 1 Jan ค.ศ. 1900)
                          ใดๆTextText.From(value as any) as text=Text.From(123)
                          =”123″
                          ใดๆLogicLogical.From(value as any) as logical= Logical.From(1)
                          = Logical.From(“True”)
                          = true
                          ใดๆDateDate.From(value as any, optional culture as nullable text) as nullable date=Date.From(1)
                          =31/12 ค.ศ.1899 หรือ พ.ศ. 2442

                          =Date.From(“21 July 2019″,”en-GB”)
                          =21/7 ค.ศ.2019 หรือ พ.ศ. 2562
                          ใดๆDateTimeDateTime.From(value as any, optional culture as nullable text) as nullable datetime=DateTime.From(“21 July 2019 13:30″,”en-GB”)
                          =21/7 ค.ศ.2019 หรือ พ.ศ. 2562 เวลา 13:30 น.

                          Tips: ถ้าจะทำเป็นจำนวนเต็ม แล้วจะใช้ Int64 ต้องระวัง เพราะถ้าใช้ Int64 มีการปัดตัวเลขตามหลักคณิตศาสตร์ด้วย

                          =Int64.From(1234.789)
                          =1235

                          ถ้าจะปัดเศษทิ้งไปเลย แนะนำให้ใช้ RoundDown แทน

                          = Number.RoundDown(1234.789,0)
                          =1234

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

                            แหล่งอ้างอิง M Code เจ๋งๆ

                            Website

                            YouTube

                          • Statistics with Excel ตอนที่ 6 :  Hypothesis Testing

                            Statistics with Excel ตอนที่ 6 : Hypothesis Testing

                            Hypothesis Testing หรือการทดสอบสมมติฐาน คือกระบวนการที่เราใช้ข้อมูลจาก Sample มาตัดสินเกี่ยวกับ Population โดยจะตัดสินเลือกสมมติฐาน (Hypothesis) ที่มีข้อมูลสนับสนุนว่าน่าจะถูกต้องมากกว่า โดยเราจะตั้งสมมติฐาน 2 อัน คือ…

                            Null Hypothesis vs Alternative Hypothesis

                            • Null Hypothesis, H0 (H null หรือ H ตามด้วยศูนย์) : เป็นแนวความคิดเดิมที่เป็นที่ยอมรับในปัจจุบัน
                              • มักจะมีเครื่องหมาย = อยู่ อาจจะเป็น =,>=,<= เป็นต้น
                            • Alternative Hypothesis, Ha: แนวความคิดใหม่ ที่เราอยากจะนำเสนอ หรือบางทีก็เรียกว่า Research Hypothesis
                              • มีเครื่องหมาย ตรงข้ามกับ H0

                            ตัวอย่างเช่น บริษัทแห่งหนึ่งผลิตยาพิษซึ่งในขวดควรจะมีปริมาตรเฉลี่ย 250 cc ขึ้นไป ทางลูกค้าที่อยากซื้อยาพิษไปใช้เกิดความสงสัยว่ายาพิษในขวดอาจมีการใส่น้อยเกินไป (กลัวคนกินแล้วไม่ตาย) จึงมีสมมติฐานดังนี้

                            Statistics with Excel ตอนที่ 6 : Hypothesis Testing 250
                            • H0 : µ >= 250 cc (ถ้ามันมากกว่าหรือเท่ากับ 250 แสดงว่ายาพิษเยอะดี ok)
                            • Ha: µ < 250 cc (ที่กำลังอยากจะทดสอบ ว่ามันน้อยกว่า 250 ป่าว ซึ่งจะต้องใส่ให้ตรงข้ามกับ H0)

                            ที่นี้เราจะรู้ได้ยังไงว่าสมมติฐานอันไหนที่เป็นความจริง?

                            หลักการคิดก็คือ

                            1. ให้เรา Assume ว่า Null Hypothesis (H0) นั้นถูกต้องไว้ก่อน
                            2. ดูหลักฐานจากการทดสอบของเรา เช่น จากข้อมูลที่สุ่มออกมา
                              • ถ้าสิ่งที่สุ่มออกมามีความน่าจะเป็นต่ำ แสดงว่า H0 ไม่จริง (Reject H0) ดังนั้นเราก็จะหันมาสนับสนุน Ha แทน
                              • ถ้าสิ่งที่สุ่มออกมามีความน่าจะเป็นไม่ต่ำ แสดงว่าเราไม่สามารถปฏิเสธ H0 ได้ (Fail to Reject H0)

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

                            ค่า p-Value และคำว่า Significant

                            วิธีคิดคือ ถ้าสมมติว่า H0 เป็นจริง ความน่าจะเป็นที่จะพบข้อมูลที่สำรวจได้ในปัจจุบันหรือไปในทิศทางเดียวกับ Ha จะเป็นเท่าไหร่? ซึ่งเราจะเรียกความน่าจะเป็นนี้ว่า p-value

                            จะเห็นว่า P-Value ก็คือความน่าจะเป็นอย่างนึง ดังนั้นค่ามันจะต้องออกมาอย่ระหว่าง 0-1 แน่นอน ซึ่งมันวัดความน่าจะเป็นของสิ่งนี้

                            P-Value = มีความเป็นไปได้แค่ไหน ถ้าหากว่า H0 จริง แล้วจะเกิดเหตุการณ์แบบที่เรากำลังเจออยู่หรือไปสุดขั้วไปในทิศของ Ha

                            เช่น ในตัวอย่างยาพิษ

                            • H0 : µ >= 250 cc (ถ้ามันมากกว่าหรือเท่ากับ 250 แสดงว่ายาพิษเยอะดี ok)
                            • Ha: µ < 250 cc (ที่กำลังอยากจะทดสอบ ว่ามันน้อยกว่า 250 ป่าว ซึ่งจะต้องใส่ให้ตรงข้ามกับ H0)

                            สมมติว่าเราสุ่มแล้วได้ค่าเฉลี่ยยาพิษอยู่ที่ 230 cc

                            p-value จะแปลว่า ความน่าจะเป็น ที่เราสุ่มแล้วได้ค่าเฉลี่ย น้อยกว่าหรือเท่ากับ 230 เมื่อ assume ว่า Ho จริง นั่นเอง (ซึ่ง P-Value ออกมาเป็นความน่าจะเป็น “น้อยกว่า”หรือเท่ากับ 230 เพราะ Ha ทิศทางคือ”น้อยกว่า” ซึ่งเป็นทิศทางที่โต้แย้ง H0 นั่นเอง)

                            ดังนั้นการคำนวณ P-Value จะขึ้นอยู่กับตัว Hypothesis ด้วยว่าเรากำลังทดสอบด้วยเครื่องหมายเปรียบเทียบอะไร เช่น

                            Hypothesis Testing หรือการทดสอบสมมติฐาน

                            ค่า p-value ที่น้อย แปลว่า โอกาสที่จะเกิดเหตุการณ์แบบที่กำลังพบอยู่นั้นน้อยมากๆ อย่างมีนัยสำคัญ ดังนั้นเราก็จะมีหลักฐานไปแย้ง Null Hypothesis ได้ เรียกว่า Reject H0

                            ซึ่งจริงๆ แล้วระดับนัยสำคัญนั้นมีอยู่หลายระดับ ซึ่งเรียกว่า significant level (α) เราจึงควรกำหนดเอาไว้ก่อนว่า เราจะคิด p-Value เทียบกับเกณ์ significant level (α) ที่ระดับเท่าไหร่ดี ซึ่ง ปกติแล้วเรามักจะใช้ significant level (α) ที่ 0.05 หรือ 5% ครับ

                            หาก p-value <  α ที่เราตั้งไว้เราก็จะทำการปฏิเสธ H0 และยอมรับ Ha นั่นเอง

                            หรือจะมองมุมกลับก็ได้ว่า หากเราสุ่ม Sample มาแล้วหาค่า Test Statistic ของ Sample นั้นออกมาแล้วเปรียบเทียบกับค่่า Critical Value ที่จะทำให้ P-value < α ก็สามารถตอบได้เช่นกันว่าจะ Reject H0 หรือไม่ (ใครงงรอดูตัวอย่างท้ายตอนนะ)

                            Statistics with Excel ตอนที่ 6 : Hypothesis Testing 251

                            เอาล่ะ ในชีวิตจริงส่วนใหญ่เราจะใช้ α ที่ 5% ดังนั้นก็เลยจะมีคนแนะนำกันแบบนี้ไปเลยว่า

                            ถ้า p value ≤ 0.05 หรือ 5% → ความแตกต่างที่พบนั้น Significant หรือ “มีนัยสำคัญ” นั่นเอง

                            โดยเราจะคำนวณค่า p-Value ได้จาก Test Statistic ต่างๆ เช่น ความรู้จาก Central Limit Theorem ที่เราได้เรียนมาในตอนที่แล้ว ได้อธิบายถึงการแจกแจงของ Sample Mean ที่เป็นไปได้ เราก็จะคำนวณความน่าจะเป็นได้แล้วล่ะ ซึ่งเดี๋ยวเรามาดูตัวอย่างกันครับจะได้เห็นภาพ

                            ตัวอย่าง

                            Statistics with Excel ตอนที่ 6 : Hypothesis Testing 252
                            ต้องการขวดยาพิษจำนวนมากจ้า

                            เรายังอยู่ที่ตัวอย่างเดิมนะนั่นคือ บริษัทแห่งหนึ่งผลิตยาพิษซึ่งในขวดควรจะมีปริมาตรเฉลี่ย 250 cc ขึ้นไป ทางลูกค้าที่อยากซื้อยาพิษไปใช้เกิดความสงสัยว่ายาพิษในขวดอาจมีการใส่น้อยเกินไป (กลัวคนกินแล้วไม่ตาย) ปรากฏว่าลูกค้าทำการสุ่มตัวอย่างยาพิษมา 100 ขวด และพบว่ามีปริมาณยาพิษเฉลี่ยอยู่ที่ 240 cc และมี sd ของ sample อยู่ที่ 30 cc

                            ลูกค้าไม่แน่ใจว่า 240 cc ที่ได้ ซึ่งน้อยกว่า 250 cc ที่เคยได้สำรวจไว้นั้น มันน้อยกว่าจริงๆ อย่างมีนัยสำคัญมั้ย หรือแค่บังเอิญกันแน่?? วิธีการทดสอบก็คือ เราต้องตั้งสมมติฐาน 2 อันคือ

                            • H0 : µ >= 250 cc (ถ้ามันมากกว่าหรือเท่ากับ 250 แสดงว่ายาพิษเยอะดี ok)
                            • Ha: µ < 250 cc (ที่กำลังอยากจะทดสอบ ว่ามันน้อยกว่า 250 ป่าว ซึ่งจะต้องใส่ให้ตรงข้ามกับ H0)

                            หากเราสมมติว่า H0 จริงไว้ก่อน

                            จาก Central Limit Theorem ที่เราเรียนในตอนที่แล้ว เราจะได้ว่า Sample Mean ที่สุ่มออกมา แต่ไม่รู้ค่า σ หรือ Standard deviation ของ population จะต้องใช้ t-distribution มาช่วย

                            จากบทที่แล้วเรารู้ว่า ค่า t สามารถคำนวณได้จาก

                            t (df=n-1) = (sample mean – µ) / (s / √ n)
                            • ในที่นี้เราไม่รู้ σ จึงใช้ t-distribution ที่ df=n-1 แทนครับ จึงจะใช้ s แทน σ ได้
                            • sample mean = 240
                            • µ = 250
                            • s= 30
                            • n=100

                            จะได้ว่าจากการทดลองของเรา ค่า t นั้นจะคำนวณได้ว่า

                            t = (240-250)/(30/SQRT(100))
                            = -3.333

                            วิธีสรุปด้วยการหาค่า P-Value

                            p-value = ความน่าจะเป็นที่จะพบข้อมูลเท่ากับที่สำรวจได้ในปัจจุบัน (240) หรือไปในทิศทางเดียวกับ Ha ( µ < 250)

                            ดังนั้น p-value = โอกาสที่จะเกิดค่า Sample Mean <= 240 เป็นเท่าไหร่ นั่นเอง ซึ่งสามารถใช้สูตรนี้

                            =T.DIST(x,deg_freedom,cumulative)
                            ซึ่งจะให้ค่าความน่าจะเป็นที่น้อยกว่าหรือเท่ากับค่า x จาก t-distribution ที่มีค่า mean และ standard deviation ที่กำหนดครับ
                            =T.DIST(-3.333,100-1,TRUE)
                            = 0.000604652 หรือ 0.06%
                            ซึ่งเป็นพื้นที่ฝั่งซ้ายที่เราต้องการพอดี จึงใช้ได้เลย

                            แปลว่าโอกาสที่ sample mean <=240 นั้นมีค่า = 0.000604652 หรือ 0.06% ซึ่งน้อยมาก (p-value น้อยมาก) จึงสรุปได้ว่า
                            p-value 0.000604652 นั้น <0.05 แปลว่า เราจะปฏิเสธ H0 ที่บอกว่า µ >= 250 แล้วยอมรับ Ha ที่บอกว่า µ < 250 นั่นเอง

                            นั่นคือ เรายอมรับว่า µ < 250 จริงๆครับ ( อย่างไรก็ตาม โอกาสที่จะเกิดความผิดพลาดในการสรุป หรือ Type I Error อยู่ที่ 5% ครับ เนื่องจากเราใช้ค่า 0.05 เป็นตัวเทียบกับ p-value นั่นเอง)

                            วิธีสรุปด้วยการเทียบกับ Critical Value

                            ถ้าหากเราเปลี่ยนมุมมองไปว่า ค่า t เท่าไหร่ ที่จะได้ p-value 0.05 พอดี จะคำนวณได้ด้วยวิธีนี้

                            =T.INV(probability,deg_freedom)
                            =T.INV(0.05,100-1)
                            = -1.66039

                            แปลว่าถ้าเราคำนวณค่า t ได้ไปไกลกว่า -1.66039 (ในที่นี้คือ ถ้าได้น้อยกว่า -1.66039) ก็จะแปลว่า p-Value 0ะน้อยกว่า 0.05 ไปด้วย แบบนี้จะ Reject H0 ได้เช่นกัน

                            ซึ่งในเคสนี้เราคำนวณได้ t ของ sample เท่ากับ -3.333 ซึ่งมันน้อยกว่า -1.66039 จริง แสดงว่า Reject H0 นั่นเอง

                            Error ในการสรุปผล Hypothesis Testing

                            อย่างไรก็ตามที่ เรายังมีโอกาสสรุปผิดได้อยู่ดี เช่น ที่ระดับ significant level (α) ที่ 0.05 หรือ 5% แปลว่า
                            เรามีโอกาส 5% ที่ดันไป Reject H0 ทั้งๆ ที่จริงแล้ว H0 มันถูกต้องอยู่แล้ว ซึ่งความคิดพลาดนี้เราจะเรียกว่า Type I error หรือ False Positive/False Alarm (ซึ่งเกิดจากความซวยจากความน่าจะเป็น α นั้นๆ)

                            แต่ในทางกลับกัน หากเราดันไม่ Reject H0 ทั้งๆ ที่ Ha มันเป็นจริง แบบนี้จะเรียกว่า Type II Error หรือ False Negative ครับ (ก็แปลว่าเราก็จะยังมีความเชื่อผิดๆ ตาม H0 ต่อไปนั่นเอง อดได้โอกาสเลือกสิ่งที่ถูกต้องมากกว่าอย่าง Ha)

                            Statistics with Excel ตอนที่ 6 : Hypothesis Testing 253
                            https://www.weibull.com/hotwire/issue88/relbasics88.htm

                            ตอนต่อไป

                            ในตอนนี้เราก็ได้ทำความเข้าใจ Concept ของ Hypothesis Test ในภาพรวมกันไปแล้ว ในตอนต่อไปเราจะมาเจาะลึก Hypothesis Test ในหลายๆ กรณีกันครับ เช่น One Sample t-test, Two Sample t-test, ANOVA (F-test), Large sample z-test : One proportion, Large sample z-test : Two proportions

                            สารบัญซีรีส์ Statistics

                            • Statistics with Excel ตอนที่ 5 : Central Limit Theorem

                              Statistics with Excel ตอนที่ 5 : Central Limit Theorem

                              ทฤษฎีสุดเจ๋งอย่าง Central Limit Theorem นั้นเป็นสิ่งที่มีประโยชน์มากในการประมาณค่า Parameter ของ Population ได้จากการคำนวณค่า Statistic ของ Sample ครับ ดังนั้นเพื่อไม่ให้เสียเวลา เราไปดูกันเลย!

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

                              • Population คือ คนในบริษัททั้งหมด
                              • Sample คือ คนในบริษัทที่ผมสุ่มมา 100 คน
                              • Parameter = เช่น ค่าเฉลี่ยของส่วนสูงของคนในบริษัททั้งหมด ( µ = ไม่รู้)
                              • Statistic = เช่น ค่าเฉลี่ยของส่วนสูงของคนในบริษัทที่ผมสุ่มมา 100 คน = xบาร์ = ได้ 165 cm

                              คำถามคือแล้วไอ้ 165cm ที่ผมได้นั้นมันจะใกล้เคียงกับค่า µ แค่ไหน?? และถ้าสุ่มมา 100 คนอีกที จะเฉลี่ยได้เท่าเดิมหรือไม่?? (แน่นอนว่าไม่) และไอ้เจ้า Mean (xบาร์) ของตัวอย่างที่สุ่มมาก็ดูจะไม่ค่อยมีความแน่นอนด้วย แล้วเราจะคิดยังไงต่อไปดีล่ะ?

                              โชคดีที่มันมีทฤษฎีที่ช่วยเราตอบได้ครับ ทฤษฎีนี้ชื่อว่า Central Limit Theorem (CLT) ซึ่งเป็นอะไรที่เจ๋งมากๆ เลย

                              Central Limit Theorem (CLT) สำหรับ Mean

                              ทฤษฎีนี้บอกว่า ถ้าเราสุ่มตัวอย่างจาก Population (ที่มี distribution แบบไหนก็ได้ !!) ที่มีค่า Mean = µ และมีค่า Standard deviation = σ แล้วล่ะก็

                              เมื่อมีการสุ่มตัวอย่างในอุดมคติ ที่สุ่มแล้วมีการใส่คืน* ด้วย sample size ที่ใหญ่มากพอ (จะให้ดี n ต้อง ≥ 30** ) การแจกแจงความน่าจะเป็นของ xบาร์ของตัวอย่างที่สุ่มมา (Distribution of Sample Mean) จะสามารถอธิบายได้ด้วย Normal Distribution

                              • มี Mean = µ (แปลว่า distribution นี้จะมี mean เท่ากับ population จริง)
                              • Standard deviation = σ / √ n (แปลว่า distribution นี้จะมี sd น้อยกว่า population จริง
                              • เราจะเรียก Standard deviation ของ การแจกแจง Sample Mean หรือเจ้า σ / √ n ว่า Standard Error of Estimates หรือ  SE (estimate) ซึ่งผมอาจจะใช้คำสั้นๆ ว่า Standard Error หรือ SE นะครับ
                              • ย้ำว่า ไม่ใช่การแจกแจงของ item ในตัวอย่างแต่ละชุดนะครับ แต่เป็นการแจกแจงของ xบาร์ของตัวอย่างที่เป็นไปได้ทั้งหมดจากทุกๆ trial (Distribution of Sample Mean) ถ้าใครงงเดี๋ยวดูตัวอย่างในหัวข้อ Simulation ได้ครับ
                              Central Limit Theorem

                              * ถ้าสุ่มในชีวิตจริงมันใส่คืนไม่ได้อยู่แล้ว ขอให้สุ่มมาไม่เกิน 5-10% ของ population ละกัน เพื่อจะได้ให้แต่ละ sample นั้น independent กัน จะได้ไม่ bias จนเกินไป เพราะสูตร Standard deviation จริงๆ ต้องเป็น ( σ / √ n )* SQRT( (N-n)/(N-1) ) แต่ถ้า n (จำนวน sample) น้อยมากๆ เมื่อเทียบกับ N (จำนวน Population) จะทำให้ SQRT( (N-n)/(N-1) ที่เรียกว่า Finite Population Correction Factor มีค่าเป็น 1 ทำให้ Standard deviation = σ / √ n ง่ายๆ ได้เลย

                              ** อย่างไรก็ตามถ้า Population มี Distribution แบบ Normal อยู่แล้ว ถึงจะสุ่ม Sample จำนวนน้อยกว่า 30 ก็ยังจะได้ออกมาเป็น Normal Distribution อยู่ดีครับ แต่ถ้า distribution ของ population เบ้หนักมากๆ n อาจต้อง ≥ 50 จะปลอดภัยกว่า

                              นั่นคือ

                              xบาร์ ~ Normal (µ, σ / √ n )

                              ถ้าแปลงเป็น standard normal distribution แบบบทที่แล้ว จะได้ว่า

                              z = (xบาร์ – µ) / (σ / √ n) ~ Normal (0,1)

                              ลองทดสอบ CLT ดูด้วย Simulation ใน Excel

                              ผมจะสุ่มค่าจากเลข Random 0-1000 ออกมาด้วย RAND()*1000 เราได้เรียนรู้ไปในตอนที่แล้วว่ามันเป็น Uniform Distribution (ซึ่งเป็นรูปสี่เหลี่ยมผืนผ้าโง่ๆ เลยนะ ไม่มีความคล้าย Normal ด้วยซ้ำจริงมะ )โดยสุ่มออกมาครั้งละ 50 ตัว จากนั้นหาค่า Mean ซึ่งถ้ากด F9 เลขที่ได้จะเปลี่ยนไปเรื่อยๆ จากการ Random

                              ตัวนี้เราแอบรู้อยู่แล้วว่า Uniform Distribution มี population mean และ sd ดังนี้

                              • Mean = ค่าเฉลี่ยตรงกลาง = (a+b)/2 = (0+1000)/2 =500
                              • Variance = 1/12 * (b-a)^2
                              • σ= SQRT(Variance) = SQRT(1/12 * (1000-0)^2) = 288.675

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

                              สุ่มครั้งแรก

                              Statistics with Excel ตอนที่ 5 : Central Limit Theorem 254

                              สุ่มครั้งที่ 2 : โดยกด F9 เพื่อสุ่มใหม่ ค่าที่ได้ก็จะเปลี่ยนไป

                              Statistics with Excel ตอนที่ 5 : Central Limit Theorem 255

                              เราจะทำ Simulation เหตุการณ์แบบนี้ 100 ที (สุ่ม 100 รอบ) ใน Excel แล้วนำค่า Mean ที่ได้มา Plot Distribution ดูสิว่าจะออกมาเป็นยังไง?

                              เทคนิคการทำ Simulation ใน Excel ที่เป็นที่นิยม คือใช้ Data -> What if Analysis -> Data Table มาช่วย ดังนี้ (เลขจะเปลี่ยนไปมาก็ช่างมัน)

                              Statistics with Excel ตอนที่ 5 : Central Limit Theorem 256
                              1. สร้างเลขเรียง 1-100 ใน H5:H104
                              2.เลือกคลุมพื้นที่ H4:I104
                              3. เรียกใช้เครื่องมือ Data -> What if Analysis -> Data Table
                              4. เลือก Column Input Cell เป็นช่องว่างๆ ช่องไหนก็ได้
                              5. กด ok

                              ผลลัพธ์ที่ออกมาจะได้ค่าที่ผ่านวิธีการแบบเดียวกับ I4 ออกมาอีก 100 ช่อง (แต่ random เลขเลยเปลี่ยนไป)

                              ถ้าเรานำ Data ใน I5:I104 มา Plot Histogram จะได้ดังรูป ซึ่งดูใกล้เคียงกับกราฟ Normal หรือ t-distribution ใช้ได้เลย

                              และจะเห็นว่า

                              • ค่าเฉลี่ยของ Sample Mean =AVERAGE(I5:I104) = 499.2247 ซึ่งใกล้เคียงกับ Mean Population จริงซึ่งก็คือ 500 มากๆ
                              • ค่า SE (estimate) =46.61 ซึ่งจาก CLT ควรจะประมาณ σ / √ n = 288.675/SQRT(50) = 40.82 ซึ่งก็ถือว่าใกล้เคียงล่ะ
                              Statistics with Excel ตอนที่ 5 : Central Limit Theorem 257

                              จะเห็นว่ายิ่งเราทำ Simulation จำนวน trial เยอะๆ เช่น 1000 ครั้ง แล้วเอามาทำ Distribution จะได้การแจกแจงของ Sample Mean ที่สวยเป็น Normal มากขึ้น และมี Mean ของ Sample Mean และ SE (estimate) ที่แม่นตรงกับทฤษฎี CLT มากขึ้นไปอีก

                              Statistics with Excel ตอนที่ 5 : Central Limit Theorem 258

                              ถ้าเราไม่รู้ standard deviation ของ population ล่ะ?

                              แต่ถ้าหากเรายังไม่รู้ standard deviation ของ population อีกจะทำยังไงดี? (ซึ่งในชีวิตจริงไม่รู้หรอก ถ้ารู้แล้วจะสุ่ม sample ทำไมฟะ)

                              คำตอบก็คือ ใน SE (estimate) ให้เราสามารถแทน σ ด้วย s (standard deviation ของ sample) ที่เราสุ่มได้เลย เพียงแต่มันจะเปลี่ยน distribution จาก Normal Distribution เป็น t-distribution ที่มี degree of freedom = n-1 แทน (จำนวน sample size -1)

                              t-Distribution

                              ลักษณะของ t distribution นั้น หน้าตาคล้ายๆ กับ Normal Distribution มีลักษณะสมมาตร ที่ mean =0 เช่นกัน

                              ซึ่ง degree of freedom (df) คืออะไร ช่างมันไปก่อนนะ เอาเป็นว่า

                              • ถ้า df น้อยๆ shape ของ t-distribution จะบานออกและเตี้ยลง
                              • ถ้า df เยอะๆ shape ของ t-distribution จะผอมลง สูงขึ้น จนเริ่มคล้ายกับ standard normal distribution มากขึ้น
                              Statistics with Excel ตอนที่ 5 : Central Limit Theorem 259

                              การใช้ t-distribution นั้นมีประโยชน์ตรงที่เราไม่จำเป็นต้องรู้ standard deviation ของ population ก็ได้ และยังสามารถใช้กับ sample size น้อยๆได้ด้วย เพียงแต่ว่า หาก sample มาจาก population ที่ไม่ได้เป็น normal ก็ควรจะมี sample size ≥ 30 จึงจะแม่นยำ

                              นั่นคือ จาก (xบาร์ – µ) / (σ / √ n) ~ N (0,1)  จะกลายเป็น

                              (xบาร์ – µ) / (s / √ n) ~ t (df=n-1)

                              ดังนั้น SE (estimate) ของ t-distribution จะเป็น s / √ n แทน

                              ตัวอย่างของการใช้ฟังก์ชัน T.DIST ทั้งหลาย จะมี 3 แบบ คือ แบบ Left Tail, 2Tails, Right Tail เป็นดังนี้

                              Statistics with Excel ตอนที่ 5 : Central Limit Theorem 260

                              สรุปการใช้ Central Limit Theorem กับค่า Sample Mean

                              • เมื่อใดก็ตามที่เรารู้ σ ของ population ก็สามารถใช้ Normal Distribution ได้
                                • xบาร์ ~ Normal (µ, σ / √ n )
                              • เมื่อใดก็ตามที่เราไม่รู้ σ ของ population ก็สามารถใช้ sd ของ sample ใน SE (estimate) โดยใช้ t-Distribution ได้
                                • xบาร์ ~ t (µ, s / √ n, df=n-1)
                                • ย้ำว่า s คือ standard deviation ของ sample ของเรา (ไม่ใช่ sd ของ sample mean นะ)

                              ซึ่งสถานการณ์ที่เราใช้ t-distribution แทน normal ก็คือ ใช้กับกรณีที่เราไม่รู้ทั้ง µ และ σ ของ population เราเลยใช้ s (standard deviation ของ sample) แทน σ ไป และใช้ t-distribution ที่มี Shape อ้วนกว่า Normal ปกติมาดัก error นั่นเอง แต่ถ้าเราไม่รู้ µ อย่างเดียว เราก็ใช้ Normal Distribution ได้ครับ

                              แล้วจะรู้ได้ไงว่าการสุ่ม 1 Trial ของเรานั่นแม่นยำแค่ไหน?

                              เนื่องจากเวลาเราสุ่ม sample ออกมาแล้วหาค่า Mean กับ Sd มันอาจจะไม่ตรงกับ Parameter จริงๆของ population ก็ได้ และอาจห่างกันได้มากด้วย เช่น

                              • สุ่มครั้งแรก ได้ Mean 517.2163, SD = 259.1704
                              • สุ่มครั้งสอง ได้ Mean 483.0414, SD = 311.7958
                              • แต่ค่า Population จริง Mean = 500, SD = 288.675 (แต่เราทำเป็นไม่รู้ไปก่อน)

                              มันจึงควรมีการบอกว่า จากการสุ่ม 1 ทีของเราแล้วได้ค่า Mean มา จะสามารถประมาณการค่าของ Parameter จริงเป็นเท่าไหร่ โดยจะต้องบอกด้วยว่ามีความแม่นยำแค่ไหน และนั่นก็คือที่มีของคำศัพท์ว่า Confidence Level และ Confidence Interval นั่นเอง

                              Confidence Level และ Confidence Interval

                              เราจะบอกได้ว่า ด้วยระดับความมั่นใจ (Confidence Level) เท่านี้เปอร์เซ็นต์ ค่า Parameter จริงๆ ของ population น่าจะตกอยู่ในช่วงไหนถึงไหน (Confidence Interval)

                              มาดูแนวคิดของเรื่องนี้กันนะครับ สมมติว่า Distribution เป็น Normal Distribution ก่อนจะได้ไม่งง จากความรู้เรื่อง Standard Normal Distribution เราจะรู้ว่า

                              z = (x - Mean) / sd

                              ซึ่งในกรณี distribution ของ sample mean จะได้ว่า

                              • x = sample mean ที่เราสนใจ
                              • mean = µ ของ population
                              • sd = SE (estimate)

                              ดังนั้นค่า z จะได้ว่า

                              z = ( sample mean - µ ) / SE (estimate)

                              และรู้ว่าสำหรับ standard normal distriution ค่า mean ± 1.96 จะกินพื้นที่ 95% ของส่วนกลางของ distribution (ซึ่งmean คือ 0)

                              นั่นคือ ( sample mean – µ ) / SE (estimate) = 0 ± 1.96

                              ซึ่งพอย้ายข้างจะได้ว่า

                              • Sample mean – µ = ± 1.96 * SE (estimate)
                              • สลับย้ายค่า µ ให้อยู่ซ้ายสุดตัวเดียว จะได้ว่า
                              • µ = Sample mean ± 1.96 * SE (estimate) นั่นเอง ที่ความมั่นใจ 95%

                              ดังนั้นเราเลยสามารถสรุปสูตรทั่วๆไปของช่วงที่ µ จะอยู่ ซึ่งเรียกว่า Confidence Interval คือ

                              Confidence Interval = sample mean ± multiplier x SE (estimate)
                              • multiplier จะขึ้นอยู่กับ Confidence Level (ระดับความมั่นใจ) ยิ่งระดับมั่นใจมาก multiplier ก็จะยิ่งมาก (ทำให้กินช่วงกว้างขึ้น) ซึ่งก็ขึ้นอยู่กับว่าใช้ Normal Distribution หรือ t-distribution ด้วยนั่นเอง ซึ่ง 1.96 มาจาก 95% ของ Standard Normal
                                • ค่า multiplier แบบเป๊ะๆ สามารถใช้ฟังก์ชันกลุ่ม INVERSE ของแต่ละ Distribution มาช่วยคำนวณหาได้ (จะแสดงให้ดูในตัวอย่างถัดไป)
                              • SE (estimate) ก็คือค่า (σ / √ n) ถ้ารู้ σ ของ population หรือ (s / √ n) ถ้าไม่รู้ σ ของ population (ซึ่งต้องใช้ t-distribution ไปด้วย)

                              กลับมายังโจทย์ที่เรา Random เลข 0-1000

                              ลองหา confidence interval ที่ความมั่นใจระดับ 95% จากข้อมูลในรูปแรก (Mean 517.2163, SD = 259.1704)

                              Confidence Interval = Sample Mean ± multiplier x SE (estimate)

                              ถ้าเรารู้ σ ของ population

                              ก็สามารถใช้ normal distribution ได้นะ ดังนั้นจะได้ว่า

                              Confidence Interval ของ µ = Sample Mean ± z.multiplier x σ / √ n
                              • Sample Mean = 517.2163
                              • σ = population standard deviation = 288.675
                              • n = 50 เพราะสุ่มมา 50 ตัว
                              • z-Distribution ความมั่นใจ 95% อยากรู้ว่า z.multiplier มีค่าเท่าไหร่ สามารถใช้ NORM.S.INV มาช่วยได้
                                • เนื่องจาก NORM.S.INV นับพื้นที่จากฝั่งซ้าย การจะได้ความเชื่อมั่น 95% จะต้องนับจากขอบซ้ายมา 2.5%
                                • =NORM.S.INV(2.5%)
                                • =-1.959963985
                                • = จะได้ว่า z-multiplier ก็คือ 1.96 ตามที่เคยเรียนมาสมัยเด็กๆนั่นเอง
                              Confidence Interval ที่ 95% = 517.2163 ± 1.96 * 288.675 / SQRT(50)
                              • ขอบล่าง = 517.2163 – 1.96 * 288.675 / SQRT(50) = 437.20
                              • ขอบบน = 517.2163 + 1.96 * 288.675 / SQRT(50) = 597.23

                              ดังนั้น µ ของ Population จะอยู่ในช่วง 437.20 – 597.23 ด้วยความมั่นใจ 95% นั่นเอง

                              ถ้าเราไม่รู้ σ ของ population

                              ก็ต้องใช้ t-distribution นะ ดังนั้นจะได้ว่า

                              Confidence Interval ของ µ = Sample Mean ± t.multiplier x s / √ n
                              • Sample Mean = 517.2163
                              • s = sample standard deviation = 259.1704
                              • n = 50 เพราะสุ่มมา 50 ตัว
                              • t-Distribution ความมั่นใจ 95% อยากรู้ว่า t.multiplier มีค่าเท่าไหร่ สามารถหาได้ 2 วิธี
                                • ใช้ T.INV มาช่วยได้
                                  • เนื่องจาก T.INV นับพื้นที่จากฝั่งซ้าย การจะได้ความเชื่อมั่น 95% จะต้องนับจากขอบซ้ายมา 2.5%
                                  • =T.INV(probability,deg_freedom)
                                  • =T.INV(2.5%,50-1) = -2.009
                                • ใช้ T.INV.2T มาช่วย
                                  • เนื่องจาก 2T นับพื้นที่จากขอบทั้งสองฝั่ง การจะได้ความเชื่อมั่น 95% จะต้องนับจากขอบมา 2 ฝั่งรวมกันให้ได้ 5%
                                  • =T.INV.2T(probability,deg_freedom)
                                  • =T.INV.2T(5%,50-1) = 2.009
                                • สรุปแล้วจะได้ว่า t-multiplier ก็คือ 2.00 นั่นเอง (ซึ่งจะกว้างกว่า 1.96 กรณีเป็น normal)
                              Confidence Interval ที่ 95% = 517.2163 ± 2.00 * 259.1704 / SQRT(50)
                              • ขอบล่าง = 517.2163 – 2.00 * 259.1704 / SQRT(50) = 443.912
                              • ขอบบน = 517.2163 + 2.00 * 259.1704 / SQRT(50) = 590.521

                              ดังนั้น µ ของ Population จะอยู่ในช่วง 443.912 – 590.521 ด้วยความมั่นใจ 95% นั่นเอง

                              ซึ่งทั้ง 2 กรณีมันก็เดาถูกนะ เพราะจริงๆ Population Mean ของ Uniform Distribution = AVERAGE(0,1000) = 500 นั่นเอง

                              อย่างไรก็ตาม เนื่องจากนี่คือระดับความมั่นใจ 95% แปลว่ามีโอกาส 5% ที่ population mean ไม่ได้อยู่ในช่วงที่เราคิดนะครับ
                              เช่น ผมดันซวย Sampling ได้แบบนี้

                              Statistics with Excel ตอนที่ 5 : Central Limit Theorem 261
                              Confidence Interval ของ µ = Sample Mean ± t.multiplier x s / √ n
                              Confidence Interval ที่ 95% = 587.8903 ± 2.00 * 292.2328 / SQRT(50)
                              Confidence Interval ที่ 95% = 505.23 - 670.54 ซึ่ง เลข 500 ไม่ได้อยู่ในนี้

                              การใช้ Central Limit Theorem กับค่า Proportion

                              ถ้าเรามีการเก็บข้อมูลที่มีลักษณะเป็นสัดส่วน (proportion หรือ P) เราก็ยังสามารถใช้ CLT มาประยุกต์ได้ครับ แถมง่ายกว่าปกติด้วย ซึ่งข้อมูลที่เป็น Proportion นั้นแปลว่าตัวอย่างแต่ละตัวที่สุ่มมานั้นมาจาก Population ที่มีการแจกแจงแบบ 0=no,1=yes หรือ Bernouilli distribution นั่นเอง

                              ซึ่งถ้าพอจำได้ Bernouilli distribution มีลักษณะดังนี้

                              • มีค่า Mean = E(X)=P
                              • มี Variance = var(X)= P*(1-P)
                              • ดังนั้นมี SD = SQRT( P*(1-P) )

                              ตัวอย่างเช่น ถ้าผมต้องการทำการสำรวจ Portion ของผู้ชายของคนในบริษัทที่มีพนักงาน 3000 คน แต่ผมไม่รู้ว่ามีพนักงานชายกี่ % ผมก็เลยสุ่มพนักงานมาจำนวน 100 คนแล้วเช็คแล้วได้ว่าเป็นชาย 45 คน

                              • Population คือ คนในบริษัททั้งหมดมีประมาณ 3000 คน
                              • Sample คือ คนในบริษัทที่ผมสุ่มมา 100 คน
                              • Parameter = เช่น สัดส่วนที่เป็นผู้ชายของคนในบริษัททั้งหมด ( P = ไม่รู้)
                              • Statistic = เช่น สัดส่วนที่เป็นผู้ชายของคนในบริษัทที่ผมสุ่มมา 100 คน =เรียกว่า p = ได้ 45/100 = 0.45

                              จากเดิมบอกว่า CLT จะให้ดี sample size  n ต้อง ≥ 30 แต่พอมาใช้กับ proportion แล้ว จะมีเกณฑ์เปลี่ยนไปเล็กน้อยว่า

                              np ต้อง ≥ 10 และ n(1-p) ก็ต้อง ≥ 10 ด้วย จึงจะให้ผลที่ประมาณว่าเป็น Normal Distribution อยู่ 
                              (บางเกณฑ์ก็บอกว่าต้องมากกว่าหรือเท่ากับ 5 ก็พอใช้ได้แล้ว)
                              • ที่ต้องมี Condition ดักทั้งสองฝั่ง เพื่อไม่ให้ค่า p อยู่ใกล้ 0% หรือ 100% มากจนเกินไป (ถ้าเป็นงั้นกราฟจะเบ้จนไม่เป็น Normal)
                              • ยกเว้นว่าจะมีจำนวน n เยอะจนที่ให้ Standard Errorp หรือ SEp น้อยลง จนทำให้กราฟหายเบ้ได้

                              ใครอยากเห็นภาพมากขึ้นลองดูคลิปนี้ได้

                              เช่น ในตัวอย่าง

                              • np ต้อง ≥ 10 : 100*0.45 ต้อง >= 10 ซึ่งจริง เพราะได้ 45
                              • n(1-p) ต้อง ≥ 10 : 100*(1-0.45) ต้อง >= 10 ซึ่งจริง เพราะได้ 55

                              และจาก CLT จะได้ความสัมพันธ์ว่า sample proportion แจกแจงตาม Normal Distribution โดยมีลักษณะ

                              • มี Mean = P (แปลว่า distribution นี้จะมี mean เท่ากับ population จริง)
                              • Standard deviation = SE (estimate) = σ / √ n  (แปลว่า distribution นี้จะมี sd น้อยกว่า population จริง)
                                • ค่า σ ของ Bernouilli distribution = SQRT( P*(1-P) )
                                • แปลว่า σ / √ n  = SQRT( P*(1-P)/n )

                              แปลว่าเราจะรู้ว่า distribution ของ sample proportion จะแจกแจงแบบ Normal เสมอ โดยที่ไม่ต้องมีบางกรณีที่ต้องใช้ t-distribution เหมือนกับกรณี Sample Mean เลย (สาเหตุเพราะจริงๆ แล้วค่า σ ของ Bernouilli distribution มันคำนวณมาจากค่า Mean อยู่ดี แปลว่าจริงๆ แล้วเราไม่รู้ค่า Mean แค่ตัวเดียวเท่านั้น จึงถือว่าใช้ Normal Distribution ได้เสมอครับ)

                              p ~ N (P, SQRT( P*(1-P)/n )) 

                              Confidence Interval ของ Proportion

                              Confidence Interval = Sample Mean ± multiplier x SE (estimate)

                              จะกลายเป็น

                              Confidence Interval สำหรับ P = p  ±  z*  SQRT( P*(1-P)/n )

                              ค่า z* ก็ขึ้นอยู่กับระดับความมั่นใจเช่นเดิม เช่น 95% จะเป็น 1.96

                              จากตัวอย่างของเรา

                              • ค่า sample p = 45/100 = 0.45
                              • n = 100
                              • z เกิดจากการหา =NORM.S.INV(probability) ซึ่งเป็นแบบสะสมจากด้านซ้าย ถ้าอยากได้มั่นใจ 95% แปลว่า ด้านซ้ายต้องวิ่งมา 2.5% หรือไปขวาถึง 97.5% ก็ได้ว่า z=1.9599 หรือ 1.96 ที่เคยท่องมาตอนเด็กๆ นั่นเอง
                              • P ขอบล่าง = 0.45 –  1.96*  SQRT(0.45 * ( 1 – 0.45 ) / 100) = 0.3525
                              • P ขอบบน = 0.45 +  1.96*  SQRT(0.45 * ( 1 – 0.45 ) / 100) = 0.5475

                              ดังนั้น P ของ Population จะอยู่ในช่วง 0.3525 – 0.5475 ด้วยความมั่นใจ 95% นั่นเอง

                              โจทย์ตัวอย่าง : ทดสอบพลังหมัดนักสู้ฝีมือดี

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

                              Statistics with Excel ตอนที่ 5 : Central Limit Theorem 262
                              รูป Mr. Satan วัดพลังหมัดจากการ์ตูนเรื่อง Dragon Ball

                              ซึ่งเค้าอ้างว่า เค้าได้วัดพลังหมัดของนักสู้ของเค้าทุกคนจำนวน 1000 คน เรียบร้อยแล้วแต่ยังหาผลการ test ไม่เจอ ให้รอแปป…

                              ด้วยความที่เราเป็นคนใจร้อนและเชื่อคนยาก จึงได้ขอสุ่มนักสู้มา 60 คน แล้วปรากฏว่าวัดพลังหมัดเฉลี่ยได้แค่ 670 เท่านั้น โดยมี sd ของ sample = 55

                              เนื่องจากสุ่มมา 60 คน จึงเพียงพอที่จะใช้ CLT ได้ ดังนั้นมี 2 คำถาม คือ

                              มาเริ่มที่ข้อแรก : ประมาณการ Population จาก Sample

                              ให้ประมาณการค่าพลังหมัดของ Population จริง จากข้อมูลการสุ่มที่ได้ ด้วยความมั่นใจ 95%

                              เนื่องจาก ไม่รู้ข้อมูล µ กับ σ ของPopulation ดังนั้นต้องใช้ t-distribution แทน Normal

                              Confidence Interval ของ µ = Sample Mean ± t.multiplier x s / √ n
                              t.multiplier=T.INV.2T(5%,60-1)=2
                              Confidence Interval ของ µ = 670 ± 2 * 55/SQRT(60)   ที่ความมั่นใจ 95%
                              • ขอบล่าง µ = 670-2*55/SQRT(60) = 655.79
                              • ขอบบน µ = 670+2*55/SQRT(60) = 684.20

                              ดังนั้น µ หรือพลังหมดเฉลี่ยของนักสู้ทั้งหมด ควรอยู่ในช่วง 655.79-684.20 ที่ความมั่นใจ 95%

                              ต่อมาทางบริษัทบอกว่าเจอผลการทดสอบแล้ว โดยผลการวัดพลังหมัดโดยเฉลี่ยออกมาแล้วอยู่ที่ 700 และมี sd อยู่ที่ 50

                              ต่อด้วยข้อที่ 2 : หาความ Make Sense ของสิ่งที่ทางบริษัทเคลมมา

                              จงคำนวณว่ามีโอกาสแค่ไหนที่ค่าเฉลี่ยของ population อยู่ที่ 700 จริง แต่เราดัน sample มาได้ค่าเฉลี่ยน้อยกว่าหรือเท่ากับ 670

                              สมมติว่าที่บริษัทอ้างมาจริง คือ µ=700 และมี σ= อยู่ที่ 50 แปลว่าตอนนี้เรารู้ σ แล้ว ดังนั้นใช้ Normal Distribution ได้

                              การแจกแจงของ Sample Mean ควรจะเป็น Normal ที่มี Mean=700 และ sd คือ SE (estimate) = σ/√ n  = 50/SQRT(60)

                              ถ้าเราอยากหาความน่าจะเป็นที่ดันลองสุ่มแล้วได้ค่าเฉลี่ยน้อยกว่าหรือเท่ากับ 670 ก็คือพื้นที่ฝั่งซ้าย ดังนั้นใช้ NORM.DIST ได้เลย

                              =NORM.DIST(x,mean,standard_dev,cumulative)
                              =NORM.DIST(670,700,50/SQRT(60),TRUE)
                              =0.000168%

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

                              ตอนต่อไป

                              ตอนต่อไปจะเป็นเรื่องการทดสอบสมมติฐานที่เรียกว่า Hypothesis Testing แล้วครับ เป็นเรื่องที่เป็นหัวใจสำคัญของ Inferential Statistics เลยล่ะ ซึ่งเดี๋ยวคุณจะได้รู้จักกับคำว่า Significant กับคำว่า p-Value ซึ่งเป็นคำศัพท์ยอดฮิต (แต่หลายคนแปลไม่ออก) ซักที

                              สารบัญซีรีส์ Statistics

                              • Statistics with Excel ตอนที่ 4 : Normal Distribution

                                Statistics with Excel ตอนที่ 4 : Normal Distribution

                                ในตอนนี้เราจะเน้นเรื่องของ Normal Distribution ซึ่งเป็น Distribution ประเภท Continuous Probability Distribution ที่พบมากที่สุดในธรรมชาติเลย

                                แต่เราจะขอปูพื้นฐานเกี่ยวกับ Continuous Probability Distribution เบื้องต้นกันก่อนเล็กน้อยก่อนจะไปลงเรื่อง Normal Distribution กันจริงๆ ในครึ่งหลังของบทความ

                                Continuous Probability Distribution คือ การแจกแจงความน่าจะเป็นแบบที่เหตุการณ์ที่สนใจนั้นไม่สามารถนับเป็นชิ้นๆ ได้ เพราะเลขมีค่าต่อเนื่องกัน เช่น การแจกแจงของน้ำหนักของคนในบริษัท เพราะน้ำหนักของแต่ละคนมันอาจเป็น 63.43 kg ที่เป็นเศษแบบนี้ได้ ซึ่งเป็นค่าต่อเนื่อง ทำให้การอ่านความน่าจะเป็นของกราฟที่ Plot ออกมาต้องอ่านจาก “พื้นที่ใต้กราฟ” แทน ซึ่งมีอยู่หลายแบบด้วยกัน เช่น Uniform Distribution, Normal Distribution, T-Distribution, Chi-Square Distribution และอีกมากมาย

                                แต่ผมจะขอพูดถึง 2 แบบก่อน คือ Uniform Distribution และ Normal Distribution (รวมถึง แบบ Standard Normal ด้วย)

                                Uniform Distribution

                                Uniform แปลว่ามีแบบเดียวเหมือนกัน เช่น เครื่องแบบที่มีอันเดียว ดังนั้น Uniform Distribution ก็คือ Distribution ที่มีโอกาสเท่ากันหมดทุกค่านั่นเอง ถ้าลองทำเป็นกราฟจะเป็นแบบนี้

                                Statistics with Excel ตอนที่ 4 : Normal Distribution 263

                                เนื่องจากพื้นที่ใต้กราฟต้องเป็น 1 เสมอ ทำให้

                                ความสูงของ distribution = 1/ ความกว้าง

                                ซึ่งความกว้างก็แล้วแต่ว่าแกน x ของกราฟจะเริ่มจากเท่าไหร่ถึงเท่าไหร่ เช่น ถ้าเริ่มจาก 0 ถึง 1 แบบนี้ก็คือกว้าง 1 ทำให้สูง 1 ไปด้วย

                                ถ้าเริ่มตั้งแต่ 3 ถึง 5 แบบนี้กว้าง 2 ก็จะสูงแค่ =1/2 = 0.5 เพื่อให้พื้นที่ใต้กราฟเป็น 1 เสมอ เป็นต้น

                                Statistics with Excel ตอนที่ 4 : Normal Distribution 264

                                ค่าที่สถิติของ Uniform Distribution ตั้งแต่ค่า x เป็น a ถึง b

                                • Mean = ค่าเฉลี่ยตรงกลาง = (a+b)/2
                                • Variance = 1/12 * (b-a)^2

                                ตัวอย่าง : หากเครื่องจักรของเราสามารถผลิตน้ำยาวิเศษได้วันละ 3-5 ลิตร โดย assume ว่าโอกาสของผลผลิตเป็น Uniform Distribution จงหาโอกาสที่จะผลิตได้ตั้งแต่ 3.5 ลิตร ขึ้นไป และ โอกาสที่จะผลิตได้ 3.5 ลิตรพอดีเป๊ะ

                                ความน่าจะเป็นนั้นสามารถคำนวณได้จากพื้นที่ใต้กราฟของส่วนที่สนใจ

                                ถ้าบอกว่าจะให้ผลิตได้ 3.5 ลิตรขึ้นไป ก็จะเป็นพื้นที่ส่วนที่ Highlight ในรูป

                                Statistics with Excel ตอนที่ 4 : Normal Distribution 265

                                ดังนั้นโอกาสผลิตได้ตั้งแต่ 3.5 ลิตรขึ้นไป = (5-3.5) * 0.5 = 0.75 หรือ 75% นั่นเอง

                                และถ้าถามว่าโอกาสที่ได้ 3.50000000000 ลิตรพอดีเป๊ะๆๆๆๆๆๆๆ คือ เท่าไหร่? มันก็จะเป็นค่าที่น้อยมากกกกก (เข้าใกล้ 0) เนื่องจากความกว้างของสี่เหลี่ยมที่สนใจมันน้อยมากนั่นเอง

                                แต่ถ้าบอกว่าโอกาสที่ได้ตั้งแต่ 3.50-3.51 ลิตร แบบนี้ยังพอคำนวณได้ = (3.51-3.50)*0.5 = 0.005 = 0.5% นั่นเอง

                                สุ่มค่าจาก Uniform Distribution

                                ใน Excel เรามีฟังก์ชันที่สามารถสุ่มค่าจาก Uniform Distribution ที่เริ่มตั้งแต่ 0 ถึง 1 ได้โดยตรง นั่นคือ RAND นั่นเอง

                                =RAND()

                                ผลลัพธ์จะออกมาเป็นค่าจำนวนจริงที่ละเอียดเป็นทศนิยม (แต่ excel รองรับ digit ทั้งหมดได้แค่ 15 digits) โดยมีค่าตั้งแต่ 0 ถึง 1

                                แต่ผลลัพธ์ออกมาแค่ 1 ค่า ถ้าอยากได้หลายค่าต้อง copy paste เอาเอง

                                Statistics with Excel ตอนที่ 4 : Normal Distribution 266
                                • หากอยากจะ Random จาก Uniform Distribution ตั้งแต่ 0-2 ก็ใช้ RAND() *2 ได้
                                • หากอยากจะ Random จาก Uniform Distribution ตั้งแต่ 3-5 ก็ให้เลื่อนจาก 0-2 ไป 3 ค่า โดย RAND()*2 + 3 นั่นเอง

                                สรุปสูตรโดยทั่วไป ถ้าอยากจะ Random จาก a – b

                                =RAND()*(b-a) + a
                                Statistics with Excel ตอนที่ 4 : Normal Distribution 267

                                อย่างไรก็ตามใน Excel 365 ที่รองรับ Dynamic Array สามารถใช้ฟังก์ชันใหม่ นั่นคือ RANDARRAY ได้ ซึ่งกำหนดให้ผลลัพธ์ออกมาหลายค่าได้เลย (ผลลัพธ์เป็น array) โดยกำหนดจำนวนแถว จำนวนคอลัมน์ค่ามากสุด น้อยสุด และกำหนดได้ว่าจะเอาเป็นจำนวนเต็มหรือไม่ก็ได้

                                =RANDARRAY(rows,columns,min,max,integer)
                                Statistics with Excel ตอนที่ 4 : Normal Distribution 268

                                ใครอยากดูที่อธิบายแบบเป็นคลิปวีดีโอ ก็ดูได้ที่นี่

                                Normal Distribution

                                Normal Distribution มีอีกชื่อนึงว่า Gaussian distribution เป็น Distribution ที่พบมากที่สุดในธรรมชาติ (ก็เลยเรียกว่า Normal ไง) โดยมีลักษณะดังนี้

                                มีคุณสมบัติดังนี้

                                • กราฟของฟังก์ชั่นเป็นรูประฆังคว่ำ (ผมว่าชอบคิดว่ามันเหมือนภูเขามากกว่า 555 )
                                • มีจุดสูงสุดอยู่จุดเดียว (unimodal คือมี Mode เดียว ) ที่ x =  µ
                                • มีลักษณะสมมาตรโดยมีสมการ x =  µ  เป็นแกนสมมาตร (แบ่งพื้นที่ฝั่งละ 50%)
                                • ค่า Mean = Median = Mode
                                • มีค่า x ตั้งแต่ – ∞ ถึง + ∞
                                • พื้นที่ใต้กราฟรวมกันทั้งหมด มีค่าเท่ากับ 1 (อันนี้เป็นจริงสำหรับกราฟ Continuous ทุกอันแหละ)
                                • หากเราขยายช่วงค่า x ออกมาจากแกนกลาง
                                  • ข้างละ 1 sd จะกินพื้นที่รวมประมาณ = 68%
                                  • ข้างละ 2 sd จะกินพื้นที่รวมประมาณ = 95%
                                  • ข้างละ 3 sd จะกินพื้นที่รวมประมาณ = 99.7%

                                รูปร่างของ Normal Distribution จะขึ้นอยู่กับค่า Mean และ SD ของข้อมูล โดยที่ส่วนสูงสุดของภูเขาจะตรงกับค่า Mean ส่วนความกว้างของฐานจะขึ้นอยู่กับค่า SD โดยที่มักจะกินพื้นที่ไปถึงประมาณ Mean +- 3SD (แต่ในความเป็นจริงไปได้ถึง Infinity เลยนะ)

                                จะเห็นจากรูปว่ายิ่งฐานกว้าง ความสูงก็จะน้อยลง (เพราะพื้นที่ใต้กราฟต้องเป็น 100% เสมอไง )

                                ที่มาที่ไปของ Normal Distribution

                                จริงๆ แล้วถ้ายังจำ Binomial Distribution ในตอนที่แล้วได้ หากเราโยนเหรียญ 10 ครั้ง แล้ว Plot จำนวนครั้งที่ออกหัว จะได้ Distribution แบบนี้

                                Statistics with Excel ตอนที่ 4 : Normal Distribution 270

                                ถ้าโยน 100 ครั้งล่ะ? ก็จะเห็นว่ากราฟมันหน้าตาเริ่มเป็นเส้นโค้งคล้ายๆ Normal ใช่มะ?

                                Statistics with Excel ตอนที่ 4 : Normal Distribution 271

                                เรื่องของเรื่องคือ ไอ้ความน่าจะเป็นเนี่ย คนที่ให้ความสำคัญกับมันมากๆ ก็คือนักพนัน (เพราะเป็นความน่าจะเป็นที่เกี่ยวกับเรื่องเงินๆ ทองๆ โดยตรง) เค้าก็อยากจะให้นักคณิตศาสตร์ช่วยคำนวณความน่าจะเป็นให้ และจะให้คำนวณแบบ Binomial สำหรับจำนวนเยอะๆ ในสมัยที่ไม่มี Computer ก็ไม่ไหวหรอก ดังนั้นนักคณิตศาสตร์สมัยนั้นจึงคิดว่า ถ้าสามารถหาสมการที่อธิบายถึงเส้นโค้งของรูประฆังคว่ำที่เกิดขึ้นได้ ก็จะสามารถคำนวณความน่าจะเป็นของจำนวนที่เยอะมากๆ ได้ง่ายขึ้น

                                สุดท้ายคิดค้นไปมา ก็ได้ออกมาเป็นสูตรที่ดูแล้วโคตรน่ากลัวมากๆ ที่บอกว่า เส้นโค้งของ distribution ขึ้นกับค่า Mean และ SD (เพราะค่า Pi กับ e คือค่าคงที่) แบบนี้นั่นเอง

                                Statistics with Excel ตอนที่ 4 : Normal Distribution 272

                                พอรู้ฟังก์ชันที่อธิบายเส้นโค้งของกราฟ Normal แล้วการจะหาพื้นที่ใต้กราฟก็สามารถทำได้ด้วยการคำนวณ Integrate นั่นเอง… (อ๊าก) แต่ถ้าจะให้คนธรรมดามานั่ง Integrate เอาก็คงยากเกินไป คนสมัยก่อนจึงพยายามทำให้กราฟเป็นมาตรฐานซึ่งเรียกว่า Standard Normal distribution แล้วสร้างตารางอ้างอิงสำเร็จรูปที่ได้คำนวณพื้นที่ใต้กราฟของจุดต่างๆ ไว้ให้แล้ว

                                Standard Normal Distribution

                                เราสามารถแปลงให้ กราฟ normal ที่มี µ (mean) และ σ (standard deviation) ใดๆ ก็ตามให้กลายเป็น การแจกแจงแบบปกติที่  µ (mean)  =  0   และ σ  =  1 และเปลี่ยนจากตัว x ให้กลายเป็นตัว z มันก็จะได้ผลลัพธ์เป็นกราฟ standard normal แทนครับ

                                โดยเราคำนวณค่า z ได้ดังนี้

                                z= (x-µ)/σ
                                Statistics with Excel ตอนที่ 4 : Normal Distribution 273

                                คนสมัยก่อนก็เลยสามารถสร้างตารางอ้างอิงที่จะอธิบายได้ว่าค่า z แต่ละตัวเนี่ย มีความน่าจะเป็นเท่าไหร่บ้าง เช่น

                                ตัวอย่าง : สมมติการแจกแจงของคะแนนสอบปลายภาคของนักเรียนในโรงเรียนแจกแจงแบบ Normal โดยที่มี Mean = 60 SD =8 โดยที่ตัวเราได้คะแนน 70 ให้หาว่ามีนักเรียนกี่ % ที่คะแนนน้อยกว่าเรา

                                z = (x- mean / sd) = (70-60)/8
                                z = 1.25

                                สมัยเด็กๆ เราต้องเปิดตารางเทียบแบบนี้

                                Statistics with Excel ตอนที่ 4 : Normal Distribution 274

                                จะได้ว่าพื้นที่น้ำเงิน = 0.3944

                                แต่ว่าจะหาว่ามีกี่ % ที่ได้คะแนนน้อยกว่าเรา ต้องอย่าลืมบวกพื้นที่ใต้กราฟฝั่งซ้ายอีก 0.5 ด้วย

                                ดังนั้น % นักเรียนที่ได้คะแนนน้อยกว่าเรา = 0.3944+0.5 = 0.8944 = 89.44% นั่นเอง

                                ถ้าทำด้วย Excel

                                ในโจทย์เดียวกัน ถ้าทำด้วย Excel เราสามารถใช้ฟังก์ชัน NORM.DIST ได้เลยโดยไม่ต้องมาทำเป็น Standard Z ด้วยซ้ำ

                                =NORM.DIST(x,mean,standard_dev,cumulative)
                                =NORM.DIST(70,60,8,TRUE)
                                =0.89435 = 89.435% นั่นเอง

                                หรือจะใช้ NORMS.DIST เพื่อใช้ค่า z แทน x, mean, sd ก็ได้

                                =NORM.S.DIST(z,cumulative)
                                =NORM.S.DIST(1.25,TRUE)
                                =0.89435 = 89.435% เท่ากันเป๊ะ

                                นั่นแปลว่าถ้ามี Excel แล้วเราก็ไม่ต้องไปแปลงให้เป็น z ก็ได้ครับ ใช้ NORM.DIST ได้เลย 555

                                ในทางกลับกัน หากอยากรู้ว่า ความน่าจะเป็น 89.435% นั้น เมื่อมี Mean =60, SD =8 แล้ว เทียบเท่ากับ X เท่าใด ก็ใช้ NORM.INV ได้เลย ง่ายมากๆ (INV= Inverse แปลว่ากลับด้าน)

                                =NORM.INV(probability,mean,standard_dev)
                                =NORM.INV(0.89435,60,8)
                                =69.99999 หรือ 70 นั่นเอง

                                สุ่มค่าจาก Normal Distribution

                                เราสามารถใช้ความรู้ของ NORM.INV มาประยุกต์ได้ โดย Random probability ที่มีค่าได้ตั้งแต่ 0-1 ด้วย RAND() นั่นเอง

                                สรุป สามารถทำได้ด้วยวิธีนี้

                                =NORM.INV(probability,mean,standard_dev)
                                =NORM.INV(RAND(),mean,standard_dev)

                                เช่นผมลองสุ่มดังรูป 500 ครั้ง ผลลัพธ์ออกมาค่อนข้างเป็น Normal สวยงามเลยล่ะ

                                Statistics with Excel ตอนที่ 4 : Normal Distribution 275

                                ตัวอย่างเพิ่มเติม

                                ตัวอย่าง : ใครเทพกว่า

                                Statistics with Excel ตอนที่ 4 : Normal Distribution 276
                                ภาพประกอบจากการ์ตูนเรื่อง Attack on Titan

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

                                • วิชาต่อสู้ด้วยมือเปล่า มีคะแนนเฉลี่ยอยู่ที่ 70 และมี SD ที่ 10
                                • วิชาบังคับเครื่องเคลื่อนย้ายสามมิติ มีคะแนนเฉลี่ยอยู่ที่ 80 และมี SD ที่ 15

                                อาร์มินเลยคิด Percentile ของคะแนนสอบเอเรน และแจน โดยใช้ NORM.DIST ดังนี้

                                =NORM.DIST(x,mean,standard_dev,cumulative)

                                Percentile ของคะแนนสอบเอเรน

                                =NORM.DIST(60,70,10,TRUE)
                                =15.87%

                                Percentile ของคะแนนสอบแจน

                                =NORM.DIST(65,80,15,TRUE)
                                =15.87%

                                อาร์มินจึงสรุปให้ทั้งสองฟังได้ว่า ทั้งสองคนนั้นได้ Percentile เท่ากัน โดยที่กากเท่ากันทั้งคู่ ไม่ควรมาต้องทะเลาะกัน ดังนั้นเอเรนกับแจนจึงหยุดทะเลาะกัน (แล้วมาอัดอาร์มินแทน 555)

                                ตัวอย่าง : รู้แค่เลขขอบๆ ที่ 95%

                                สมมติน้ำหนักของพนักงานบริษัทจำนวน 95% อยู่ระหว่าง 50 kg และ 100 kg โดย assume ว่าเป็นการแจกแจงแบบ Normal Distribution ถ้าหากเรามีน้ำหนัก 70 kg จะหาว่าเราหนักเป็น Percentile ที่เท่าไหร่?

                                แบบนี้โจทย์ไม่ได้บอก Mean กับ SD มาตรงๆ แถมไม่ได้ให้ Data มาด้วย ดังนั้นต้องใช้ความรู้เรื่อง shape ของ normal มาช่วย

                                เรารู้ว่า Mean คือค่าที่อยู่ตรงกลางระหว่างขอบ 2 ตัว

                                • ดังนั้น Mean = AVERAGE(50,100) = 75 อันนี้ไม่ยากอะไร

                                SD นี่จะยากกว่า แต่ถ้าเอาแบบประมาณๆ ก็ยังง่าย เพราะเรารู้ว่า Normal Distribution พื้นที่ประมาณ 95% คือ Mean+- 2 SD ดังนั้น

                                • 75-2SD = 50
                                • SD = (75-50)/2 = 12.5

                                หา Probability ด้วย NORM.DIST

                                =NORM.DIST(x,mean,standard_dev,cumulative)
                                =NORM.DIST(70,75,12.5,TRUE)
                                =34.46% ซึ่งก็คือ Percentile ด้วยนั่นเอง

                                แต่ถ้าเอาแบบเป๊ะมากขึ้น (ซึ่งไม่รู้จะเป๊ะทำไม เพราะค่าพื้นที่ 95% ก็คงประมาณมา 555) หรือจำไม่ได้ว่าพื้นที่ 95% คือ Mean+กี่SD ก็ให้ใช้ NORM.S.INV มาช่วย

                                แต่เราจะใช้ NORM.S.INV(95%) ตรงๆ ก็ไม่ได้อีก เพราะมันจะสะสมตั้งแต่ 0 เราต้องพลิกแพลงเป็น 2.5% แทน เพื่อเอาค่า z ฝั่งซ้ายมา

                                =NORM.S.INV(2.5%) = -1.959963985 

                                ซึ่งคือค่า z ซึ่งเป็นตัวที่บอกว่าเลื่อนไปกี่เท่าของ sd นั่นเอง

                                ดังนั้นข้อนี้เอาแบบเป๊ะๆ

                                SD = (75-50)/1.9599 = 12.7557 นะ

                                =NORM.DIST(70,75,12.7557,TRUE) = 34.75% นั่นเอง

                                ตอนต่อไป

                                พอเรามีความรู้เกี่ยวกับกราฟ Normal Distribution แล้ว ตอนต่อไปเราจะมาทำความรู้จัก Central Limit Theorem ซึ่งเป็นทฤษฎีสุดเจ๋งเกี่ยวกับกับการสุ่มตัวอย่างกันในบทถัดไปครับ

                                สารบัญซีรีส์ Statistics

                                • Statistics with Excel ตอนที่ 3 : Discrete Probability Distribution

                                  Statistics with Excel ตอนที่ 3 : Discrete Probability Distribution

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

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

                                  Probability Distribution สามารถแบ่งออกเป็น  2 ประเภทใหญ่ๆ คือ

                                  1. Discrete Probability Distributions : การแจกแจงความน่าจะเป็นแบบที่เหตุการณ์ที่สนใจนั้นสามารถนับแยกเป็นชิ้นๆ ได้(ไม่ได้มีค่าต่อเนื่องกัน) จึงสามารถ Plot กราฟเป็นแท่งๆ ได้เลย เช่น ใช้แจกแจงความน่าจะเป็นที่ที่ข้อสอบ 10 ข้อแล้วถูกต้อง 0,1,2,3,… 10 ข้อ ซึ่งจะได้กราฟ 10 แท่ง เป็นต้น ดังนั้นเราจะสามารถอ่านความน่าจะเป็นของเหตุการณ์ที่สนใจจากค่าแกน Y ได้เลยง่ายๆ
                                  2. Continuous Probability Distributions : การแจกแจงความน่าจะเป็นแบบที่เหตุการณ์ที่สนใจนั้นไม่สามารถนับเป็นชิ้นๆ ได้ เพราะเลขมีค่าต่อเนื่องกัน เช่น การแจกแจงของน้ำหนักของคนในบริษัท น้ำหนักมันอาจเป็น 63.43 kg แบบนี้ได้ ซึ่งเป็นค่าต่อเนื่อง ทำให้การอ่านความน่าจะเป็นของกราฟที่ Plot ออกมาต้องอ่านจาก “พื้นที่ใต้กราฟ” แทน

                                  ในบทความนี้เราจะมาเรียนรู้เรื่อง Discrete Probability Distribution กันก่อนนะครับ

                                  Discrete Probability Distributions

                                  เป็นการแจกแจงความน่าจะเป็นที่นับเป็นชิ้นๆ ได้ (ไม่ได้มีความต่อเนื่องกันจนแยกเป็นชิ้นไม่ได้) ซึ่งการที่เราเข้าใจ Distribution แบบนี้แล้ว จะทำให้เข้าใจที่มาที่ไปของ Distribution แบบ Continuous ที่เกิดขึ้นมากที่สุดในโลกที่มีชื่อว่า Normal Distribution ได้ด้วย

                                  การแจกแจงความน่าจะเป็นแบบ Discrete ที่ผมจะขอพูดถึงมี 3 อัน คือ Bernoulli Distribution, Binomial Distribution, และ Poisson Distribution

                                  Bernoulli Distribution

                                  • คือการแจกแจงความน่าจะเป็นที่มีผลลัพธ์ 2 แบบ คือ สำเร็จ (จริง) และ ล้มเหลว(เท็จ) โดยมีความน่าจะเป็นของความสำเร็จคือ P และล้มเหลวคือ (1-P)
                                  • มีค่า Mean = E(X)=P
                                  • มี Variance = var(X)= P*(1-P)

                                  ตัวอย่าง การมั่วข้อสอบ 1 ข้อ (มี choice 4 อัน)

                                  • Mean = โอกาสที่จะสำเร็จ = 1/4 = 0.25
                                  • Variance = (0.25)*(1-0.25) = 0.25*0.75 = 0.1875

                                  หมายเหตุ: Bernoulli Distribution ถือเป็นตัวพื้นฐานที่แทบใช้อะไรไม่ได้มากเพราะใช้ได้แค่กรณีมี Trial ครั้งเดียว แต่เดี๋ยวเราจะได้เรียนตัวถัดไปที่มีชื่อว่า Binomial Distribution ซึ่งใช้ได้กับกรณีที่มี Trial กี่ครั้งก็ได้ อันนี้สิเจ๋งจริง! (แปลว่าจริงๆ แล้ว Bernoulli Distribution ก็คือการใช้ Binomial Distribution แบบมี Trial 1 รอบนั่นเอง)

                                  รูปการ Plot Bernoulli Distribution

                                  เนื่องจากผลลัพธ์ของ Bernoulli Distribution เป็นไปได้แค่ 0=ไม่สำเร็จ, 1=สำเร็จ และมันมีแค่ Trial เดียว ดังนั้นผลลัพธ์ก็เลยมีแค่ 2 แท่งแบบ Basic ๆ นี่แหละ…

                                  Statistics with Excel ตอนที่ 3 : Discrete Probability Distribution 277

                                  Binomial Distribution

                                  • เป็นการทดสอบคล้ายๆ Bernoulli ก่อนหน้านี้ แต่คราวนี้โดยทำซ้ำๆ กัน n ครั้ง
                                  • แต่ละครั้งมีผลลัพธ์ได้ 2 แบบ คือ สำเร็จ และ ล้มเหลว ความน่าจะเป็นของความสำเร็จ ในการทดลองแต่ละครั้งเท่ากัน คือ P
                                  • การทดลองแต่ละครั้งเป็นอิสระต่อกัน (Independent) นั่นคือ ผลการทดลองครั้งต่อไปไม่ได้ขึ้นกับผลในครั้งก่อนหน้า
                                  • ตัวอย่างเช่น มั่วข้อสอบ choice จำนวน 10 ข้อ แล้วดูว่าโอกาสถูก xx ข้อเป็นเท่าไหร่บ้าง

                                  ดังนั้น Binomial Distribution เป็นการแจกแจงของจำนวนครั้งที่เกิดความสำเร็จ (X) ในการทดลอง Bernoulli trial ทั้งหมด n ครั้ง โดยมีความน่าจะเป็นของความสำเร็จคือ P

                                  • มีค่า Mean คือ n*P
                                  • มีค่า Variance คือ n * P * ( 1 – P )

                                  เช่น มั่วข้อสอบ Choice จำนวน 10 ข้อ

                                  • มีค่า Mean คือ n*P = 10 * 1/4 = 2.5
                                  • มีค่า Variance คือ n * P * ( 1 – P ) = 10*1/4*3/4 = 1.875

                                  การคำนวณ Binomial Probability หรือ ความน่าจะเป็นที่ความสำเร็จจำนวน X ครั้งจะเกิดขึ้น (ความน่าจะเป็นแต่ละแท่ง) มีสูตรดังนี้ 

                                  b(xn, P) = nCx * Px * (1 – P)n – x

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

                                  ตัวอย่าง 1 : สมมติว่ามั่วข้อสอบ 10 ข้อ โอกาสที่ตอบถูก 6 ข้อพอดีคือเท่าไหร่?

                                  • มีการทดลอง 10 ครั้ง n= 10
                                  • จำนวนครั้งที่สำเร็จ X=6
                                  • โอกาสที่จะสำเร็จได้แต่ละครั้ง = P = 1/4
                                  • โอกาสที่ตอบถูก 6 ข้อพอดี = 10C6 * (1/4)^6 * (3/4)^4
                                  • โอกาสที่ตอบถูก 6 ข้อพอดี = 0.016222 = 1.62%

                                  ซึ่งที่มาที่ไปของสูตร จริงๆ ก็มาจากเนื้อหาตอนที่แล้วนี่แหละ

                                  จากสูตรนี้ 10C6 * (1/4)^6 * (3/4)^4 เดี๋ยวเรามาดูกันว่าที่มาที่ไปแต่ละตัวมาจากไหน

                                  • ทำข้อสอบ 10 ข้อ ตอบถูก 6 ข้อ แปลว่ามี 10 ขั้นตอน แล้วทำสำเร็จ 6 ขั้นตอน ไม่สำเร็จ 4 ขั้นตอน
                                  • ในครั้งที่สำเร็จ จำนวน 6 ครั้งนั้น แต่ละอันมีโอกาส 1/4 ดังนั้นโอกาสจะเป็น 1/4 คูณกัน 6 รอบ หรือ (1/4)^6
                                  • ในครั้งที่ไม่สำเร็จ จำนวน 4 ครั้งนั้น แต่ละอันมีโอกาส 3/4 ดังนั้นโอกาสจะเป็น 3/4 คูณกัน 4 รอบ หรือ (3/4)^4
                                  • มีรูปแบบ Pattern ทั้งหมด เหมือนการสลับเพื่อสร้างคำใหม่จาก S6ตัวF4 ตัว = 10!/6!4! = 10C6
                                  • Action ต้องทำต่อเนื่องกันดังนั้นก็เลยต้องเอาทุกตัวมาคูณกันทั้งหมด ก็เลยได้ว่า =10C6 * (1/4)^6 * (3/4)^4
                                  Statistics with Excel ตอนที่ 3 : Discrete Probability Distribution 278

                                  แต่เรามี Excel ให้ใช้ ดังนั้นเราไม่ต้องมานั่งเขียนสูตรยากๆ เลย แต่ใช้ฟังก์ชัน BINOM.DIST ก็จะง่ายกว่ามากๆ 555

                                  =BINOM.DIST(number_s,trials,probability_s,cumulative)
                                  โดยที่ cumulative ถ้าเป็น TRUE คือโอกาสสะสมตั้งแต่ success เป็น 0 จนถึงจำนวนที่ต้องการ
                                  โดยที่ cumulative ถ้าเป็น FALSE คือค่าโอกาสของจำนวน success ที่ต้องการตัวเดียว (ไม่สะสม)

                                  ในที่นี่เราต้องการหาโอกาสที่ตอบถูก 6 ข้อพอดี ต้องใช้ cumulative ถ้าเป็น FALSE เพราะว่าไม่สะสม

                                  =BINOM.DIST(6,10,1/4,FALSE) = 0.016222 = 1.62%

                                  ตัวอย่าง 2 : สมมติเปลี่ยนคำถามเป็น ว่ามั่วข้อสอบ 10 ข้อ โอกาสที่ตอบถูกตั้งแต่ 6 ข้อขึ้นไป คือ เท่าไหร่?

                                  แบบนี้คิดได้ 2 วิธี คือ เอาความน่าจะเป็นของถูก 6, 7, 8, 9, 10 ข้อ บวกกันให้หมด

                                  Statistics with Excel ตอนที่ 3 : Discrete Probability Distribution 279

                                  ซึ่งจะเห็นว่าต้องคำนวณเยอะ เรามาใช้อีกวิธีนั่นคือ การคิดในมุมกลับด้วยหลักการ Complement จะง่ายกว่าเยอะ

                                  นั่นคือเอา 1- ความน่าจะเป็นสะสมจนถึง 5 ข้อ โดยที่เราจะเขียนเป็น 6-1 จะได้รู้ว่า 5 มาจากไหน และเราจะใช้ Cumulative เป็น TRUE

                                  =1 - BINOM.DIST(6-1,10,1/4,TRUE) = 0.01973 = 1.973% เท่ากันเลยแต่ใช้สูตรช่องเดียว

                                  รูปการ Plot Binomial Distribution

                                  ที่โอกาสสำเร็จ 25% จะเห็นว่ากราฟค่อนข้างเบี้ยวๆ (รูปนี้เรียกว่าเบ้ขวา เพราะมีหางยาวไปด้านขวา)

                                  Binomial Distribution - Discrete Probability Distribution

                                  แต่ถ้าโอกาส Success เป็น 50% จะทำให้ Shape สมมาตรเลย

                                  Statistics with Excel ตอนที่ 3 : Discrete Probability Distribution 280

                                  เช่น โอกาส Success เป็น 75% จะทำให้ Shape เบ้ไปอีกทิศ (เรียกว่าเบ้ซ้าย เพราะหางยาวไปด้านซ้าย)

                                  Statistics with Excel ตอนที่ 3 : Discrete Probability Distribution 281

                                  Poisson Distribution

                                  เป็นการแจกแจงจำนวนครั้งของความสำเร็จที่เกิดขึ้น (X) ภายในขอบเขตหรือระยะเวลาที่กำหนด โดยมีจำนวนครั้งของความสำเร็จโดยเฉลี่ยภายในขอบเขตหรือระยะเวลาที่กำหนดดังกล่าว เท่ากับ μ (จริงๆ จะเอาสัญลักษณ์อะไรก็ได้นั่นแหละ)

                                  • มี Mean = μ
                                  • มี Variance = μ (เท่ากับ Mean)

                                  Poisson Probability หรือความน่าจะเป็นที่จะเกิดความสำเร็จ x ครั้งเป๊ะๆ ในเวลาที่กำหนดมีดังนี้ 

                                  P(x; μ) = (e) (μx) / x!

                                  เช่น ปกติโดยเฉลี่ยแล้วบริษัทจะขายรถได้ 2 คัน ภายใน 1 วัน ถามว่าความน่าจะเป็นที่จะขายรถได้ 3 คันเป๊ะๆ ในวันพรุ่งนี้เป็นเท่าไหร่?

                                  P(x; μ) = (e^) (μ^x) / x!
                                  P(3; 2) = (2.71828^-2) (2^3) / 3!
                                  P(3; 2) = (0.13534) (8) / 6
                                  P(3; 2) = 0.1804 หรือ 18% นั่นเอง

                                  ซึ่งใน Excel เราสามารถใช้ฟังก์ชัน POISSON.DIST ได้เลย

                                  =POISSON.DIST(x,mean,cumulative) 

                                  โดยที่ x คือจำนวนความสำเร็จที่ต้องการ mean คือ จำนวนความสำเร็จเฉลี่ย cumulative ถ้าเป็น TRUE คือโอกาสสะสมตั้งแต่ success เป็น 0 จนถึงจำนวนที่ต้องการ cumulative ถ้าเป็น FALSE คือค่าโอกาสของจำนวน success ที่ต้องการตัวเดียว (ไม่สะสม)

                                  ดังนั้นข้อนี้ โอกาสจะขายรถได้ 3 คันเป๊ะภายใน 1 วันจะสามารถใช้สูตรได้ว่า

                                  =POISSON.DIST(3,2,FALSE)  = 0.1804 หรือ 18% นั่นเอง

                                  ถ้าข้อนี้ถามว่าโอกาสขายได้ตั้งแต่ 3 คันขึ้นไปภายใน 1 วันจะสามารถใช้สูตรได้ว่า

                                  =1 - โอกาสสะสมที่ขายได้แค่ 2 คัน
                                  =1 - POISSON.DIST(3-1,2,FALSE)
                                  =0.72933 = 72.93%

                                  รูปการ Plot Poisson Distribution

                                  กรณี Success เฉลี่ยคือ 2

                                  Statistics with Excel ตอนที่ 3 : Discrete Probability Distribution 282

                                  กรณี Success เฉลี่ยคือ 7

                                  Statistics with Excel ตอนที่ 3 : Discrete Probability Distribution 283

                                  กรณี Success เฉลี่ยคือ 14

                                  Statistics with Excel ตอนที่ 3 : Discrete Probability Distribution 284

                                  จะเห็นว่า Distribution จะเด้งสูงขึ้นมาที่ค่า Mean แล้วแผ่ออกไปทั้ง 2 ด้าน เป็นเหมือนภูเขา ยกเว้นว่าค่า Mean จะน้อยๆ ฝั่งซ้ายก็จะไปตันที่เลข 0 นั่นเอง

                                  เอาล่ะสำหรับ Discrete Probability Distribution ที่ควรรู้จักก็ประมาณนี้แหละครับ หวังว่าจะเป็นประโยชน์สำหรับทุกท่านนะ

                                  ตอนต่อไป

                                  ในตอนต่อไปเราจะมาเรียนรู้เรื่องของ Continuous Probability Distributions ที่พบมากที่สุดในธรรมชาตินั่นก็คือ Normal Distribution นั่นเองครับ

                                  สารบัญซีรีส์ Statistics

                                  • Statistics with Excel  ตอนที่ 2 : ความน่าจะเป็น

                                    Statistics with Excel ตอนที่ 2 : ความน่าจะเป็น

                                    ในตอนที่แล้วเราได้พูดถึงภาพรวมของสถิติและค่าทางสถิติเบื้องต้นกันไปแล้ว ในตอนนี้เราจะมาปูพื้นฐานอีกเรื่องที่สำคัญมากๆ นั่นก็คือเรื่อง ความน่าจะเป็น หรือภาษาอังกฤษว่า Probability นั่นเอง

                                    Probability (ความน่าจะเป็น) คือ ค่าที่บอกให้รู้ว่าเหตุการณ์ที่เราสนใจจะมีโอกาสเกิดขึ้นมากหรือน้อยแค่ไหน
                                    โดยมีค่าตั้งแต่ 0 (ไม่มีทางเกิดขึ้น) ถึง 1 (เกิดขึ้นแน่นอน) หรือจะเขียนเป็น 0% – 100% ก็ได้ (เพราะ % คือหาร 100)

                                    เช่น ความน่าจะเป็นของการถูกรางวัลเลขท้าย 2 ตัว คือ 1 ใน100 หรือ 0.01 หรือ 1% เราก็จะรู้ว่าโอกาสมันน้อยมาก…

                                    การเข้าใจความน่าจะเป็น จะช่วยให้เราตัดสินใจได้ดีขึ้น (กว่าไม่รู้) ซึ่งเรื่องนี้เป็นเรื่องที่มีประโยชน์มากๆ

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

                                    นิยามของคำที่เกี่ยวข้อง

                                    การที่เราจะเข้าใจเรื่องความน่าจะเป็นนั้นเราจะต้องทำความรู้จักคำศัพท์ต่างๆ เหล่านี้ก่อน ดังนั้นมาลุยกันเลย!

                                    • Trial = การทดลอง หรือ การสังเกตการณ์ ซึ่งมักจะเป็นเหตุการณ์ที่เราไม่รู้แน่ชัดถึงผลลัพธ์  เช่น Trial คือการโยนเหรียญ การทอยลูกเต๋า การการดึงไพ่ เป็นต้น ซึ่งความน่าจะเป็นนั้นจะให้ความสนใจถึงผลลัพธ์ของ Trial นั้นๆ
                                    • Sample Space (S) = ผลลัพธ์ทั้งหมดที่เป็นไปได้ของ Trial
                                      เช่น การโยนเหรียญ ซึ่งหน้าเหรียญที่เป็นไปได้มี 2 แบบ คือ h=หัว, t= ก้อย
                                      • ถ้า Trial เป็นการโยนเหรียญ 1 ครั้ง S ={h,t} คือมีทั้งหมด 2 แบบ
                                      • ถ้า Trail เป็นการโยนเหรียญ 2 ครั้ง S = {(h, h), (h, t), (t, h), (t, t)} ซึ่งจะมีทั้งหมด 4 แบบ
                                    • Events (E) = เหตุการณ์ใน Sample Space ที่เราสนใจ เช่น เหตุการณ์ที่เหรียญออกหัวอย่างน้อย 1 ครั้ง ในการโยนเหรียญ 2 ครั้ง คือ E={(h, h), (h, t), (t, h)} ซึ่งเป็นไปได้ 3 แบบ

                                    ดังนั้น ความน่าจะเป็นของสิ่งที่เราสนใจ จะเขียนได้ว่า 

                                    Probability of Event หรือ P(E) = จำนวน Event E / จำนวน Sample Space = E/S
                                    • S = {(h, h), (h, t), (t, h), (t, t)} = 4 แบบ
                                    • E = {(h, h), (h, t), (t, h)} = 3 แบบ

                                    ดังนั้น P(ออกหัวอย่างน้อย 1 ครั้งในการโยนเหรียญ 2 ครั้ง) = 3/4 = 0.75 หรือ 75% นั่นเอง

                                    Counting Theory  (กฎการนับ)

                                    การที่จะคำนวณความน่าจะเป็นได้ดีแบบไม่ต้องมานั่งเขียนผลลัพธ์ที่เป็นไปได้ทีละตัวนั้น เราจะต้องนับ Event และ Sample Space ให้ถูกต้องโดยใช้หลักการต่างๆ เหล่านี้ให้เป็นเสียก่อน

                                    กฏพื้นฐานของการนับ (Fundamental Principle of Counting)

                                    มีกฎ หลักๆ 2 อันในการหาจำนวนผลลัพธ์ที่เป็นไปได้ คือ

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

                                    ตัวอย่าง : แต่งตัวเล่นละคร Titan

                                    สมมติว่าในการเล่นละครเวทีคุณต้องเลือกว่าจะเล่นเป็นฝ่ายมนุษย์ หรือฝ่าย Titan (ยักษ์)

                                    • ถ้าเป็นฝ่ายมนุษย์ : จะมีเสื้อให้เลือก 4 แบบ กางเกง 2 แบบ
                                    • ถ้าเป็นฝ่าย Titan : จะเลือกใส่ชุดได้ 9 ชุด แต่ละชุดมี 3 สี

                                    ถามว่ามีความเป็นไปได้ในการแต่งตัวเล่นละครเวทีทั้งหมดกี่แบบ?

                                    แบบนี้จะเห็นว่ามี 2 กรณี คือ กรณีเล่นเป็นมนุษย์ กับเล่นเป็นฝ่าย Titan ซึ่งเราต้องคิดแยกกรณีกัน แล้วเอามาบวกกัน

                                    ฝ่ายมนุษย์ : มีเสื้อ 4 แบบ กางเกง 2 แบบ จะแต่งตัวได้กี่แบบ = มีขั้นตอนต้องทำ 2 ขั้นคือ เลือกเสื้อกับเลือกกางเกง
                                    ดังนั้นต้องเอารูปแบบของทั้ง 2 ขั้นตอนคูณกัน = ใส่เสื้อ ได้ 4 แบบ * ใส่กางเกงได้ 2 แบบ = มีการใส่เสื้อผ้า 8 วิธี

                                    ฝ่าย Titan : มี 9 ชุด 3 สี = มีขั้นตอนต้องทำ 2 ขั้นคือ เลือกชุดกับเลือกสี
                                    ดังนั้นต้องเอารูปแบบของทั้ง 2 ขั้นตอนคูณกัน = ใส่ชุด ได้ 9 แบบ * เลือกสีได้ 3 แบบ = มีการใส่เสื้อผ้า 27 วิธี

                                    รวมทุกกรณี มีรูปแบบการใส่เสื้อผ้า = 8 + 27 = 35 วิธี

                                    ทำไมมีหลายขั้นตอนแล้วต้องคูณกัน?

                                    วิธีที่จะเข้าใจเรื่องการนับพื้นฐานได้ดี คือ การวาดแผนผังต้นไม้ (Tree Diagram) ดังนี้ จะเข้าใจได้เลยว่าทำไมต้องคูณกัน

                                    Statistics with Excel ตอนที่ 2 : ความน่าจะเป็น 285

                                    โดยที่ใน Excel เราสามารถเอาตัวเลขทั้งหมดใน Range คูณกันได้ง่ายๆ โดยใช้ฟังก์ชัน PRODUCT มาช่วย

                                    =PRODUCT(data)    // ใส่ data เป็น range ได้เลย

                                    ใครสนใจวิธี List ความเป็นไปได้ทั้งหมดออกมา สามารถดูในคลิปนี้ได้ครับ

                                    ทำความรู้จัก Factorial

                                    คำถาม : ตัวอักษรคำว่า SIRA สามารถนำมาสลับกันได้กี่รูปแบบ? (ไม่สนใจความหมาย)

                                    วิธีคิดให้เข้าใจง่ายๆ คือ เหมือนมี Slot ให้ใส่ข้อความได้ 4 ตำแหน่ง แล้วเรามี Block ตัวอักษรอยู่ 4 ตัวคือ S, I, R, A เราจะสามารถสร้างคำได้กี่รูปแบบ?

                                    แสดงว่าการทำงานมี 4 ขั้นตอน คือ เลือกตัวใส่ Slot1, 2, 3, และ 4 ตามลำดับ ดังนั้นเราต้องเอารูปแบบแต่ละขั้นตอนมาคูณกัน

                                    • Slot 1 = มีให้เลือก 4 ตัว
                                    • Slot 2 = มีให้เลือก 3 ตัว (เพราะหยิบไปใส่ใน Slot 1 แล้วอันนึง)
                                    • Slot 3 = มีให้เลือก 2 ตัว
                                    • Slot 4 = มีให้เลือก 1 ตัว

                                    ดังนั้นการคำนวณ = 4*3*2*1 = 24 วิธี ดังนี้ (เห็นมะว่าเยอะ ผม List เองยังเหนื่อยเลย)

                                    Statistics with Excel ตอนที่ 2 : ความน่าจะเป็น 286

                                    ซึ่งเจ้า 4*3*2*1 นั้น สามารถเขียนได้อีกอย่างว่า 4! ซึ่งอ่านว่า “4 แฟคตอเรียล”

                                    โดยที่ n! อ่านว่า “n แฟคตอเรียล” หมายถึง เอาตัวมันเองคูณด้วยตัวมันเองลบ 1 ไปเรื่อยๆ จนถึง 1  นั่นเอง

                                    *สิ่งที่ควรรู้คือ ค่า 0! จะได้ 1 นะครับ

                                    ซึ่งใน Excel สามารถใช้ฟังก์ชัน FACT ได้แบบง่ายๆ คือ

                                    =FACT(number)
                                    =FACT(4) จะออกมาได้ =24 เลย

                                    กรณีมีตัวซ้ำที่เราไม่อยากจะนับ

                                    อย่างไรก็ตามหากรูปแบบบางอย่างให้ผลลัพธ์เหมือนกันแล้วเราไม่อยากจะนับซ้ำ เราสามารถหารทิ้งเพื่อกำจัดตัวซ้ำได้

                                    เช่น ตัวอักษรคำว่า SIRI สามารถนำมาสลับกันได้กี่รูปแบบ? (ไม่สนใจความหมาย)

                                    ถ้าคิดแบบผิวเผิน เผลอคำนวณด้วยหลักการเดิมว่ามี 4 Slot จะได้ออกมาเป็น 4! คือ 24 รูปแบบ
                                    แต่ถ้าดูผลลัพธ์แล้วจะพบเหตุการณ์เหล่านี้… ว่ามันมีข้อมูลซ้ำกันอยู่

                                    Statistics with Excel ตอนที่ 2 : ความน่าจะเป็น 287

                                    รูปแบบมันซ้ำกันเพราะตัว i มี 2 ตัว ซึ่งสลับที่กันแล้วไม่มีความหมาย ทำให้หากลอง Remove Duplicates ใน Excel จะเห็นว่ามีรูปแบบผลลัพธ์แค่ 12 แบบเท่านั้น ไม่ใช่ 24

                                    วิธีคำนวณที่ถูกต้อง ต้องเอาจำนวนรูปแบบการสลับของตัวที่ซ้ำไปหารทิ้ง คือ i ที่มี 2 ตัว ไปคำนวณรูปแบบการสลับได้ 2! (แฟคตอเรียล) แล้วเอาไปหารทิ้ง นั่นคือ

                                    =4!/2! = FACT(4)/FACT(2) = 12     //โดยที่หารด้วย 2! เพราะมีตัว i ซ้ำกัน 2 ตัว 

                                    ถ้าถามว่า คำว่า THEPEXCEL สลับกันได้กี่แบบ?

                                    =9! /3!  = FACT(9)/FACT(3) = 60480 วิธี   //โดยที่หาร 3! เพราะมีตัว e ซ้ำกัน 3 ตัว

                                    ถ้าถามว่าคำว่า GOOGLE สลับกันได้กี่แบบ?

                                    =6!/2!2!  = FACT(6)/(FACT(2)*FACT(2)) = 180 วิธี   
                                    //โดยที่หาร 2! 2รอบ เพราะมีตัว G ซ้ำกัน 2 ตัว และ O ซ้ำกัน 2 ตัว นั่นเอง

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

                                    Permutation  (เรียงสับเปลี่ยน)

                                    คือการหาจำนวนรูปแบบที่เป็นไปได้ทั้งหมดจากการเลือกของ k สิ่งจาก n สิ่ง โดยที่ลำดับมีความสำคัญ มีสูตรคือ

                                    nPk = n! / (n-k)!    //โดยที่ลำดับมีความสำคัญ

                                    เช่น มีของกิน 5 อย่าง เลือกกิน 2 อย่าง จะเลือกได้กี่แบบ โดยที่ลำดับในการกินมีความสำคัญ
                                    จะได้ว่า

                                    5P2 = 5!/(5-2)! = 5!/3! = 5*4 = 20 แบบ

                                    ใน Excel เราสามารถใช้ฟังก์ชัน PERMUT ได้เลย

                                    =PERMUT(number,number_chosen)
                                    =PERMUT(5,2) จะออกมาได้ 20 เลยแบบชิวๆ

                                    จริงๆ ถ้ามองด้วยกฎการนับมันก็ Make Sense มากๆ อยู่แล้ว ตอนแรกมีของ 5 อย่างให้เลือก คือ 5 วิธี เมื่อเลือกไปแล้ว 1 อย่าง ทำให้เหลือให้เลือกในขั้นตอนต่อไปเพียง 4 วิธี ทำให้เป็น 5 * 4 = 20 แบบ นั่นเอง

                                    ซึ่งถ้าหากมีของ 5 อย่าง เลือกกิน ทั้งหมด 5 อันเลย ก็จะมีลำดับการกิน = 5*4*3*2*1 หรือ 5! นั่นเอง

                                    Combination (การจัดหมู่)

                                    Combination นั้นจะเหมือนกับ Permutation แต่ว่าการเรียงลำดับไม่มีความหมาย ดังนั้น จำนวนวิธีในการจัดเรียงจึงต้องน้อยกว่า Permutation แน่นอน ทำให้ต้องหาร Permutation ด้วย k! (เพื่อกำจัดตัวซ้ำความหมาย คล้ายๆ กับตัวอย่างข้างบนที่เราหารตัวซ้ำ) ได้ว่า 

                                    nCk = n! / (n-k)!k!         //โดยที่ลำดับไม่มีความสำคัญ

                                    เช่น ถ้าคล้ายๆ ในตัวอย่างที่แล้วคือ มีของกิน 5 อย่าง เลือกกิน 2 อย่าง แต่คราวนี้ลำดับการกินไม่สำคัญ
                                    เราจะได้ว่า

                                    5C2 = 5!/(5-2)!2! = 10 แบบ

                                    ใน Excel เราสามารถใช้ฟังก์ชัน COMBIN ได้เลย

                                    =COMBIN(number,number_chosen)
                                    =COMBIN(5,2) จะออกมาได้ 10 เลยง่ายๆ

                                    ตัวอย่าง Permutation, Combination

                                    ตัวอย่าง : เลือกคนมาเข้าขบวนการ 5 สี

                                    จะมีวิธีในการเลือกคนมาเป็นขบวนการ 5 สี ที่มี 3 สีเป็นผู้ชาย อีก 2 สีเป็นผู้หญิง จากชายที่มีศักยภาพ 10 คน หญิง 7 คน ได้กี่วิธี

                                    จะเห็นว่ามี 2 ขั้นตอน คือ ขั้นตอนการเลือกผู้ชาย กับ ขั้นตอนเลือกผู้หญิง ดังนั้นต้องเอารูปแบบคูณกัน

                                    • ขั้นตอนการเลือกผู้ชาย = 10P3 ซึ่งใช้ Permutation เพราะลำดับของสีมีความสำคัญ =PERMUT(10,3)
                                    • ขั้นตอนการเลือกผู้หญิง = 7P2 ซึ่งใช้ Permutation เพราะลำดับของสีมีความสำคัญ =PERMUT(7,2)

                                    สรุป

                                    =PERMUT(10,3)*PERMUT(7,2) = 30240 วิธี

                                    ตัวอย่าง : เลือกดินสอสีมา 4 สี จากกล่องดินสอ 12 สี

                                    ความต้องการ 1 : เลือกสีมา 4 สี สีอะไรก็ได้ จากดินสอ 12 สี

                                    =12C4 =COMBIN(12,4) = 495 แบบ

                                    ความต้องการ 2 : เลือกสีมา 4 สี ต้องมีสีเขียวด้วยเสมอ จากดินสอ 12 สี

                                    ให้มองเป็นเลือกสีเขียวมาก่อน แล้วค่อยเลือกสีอื่นอีก 3 สี

                                    =1C1 * 11C3 = COMBIN(11,3) = 165 แบบ

                                    คำนวณความน่าจะเป็น

                                    Statistics with Excel ตอนที่ 2 : ความน่าจะเป็น 288

                                    พอเราสามารถนับเหตุการณ์ทั้งหมดได้ (Sample Space) และนับเฉพาะเหตุการณ์ที่สนใจได้ (Event)

                                    เราก็จะสามารถคำนวณความน่าจะเป็นของ Event E ได้ว่า

                                    P(E) = จำนวน Event E / จำนวน Sample Space = E/S นั่นเอง

                                    รูปแบบความสัมพันธ์ทางตรรกศาสตร์ของเหตุการณ์

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

                                    • S คือ คนในบริษัททั้งหมด (Sample Space คือ สิ่งที่เป็นไปได้ทั้งหมด)
                                    • E คือ คนในบริษัทที่ใส่แว่น (Eye Glass)
                                    • F คือ คนในบริษัทที่เป็นผู้หญิง (Female)

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

                                    Union การรวมเหตุการณ์ด้วยเงื่อนไขแบบ OR หรือ เขียนโดย E U F คือ เหตุการณ์ E หรือ F หรือ ทั้ง 2 อย่างเกิดขึ้น

                                    Statistics with Excel ตอนที่ 2 : ความน่าจะเป็น 289

                                    ดังนั้น E U F คือ เหตุการณ์ที่เจอคนที่ใส่แว่น หรือ เป็นผู้หญิงก็ได้ ซึ่งรวมถึงคนเหล่านี้ทั้งหมด

                                    • เป็นผู้ชายใส่แว่น
                                    • เป็นผู้หญิงไม่ใส่แว่น
                                    • เป็นผู้หญิงใส่แว่น

                                    Intersection = เหตุการณ์ที่ซ้ำกัน E ∩ F คือ ต้องเกิดทั้งเหตการณ์ E และ F พร้อมกัน

                                    Statistics with Excel ตอนที่ 2 : ความน่าจะเป็น 290

                                    ดังนั้น E ∩ F คือ เหตุการณ์ที่ต้องเป็นเจอผู้หญิงใส่แว่นเท่านั้น

                                    Complement = ~E  คือ เหตการณ์ที่ไม่ใช่เหตการณ์ E

                                    Statistics with Excel ตอนที่ 2 : ความน่าจะเป็น 291

                                    ดังนั้น ~E คือ เหตุการณ์ที่เจอคนไม่ใส่แว่นเท่านั้น

                                    ซึ่ง P(E) + P(~E) = P(S) = 1  

                                    ประโยชน์ของกฎเรื่อง Complement

                                    จาก P(E) + P(~E) = 1 เราสามารถเขียนได้ว่า

                                    P(E)= 1 - P(~E) 

                                    เช่น ถ้ารู้ความน่าจะเป็นคนที่ไม่ใส่แว่นว่าคือ 70% ดังนั้นความน่าจะเป็นของคนใส่แว่นคือ 30% นั่นเอง

                                    ซึ่งแปลว่าบางทีเมื่อเราหาความน่าจะเป็น P(E) ตรงๆ ยาก เราก็หาตัวที่ไม่ใช่ E ที่เรียกว่า P(~E) แล้วค่อยเอา 1 มาลบจะง่ายกว่า อย่างเช่นตัวอย่างต่อไปนี้

                                    ตัวอย่าง : วันเกิดตรงกัน

                                    จงหาโอกาสที่กลุ่มคนจำนวน 30 คนจะมีอย่างน้อย 1 คู่ที่มีวันเกิดตรงกัน?

                                    การจะหาอย่างน้อย 1 คู่ที่วันเกิดตรงกันตรงๆ นั้นยาก ให้หาโอกาสที่คน 30 คนจะมีวันเกิดไม่ตรงกันเลยดีกว่า (ผมขอ assume ว่าปีนึงมี 365 วันเสมอเพื่อความง่าย)

                                    ให้คิดว่าวัน 365 วันในปีเป็นลูกบอลในโหลจำนวน 365 ลูก แล้วเราต้องสุ่มทั้งหมด 30 ครั้ง = 365^30 แบบ

                                    กรณีที่คน 30 คนมีวันเกิดไม่ตรงกันเลย ก็คือ คนแรกเป็นไปได้ 365 แบบ แต่คนต่อไป เหลือ 364,363,362… ไปเรื่อยๆ
                                    อยากให้คูณไล่จาก 365 ไปแค่ 30 รอบ ซึ่งมองได้ว่า= 365!/(365-30!) = ใช้สูตร Permutation ได้= 365P30 ก็ได้ =PERMUT(365,30)

                                    ดังนั้นความน่าจะเป็น ที่คน 30 คนมีวันเกิดไม่ตรงกันเลย คือ

                                    =PERMUT(365,30)/365^30
                                    =29.368%

                                    โอกาสที่คน 30 คนจะมีอย่างน้อย 1 คู่ที่วันเกิดตรงกัน = 1 – ความน่าจะเป็น ที่คน 30 คนมีวันเกิดไม่ตรงกันเลย

                                    =1-PERMUT(365,30)/365^30
                                    =70.63 %

                                    ดังนั้นไม่ใช่เรื่องแปลกเลยที่นักเรียนในห้องเดียวกันมักจะมีอย่างน้อย 1 คนที่มีวันเกิดเดียวกันครับ

                                    ถ้าลองเอาไป Plot กราฟใน Excel ก็จะได้ประมาณนี้

                                    ความน่าจะเป็น Probability

                                    ความรู้เบื้องต้นเกี่ยวกับสำรับไพ่เพื่อเรียนรู้ความน่าจะเป็น

                                    ในตัวอย่างหลายๆ อันในนี้จะมีการพูดถึงไพ่ โดยไพ่มาตรฐานจะมีลักษณะดังนี้ (แต่คิดว่าหลายๆ คนคงรู้จักไพ่อยู่แล้วเนอะ 555)

                                    • ไพ่ 1 สำรับมี 52 ใบ (ไม่เอา Joker)
                                    • ประกอบด้วย 4 ชุด คือ ดอกจิก (clubs) ,โพธิ์ดำ (spades), ข้าวหลามตัด (diamonds), โพธิ์แดง หรือหัวใจ (hearts)
                                    • โดยที่ 2 ชุดแรกสีดำ, 2 ชุดหลังสีแดง (พูดง่ายๆ คือมีดำครึ่งนึง แดงครึ่งนึง)
                                    • แต่ละชุดมีไพ่ 13 ใบ คือ Ace, เลข 2-10, และอีก 3 หน้า แจค (jack), แหม่ม (queen), คิง (king)
                                    • ผมทำเป็นภาพสรุปไว้ให้ดังนี้
                                    Statistics with Excel ตอนที่ 2 : ความน่าจะเป็น 292

                                    การคำนวนความน่าจะเป็น (หรือใช้กับกฎการนับก็ได้) เมื่อมีเหตุการณ์มากกว่า 1 เหตุการณ์

                                    แบบเกิดอย่างน้อยเหตุการณ์ใดเหตุการณ์หนึ่ง (Union=OR)

                                    Statistics with Excel ตอนที่ 2 : ความน่าจะเป็น 289
                                    • หลักการคือเอาความน่าจะเป็นมารวมกัน แค่ว่าระวังว่าการรวมนั้นจะทำให้เบิ้ลหรือไม่ เช่น
                                    • กรณีที่เหตุการณ์ทั้งสองอย่างไม่สามารถเกิดพร้อมกันได้ (เรียกว่า Mutually Exclusive)
                                      • เมื่อไม่มีส่วนซ้ำ ก็จะบวกกันตรงๆ ได้เลย
                                      • P (E U F) = P(E) + P(F)
                                    • กรณีเหตุการณ์ทั้งสองอย่าง สามารถเกิดพร้อมกันได้
                                      • เพราะ E และ F มีส่วนซ้ำกัน ทำให้ถ้าบวกตรงแล้วเราจะนับเบิ้ลไป 1 ที จึงต้องเอาส่วนที่ซ้ำกันออกไป 1 ที (ให้หายเบิ้ล)
                                      • P (E U F) = P(E) + P(F) – P(E ∩ F)
                                      • ซึ่งจะเห็นว่า ถ้าเป็น Mutually Exclusive แล้ว   P(E ∩ F) จะเท่ากับ 0 ทำให้ได้สูตรข้างบนนั่นเอง

                                    แบบต้องเกิดทั้ง 2 เหตุการณ์ (Intersect=AND)

                                    Statistics with Excel ตอนที่ 2 : ความน่าจะเป็น 290
                                    • หลักการคือเอาความน่าจะเป็นมาคูณกัน เหมือนกับกฏการนับทั่วไปเลย ซึ่งขึ้นกับว่าเมื่อเกิดเหตุการณ์แรกไปแล้วเหตุการณ์ที่ 2 ที่จะเกิดขึ้นนั้น มีความน่าจะเป็นเปลี่ยนไปหรือไม่ ? ถ้าไม่เปลี่ยนก็ใช้ตัวเดิม (เรียกว่า Independent) ถ้าเปลี่ยน (เรียกว่า Dependent) ก็ต้องแก้ความน่าจะเป็นให้สอดคล้องกับความเป็นจริงนั้นๆ
                                    • กรณีเหตุการณ์ทั้งสองไม่ขึ้นต่อกัน (Independent) 
                                      • เช่น หาความน่าจะเป็นของการโยนเหรียญ 2 ครั้งแล้วออกหัวทั้ง 2 ครั้ง จะได้ว่า
                                      • เรามีเหตุการณ์ที่เกิดขึ้น 2 อัน คือ E = การโยนเหรียญครั้งแรกได้หัว , F = การโยนเหรียญครั้งที่สองได้หัว
                                      • P(E) = P(ออกหัว) = 0.5
                                      • P(F) = P(ออกหัว) = 0.5
                                      • P(E ∩ F) = ความน่าจะเป็นที่ครั้งแรกและครั้งที่สองออกหัว = P(E) × P(F) = 0.5 x 0.5 = 0.25
                                    • กรณีที่เหตุการณ์นั้นขึ้นต่อกัน (Dependent) :
                                      • เช่น หาความน่าจะเป็นที่จะจั่วไพ่ Q 2 ครั้งติดกัน โดยไม่มีการใส่ไพ่คืน (การจั่วครั้งแรกมีผลต่อครั้งที่สองแน่นอน)
                                      • เรามีเหตุการณ์ที่เกิดขึ้น 2 อัน คือ E = การจั่วครั้งแรกได้ Q, F = การจั่วครั้งที่สองได้ Q
                                      • ซึ่งความน่าจะเป็นของการจั่วได้ Q = 4/52 (เพราะในไพ่ 52 ใบ นั้นมี Q 4 ตัว)
                                      • ดังนั้น P(E) = P(จั่วได้ Q) = 4/52 อันนี้ไม่มีอะไรแปลก
                                      • แต่สำหรับการจั่วครั้งที่สอง เราจะใช้ P(จั่วได้ Q) ซึ่งคือ ความน่าจะเป็นของการจั่วได้ Q เฉยๆ ไม่ได้ เพราะในความเป็นจริงโอกาสในการได้ Q ในครั้งที่สองมันเปลี่ยนไปแล้ว เป็น 3/51 (เพราะเหลือ Q3 ใบ จากไพ่ที่เหลือ 51 ใบ)
                                      • เราเรียกความน่าจะเป็นของการจั่ว Q ในครั้งที่สอง (ที่เปลี่ยนไปจากการจั่ว Q ไปครั้งแรกสำเร็จแล้ว)
                                        ว่า P(จั่วQครั้งสอง | จั่ว Q ครั้งแรก) ซึ่งมีชื่ออย่างเป็นทางการว่า Conditional Probability นั่นเอง ในที่นี้ผมใช้ว่า P(F|E)
                                      • สูตรคือ P(E ∩ F) = P(E) × P(F|E)
                                      • สรุปแล้ว P(E ∩ F) = ความน่าจะเป็นที่จะจั่วไพ่ได้ Q 2 ครั้งติดกัน = P(E) × P(F|E) = 4/52 * 3/51 = 0.004525 หรือ 0.45% นั่นเอง
                                      • หากจริงๆ แล้วเหตุการณ์ E กับ F ไม่ขึ้นต่อกัน จะทำให้ P(F|E) เท่ากับ P(F) เฉยๆ
                                        • ทำให้ P(E ∩ F) = P(E) × P(F) เท่ากับกรณี Independent นั่นเอง

                                    ตัวอย่าง 1 : จั่วไพ่ J Q K และสีดำ

                                    ถ้าจั่วไพ่ออกมา 1 ใบจากสำรับ 52 ใบ จงหาโอกาสที่จะได้ไพ่ที่เป็นหน้า J Q K และมีสีดำ?

                                    1. trial = การจั่วไพ่ 1 ใบจากสำรับ 52 ใบ
                                    2. sample space = ไพ่ 52 ใบ ที่มีความน่าจะเป็นที่จะได้แต่ละใบเท่าๆ กัน
                                    3. event = ไพ่ J, Q, K ที่มีสีดำ (ดอกจิก ไม่ก็โพธิ์ดำ) จึงมีที่ตรงตามต้องการแค่ 6 ใบ
                                    4. probability = 6/52 = 0.1154 =11.54%

                                    หรือจะคำนวนอีกวิธีได้ว่า

                                    เนื่องจากทั้งสองอัน independent กัน P(JQK ∩ ดำ) = P(JQK) x P(ดำ)

                                    = 12/52  x 1/2  = 6/52 = 0.1154 =11.54%

                                    ตัวอย่าง 2 : จั่วไพ่ J Q K หรือไพ่สีดำ

                                    ถ้าจั่วไพ่ออกมา 1 ใบจากสำรับ 52 ใบ จงหาโอกาสที่จะได้ไพ่ที่เป็นหน้า J Q K หรือไพ่สีดำ?

                                    1. trial = การจั่วไพ่ 1 ใบจากสำรับ 52 ใบ
                                    2. sample space = ไพ่ 52 ใบ ที่มีความน่าจะเป็นที่จะได้แต่ละใบเท่าๆ กัน
                                    3. event = ไพ่ J, Q, K 12 ใบ หรือ ไพ่ที่มีสีดำ 26 ใบ ก็ตรงตามต้องการ เนื่องจากทั้ง 2 เหตุการณ์มีส่วนซ้ำกันได้ทำให้ต้องหัก ไพ่ JQK ที่มีสีดำออก (มี6 ใบจากที่คิดในคำถามแรก) ทำให้เหลือไพ่ที่ตรงความต้องการ = 12+26-6 = 32 ใบ
                                    4. probability = 32/52 = 0.615

                                    หรือจะคำนวนอีกวิธีได้ว่า

                                    กัน P(JQK U ดำ) = P(JQK) + P(ดำ) – P(JQK ∩ ดำ)

                                    = 12/52  +   26/52  –  6/52  = 0.615

                                    สิ่งที่ได้จากการเขียนความสัมพันธ์ Conditional Probability

                                    P(E ∩ F) = P(E) × P(F|E)

                                    หลักการของ Conditional Probability ข้างบนนี้ไม่มีอะไรเลย จริงๆ มันก็คือการบอกว่า

                                    ความน่าจะเป็นของการเกิดทั้งเหตุการณ์ E และ F ทั้งคู่
                                    = ความน่าจะเป็นของเหตุการณ์ E * ความน่าจะเป็นของเหตุการณ์ F หลังจากเกิด E ขึ้นแล้ว

                                    ซึ่งมันก็คือการใช้ Common Sense ทั่วไปนั่นแหละ จริงมะ?

                                    แต่เรื่องของเรื่องคือ เมื่อเรานำมันมาจัดเรียงใหม่ นำมาดัดแปลงมุมมองเล็กน้อย เราจะได้ทฤษฎีที่ทรงพลังมากที่สุดอันนึงของเรื่อง Probability นั่นก็คือ Bayes’s Theorem นั่นเอง

                                    Bayes’ Theorem

                                    ก่อนที่ผมจะอธิบายว่า Bayes’ Theorem คืออะไร? ผมจะยกตัวอย่าโจทย์ปัญหาที่ Bayes’ Theorem สามารถช่วยหาคำตอบได้ง่ายกว่าการใช้ Common Sense ทั่วไป

                                    สถานการณ์ คือ

                                    มีโหล 2 โหล คือ โหล ก กับ ข แต่ละโหลใส่ลูกบอลสีแดงกับเขียวปนกัน

                                    • โหล ก มี 4 ลูก โอกาสได้บอลแดง 50%
                                    • โหล ข มี 10 ลูก โอกาสได้บอลแดง 30%

                                    มีคนสลับโหลไปๆ มาๆ แล้วให้คุณหลับตาแล้วหยิบลูกบอลมั่วขึ้นมาลูกนึง ปรากฏว่าได้บอลสีแดง ถามว่าโอกาสที่คุณหยิบบอลมาจากโหล ข เป็นกี่ %

                                    คุณคิดด้วย Common Sense ได้หรือไม่?? ถ้าคุณเริ่มงง ลองมาดูต่อ

                                    การตีโจทย์ หากเราสามารถวาดรูปออกได้จะทำให้เข้าใจง่ายขึ้นเยอะ

                                    ความน่าจะเป็น Probability

                                    สิ่งที่ต้องการหา สามารถเขียนได้ในรูปของ Conditional Probability คือ P(หยิบจากโหล ข | ได้สีแดง) ซึ่งหายากกว่าในทิศกลับกันมาก นั่นคือ P(ได้สีแดง | หยิบจากโหล ข) ซึ่งรู้อยู่แล้วว่าคือ 30%

                                    นี่แหละที่เจ้า Bayes’s Theorem เริ่มมีประโยชน์ในการเข้ามาช่วยครับ มันเจ๋งตรงที่มันใช้ความน่าจะเป็นในทิศกลับกันมาช่วยหาได้

                                    ทฤษฎี

                                    ทีนี้เรามาดูกันว่าเจ้า Bayes’s Theorem เค้าบอกว่ายังไง

                                    Statistics with Excel ตอนที่ 2 : ความน่าจะเป็น 295

                                    ซึ่งจริงๆ แล้วเป็นสูตรที่ Make Sense มากๆ หากลอง พิจารณาจากความรู้เรื่อง Conditional Probability ที่ว่า

                                    P(A ∩ B) = P(A) × P(B|A)

                                    ดังนั้นสูตรข้างบนมันก็คือ

                                    P(A | B) = P (A ∩ B) / P(B)

                                    หากพิจารณาจาก Venn Diagrams จะเข้าใจง่ายมาก ว่าทำไมสูตรถึงออกมาแบบนั้น

                                    ซึ่งแปลว่า ความน่าจะเป็นของ A หลังจากเกิด B แล้ว เท่ากับ ความน่าจะเป็นของการเกิดทั้ง A และ B หารด้วย ความน่าจะเป็นของ B นั่นเอง

                                    Statistics with Excel ตอนที่ 2 : ความน่าจะเป็น 296

                                    แก้โจทย์ปัญหา

                                    Statistics with Excel ตอนที่ 2 : ความน่าจะเป็น 297

                                    P(หยิบจากโหล ข | ได้สีแดง) = P(ได้สีแดง | หยิบจากโหล ข) * P(หยิบจากโหล ข) / P (ได้สีแดง)

                                    Statistics with Excel ตอนที่ 2 : ความน่าจะเป็น 298
                                    • P(ได้สีแดง | หยิบจากโหล ข) คือ 3/10 อันนี้ง่ายมาก
                                    • P(หยิบจากโหล ข) = 10/14 เพราะมีบอลจากโหล ข 10 ลูก จากบอลทุกโหล 14 ลูก
                                    • P(ได้สีแดง) = ถ้านับเอาเราจะได้ 5/14 ซึ่งง่ายๆ เนอะ

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

                                    สรุป : P(หยิบจากโหล ข | ได้สีแดง)

                                    = (3/10) * (10/14) / (5/14)   =  ( 3/14 ) / (5/14)  หรือ 3/5 นั่นเอง

                                    ซึ่งถ้าดูจากรูปนี่โคตร Make Sense เพราะจากสีแดงทั้งหมดที่มี 5 ลูก มันอยู่ที่ โหล ข 3 ลูก นั่นเอง!! (สูตรมันหมายความงี้เองเรอะ!)

                                    Statistics with Excel ตอนที่ 2 : ความน่าจะเป็น 299

                                    ตัวอย่างโจทย์

                                    ตัวอย่าง 1 : ผู้ติดเชื้อ Covid

                                    จาก Data ของผู้ติดเชื้อ Covid-19 เมื่อวันที่ 13 มิย. 63 ผมลอง Pivot ข้อมูลออกมาได้ดังตาราง

                                    Count of noProvince
                                    sexกทมต่างจังหวัดGrand Total
                                    ชาย8139111724
                                    หญิง7256851410
                                    Grand Total153815963134

                                    สมมติผมสุ่มคนออกมาคนนึงปรากฏว่าได้เป็นผู้ชาย จงหาความน่าจะเป็นที่คนคนนั้นจะเป็นคน กทม.

                                    ถ้าเราเห็นเลขทุกตัวครบแล้ว จริงๆ มันง่ายมาก เพราะ P(กทม|ชาย) ก็คือ = 813/1724 = 47.16% ได้เลย (ก็ชายทั้งหมด 1724 คน เป็น กทม 813 คนไง)

                                    แต่ถ้าจะใช้สูตรจาก Bayes ก็จะเป็นดังนี้

                                    P(กทม|ชาย) = P(ชาย ∩ กทม) / P(ชาย)
                                    • P(ชาย ∩ กทม) = 813/3134
                                    • P(ชาย) = 1724/3134
                                    • P(กทม|ชาย) = 813/1724 นั่นเอง

                                    หรือจะมองอีกแบบก็ยังได้

                                    P(กทม|ชาย) = P(ชาย|กทม) * P(กทม) / P(ชาย)
                                    =(813/1538) * (1538/3134) / (1724/3134)
                                    =813/1724 = 47.16% อยู่ดี

                                    ถ้าเราได้ Data มาเป็น Portion ของ Grand Total แบบนี้ ก็สามารถคิดได้เช่นกัน

                                    Count of noProvince
                                    sexกทมต่างจังหวัดGrand Total
                                    ชาย25.94%29.07%55.01%
                                    หญิง23.13%21.86%44.99%
                                    Grand Total49.07%50.93%100.00%
                                    P(กทม|ชาย) = ภายในชาย ให้ดูเฉพาะ กทม. 
                                    = 25.94% / 55.01% = 47.16%

                                    ดังนั้นจะเห็นได้ว่าหากเราเห็นภาพของข้อมูลครบถ้วนด้วยตารางแบบนี้นะ ทุกอย่างมันจะง่ายขึ้นมากๆ เลย

                                    ตัวอย่าง 2 : จั่วไพ่

                                    ถ้าจั่วไพ่ออกมา 1 ใบจากสำรับ 52 ใบ แล้วเป็นสีดำ จงหาโอกาสที่มันจะเป็นไพ่ดอกจิก

                                    1. trial = การจั่วไพ่ 1 ใบจากสำรับ 52 ใบ
                                    2. sample space หลังจากการรู้ว่าเป็นสีดำ= ไพ่สีดำ มี 26 ใบ
                                    3. event = ได้ไพ่ดอกจิก
                                    4. probability = 13/26 = 0.5

                                    หรือจะคำนวนอีกวิธีได้ว่า

                                    P(ดอกจิก | ไพ่ดำ) = P(ดอกจิก ∩ ไพ่ดำ) / P(ไพ่ดำ) 
                                    = P(ดอกจิก) / P(ไพ่ดำ) = 0.25 / 0.5 = 0.5 = 50%

                                    ตัวอย่าง 3 : สาวสวยแปลงเพศ

                                    สถานการณ์คือ คุณกับเพื่อนเดินไปเจอสาวสวยคนหนึ่ง ช่างเป็นสาวที่ตรง Spec ของคุณ จนอยากจะเข้าไปขอ ID Line เดี๋ยวนี้เลย แต่แล้วเพื่อนของคุณทักขึ้นมาว่า เดี๋ยวนี้ผู้หญิงสวยๆ อาจจะเป็นผู้ชายที่แปลงมาก็ได้… ตอนนี้คุณเริ่มลังเล และอยากจะหาความน่าจะเป็นที่สาวสวยที่คุณเจอจะเป็นผู้ชายแปลงเพศมา!

                                    ความน่าจะเป็นที่คนที่คุณเจอจะเป็นผู้ชายแปลงเพศ เมื่อรู้แล้วว่าเป็นคนสวย สามารถเขียนได้ว่า = P(เจอผู้ชายแปลงเพศ|เจอคนสวย)

                                    จาก Bayes จะได้ว่า

                                    P(เจอผู้ชายแปลงเพศ|เจอคนสวย) = P(เจอคนสวย|เจอผู้ชายแปลงเพศ) * P(เจอผู้ชายแปลงเพศ) / P(เจอคนสวย)

                                    สมองของคุณเริ่มเดาๆ ตัวเลขที่เกี่ยวข้องออกมาได้ ดังนี้ (เดาผิดอย่าว่ากัน assume ว่าไม่มีตัวเลขที่ดีกว่านี้แล้ว)

                                    • โอกาสที่ผู้ชายแปลงเพศแล้วจะสวย = P(คนสวย|ผู้ชายแปลงเพศ) = 60%
                                    • โอกาสที่จะเจอผู้ชายแปลงเพศ =P(ผู้ชายแปลงเพศ) = 5%
                                    • โอกาสที่จะเดินเจอคนสวย = P(เจอคนสวย) = 20%
                                    P(ผู้ชายแปลงเพศ|คนสวย) = 60% * 5% / 20% = 15% นั่นเอง

                                    สรุปแล้ว คุณก็เลยตัดสินใจไปหาสาวสวยคนนั้น เพราะโอกาส 15% ก็ไม่ใช่น้อยๆ นะที่คุณจะได้เจอคนที่ตามหามานาน (อ้าว 555)

                                    ตัวอย่าง 3 : ดักจับ Spam

                                    อยากหาโอกาสที่ใน Email ที่ส่งมาจะเป็น Spam เมื่อเจอคำว่า Viagra อยู่ในข้อความ Email

                                    นั่นคืออยากหา P(Spam|Viagra) ซึ่งเราเขียนสูตรได้ดังนี้

                                    P(Spam|Viagra) = P(Viagra|Spam) * P(Spam) / P(Viagra)

                                    สมมติเราไปเก็บ Data มาแล้วได้ข้อมูลดังนี้

                                    • โอกาสที่ข้อความที่รู้ว่าเป็น Spam จะมีคำว่า Viagra อยู่นั้นคือ 70%
                                    • โอาสที่ข้อความที่รู้ว่าไม่ใช่ Spam จะมีคำว่า Viagra อยู่นั้นคือ 10%
                                    • โอกาสที่จะเจอข้อความเป็น Spam =P(Spam) = 80%
                                    P(Spam|Viagra) = 70%*80% / P(Viagra)

                                    แล้ว P(Viagra) จะหาได้ยังไง?

                                    ถ้าวาดข้อมูลลงตารางและปรับฐานให้เท่ากันเป็น %of Grand Total ได้ จะทำให้เข้าใจง่ายขึ้นมากๆ

                                    Statistics with Excel ตอนที่ 2 : ความน่าจะเป็น 300

                                    จริงๆ แล้วมันก็คือ ช่อง K10 จริงมะ ซึ่งคิดได้แบบนี้

                                    P(Viagra) = P(Viagra|Spam) * P(Spam)  +  P(Viagra|Not Spam)*P(Not Spam)
                                    P(Viagra) = 70%*80% + 10%*(1-80%) = 58%

                                    สรุปแล้ว

                                    P(Spam|Viagra) = 60%*80% / 58% = 82.7% นั่นเอง

                                    และเรื่องแบบนี้แหละซึ่งเค้าเอาไปใช้ในการทำ Machine Learning เพื่อพัฒนา AI ที่ใช้ดัก Spam ด้วย แต่มันจะซับซ้อนกว่านี้เนอะ

                                    แหล่งศึกษาความรู้เพิ่มเติม

                                    ตอนต่อไป

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

                                    เดี๋ยวตอนต่อไปจะเป็นเรื่องของ Discrete Probability Distribution หรือการแจกแจงความน่าจะเป็นแบบที่เหตุการณ์ที่สนใจนั้นสามารถนับแยกเป็นชิ้นๆ ได้(ไม่ได้มีค่าต่อเนื่องกัน)

                                    สารบัญซีรีส์ Statistics

                                    • Statistics with Excel  ตอนที่ 1  : ค่าสถิติที่สำคัญ

                                      Statistics with Excel ตอนที่ 1 : ค่าสถิติที่สำคัญ

                                      Statistics (สถิติ) นั้นเป็นศาสตร์ที่สามารถช่วยให้เราเปลี่ยนข้อมูลดิบ (Data) ให้เป็นข้อมูลที่มีประโยชน์ (Information) ได้ ซึ่งมีความจำเป็นและมีประโยชน์มากต่อการช่วยให้เราสามารถตัดสินใจด้วยข้อมูลได้ดีขึ้น เหมาะกับองค์กรในยุคปัจจุบันที่ต้องใช้ Data ในการตัดสินใจ หรือที่เรียกว่า Data-Driven Organization

                                      ซึ่งในซีรีส์นี้เราจะมาเรียนรู้เรื่องสถิติกันตั้งแต่พื้นฐานกันเลยครับ

                                      Version VDO บน YouTube (ฝาก subscribe ด้วยน้าาาา)

                                      ภาพรวมของสถิติ

                                      • Descriptive Statistics (สถิติเชิงพรรณนา) = การสร้างตัวเลขมาบรรยายลักษณะข้อมูลที่มีอยู่ในรูปแบบของผลสรุปต่างๆ ไม่ว่าจะมาจากข้อมูลทั้งหมดหรือมาจากกลุ่มตัวอย่างก็ตาม ซึ่งสามารถแบ่งการสรุปออกเป็น 2 กลุ่มใหญ่ๆ คือ
                                        • Central Tendency (แนวโน้มค่ากลาง) เช่น Mean (ค่าเฉลี่ยเลขคณิต), Median (มัธยฐาน)
                                        • Dispersion (การกระจาย) เช่น Standard Deviation (ส่วนเบี่ยงเบนมาตรฐาน)
                                      • Inferential Statistics (สถิติเชิงอนุมาน) = การนำข้อมูลจากตัวอย่างที่เก็บมาจำนวนน้อย ไปใช้อนุมาน (infer) เพื่อตอบคำถามเกี่ยวกับข้อมูลที่แท้จริงที่มีจำนวนมากกว่า ซึ่งเราไม่สามารถเก็บข้อมูลมาทั้งหมดได้จริงๆ โดยแบ่งเป็น
                                        • Estimation (การประมาณค่า) = การเอาข้อมูลจาก Sample ไปสรุปหรือประมาณค่าของข้อมูล Population
                                        • Hypothesis Testing (การทดสอบสมมติฐาน) = การใช้หลักการสถิติไปตอบคำถามที่เราสนใจ เช่น ยาตัวใหม่ได้ผลจริงๆ หรือแค่มโนไปเอง

                                      นิยามของข้อมูลทางสถิติ

                                      • ข้อมูลทั้งหมดที่เราสนใจเรียกว่า Population (ประชากร) ถ้าเราเลือกที่จะเก็บข้อมูล Population ทั้งหมดเลยเราจะเรียกข้อมูลนั้นว่า Census และสิ่งที่เป็นตัวแปรวัดค่าของมันจะเรียกว่า Parameter (ใช้ตัวอักษรกรีก)
                                      • แต่ถ้าเราเก็บตัวอย่างมาบางส่วน (เนื่องจากเก็บหมดไม่ไหว) เราจะสิ่งที่เราเก็บมาว่า Sample (กลุ่มตัวอย่าง) และมีตัวแปรวัดค่าที่เรียกว่า Statistic (ใช้ตัวอักษรโรมัน)

                                      ข้อมูลทางสถิตินั้นแบ่งได้เป็น 2 ประเภทใหญ่ๆ คือ

                                      • Qualitative Data เมื่อข้อมูลนั้นถูกจัดอยู่ในประเภท หรือหัวข้อ เช่น สีต่างๆ, ผ่าน หรือ ตก, ต่ำ กลาง สูง และสามารถแบ่งย่อยออกเป็น 2 ประเภทคือ
                                        • Nominal = เมื่อการเรียงของข้อมูลไม่มีความหมาย เช่น สีแดง เหลือง เขียว (การเรียงของสีไม่มีความหมาย)
                                        • Ordinal = เมื่อการเรียงข้อมูลมีความหมาย เช่น ต่ำ กลาง สูง, หรือ เกรด A-F เป็นต้น
                                      • Quantitative Data เมื่อข้อมูลนั้นสามารถนับหรือวัดได้ ซึ่งสามารถแบ่งย่อยออกเป็น 2 อย่างคือ
                                        • Discrete เมื่อข้อมูลนั้นวัดเป็นจำนวนเต็มได้เท่านั้น (สามารถนับเป็นชิ้นๆ ได้ เช่น จำนวนคนที่อยู่ในห้องเรียน)
                                        • Continuous เมื่อข้อมูลนั้นจะเป็นตัวเลขค่าอะไรก็ได้ (เช่น ส่วนสูง น้ำหนัก)

                                      เอาล่ะเมื่อเห็นภาพรวมแล้ว ในตอนที่ 1 นี้เราจะมาเจาะลึกตัว Descriptive Statistics กัน และจะลองทำใน Excel กันด้วยครับ

                                      ข้อมูลที่จะนำมาวิเคราะห์

                                      ซึ่งข้อมูลก็ไม่มีอะไรมากครับ ให้ทุกคนสร้างเลข running 1-10 ใน Excel (โดยใส่ 1 แล้วคลิ๊กขวาที่ Fill Handle แล้วลากลงมา) จากนั้นให้เปลี่ยนเลขบางส่วนดังต่อไปนี้

                                      • เปลี่ยน 4 เป็นเลข 3
                                      • เปลี่ยน 8 เป็นเลข 7
                                      • เปลี่ยน 10 เป็น 100

                                      สรุปจะได้ Data หน้าตาแบบนี้นะ ซึ่งผมตั้งชื่อ (Define Name) เจ้า Range A2:A11 นี้ ว่า data เพื่อให้ดูสูตรแล้วเข้าใจง่ายขึ้น และ copy paste ง่ายขึ้นด้วย

                                      Statistics with Excel ตอนที่ 1 : ค่าสถิติที่สำคัญ 301

                                      การคำนวณสุดฮิตที่ใช้ใน Descriptive Statistics

                                      ปกติการทำผลสรุปทั้งสถิติต่างๆ เพื่ออธิบายลักษณะของข้อมูลนั้น มักจะแบ่งเป็น 2 กลุ่ม คือ

                                      Central Tendency (แนวโน้มค่ากลาง)

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

                                      Mean (ค่าเฉลี่ยเลขคณิต)

                                      คือ ค่าเฉลี่ยที่เกิดจากผลรวมข้อมูลทั้งหมดหารด้วยจำนวนข้อมูล นี่น่าจะเป็นค่าสถิติที่คนส่วนใหญ่รู้จักดีกันมากที่สุดเลยล่ะ
                                      แต่มันมีข้อเสียที่สำคัญ คือ มันจะได้รับอิทธิพลจากค่าที่น้อยหรือเยอะมากๆ มาดึงค่าเฉลี่ยไป ทำให้อาจเข้าใจผิดได้ (เดี๋ยวจะได้เห็นว่าค่า 100 จะดึง Mean ขึ้นไปขนาดไหน หึหึ)

                                      =AVERAGE(data)              // Excel จะคำนวณเฉพาะค่าที่เป็น Number เท่านั้น
                                      =SUM(data)/COUNT(data)      // Excel จะคำนวณเฉพาะค่าที่เป็น Number เท่านั้น

                                      Median (มัธยฐาน)

                                      คือ ค่าที่อยู่ตำแหน่งกึ่งกลาง เมื่อนำข้อมูลมาเรียงกันจากน้อยไปมาก
                                      ดีตรงที่แทบไม่ได้รับอิทธิผลจากค่ามากหรือน้อยจัดๆ

                                      = MEDIAN(data)

                                      Mode (ฐานนิยม)

                                      คือ ค่าที่เกิดขึ้นบ่อยที่สุดในชุดข้อมูล อาจมีค่าเดียวหรือหลายค่าก็ได้
                                      ข้อดีคือมั่นใจได้ว่าเป็นค่าที่มีอยู่จริงในข้อมูล ไม่เหมือน Mean ซึ่งอาจได้เลขที่ไม่มีอยู่จริงๆ

                                      = MODE.SNGL(data)         // ใช้กรณีที่อยากได้ผลลัพธ์ค่าเดียว (MODE ใน version เก่าก็คือตัวนี้)
                                      = MODE.MULT(data)         // สามารถแสดงผลลัพธ์หลายค่าได้ (ออกมาเป็น array)

                                      เมื่อทดลองกับข้อมูลของเราแล้วจะได้ผลลัพธ์แบบนี้ครับ

                                      Statistics with Excel ตอนที่ 1 : ค่าสถิติที่สำคัญ 302

                                      Dispersion (การกระจาย)

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

                                      Range (พิสัย)

                                      วัดการกระจายโดยเอาค่ามากสุด – ค่าน้อยสุด

                                      =MAX(data) - MIN(data)

                                      Variance (ความแปรปรวน)

                                      วัดการกระจายโดยเอาความต่างของแต่ละจุดข้อมูลกับค่าเฉลี่ยมากยกกำลังสอง แล้วหาค่าเฉลี่ย
                                      (ที่ใช้วิธียกกำลังสองเพื่อแก้ปัญหาเรื่องเครื่องหมายบวกลบ และลงโทษค่าที่ไกลจากค่า Mean มากๆ ได้ดีกว่าการหาค่า Absolute)

                                      =VAR.P(range)      //ใช้กับข้อมูลที่มาจาก Population ทั้งหมด
                                      =VAR.S(range)      //ใช้กับข้อมูลที่มาจาก Sample (มีการแยกสูตรเพราะถ้าคำนวณตามปกติค่าที่ได้จะน้อยเกินจริง เลยพยายาม adjust สูตรให้ตัวหารน้อยลง ค่าที่จะได้จะเยอะขึ้นจนใกล้เคียงค่าจริงของ Population มากขึ้น)
                                      Statistics with Excel ตอนที่ 1 : ค่าสถิติที่สำคัญ 303
                                      อันบนคือสูตรของ Variance ที่คิดจาก Population
                                      อันล่างคือสูตรของ Variance ที่คิดจาก Sample

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

                                      เมื่อเราเอาระยะห่างของแต่ละจุดกับค่าเฉลี่ย มายกกำลังสอง ก็จะได้พื้นที่สี่เหลี่ยม จากนั้นเอาขนาดสี่เหลี่ยมทุกอันมาเฉลี่ยกันจะได้ Variance นั่นเอง

                                      Statistics with Excel ตอนที่ 1 : ค่าสถิติที่สำคัญ 304
                                      https://towardsdatascience.com/a-visual-interpretation-of-the-standard-deviation-30f4676c291c

                                      ข้อเสียของ Variance คือ มีปัญหาเรื่องหน่วยที่ไม่เหมือนกับ Data ต้นฉบับ (เพราะดันมีการยกกำลังสอง)

                                      Standard Deviation (ส่วนเบี่ยงเบนมาตรฐาน)

                                      คือการเอาค่า Variance มาหารากที่สอง เพื่อแก้ปัญหาเรื่องหน่วยให้ได้หน่วยเดียวกับ Data จริงๆ

                                      =STDEV.P(range)   // ใช้กับข้อมูลที่มาจาก Population ทั้งหมด
                                      =STDEV.S(range)   //ใช้กับข้อมูลที่มาจาก Sample ด้วยเหตุผลเดียวกับ VAR.S
                                      Statistics with Excel ตอนที่ 1 : ค่าสถิติที่สำคัญ 305

                                      Percentile

                                      คือการเรียงข้อมูลจากน้อยไปมาก แล้วแบ่งข้อมูลออกเป็น 100 ส่วน สมมติว่าเราสอบได้คะแนน Percentile ที่ 83 หมายความว่า มีคน 83% ที่สอบได้คะแนนน้อยกว่าเรา

                                      =PERCENTILE.INC(array, k)   // แบบ Inclusive หรือแบบที่เป็น =PERCENTILE เฉยๆ
                                      =PERCENTILE.EXC(array, k)   // แบบ Exclusive
                                      • แบบ Inclusive : อันดับโดย คำนวณจาก k*(N-1)+1 โดยที่ N คือจำนวนข้อมูล
                                      • แบบ Exclusive : อันดับ คำนวณจาก k*(N+1) โดยที่ N คือจำนวนข้อมูล (นักสถิติมองว่าตัวนี้ตรงตามนิยามมากกว่า แต่มันจะมีปัญหากับ Percentile ที่ 0 กับ 100 ว่ามันจะ Error)

                                      สำหรับคนที่สงสัยว่า Inclusive กับ Exclusive ต่างกันยังไง ลองดูคลิปที่ผมเคยทำไว้ได้ครับ

                                      คลิปอธิบายความแตกต่างระหว่าง Inclusive กับ Exclusive

                                      Quartile

                                      คือการเรียงข้อมูลจากน้อยไปมาก แล้วแบ่งข้อมูลออกเป็น  4 ส่วน ถ้าเราอยู่ Quartile ที่ 3 แปลว่า มีข้อมูล 75% ที่น้อยกว่าเรา

                                      =QUARTILE.INC(array,quart)  // แบบ Inclusive หรือแบบที่เป็น =QUARTILE เฉยๆ
                                      =QUARTILE.EXC(array,quart)  // แบบ Exclusive

                                      โดยที่

                                      • Percentile ที่ 0 = Min (กรณี Inclusive)
                                      • Q1 = Percentile ที่ 25
                                      • Q2 = Percentile ที่ 50 = Median
                                      • Q3 = Percentile ที่ 75
                                      • Q4 = Percentile ที่ 100 = Max (กรณี Inclusive)

                                      IQR (Interquartile Range)

                                      คือการนำเอา Quartile 3- Quartile1

                                      Statistics with Excel ตอนที่ 1 : ค่าสถิติที่สำคัญ 306

                                      Box Plot หรือ Box and Whiskers Plot

                                      เราสามารถเอาค่าพวก Mean และ Quartile มาแสดงเป็นกราฟที่เรียกว่า Box Plot ได้ ซึ่งเป็นกราฟที่สามารถแสดงการกระจายของข้อมูลได้ดีมากๆ อันดึงเลย แถมยังเหมาะกับการเปรียบเทียบการกระจายของข้อมูลหลายๆ กลุ่มได้ดีอีกด้วย

                                      • เราเอาค่า Q1, Q2, Q3 มาสร้างเป็นตัวกล่อง (Box)
                                      • คำนวณระยะมากสุดของแขนที่ยื่นออกมา (Whiskers) จาก Q1 และ Q3 ด้วยระยะทาง 1.5 เท่าของ IQR (บางที่อาจใช้ 3 เท่า)
                                      • อย่างไรก็ตามถ้าค่า Min กับ Max ไม่เกินระยะมากสุดของแขนที่คำนวณ เราก็จะเอาแขนยื่นออกไปเท่ากับค่า Min, Max นะครับ
                                      • ข้อมูลอะไรที่อยู่ไกลกว่าแขน Whiskers ที่ยื่นออกไป จะถูกมองว่าเป็น Outlier (ค่าที่น้อยหรือเยอะมากๆ เมื่อเทียบกับค่าอื่น) ซึ่งจะแสดงด้วยจุดแทนครับ
                                      • และบางทีก็จะเอาค่า Mean มา Plot ด้วยเครื่องหมายกากบาทด้วย
                                      • กราฟจะทำเป็นแนวนอนหรือแนวตั้งก็ได้ แล้วแต่ความชอบ 555
                                      Statistics with Excel ตอนที่ 1 : ค่าสถิติที่สำคัญ 307
                                      รูปเอามาจาก https://towardsdatascience.com/understanding-boxplots-5e2df7bcbd51

                                      ใน Excel version ใหม่ๆ เราก็สร้างกราฟแบบ Boxplot ได้ง่ายๆ เลยครับ โดยที่ Excel จะใช้ Quartile แบบ Exclusive มาสร้างกราฟนะครับ

                                      Statistics with Excel ตอนที่ 1 : ค่าสถิติที่สำคัญ 308

                                      ใน Data 1 จะเห็นว่าค่า Mean ที่ควรเป็นค่ากลางของข้อมูลมันดันเด้งออกมานอกกล่องด้วยซ้ำ (ช่างเป็นค่ากลางที่แย่จริงๆ 555) ผมเลยลองแก้ค่า 100 เป็น 10 จะเห็นว่าค่า Mean ที่เด้งออกไปนอกกล่องใน Data1 นั้นกลับเข้ามาในกล่องได้อย่างสวยงาม ซึ่งแสดงให้เห็นว่าถ้าเราไม่มีค่า Outlier มาดึง Mean แล้วล่ะก็ มันก็เป็นค่ากลางที่ดีใช้ได้เลยล่ะ (หรือจริงๆ เลข 100 ที่ได้มาเป็นเลขที่พิมพ์ผิดกันนะ)

                                      Statistics with Excel ตอนที่ 1 : ค่าสถิติที่สำคัญ 309

                                      และนี่คือการคำนวณพื้นฐานทางสถิติที่ควรจะรู้จักครับ เดี๋ยวในตอนหน้าเราจะมาดูเรื่องพื้นฐานของทุกสิ่งทุกอย่าง นั่นก็คือ “การนับและความน่าจะเป็น” กันครับ

                                      สารบัญซีรีส์ Statistics

                                      • วิธี Optimize การตัดแบ่งวัตถุดิบ ด้วย Excel Solver

                                        วิธี Optimize การตัดแบ่งวัตถุดิบ ด้วย Excel Solver

                                        • ในคลิปจะสอนวิธีการเลือก Pattern การตัดวัตถุดิบ (Cutting) ให้ครบตาม Demand ที่ต้องการ และต้องได้ต้นทุนต่ำที่สุดด้วย Excel Solver (เริ่ม 0:00)
                                        • อีกทั้งยังสอนการใช้ Power Query ช่วยสร้าง Pattern การตัดวัตถุดิบให้ครบทุกแบบแบบอัตโนมัติด้วย (เริ่ม 19:00)
                                        • บอกเลยว่าคลิปนี้ยาวและค่อนข้างซับซ้อน แต่ใครดูจบน่าจะได้แนวทางไปทำให้ธุรกิจมีกำไรมากขึ้นได้เลยล่ะ
                                      • วิธี Lookup ข้อมูล แม้สะกดผิดก็ยังหาเจอ ด้วย Power Query Fuzzy Merge

                                        วิธี Lookup ข้อมูล แม้สะกดผิดก็ยังหาเจอ ด้วย Power Query Fuzzy Merge

                                        เบื่อมั้ยเวลาที่คุณได้ข้อมูลมาแบบสะกดผิด (ข้อมูลเน่านั่นแหละ) ทำให้พอเอาไป Lookup ก็หาไม่เจอ ปวดหัวได้อีก… แต่ปัญหานี้จะหมดไปถ้าคุณรู้จักการใช้เครื่องมือ Power Query Fuzzy Merge

                                      • วิธีเขียนสูตร Excel ที่ใช้บ่อย ในพริบตา

                                        วิธีเขียนสูตร Excel ที่ใช้บ่อย ในพริบตา

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

                                      • ไขความลับ เลข Digit สุดท้าย ของเลขบัตรประชาชน (Check Digit) และเทคนิคการรวบสูตร Excel

                                        ไขความลับ เลข Digit สุดท้าย ของเลขบัตรประชาชน (Check Digit) และเทคนิคการรวบสูตร Excel

                                        เลข Digit สุดท้ายของเลขบัตรประชาชนของพวกเราทุกคน มันไม่ได้มาแบบมั่วๆ แต่ถูกคำนวณมา และมันคำนวณมายังไง? จะเอามาใช้ประโยชน์อะไรได้บ้าง? มาดูกันครับ

                                        ไขความลับ เลข Digit สุดท้าย ของเลขบัตรประชาชน

                                        มีเพื่อนถามมาว่า Digit อื่นๆ มีความหมายหรือไม่? ถ้าอยากรู้ไปดูรายละเอียดต่อได้ที่นี่ครับ https://stat.bora.dopa.go.th/fop/pid13.htm

                                        เทคนิคการรวบสูตร Excel ให้เหลือช่องเดียว

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

                                        ซึ่งถ้าทำแล้วจะช่วยให้ copy paste ได้สะดวกขึ้นเยอะ และที่สำคัญคือจะดูเทพขึ้นหลายสิบเท่าเลย 555

                                        ใครดูแล้วสงสัยตรงไหน ก็ comment ได้ใน YouTube เลยนะครับ