Month: May 2020

  • แชร์หน้าจอมือถือขณะ VDO Call ด้วย LINE

    สำหรับ Blog ในวันนี้จะมาขอแชร์เกร็ดความรู้เล็กๆ น้อยๆ ที่หลายๆคนอาจจะยังไม่เคยรู้มาก่อน (ถึงแม้จะใช้ LINE กันอยู่ทุกวันก็เถอะ)

    เมื่อไม่กี่วันที่ผ่านมาทาง LINE ได้มีการ update version ล่าสุด คือ10.6.5 ซึ่งใน version นี้จะเน้นไปที่การเพิ่มคุณสมบัติขณะวิดีโอคอล เช่น สามารถดู YouTube ร่วมกันได้ หรือสามารถแชร์หน้าจอตัวเองได้ เป็นต้น จริงๆแล้ว เรื่องของการแชร์หน้าจอขณะ VDO Call เนี่ย เดิมบนคอมพิวเตอร์ก็ทำได้อยู่ก่อนแล้วนะ แต่ตอนนี้ update ให้สามารถแชร์ผ่าน application บน smart phone ได้ด้วย

    วิธีการก็ไม่ยากเลย ปะ ไปดูกันว่าเค้าทำกันยังไง !!

    Step1 : เริ่มจากเปิด LINE และเลือก VDO Call หาคนที่เราต้องการ

    Step2 : เมื่อเริ่มการ VDO Call เรียบร้อยแล้ว แตะหน้าจอเบาๆ 1 ครั้ง จากนั้นให้สังเกตุมุมบนด้านขวาของหน้าจอ จะปรากฏicon เล็กๆ ให้กดเลือกตรงจุด3จุด

    Step3 : หน้าจอจะแสดงเมนูให้เราเลือก ให้เลือก “Share screen

    Step4 : เมื่อกดเลือกเรียบร้อยแล้วหน้าจอก็จะถามเราว่า “LINE will start capturing everything that’s displayed on your screen.” ให้เลือกว่าจะ cancel หรือ start now เลือกแบบไหนก็เลือกเลย หากไม่ต้องการให้รอบหน้าแสดงข้อความนี้อีกก็สามารถ Checkbox ด้านหน้าคำว่า Don’t show again ได้เลย

    Step5 : เมื่อเราเริ่มต้นการ Share screen เรียบร้อยแล้ว หน้าจอเราเปิดอะไรอยู่ เพื่อนที่เรา VDO Call ด้วยก็จะเห็นเหมือนกัน ตัวอย่างก็จะได้ดังรูป ^^

    จะว่าไปก็มีประโยชน์อยู่ไม่น้อยเลยนะ ยิ่งช่วงนี้อะไรๆก็ออนไลน์ ทั้งเรียน ทั้งประชุม ทั้งพูดคุย ตัวคุณสมบัติที่เพิ่มเข้ามาอันนี้ตอบรับนโยบาย social distancing ได้ดีมากๆ

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

    อ้างอิง
    https://www.rainmaker.in.th/line-update-video-call/

  • ไม่มีเวลา, ไม่มีเงิน, ไม่มีปัญหา: ต้นไม้ต้นแรกแห่งความสำเร็จ

    สวัสดีครับวันนี้ผมมีเรื่องราวที่จะมาช่วยสร้างแรงบันดาลใจให้กับทุกคนในช่วงวิกฤตโควิท-19 ให้กลับมาลุกขึ้นมาสู้อีกครั้งและเป็นแรงบันดาลใจให้กับคนที่มีความฝันที่อยากจะสร้างเกม

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

    จุดเริ่มต้นมาจากมีเพื่อนคนนึงได้แนะนำการใช้งานโปรแกรม Unity (โปรแกรมสำหรับสร้างเกม) เมื่อเดวิดเห็นครั้งแรกก็พูดกับตัวเองว่า “ฉันรู้ว่าฉันจะต้องสร้างเกม” จึงเริ่มฝึกฝนการใช้งานโปรแกรมและทำงานอย่างหนักจนกระทั้งได้ปล่อยเกมแรกบน Steam ที่ชื่อว่า Home is Where One Starts… 

    ผลปรากฏว่าได้รับคำวิจารณ์จากเหล่าเกมเมอร์อย่างล้นหลามว่าเป็นเกมที่ “ห่วย” สิ้นดี แต่อย่างน้อยมันก็ทำให้ความฝันของเดวิดกลายเป็นจริงและได้มีอาชีพเป็น Unity technical artist ที่บริษัท The VOID ได้รับหน้าที่ในการสร้างงาน VR ให้กับเกมดังๆ มากมาย อาทิเช่น  Ghostbusters Dimension, Avengers: Damage Control, และ Star Wars: Secrets of the Empire.

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

    เกม The First Tree จึงถือกำเนิดขึ้น เดวิดจึงเริ่มสร้างเกมตามแนวทางของตัวเอง… แต่แน่นอนว่ามันไม่ใช่เรื่องง่ายเลย เพราะเค้าต้องทำงานประจำและต้องเลี้ยงดูลูกคนใหม่ เค้าเริ่มจัดตารางเวลาและทำมันถึงแม้จะไม่ชอบก็ตาม ทุกคืนที่ทำงานเกมของตัวเองก็เกือบจะยอมแพ้หลายครั้ง แต่ติดตรงที่เดวิดต้องการให้ผลงานนี้บอกเล่าเรื่องราวและแบ่งปันบนโลกใบนี้  เค้าจึงทำการตลาดทุกในสัปดาห์ เพราะรู้ตัวว่าถ้าไม่มีทำการเปิดตัวเกมจะทำให้เกมเค้าล้มเหลว 100% จนในที่สุดในเดือนกันยายน ปี 2560 เกม The First Tree ก็ปล่อยบน Steam ได้สำเร็จ

    เดวิดแทบจะไม่อยากจะเชื่อสายตาตัวเองว่าเกมที่เป็นงานอดิเรกชิ้นเล็กๆ ที่ทำหลังเลิกงานจะประสบความสำเร็จได้ขนาดนี้ เกมของเค้าติดอันดับหน้าแรกของ Steam 5 วัน ความสำเร็จครั้งนี้ทำให้ชีวิตของเค้าเปลี่ยนแปลงไปทันที เดวิดลาออกจากงานประจำแล้วมาเริ่มทำเกมอินดี้แบบเต็มเวลา พร้อมเริ่มสร้างเว็บไซต์  Game Dev Unlocked เพื่อถ่ายทอดเทคนิคและความรู้การสร้างเกม การทำการตลาด ให้กับเหล่านักสร้างเกมที่มีความฝันแบบเดียวกัน

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

  • ข้อมูลใน DropdownList แรกจนถึง DropdownList สุดท้ายกับค่าที่เหลืออยู่ของเขา ด้วย LINQ

    ในช่วงที่ผ่านมา ได้มีการพัฒนาระบบโดยมีการนำ LinQ มาใช้นิด ๆ หน่อย ๆ (มือใหม่หัดใช้ >< ) ซึ่งมีอยู่ฟังก์ชันนึงที่เกี่ยวกับ การ Bind ค่า DropdownList กรณีที่มี DropdownList หลาย ๆ ตัวและไม่อยากให้ค่าที่เคยเลือกจาก DropdownList ก่อนหน้าไปแสดงใน DropdownList ถัดไปอีก น่าสนใจทดลองใช้แล้วทำงานได้ดี ผู้เขียนจึงนำมาเขียนเพื่อไว้เตือนความจำ จะได้กลับมาอ่าน แนวคิดและวิธีการดังนี้ค่ะ

    ในขั้นตอนแรก สร้าง Data ที่ชื่อว่า MyList เก็บข้อมูล id และชื่อ เพื่อเตรียมเป็น DataSource สำหรับ Bind ให้กับ DropdownList1 ดังนี้

    class MyList
    {
        private string id = string.empty;
        private string name = string.empty;
    
        public MyList(string _id, string _name)
        {
            id = _id;
            name = _name;
        }
    
        public string ID
        {
            get{return id;}
            set {id = value;}
        }
    
        public string Name
        {
            get{return name;}
            set {name = value;}
        }
    }

    ต่อมากำหนดค่าให้กับ MyList เพื่อผูกให้กับ DropdownList1

    List<MyList> mylist = new List<MyList>{
                        new MyList(1,'name1'),
                        new MyList(2,'name2'),
                        new MyList(3,'name3'),
                        new MyList(5,'name5'),
                        new MyList(10,'name10')
                        };

    ผลลัพธ์ของ DropdownList1 ได้ดังนี้

    ID          Name
    1 name1
    2 name2
    3 name3
    5 name5
    10 name10

    ต่อมา กำหนดว่า DropdownList1 เลือกค่าเป็น ID = ‘2’

    string mySelectedValue = '2';

    จากนั้น ที่ Event SelectedIndexChange ของ DropdownList1 ให้ใส่ Code ดังนี้

    var myDataSource = from d in MyList
    where !mySelectedValue.Contains(d.ID)
    select d;

    จากนั้นผูก myDataSource ให้กับ DropdownList2 ค่าล่าสุดใน DropdownList2 จะแสดงดังด้านล่าง โดยที่ ID = ‘2’ จะหายไป เนื่องจากถูกเลือกไปแล้ว ดังนี้

    ID          Name
    1           name1
    3           name3
    5           name5
    10          name10

    กรณีที่มี DropdownList3 ก็ให้ทำเหมือนขั้นตอนก่อนหน้า ตัวอย่างกำหนดค่าการเลือกของ DropdownList1 = ‘2’ และ DropdownList2 = ‘5’ ดังนี้

    string mySelectedValue = '2,5';

    จากนั้น ที่ Event SelectedIndexChange ของ DropdownList2 ให้ใส่ Code แบบเดิม

    var myDataSource = from d in MyList
    where !mySelectedValue.Contains(d.ID)
    select d;

    จากนั้นผูก myDataSource ให้กับ DropdownList3 ค่าล่าสุดใน DropdownList3 จะแสดงดังด้านล่าง โดยที่ ID = ‘2’ และ ‘5’ จะหายไป เนื่องจากถูกเลือกไปแล้ว ดังนี้

    ID           Name
    1            name1
    3            name3
    10           name10

    จะเห็นได้ว่าเราใช้ Query เดียวกันในหลาย ๆ DropdownList ดังนั้นสามารถทำ Query นี้ให้เป็นฟังก์ชันเพื่อเรียกใช้งานได้

    หวังว่าจะเป็นประโยชน์ไม่มากก็น้อยสำหรับผู้อ่านนะคะ \(@^0^@)/

  • Crystal Report : Suppress การซ่อน/แสดง Section

    ปกติแล้วการจัดรายงานใน Crystal Report จะมีการแบ่งเป็น 5 ส่วนดังนี้ค่ะ

    Report Header Section

    เป็นส่วนที่อยู่บนส่วนหัวรายงาน แสดงแค่หน้าแรกเพียงหน้าเดียวเท่านั้น

    Page Header Section

    เป็นส่วนที่แสดงต่อจากส่วน Report Header Section แสดงอยู่ทุกหน้า

    Details Section

    ส่วนแสดงรายละเอียดที่ต้องการ สามารถจัดกลุ่มข้อมูล แบ่งรายงานเป็น 2 ส่วนและอื่น ๆ ได้

    Page Footer Section

    เป็นส่วนที่แสดงในรายงานทุกหน้าอยู่บนส่วนท้ายของรายงาน

    Report Footer Section

    เป็นส่วนที่อยู่ส่วนท้ายสุดของรายงานจะแสดงแค่หน้าสุดท้ายเท่านั้น

    ซึ่งในแต่ละ Section นั้นสามารถมี Section ย่อย ๆ ได้มากกว่า 1 Section ย่อยดังภาพ

    ซึ่งเราสามารถแสดงหรือซ่อน Section ย่อย ๆ เหล่านี้ได้ตามเงื่อนไขที่เราต้องการ โดยใช้เมนู “Suppress” จัดการ ดังนี้ค่ะ

    คลิกขวาที่ Section ใดก็ได้ เลือกเมนู “Section Expert”

    จะพบกับหน้าจอ Section Expert ดังภาพโดยหน้าจอจะแบ่งเป็น 2 ส่วน

    👈 ซ้ายมือ เป็นส่วนแสดงรายการ section ทั้งหมดของเราที่มีสามารถเพิ่ม ลบ หรือย้าย Section ขึ้นและลงตามที่ต้องการได้

    👉 ขวามือ จะแบ่งเป็น Tab ย่อย ๆ ในวันนี้ส่วนที่ผู้เขียนต้องการนำเสนออยู่ที่ Tab “Common”

    ที่ Tab “Common” หาบรรทัดที่ชื่อว่า “Suppress (No Drill-Down)”

    ดูที่ด้านขวา

    ถ้าสัญลักษณ์ “x-2” เป็น สีฟ้า แสดงว่า เรา ไม่ได้ มีการเขียนคำสั่งให้ซ่อนตามเงื่อนไข

    ถ้าสัญลักษณ์ “x-2” เป็น สีแดง แสดงว่า มี การเขียนคำสั่งให้ซ่อนตามเงื่อนไข

    จากรูปด้านล่างสามารถอธิบายได้ว่า ให้ซ่อน Page Header a โดยไม่มีเงื่อนไข

    ส่วนรูปด้านล่างสามารถอธิบายได้ว่า ให้ซ่อน Page Header l โดยมีเงื่อนไข ซึ่งสามารถกดเข้าไปดูเงื่อนไขที่เขียนไว้ได้

    ส่วนของคำสั่งที่เขียนไว้

    สามารถอธิบายได้ดังนี้

    เงื่อนไขคือ ถ้า Formula Field “@hdLang” มีค่าเป็น “E” และ ไม่ใช่รายงานหน้าแรก

    ผลลัพธ์ที่ต้องการ

    ✅ถ้าตรงตามเงื่อนไข ให้แสดง Page Header l

    ❌ถ้าไม่ตรงตามเงื่อนไข ให้ซ่อน Section นี้

    เพียงเท่านี้ ก็สามารถจัดการการซ่อนหรือแสดง Section ตามเงื่อนไขต่าง ๆ ได้ตามต้องการ o(*°▽°*)o d=====( ̄▽ ̄*)b

  • Crystal Report : Grid กับการจัดรูปแบบรายงาน

    ปกติแล้วการจัดรายงานใน Crystal Report ตัวหน้ากระดาษหรือหน้าจอนั้น จะเป็นหน้ากระดาษสีขาวปกติ ทำให้การจัดข้อความที่มีระยะเยื้องนั้นจัดได้ค่อนข้างยาก ตรงกันรึยังนะ หรือยังไม่ตรง นี่คือ 1 ในปัญหาของผู้เขียนเช่นกัน 🤣

    ดังนั้นวันนี้ ผู้เขียนจะมาแนะนำการตั้งค่า Grid เพื่อให้การขยับ Object ในรายงานของเราง่ายขึ้น ขั้นตอนดังนี้ค่ะ

    1️⃣ คลิกขวาพื้นที่โล่ง ๆ เลือกเมนู “Design”


    2️⃣ ต่อด้วยเมนู “Default Setting”



    3️⃣ ใน Tab “Layout” สังเกตส่วนด้านขวาที่ชื่อว่า “Grid”
    👀 จะพบ Checkbox “Show Grid” ให้ ✅ ไว้
    👀 ในส่วนของ Grid Size เราสามารถกำหนดได้ว่าจะให้ตัวกระดาษรายงานของเราแสดง Grid ถี่แค่ไหน ในที่นี้ผู้เขียนให้ความละเอียดมากสุดเลยกำหนดไว้ที่ 0.157



    4️⃣หลังจากกำหนดค่าทุกอย่างเสร็จแล้วกลับมาหน้ารายงานเดิมจะพบว่า หน้าจอเราดำมืด ไม่ต้องตรงใจค่ะ เป็นเพราะค่า Grid ที่เรากำหนดไว้ถี่มาก หน้าจอเลยกลายเป็นท่านเปา วิธีการก็คือ ไปขยายหน้าจอค่ะ โดยไปที่เมนูบาร์ด้านบน จะพบค่าที่ Default อยู่ที่ 200% ให้ขยายเป็น 400% หรือตามที่ต้องการเลยค่ะ



    ✨หน้าจอหลังจากขยายก็จะเห็นดังภาพนะคะ เราสามารถจัด Object ให้ตรงตามที่เราต้องการได้เล้ย ^^



  • Windows Terminal (1)

    เบื่อ cmd ใช้ Windows Terminal แทนกันดีกว่า… ให้ดูรูปก่อน

    สวยงามตระการตา!!!

    บางคนใช้แล้วอาจจะมีความสุข

    เริ่มได้

    • เหมาะสำหรับ Windows 10 version 1909 ขึ้นไป
    • ติดตั้ง Git
    • ติดตั้ง Windows Terminal จาก Microsoft Store หรือ จาก Github

    ถ้าหากติดตั้งจาก Github ต้องติดตั้ง Desktop Bridge VC++ v14 Redistributable Package ด้วย และโปรแกรมจะไม่อัพเดตตัวเองต้องโหลดมาปรับรุ่นเองทุกครั้ง

    ระวัง!!!
    • ติดตั้งแล้วเปิดใช้งานจะได้หน้าตาประมาณนี้
    • เราจะเปลี่ยนหน้าตากันเริ่มจากพิมพ์คำสั่งต่อไปนี้ (ต้องเชื่อมต่ออินเตอร์เน็ต)
    Install-Module posh-git -Scope CurrentUser
    Install-Module oh-my-posh -Scope CurrentUser

    Posh-Git เอาไว้แสดงข้อมูลของ Git ใน prompt
    Oh-My-Posh เป็น theme สวยๆ ของ powershell นั่นเอง

    • ต่อด้วยคำสั่ง
    Set-ExecutionPolicy Unrestricted -Scope CurrentUser
    • ตรวจสอบโฟลเดอร์สำหรับเก็บ Profile ของ PowerShell ด้วยคำสั่ง
    echo $PROFILE
    • สร้างแฟ้ม $PROFILE (ไฟล์ขื่อ Microsoft.PowerShell_profile.ps1 ในโฟลเดอร์ C:\Users\haruo\OneDrive\Documents\WindowsPowerShell\) โดยมีข้อความต่อไปนี้
    Import-Module posh-git
    Import-Module oh-my-posh
    Set-Theme Paradox
    • ปิดแล้วเปิดใหม่ก็จะได้ดังภาพ
    • จะเห็นว่ามีเครื่องหมาย  อยู่ที่ prompt ด้วยจำเป็นต้องลงฟอนท์เพิ่มเติมนั่นคือฟอนท์ Powerline ซึ่งสามารถติดตั้งโดยโหลด Cascadia Code มาติดตั้ง
    • เมื่อติดตั้งแล้วให้เปลี่ยนฟอนท์ของ Windows Terminal โดยคลิก แล้วเลือก Settings
    • จะเป็นการเปิดการตั้งค่า default ที่เรียกใช้งานอยู่ ด้วย default text editor
    • เลื่อน cursor ลงมาประมาณบรรทัดที่ 38 แล้วกด enter เพิ่มข้อความว่า
    "fontFace": "Cascadia Code PL",
    "fontSize": 10,
    • save แล้วไปดูผลได้เลย
    • สวยแล้ว!
    • จบขอให้สนุก
    • Oh-My-Posh ยังมี Theme อื่นๆ ลองเข้าไปเลือกดูได้
    • เปลี่ยน theme ได้โดยแก้แฟ้ม $PROFILE เปลี่ยนจาก Paradox เป็นอย่างอื่นเช่น Darkblood เป็นต้น save ปิดแล้วเปิด Windows Terminal ใหม่
  • Transcribe speech with Google Translate

    สวัสดีคุณผู้อ่านทุกท่าน หลังจากเงียบหายไปนาน และแล้ว วันนี้ก็มาถึง วันที่ต้องกลับมาเขียน Blog อีกรอบ

    เพราะ …. เพราะ …. เพราะอยากเขียนนี่แหละ (หื้มมม) ไม่มีอะไรในก่อไผ่หรอก 55 อะๆ อย่ามามัวเสียเวลากันเลยเนอะ มาเข้าเรื่องกันเลยดีกว่า !!

    วันนี้ขอว่าด้วยเรื่องของ feature บน google translate กันหน่อย feature ที่เพิ่มเข้ามาคือ “Transcribe” การถอดข้อความจากไฟล์เสียงนั่นเอง

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

    สำหรับวิธีการใช้งาน feature Transcribe ที่เพิ่มเข้ามาเนี่ย ง่ายดายมากๆ

    1. เปิดเข้าไปที่ app google translate
    2. ให้กดไปที่ icon “Transcribe” ดูได้จากรูป

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

    จากวิดีโอตัวอย่างก็จะเป็นการอ่านบทความภาษาไทยและเจ้า app ตัวนี้ก็จะแปลเป็นภาษาอังกฤษ เราก็จะได้ผลลัพธ์ประมาณนี้ เจ๋งดีเนอะ ^^

    เราสามารถตั้งค่าขนาดการแสดงผลของตัวอักษร หรืออื่นๆ ได้เล็กน้อยนะ สามารถลองเล่นได้โดยกดตรง รูปฟันเฟือง (มุมล่างซ้าย) กดๆดู ไม่ยากๆ

    สำหรับภาษาที่จะใช้ได้นั้น ขณะนี้รองรับ 8 ภาษา คือ อังกฤษ ฝรั่งเศส เยอรมัน ฮินดี โปรตุเกส รัสเซีย สเปน และ ไทย เน้ออออออ ^__^

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

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

    อ้างอิง
    https://blog.google/products/translate/transcribe-speech/
    https://www.rainmaker.in.th/transcribe-speech-with-google-translate/

  • วิธีใช้งาน Google Form ให้เฉพาะผู้เกี่ยวข้องเท่านั้นที่จะตอบแบบฟอร์มได้ โดยต้องไม่บังคับ Login ด้วย Google Account ด้วย

    Google Form เป็นเครื่องมือสร้างแบบสำรวจยอดฮิต สร้างง่าย ใช้ง่าย เหมาะสำหรับงานที่เปิดให้ใครก็ได้ สามารถตอบแบบสอบถาม

    แต่ ถ้าต้องการให้เฉพาะคนในองค์กรซึ่งใช้ G Suite (เช่น กรณีของ มหาวิทยาลัยสงขลานครินทร์ ใช้ G Suite for Education โดเมน psu.ac.th เป็นต้น) ตอบแบบสอบถามเท่านั้น ก็พอจะทำได้ แต่ก็จะเจอปัญหาคือ ผู้ใช้ในองค์กรอาจจะ Login ด้วย Web Browser ซึ่ง Sign-In ด้วย Gmail ส่วนตัว ก็จะยุ่งยากหน่อย ต้องสลับ Account เป็นต้น แล้วยิ่งบางคน ใช้ LINE เพื่อ Scan QR Code แล้วก็ไปใช้ In-App Browser ซึ่งก็ไม่รู้ว่า Sign-In ด้วย Account ไหน ยิ่งไปกว่านั้น ถ้าเป็นการไปใช้งานนอกสถานที่ที่ใช้ประจำ Google ก็มักจะ Challenge โดยการ ให้ระบุ เบอร์โทรศัพท์มือถือ หรือ Email ที่ใช้ Recovery สร้างความวุ่นวายได้เป็นอย่างมาก

    แล้ว ก็มี Requirement “ง่าย ๆ” มาให้คิด

    • ต้องการออกแบบระบบ ลงคะแนน ให้คณะกรรมการ ซึ่งอยู่ทั้งในและนอกองค์กร
    • ท่าน ๆ เหล่านี้ ล้วน … ทรงคุณวุฒิ และ วัยวุฒิ
    • ใช้อุปกรณ์หลากหลาย
    • ส่งแบบฟอร์มไปให้กรอก โดยผ่าน Email ท่าน ๆ ซึ่งเป็น @yahoo.com, @hotmail.com, @gmail.com, @xxx.edu, @xxxxxxxxx
    • บางท่าน ไม่มี Email แต่มี LINE เท่านั้น
    • การลงคะแนน ต้องมั่นใจว่า กรรมการแต่ละท่าน เป็นผู้ลงคะแนนจริง ๆ
    • ท่าน ๆ ลงคะแนนได้ 1 เสียงเท่านั้น
    • เปลี่ยนใจได้ด้วย คือ ตอนแรกจะลงคะแนนอย่างนึง แล้วก็ Submit ไปแล้ว แต่ก็คิดว่า เอ๊ะ เปลี่ยนใจแระ (ในกรอบเวลา)
    • ไม่สามารถทราบได้ว่าใครเป็นผู้ลงคะแนนได้ (โดยง่าย)

    แนวทางการแก้ปัญหา

    Google Form มี Feature นึง ที่บางคนไม่เคยใช้ นั่นคือ “Get pre-filled link”

    Pre-filled Link กล่าวคือ ทำการกรอกข้อมูลบางอย่างใน Google Form แล้วส่งให้ผู้ใช้ เช่น เรารู้อยู่แล้วว่า จะส่งแบบฟอร์มนี้ ไปทาง Email ของกรรมการท่านนี้ ก็แทนที่ต้องให้ท่าน กรอกชื่อตัวเอง เราก็กรอกไปให้ท่านเลย อะไรทำนองนั้น

    Idea ของเราคือ จะสร้าง “Question” ชื่อ Token ขึ้นมา (จะตั้งว่าอะไรก็ได้นะ)

    แล้วคลิกที่ “Get Pre-filled Link”

    จะได้แบบฟอร์มพร้อมกรอกอย่างนี้ เราก็จะ Mark ตำแหน่งที่จะแทนค่า Token ด้วยการใส่คำอะไรก็ได้ แต่ในที่นี้ จะใส่เป็นคำว่า “token” ตัวพิมพ์เล็ก ไปใส่ แล้วคลิกปุ่ม Get Link จากนั้น คลิกปุ่ม COPY LINK

    Link ที่ได้ จะเป็นแบบนี้

    https://docs.google.com/forms/d/e/XXXXXXXXXX/viewform?usp=pp_url&entry.625502761=token

    จากนั้นแค่ค่า ข้อความ “token” ด้วยค่า Hash เช่น เอาชื่อ นามสกุล และ email address ของแต่ละคนมาเข้ารหัส MD5 (จะกล่าวถึงวิธีการได้มาในตอนท้าย) เช่น ได้เป็น

    b4771c1c4d65442b32d7029d13fb6e41

    ก็จะได้ URL ที่จะส่งให้ท่านกรรมการ อย่างนี้

    https://docs.google.com/forms/d/e/XXXXXXXXXX/viewform?usp=pp_url&entry.625502761=b4771c1c4d65442b32d7029d13fb6e41

    เมื่อผู้รับคลิก Link ก็จะได้หน้าตาฟอร์มแบบนี้

    คราวนี้ ในภาพใหญ่ ก็ต้องหาทางทำสร้าง Hash ของกรรมการแต่ละท่าน อันนี้เป็นตัวอย่าง

    ต่อไปนี้เป็นวิธีการหาค่า Hash (เขียนด้วย Google App Script)
    Source: https://www.answiz.com/questions/2594/hash-of-a-cell-text-in-google-spreadsheet

    function MD5 (input) {
      var rawHash = Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, input);
      var txtHash = '';
      for (i = 0; i < rawHash.length; i++) {
        var hashVal = rawHash[i];
        if (hashVal < 0) {
          hashVal += 256;
        }
        if (hashVal.toString(16).length == 1) {
          txtHash += '0';
        }
        txtHash += hashVal.toString(16);
      }
      return txtHash;
    }

    จากนั้นก็เขียน Script ส่ง Email / LINE แจ้งข้อความที่ต้องการ พร้อม Link ที่กรอกข้อมูล Hash ของแต่ละท่าน

    เป็นอันเรียบร้อย …

    เหมือนเดิม เพิ่มเติมคือ ความซับซ้อน

    คราวนี้ ท่าน ๆ ก็ลงคะแนนกันมา แต่ว่า

    • ช่อง Token นั้น บน Google Form มันแก้ไขได้ ไม่มีทาง Lock ทำให้บางท่าน เอ่อ เผลอ แก้ไข/ลบ/ทดลอง
    • บางท่าน ก็ ลงคะแนน Submit แล้ว อยากเปลี่ยนใจทำไงดี ?

    ดังนั้น ต้องหาทางทำให้

    • ถ้า Hash ไม่ตรงกับข้อมูลที่มี ไม่นับคะแนน
    • ถ้า Hash ตรง แต่ซ้ำ ๆ มา ให้นับคะแนนจาก Record ล่าสุด

    ก็มาร่าย Formula กันหน่อย

    หน้าตา Google Sheets ซึ่งเป็นผลการลงคะแนนที่ได้จาก Google Form

    ไปเขียนสูตรใน Column D โดย จะนำค่าจาก Column C ไปตรวจสอบกับ Hash ซึ่งขอยกตัวอย่างว่า อยู่ที่ Sheet2 ใน Column A โดยใช้สูตร

    =IF(ISNA(VLOOKUP(C2,Sheet2!A:A,1,false)),"Not Match","Match")

    จากภาพแสดงให้เห็นว่า แถว 5 นั้น ค่า Hash ไม่ตรง จึงขึ้นคำว่า “Not Match”

    ต่อไป ก็ Filter เฉพาะที่ Match แล้ว Sort ตาม Timestamp

    สูตรประมาณนี้

    =sort(filter(A2:D6,D2:D6="Match"),3,True)

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

    ใช้สูตรประมาณนี้

    =if(C14=C15,"","1")

    กล่าวคือ พอเรียงลำดับแล้ว ก็หาว่า บรรทัดไหน เป็นขอบของกลุ่ม ว่างั้น (อธิบายยากจัง) ก็แสดงค่า 1

    สุดท้าย จะก็ได้ผลสรุป Record ที่ Hash ตรง และเป็นการ Submit ล่าสุดของแต่ละกลุ่ม

    สูตรประมาณนี้

    =filter(A14:E17,E14:E17="1")

    ก็เอาไปทำ Chart สรุป ได้แล้ว

    หวังว่าจะเป็นประโยชน์ครับ