Month: July 2015

  • การวัดระยะทางบน Google Earth

    จากบทความที่แล้ว การทำแผนที่ Buffer 300 เมตร สถานที่หรือบริเวณห้ามขายเครื่องดื่มแอลกอฮอล์รอบ มอ. ทำให้สามารถมองเห็นภาพพื้นที่ห้ามฯ ได้ชัดเจนยิ่งขึ้น แต่ยังคงมีหลายๆท่านอยากรู้ว่าร้านนี้ ร้านนั้น จะอยู่ในเขตโซนนิ่งหรือเปล่า? วันนี้เลยมานำเสนอวิธีง่ายๆ ในการตรวจสอบด้วยตัวเอง ด้วยการวัดระยะทางจากสถานศึกษา ไปยังร้านที่เราสงสัยว่าจะอยู่ในข่ายโซนนิ่งหรือไม่?

    ขั้นตอน

    1. เปิดโปรแกรม Google Earth ถ้ายังไม่ได้ติดตั้งคลิกที่นี่เพื่อดาวน์โหลดโปรแกรม
    2. จากประกาศสำนักนายกฯ ในข้อ 1 ห้ามผู้ใดขายเครื่องดื่มแอลกอฮอล์ในสถานที่หรือบริเวณซึ่งอยู่ในระยะ 300 เมตร จากรั้วหรือแนวเขตของสถานศึกษาระดับอาชีวศึกษาหรือสถาบันอุดมศึกษาทั้งของรัฐและเอกชน ฉะนั้นเราต้องสร้างขอบเขตสถานศึกษาก่อน (ขั้นตอนนี้สามารถข้ามได้)
    3. คลิกไอคอน เพิ่มรูปหลายเหลี่ยม > คลิกลงบนแผนที่ที่เป็นขอบเขตสถานที่ > กำหนดให้พื้นที่เป็นแบบโปร่งแสง เพื่อแสดงเฉพาะเส้นขอบเขต > คลิก ตกลง
      01
    4. จากนั้นจะเริ่มทำการวัดระยะทาง โดยคลิกที่ไอคอนไม้บรรทัด > กำหนดหน่วยระยะทางเป็น เมตร
      02
    5. คลิก 1 ครั้งที่จุดเริ่มต้นบริเวณแนวเขตสถานศึกษา > คลิก 1 ครั้งที่จุดปลายทางสถานบันเทิงที่ต้องการตรวจสอบ จะเห็นว่า pop-up แสดงระยะทาง
      03
    6. หากต้องการไปตรวจสอบจุดต่อไป ให้คลิกปุ่ม ล้าง เพื่อลบเส้นระยะทางที่ได้ทำไว้เมื่อสักครู่นี้
      04
    7. (เสริม) หากต้องการวัดระยะทางโดยการใช้เส้นที่ประกอบด้วยจุดที่มากกว่า 2 จุด ให้ใช้แท็บ เส้นทาง ซึ่งลักษณะการวัดระยะทางจะเหมือนกับข้อ 5
      05

    หวังว่าจะเป็นประโยชน์สำหรับทุกท่านในการนำไปประยุกต์ใช้ในงานด้านต่างๆ นะคับ ^^

  • การทำแผนที่ Buffer 300 เมตร สถานที่หรือบริเวณห้ามขายเครื่องดื่มแอลกอฮอล์รอบ มอ.

    ตอนนี้เป็นกระแสที่กำลังมาแรงเรื่องการจัดระเบียบสถานบันเทิงหรือสถานที่จำหน่ายเครื่องดื่มแอลกอฮอล์ที่ใกล้บริเวณสถานศึกษา วันนี้เลยจะนำเสนอการทำ buffer 300 เมตร ตามประกาศสำนักนายกรัฐมนตรี เรื่อง กำหนดสถานที่หรือบริเวณห้ามขายเครื่องดื่มแอลกอฮอล์รอบสถานศึกษา พ.ศ.2558 โดยห่างจาก มหาวิทยาลัยสงขลานครินทร์ วิทยาเขตหาดใหญ่ เพื่อเราได้ตรวจเช็คว่า ร้านหรือสถานบันเทิงใดบ้างที่อยู่ในเขตพื้นที่ห้ามฯ*

    * ทั้งนี้เงื่อนไขต่างๆ เป็นไปตามเงื่อนไขในประกาศสำนักนายกรัฐมนตรีฯ

    โดยใช้ basemaps จากบทความที่แล้ว การติดตั้ง (OpenLayers Plugin) Google Satellite บน QGIS

    ขั้นตอน

    1. เปิดโปรแกรม QGIS > นำเข้าขอบเขต มอ. ด้วยคำสั่ง Add Vector Layer > เลือก shape file ขึ้นมา
      01
    2. จะปรากฏ Layer หรือชั้นข้อมูลขอบเขตพื้นที่ มอ. ขึ้นมา
      02
    3. นำเข้าแผนที่ Google Satellite ด้วยการคลิกที่เมนู Web > OpenLayers plugin > Google maps > Google Satellite*
      *หากไม่มีเมนูนี้ ให้ทำการติดตั้ง (OpenLayers Plugin) Google Satellite บน QGISS
      03
    4. ตอนนี้ในหน้าจอโปรแกรม QGIS ก็จะมี 2 Layers ที่เป็นแผนที่ Google และเส้นขอบเขตพื้นที่บริเวณของมหาวิทยาลัยสงขลานครินทร์ วิทยาเขตหาดใหญ่
      04
    5. คลิกเลือก Layer ที่เป็นขอบเขตพื้นที่ มอ. เพื่อที่จะทำ Buffer หรือระยะห่างจากมอ.ในรัศมี 300 เมตร > Vector > Geoprocessing Tools > Buffer(s)
      05
    6. เลือก input vector layer > กำหนดระยะห่าง(buffer distance) ใส่ 300 (หน่วยเป็นเมตร) > กำหนด output shapefile > คลิกปุ่ม OK
      06
    7. จะมี layer เพิ่มขึ้นมา โดยจะเป็นพื้นที่ buffer 300 m.
      07
    8. ปรับให้เป็นพื้นที่โปร่งแสงเพื่อให้สามารถมองเห็นแผนที่ google ด้านหลัง
      08
    9. จะได้เส้นขอบเขตพื้นที่ buffer 300 เมตรของบริเวณพื้นที่ มอ.
      จากนั้นทำการ save as เป็น .kml เพื่อไปนำเข้าที่ Google Maps ด้วยการคลิกขวาที่ Layer > Save As..
      10
    10. เลือก format เป็น KML > เลือกที่เก็บไฟล์สำหรับการ Save as > คลิก OK
      11
    11. เปิดเว็บ google.co.th/maps หรือ maps.google.co.th > คลิกที่ไอคอนหน้าช่อง ค้นหา
      12
    12. เลือก My Maps หรือ แผนที่ของฉัน
      13
    13. คลิกไอคอน สร้าง
      14
    14. จะมีเลเยอร์ใหม่เพิ่มขึ้นมา > คลิก นำเข้า > เลือกไฟล์จากคอมพิวเตอร์ของคุณ
      15
    15. เลือกไฟล์ kml ที่ได้จากข้อ 10 > Open
      16
    16. จะปรากฏ layer เส้น buffer 300 เมตร ขึ้นมาบนแผนที่
      17
    17. แก้ไข/เปลี่ยนชื่อแผนที่ และใส่คำอธิบายแผนที่ โดยการ copy ข้อความมาจากเว็บ http://www.matichon.co.th เพื่อแสดงข้อความประกาศฯ
      18
    18. ปรับแต่งพื้นที่ให้มีสีที่โปร่งแสง เพื่อให้มองภาพพื้นที่ง่ายขึ้น
      19
    19. แผนที่จะแสดงขอบเขตห้ามฯชัดเจน โดยในแผนที่จะมีสถานที่/ร้านอาหาร/สถานบันเทิง ที่ในเขตห้ามฯ และนอกเขตห้ามฯ
      20
    20. เพิ่ม layer ขอบเขตพื้นที่ มอ. เข้ามาเพื่อแสดงให้เห็นพื้นที่มอ. และพื้นที่ห้ามฯ
      21
    21. เมื่อปรับแต่งแผนที่เสร็จเรียบร้อยแล้ว ก็ทำการ share แผนที่เป็นแบบ Public (แบบสาธารณะ ทุกคนสามารถเห็น ค้นหา และเข้าถึงแผนที่นี้ได้) > คลิก บันทึก
      22
    22. ลองเปิดแผนที่ดูนะคับ ^^

    ***เพื่อความถูกต้องที่สุดของข้อมูล จะต้องทำ buffer สถานศึกษาทั้งหมด เพื่อดูพื้นที่คาบเกี่ยวหรือซ้อนทับกันของ buffer คับ

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

    ที่มาข้อความข่าว : http://www.matichon.co.th/news_detail.php?newsid=1437545597
    ที่มา shapefile ขอบเขตพื้นที่มอ. : สถานวิจัยสารสนเทศภูมิศาสตร์ทรัพยากรธรรมชาติและสิ่งแวดล้อม คณะการจัดการสิ่งแวดล้อม มหาวิทยาลัยสงขลานครินทร์

  • การติดตั้ง (OpenLayers Plugin) Google Satellite บน QGIS

    Google Maps เริ่มมีบทบาทและได้รับความนิยมในการนำไปใช้ในการแปลภาพถ่ายในด้านทรัพยากรธรรมชาติและสิ่งแวดล้อม หรือรวมไปถึงเรื่องการใช้ประโยชน์ที่ดิน เพื่อนำไปจัดทำฐานข้อมูลภูมิสารสนเทศ หรือ GIS มากยิ่งขึ้น ด้วยความที่เป็นปัจจุบันหรือ update ค่อนข้างที่จะเป็นปัจจุบันหรือใกล้เคียงปัจจุบัน อีกทั้งผู้ใช้สามารถเข้าถึงได้ง่าย ใช้งานง่าย นักภูมิสารสนเทศ หรือนัก GIS หรือคนที่ทำงานด้าน GIS จึงมักจะเลือกที่จะนำมาใช้ในการแปลภาพถ่าย หรือเรียกว่า การสำรวจระยะไกล (Remote Sensing : RS)

    วันนี้เลยอยากจะนำเสนอ plugin ตัวนึงที่น่าสนใจ นั่นคือ OpenLayers plugin for QGIS 2.8 เพื่อใช้ในการนำเข้า Google Satellite เป็น BaseMaps (แผนที่ฐาน) ในการแปลภาพถ่าย

     

    *** ส่วนใครที่ใช้ ArcGIS ก็ลองแวะเข้าไปอ่านวิธีการ การติดตั้งและใช้งาน ArcGoogle for ArcGIS เพื่อใช้ Google Satellite เป็นแผนที่ฐาน ได้นะคัับ ^^

     

    ขั้นตอน

    1. เปิดโปรแกรม QGIS 2.8 หรือทำการติดตั้งโปรแกรม QGIS 2.8
    2. เมนู Plugin > Manage and Install Plugins…
      02
    3. เลือก OpenLayersPlugin > คลิก Install plugin
      03
    4. หลังจากติดตั้งเสร็จแล้วจะเห็นว่าหน้า OpenLayers Plugin มีไอคอนสีฟ้าและเครื่องหมายกากบาท
      04
    5. เปิดการใช้งานโดยคลิกที่เมนู web Openlayers plugin > Google Maps > จะมีให้ชนิดของแผนที่ให้เลือก คลิกเลือก Google Satellite
      05
    6. จะมี Layer Google Satellite เพิ่มขึ้นมาตรงด้านซ้ายล่างของหน้าจอ ซึ่งในพื้นที่งานจะยังไม่เห็นแผนที่ จะต้องทำการ add layer (ชั้นข้อมูล) ขึ้นมา ในตัวอย่างจะ add vector layer แผนที่ประเทศไทยขึ้นมา
      06
    7. จะมี layer เพิ่มขึ้นมาด้านซ้ายล่างของหน้าจอ ซึ่งจะซ้อนทับอยู่กับ Google Satellite Layer
      07
    8. ทำการปรับค่าให้แผนที่ประเทศไทยโปร่งแสง เพื่อจะได้มองเห็น Layer ที่เป็น google maps
      08
    9. จะเห็นว่า แผนที่ประเทศไทยโปร่งแสงแล้ว เห็นแต่เส้นขอบเขตการปกครอง
      09
    10. ลอง Zoom ใกล้ๆ ตรงบริเวณตึก LRC โดยแถบสถานะด้านล่างจะแสดงแผนที่มาตราส่วน (scale) เป็น 1:300 ( ความหมายคือ ถ้าเอาไม้บรรทัดวัดรูปได้ เท่าไร ความยาวจริงก็จะยาวกว่าที่วัดได้ 300 เท่า)
      10

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

    ปกติแล้วนักพัฒนาเว็บ (web developer) จะนิยมใช้ Google Maps API ในการพัฒนา Map on Web ….. ลองหันมาเพิ่มศักยภาพในการแสดงแผนที่ในเชิงวิเคราะห์และมีความซับซ้อนของข้อมูลเชิงพื้นที่ดูไม๊ครัช ^^

    สำหรับท่านใดที่นึกหน้าตา web map application ไม่ออก ลองแวะเข้าไปเยี่ยมชมได้ที่ http://slb-gis.envi.psu.ac.th

    หรือ download shape file เพื่อลองนำไปใช้ได้ที่ http://slb-gis.envi.psu.ac.th/ เมนู ฐานข้อมูล GIS

    ครัั้งหน้าจะนำเสนอการสร้างข้อมูลบน‬ QGIS เพื่อนำไปใช้ใน Google Earth และ Web Map นะคับ ^^

  • Dual Boot Ubuntu 14.04 & Windows 8.1 in UEFI

    • เหตุการณ์สมมติจึงใช้ VirtualBox
    • ตั้งค่า VirtualBox ดังภาพ (ขอข้ามวิธีการสร้างเครื่องใหม่บน VirtualBox ไปเลยนะครับ คิดซะว่าชำนาญแล้ว โดยขนาด HDD ที่ต้องการ 100GB เป็นอย่างน้อย) โดยเลือก option ที่เขียนว่า Enable EFI (special OSes Only) และในช่อง  Boot Order: ให้เลื่อนเป็น Optical แล้วตามด้วย Hard Disk แล้วกด OK
      uefi1
    • เมื่อเปิดเครื่องจะได้หน้าจอดังภาพ แสดงว่า BIOS ของเรากลายเป็น UEFI เรียบร้อยแล้ว
      uefi2
    • เลือกแผ่น Ubuntu 14.04 ให้ต่อเข้ากับ Device
      uefi3
    • reset เครื่อง
      uefi4
    • เลือก *Try Ubuntu without installing
      uefi5
    • รอจนได้ Windows Manager แล้วดับเบิ้ลคลิก Install Ubuntu 14.04.2 LTS บน Desktop เข้าสู่กระบวนการติดตั้ง Ubuntu ปกติทั่วไปสามารถใช้ Next Technology ได้เลยไปเรื่อยๆ จนถึงหน้า Installation type ให้เลือกหัวข้อ Something else แล้วกด Continue
      uefi6
    • คลิก New Partition Table… คลิก Continue จะได้ดังภาพ
      uefi7
    • คลิกคำว่า free space แล้วคลิกเครื่องหมายบวก (+) สร้าง Partition ขนาด 512MB มีชนิดเป็น EFI boot partition (ควรดูด้วยว่าพาทิชั่นที่ได้เมื่อสร้างเสร็จมีขนาด 512MB จริงๆ โดยใน VM ที่สร้างนี้ตอนสร้างใส่ไป 514MB) และกด + เพื่อสร้าง swap ในตัวอย่างกำหนดแรมไว้ 4GB สามารถสร้าง Swap เท่าแรมได้เลย และ / (root ขนาด 50GB) ตามลำดับโดยจะเหลือพื้นที่เปล่าไว้ด้วย
      uefi8
    • ภาพแสดงพาทิชั่นเมื่อสร้างเสร็จแล้ว
      uefi9
    • คลิก Install Now และคลิก Continue ที่เหลือหลังจากนี้สามารถกลับสู่โหมด Next Technology ได้เลยจนจบ
      uefi10
      uefi11
    • สิ้นสุดคลิก Restart Now
      uefi12
    • เอาแผ่นออกแล้วกด Enter (ปกติจะเอาออกให้อัตโนมัติ)
      uefi13
    • ลองบูตดูจนได้หน้า Log In
      uefi14
    • เลือก Devices แล้ว Optical Drives แล้วเลือกแผ่น Windows 8.1
      uefi15
    • คลิกรูปเฟืองที่มุมบนขวา เลือก Shutdown แล้วคลิก Restart
      uefi16
    • เมื่อ VM กำลัง Shutdown ให้สังเกตุดูว่า โลโก้ Ubuntu หายไปให้รีบ ESC ทันทีจะได้ดังภาพ
      uefi17
    • เลื่อน Cursor ลงมาที่ Boot Manager แล้วกด Enter จะได้ดังภาพ
      uefi18
    • เลื่อน Cursor ลงมาที่คำว่า EFI DVD/CDROM แล้วจะมีข้อความว่า Press any key to boot from CD or DVD….
      uefi19
    • เมื่อกดปุ่มใดๆ จะเข้าสู่วินโดวส์เพื่อเริ่มติดตั้ง
      uefi20
    • เมื่อได้หน้าเลือกภาษาให้เลือกดังภาพ แล้วคลิก Next
      uefi21
    • คลิก Install now
      uefi22
    • คลิกเครื่องหมายถูกหน้าข้อความ I accept the license terms คลิก Next
    • เลือก Custom: Install Windows only (advanced)
      uefi23
    • จะเห็นพื้นที่ดิสก์ที่เราใช้งานอยู่ในตอนนี้จะเห็นว่ามีที่เหลืออยู่ 48GB ที่เป็น Unallocated Space (และถูกเลือกโดยอัตโนมัติไว้อยู่แล้ว) ในตัวอย่างนี้เราจะสร้างเพียงไดรฟ์ซีเพียงอย่างเดียวให้คลิก Next
      uefi24
    • เข้าสู่การติดตั้ง Windows รอไปจนเสร็จ…
      uefi25
    • เมื่อติดตั้ง Windows  เสร็จแล้วจะถูกบังคับเข้าวินโดวส์ทันที Ubuntu หายไปแล้ว… เพราะ Boot Manager ของ Ubuntu ถูกเขียนทับไปนั่นเอง ให้ตั้งค่า Windows ให้เสร็จเรียบร้อยก่อนแล้วชัตดาวน์เครื่อง เลือก Devices แล้วเลือก Optical Drives เลือกแผ่น Ubuntu อีกครั้ง เมื่อได้ Menu ให้เลือก *Try Ubuntu without installing
      uefi26
    • เมื่อได้หน้า Windows Manager กด Ctrl+alt+T พิมพ์ข้อความดังนี้  และในขั้นตอนนี้ต้องแน่ใจว่าเครื่องเชื่อมต่อ Internet ได้เรียบร้อยแล้ว
      sudo add-apt-repository ppa:yannubuntu/boot-repair
      sudo apt-get update
      sudo apt-get install -y boot-repair
    • แล้วต่อด้วยคำสั่ง sudo boot-repair จะได้ดังภาพ
      uefi27
    • คลิกที่ Recommended repair จะได้ดังภาพ ให้รอไปจนเสร็จ
      uefi28
    • เมื่อได้หน้าจอดังภาพกด OK แล้วสั่งรีบูตได้เลยuefi29
    • เมื่อบูตขึ้นมาจะได้หน้าเมนูที่คุ้นเคยสามารถเลือกได้ว่าจะเข้าอะไร
      uefi30
    • จบขอให้สนุกครับ

    อ้างอิงเพิ่มเติม

    https://help.ubuntu.com/community/Boot-Repair

  • ใช้ google script ทำ mail merge เนื้อหาเมลที่มี pre-filled form URL

    จากตอนที่แล้ว “ใช้ google script ทำ mail merge เนื้อหาเมลที่มี link” เรารู้วิธีใส่ link ไปในเนื้อหาเมล ในตอนนี้เราจะมาเปลี่ยน static link เป็น dynamic link (คือ link ที่มีการอ้างชื่อ cell จึงเป็น link ที่เปลี่ยนแปลงไปตามค่าที่อยู่ใน cell) จุดประสงค์ก็เพื่อส่ง link ให้ผู้ที่รับอีเมลกรอกข้อมูลลง google form ที่มีข้อมูลให้บางส่วนแล้ว (pre-filled form) ซึ่งเป็นข้อมูลของผู้รับอีเมลแต่ละคนที่แตกต่างกัน เช่น ให้มีฟิลด์ ชื่อ และ หน่วยงาน ไว้แล้ว เป็นต้น เมื่อเปิดฟอร์มจึงไม่ต้องกรอกชื่อ และ หน่วยงาน แต่ยังสามารถแก้ไขได้หากต้องการ แล้วให้กรอกข้อมูลเพิ่มในส่วนอื่น ๆ

    สมมติ
    1. เรามี google sheet ชื่อ members มี 4 คอลัมน์ อยู่แล้ว ดังนี้ รายการที่, ชื่อ, หน่วยงาน, อีเมล

    mmwp01

    2. เราต้องการสร้าง google form เพื่อสอบถาม ตอบรับร่วมงาน และ ประเภทอาหาร

    วิธีทำ ดังนี้
    1. สร้าง google form ขึ้นมา 1 อัน ตั้งชื่อว่า member-meeting1

    mmwp02

    2. สร้าง form field ดังนี้ ชื่อ, หน่วยงาน, ตอบรับร่วมงาน, ประเภทอาหาร

    3. เลือกเมนู Responses > เลือก Get pre-filled URL

    mmwp03

    4. กรอกข้อมูลชื่อตัวแปรลงในช่องข้อมูล เช่น ชื่อ ให้ใส่ f1, หน่วยงาน ให้ใส่ f2

    mmwp04

    5. กรอกเสร็จให้คลิก submit จะได้หน้าต่างแสดงเป็น URL และมีข้อความบอกให้เราคัดลอก (ctrl+c)

    mmwp05

    6. URL ที่คัดลอกนี้จะไปใส่ใน google sheet ชื่อ member ในคอลัมน์ใหม่ รวมเป็น 5 คอลัมน์ ดังนี้
    รายการที่, ชื่อ, หน่วยงาน, อีเมล, URL

    7. ที่ cell URL นี้ ให้ใส่ฟังก์ชั่น =HYPERLINK(“URL”,”URL”) และนำ URL ที่คัดลอกมาวางตรงคำว่า URL

    mmwp06

    8. ให้แทนที่ข้อความ ตรงที่มีคำว่า f1 ด้วย “&B2&”, แทนที่ f2 ด้วย “&C2&”

    mmwp07

    9. จากนั้นก็นำความรู้ในเรื่อง “ใช้ google script ทำ mail merge เนื้อหาเมลที่มี link” มาใช้ในการส่งอีเมลได้แล้ว
    9.1 เตรียมเนื้อหาจดหมายไว้ใน sheet ชื่อ Template
    mmwp08

    9.2 เตรียม range ของข้อมูล คีย์เองนะ

    mmwp09

    9.3 คัดลอก google script จากตอนที่แล้วมาใช้

    mmwp10

    9.4 สั่งให้ google script ชื่อ MailMergeWithLinkv2 ทำการส่งอีเมล

    mmwp11

    9.5 ตรวจสอบดูอีเมลที่ได้รับ

    mmwp12

    9.6 เมื่อคลิก link จากในเมล จะไปเปิด google form ขึ้นมา พร้อมข้อมูล 2 ฟิลด์แรก คือ ชื่อ และ หน่วยงาน ที่ดึงข้อมูลที่มีอยู่มาไว้ให้เลย จะได้ไม่ต้องคีย์บ่อย ๆ

    mmwp13

    9.7 ตรวจสอบข้อมูลที่กรอกผ่าน google form โดยที่เมนู Responses ใน form ให้เลือก Choose response destination และเลือก สร้างไฟล์ google spreadsheet ใหม่

    mmwp14

    จากนั้น จะได้ไฟล์

    mmwp15

    เปิดดู เห็นข้อมูลที่กรอกผ่าน google form มาเก็บไว้แล้ว

    mmwp16

     

    ความรู้นำมาจากเรื่องนี้:
    Pre-populate form answers
    https://support.google.com/docs/answer/160000?hl=en

  • ใช้ google script ทำ mail merge เนื้อหาเมลที่มี link

    ผมใช้ Yet another mail merge ซึ่งเป็น add-on เพื่อส่งอีเมลเรื่องเดียวกันไปยังเพื่อนๆจำนวนหนึ่ง ก็ใช้งานได้ดีมา 5 ครั้งแล้ว แต่พอครั้งหลังนี้ ผมต้องการส่งอีเมลที่ในเนื้อหามี link ให้ผู้ที่รับอีเมลสามารถคลิกเพื่อเปิดอ่านได้ แต่ลองหลายวิธีที่จะส่งด้วยวิธีที่เคยใช้ add-on ตัวนี้ก็จะแสดงเป็นข้อความ ไม่แสดงเป็น link ในอีเมล (อันนี้ต้องบอกก่อนว่า คาดว่าผู้ใช้ส่วนใหญ่ใช้โปรแกรมอีเมลที่มีการแสดงผลมากกว่าข้อความธรรมดา)

    ค้นหาดูก็พบว่า ต้องเปลี่ยนวิธีทำมาเป็นวิธีเขียน google script เพื่อส่ง mail merge แทน

    วิธีทำ ดังนี้
    1. สร้าง google sheet ตั้งชื่อ myusers
    1.1 sheet แรก ตั้งชื่อ Data ที่มีคอลัมน์ ดังนี้
    รายการที่, ชื่อ, คณะ, อีเมล, link1, link2

    mmwl01

    1.2 sheet สอง ตั้งชื่อ Template ที่มี 1 คอลัมน์ เพื่อเขียน subject และ ข้อความจดหมายที่มี link

    mmwl02

    1.3 sheet สาม ตั้งชื่อ Range ที่มี 3 คอลัมน์ ดังนี้
    header, data, template

    mmwl03

    2. ใส่ข้อมูลตามตัวอย่างรูปภาพ

    3. ที่ google sheet ให้คลิกที่ Tool > Script editor > เลือก Blank Project > ตั้งชื่อว่า myusers project

    mmwl04

    mmwl05

    4. แปะ google script ตามซอร์สโค้ดด้านล่างบทความนี้ และคลิก Save
    หมายเหตุ ซอร์สโค้ดนี้จะวางตำแหน่งอีเมลไว้ที่คอลัมน์ที่ 4

    mmwl06

    5. ปิดแท็บ google script (myusers project)

    6. ปิดแท็บ google sheet (myusers) แล้วเปิดใหม่

    7. เมื่อเปิดใหม่จะเห็นว่ามีเมนู Email และมี submenu ชื่อ MailMergeWithLinkv2

    mmwl07

    8. คลิกเมนู Email > MailMergeWithLinkv2
    จะมีการขอสิทธิในการรัน script ดังรูป

    mmwl08   mmwl09

    9. ไปตรวจสอบว่าอีเมลถูกส่งไปและมีเนื้อหาที่มี link ตามต้องการ

    mmwl10

    10. หากต้องการส่งอีกครั้งให้กับอีเมลที่ได้ส่งแล้ว ให้ดูที่คอลัมน์ อีเมล จะเห็นว่ามี Note เนื่องจากว่า google script นี้ได้เขียน Note ไว้ใน cell ใช้เป็นการป้องกันการส่งอีเมลซ้ำ

    mmwl11

    ให้คลิกขวาและเลือก Clear Note

    mmwl12

    ซอร์สโค้ดที่ใช้:

    function onOpen() {
      var submenu = [{name:"MailMergeWithLinkv2", functionName:"MailMergeWithLinkv2"}];
      SpreadsheetApp.getActiveSpreadsheet().addMenu('Email', submenu);  
    }
    
    function MailMergeWithLinkv2() {
      var ss = SpreadsheetApp.getActiveSpreadsheet(),
      DataSheet = SpreadsheetApp.setActiveSheet(ss.getSheetByName("Data")),
      TemplateSheet = SpreadsheetApp.setActiveSheet(ss.getSheetByName("Template")),
      RangeSheet = SpreadsheetApp.setActiveSheet(ss.getSheetByName("Range")),
    
      header = RangeSheet.getRange(2, 1).getValue(),
      data = RangeSheet.getRange(2, 2).getValue(),
      template = RangeSheet.getRange(2, 3).getValue(),
    
      dataRows = DataSheet.getRange(data).getValues(),
      headerRow = DataSheet.getRange(header).getValues(),
      numColumns = DataSheet.getRange(header).getNumColumns(),
      templateRows= TemplateSheet.getRange(template).getValues();
    
      for (var i=0 ; i < dataRows.length ; i++) {
        var mailmessage = "";
        for (var k=0 ; k < templateRows.length ; k++) {
          if ( k == 0 ) {
            var subject = templateRows[0][0];
          } else {
            mailmessage += templateRows[k][0] + "<br>\n"; 
          }
        }
        for (var j=0 ; j < numColumns ; j++) { 
          mailmessage = mailmessage.replace('{' + headerRow[0][j] + '}', dataRows[i][j]); 
        }
        //Test output with logger. Uncomment the line below.
        //Logger.log(mailmessage);
        //
        //Send Email start here, starting row is 2.
        var sender = "Sawadee Krub";   //email sender name
        var emailaddress = DataSheet.getRange(2+i, 4).getValue(); //email in column 4
        var options = {}
        options.htmlBody = mailmessage;
        options.name = sender;
        //Not send email again if it was sent. Clear note then can send email again.
        if (DataSheet.getRange(2+i, 4).getNote()) {
        } else {
          MailApp.sendEmail(emailaddress, subject, '', options);
          DataSheet.getRange(2+i, 4).setNote("Email sent on " + new Date); 
        }
        //Email sent
      } 
    }

     

    ความรู้นำมาจากเรื่องนี้:
    1) Embedding a link in Mail Merge
    https://productforums.google.com/forum/#!topic/docs/WvW-lAr3pg8
    และ
    2) Google Apps Scripts Workshop – Level 1
    http://sysadmin.psu.ac.th/2015/05/06/gasws-1/

    ในตอนต่อไป จะนำเสนอวิธีสร้าง link ที่เป็น pre-filled form URL ของ google form

  • รู้จักกับ Algebraic Specification

    สวัสดีครับ

    หลังจากใช้เวลานานในการคิดว่าจะเขียนอะไรดี ก็คิดได้ว่านำเอาความรู้ที่ได้จากการไปเรียนทบทวนเรื่องวิศวกรรมซอฟต์แวร์มาเล่าสู่กันฟังดีกว่า เรื่องที่จะเล่านี้ก็คือ การเขียน Specification ในรูปแบบหนึ่งซึ่งอาจจะใหม่สำหรับบางคน เรียกว่า Algebraic Specification (ชื่อภาษาไทยว่าอะไร ไปหาเอาเองนะครับ)

    Algebraic Specification เป็นรูปแบบหนึ่งของ Formal Specification (อย่าเพิ่งงงนะครับ) ในการเขียน specification รูปแบบนี้จะใช้คณิตศาสตร์เข้ามาช่วยเพื่อให้เห็นการติดต่อระหว่าง module หรือ component ที่ชัดเจน

    แล้วมันต่างจากที่เขียนอยู่ยังไง?

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

    ดังนั้นจึงมีผู้ปราดเปรื่องบางท่านคิด Algebraic specification ขึ้นมาซึ่งหน้าตาเป็นดังนี้

    ARRAY (Elem: [Undefined -> Elem])
    sort ArrayImports INTEGER
    DescriptionArrays are collections of elements of generic type Elem. They have a lower and upper bound (discovered by the operations First and Last). Individual elements are accessed via their numeric index.Create takes the array bounds as parameters and creates the array, initializing its values to Undefined. Assign creates a new array which is the same as its input with the specified element assigned the given value. Eval reveals the value of a specified element. If an attempt is made to access a value outside the bounds of the array, the value is undefined.
    OperationsCreate (Integer, Integer) -> ArrayAssign (Array, Integer, Elem) -> Array

    First (Array) -> Integer

    Last (Array) -> Integer

    Eval (Array, Integer) -> Elem

    AxiomsFirst (Create (x, y)) = xFirst (Assign (a, n, v)) = First (a)

    Last (Create (x, y)) = y

    Last (Assign (a, n, v)) = Last (a)

    Eval (Create (x, y), n) = Undefined

    Eval (Assign (a, n, v), m) =

    if m < First (a) or m > Last (a) then Undefined

    else

    if m = n then v

    else Eval (a, m)

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

    “สิ่งมีชีวิตสามารถกินอะไรก็ได้ที่กินได้”

    Eat (Life, Eatable)

    ทั้งนี้ที่ Algebraic specification ยังไม่เป็นที่นิยมก็เพราะว่าผู้ใช้เข้าใจยากครับ ตอนทวนสอบความต้องการอาจจะต้องอธิบายกันหัวหมุน แต่ข้อดีของมันก็น่าทึ่งเพราะคนที่อ่านเข้าใจก็จะเห็นส่วนการติดต่อเชื่อมโยงกันชัดเจนระหว่าง operation  module  หรือ  component  ทั้งนี้ผู้เขียนกำลังคิดอยู่ว่าจะเอาเจ้าสิ่งนี้มาทำประโยชน์ได้อย่างไร ถ้าคิดออกแล้วจะเอามาเล่าให้ฟังนะครับ

  • Icon Font

    บทความนี้จะพูดถึงคำ 2 คำ คือ Icon และ Font ที่ใช้งานบนเว็บ ซึ่งทุกคนคงจะรู้จัก Web Icon กันดีอยู่แล้วว่ามันคือรูปภาพขนาดเล็กที่ปรากฏบนหน้าเว็บไซต์ ใช้เป็นสัญลักษณ์แทนความหมายต่างๆ เช่น รูปแว่นขยายมีความหมายถึงการค้นหาข้อมูล รูปแผ่นดิสก์ใช้แทนความหมายของการบันทึกข้อมูล เป็นต้น รูปภาพเหล่านี้ส่วนใหญ่จะเป็นไฟล์นามสกุล .png ซึ่งสามารถทำเป็นรูปที่มีพื้นหลังโปร่งใสได้

    search-iconActions-document-save-all-icon

     

     

     

    ในส่วนของการใช้งาน Font บนเว็บไซต์นั้นสามารถอ่านได้จากบทความ @font-face ครับ กล่าวโดยสรุปแบบง่ายๆ คือ Font เป็นข้อความที่ใช้นำเสนอข้อมูลบนเว็บไซต์ครับ และการพัฒนาเว็บไซต์ในปัจจุบันนี้ได้มีสิ่งที่น่าสนใจเกิดขึ้น เมื่อมีการนำ Icon และ Font มารวมกัน คือการทำ Icon ให้เป็น Font หรือการสร้างตัวอักษรที่มีรูปร่างเป็น Icon เรียกใช้งานผ่าน CSS class แล้วแสดงผลเหมือนเป็นรูปภาพรูปหนึ่ง ข้อดีของการทำแบบนี้คือเราสามารถจัดการเรื่องขนาด และสีได้ด้วยการใส่ CSS อย่างง่ายได้

    Icon Font ใน Bootstrap Framework

    Bootstrap Framework ที่นิยมใช้งานกันอย่างแพร่หลายก็ได้จัดเตรียมคอมโพเน้นต์ที่เป็น Icon Font ให้ใช้งานด้วยเหมือนกัน โดยจะใช้ชื่อว่า Gryphicons (http://getbootstrap.com/components/#glyphicons) ประกอบด้วย Icon ต่างๆ มากมายดังรูป

    gryphicons

    วิธีการใช้งานก็ไม่ยาก แค่กำหนด CSS class ให้กับแท็ก <span> ดังตัวอย่างนี้

    gryphicons-class-example

    Font Awesome

    font-awesome

    Font Awesome เป็นแหล่งรวม Icon Font ที่น่าสนใจมากอีกแหล่งหนึ่ง มี Icon สวยๆ ให้เลือกมากมาย วิธีการติดตั้งมี 2 วิธีเช่นเดียวกับการเรียกใช้งาน CSS ทั่วไป ดังนี้

    1. ติดตั้งผ่าน MaxCDN Bootstrap ในแท็ก <head> ดังนี้

    <link rel=”stylesheet” href=”//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css”>

    1. ดาวน์โหลดจากเว็บ http://fortawesome.github.io/Font-Awesome มาติดตั้งบนเว็บไซต์ของเราได้โดยตรง และติดตั้งในแท็ก <head> ดังนี้

    <link rel=”stylesheet” href=”path/to/font-awesome/css/font-awesome.min.css”>

    วิธีการใช้งานให้ใช้ผ่านแท็ก <i> หรือ <span> เช่น

    <i class=”fa fa-camera-retro”></i> fa-camera-retro

    ก็จะทำให้ได้ Icon รูปกล้องถ่ายรูปดังรูป

    camera-icon

    ท่านสามารถศึกษาเพิ่มเติมได้จากตัวอย่างในเว็บนี้ครับ http://fortawesome.github.io/Font-Awesome/examples

  • @FONT-FACE

    การใช้ฟอนต์นำเสนอข้อมูลข่าวสารบนเว็บไซต์ หรือ Web Typography ในยุคแรก นั้น Browser จะเป็นตัวกำหนดว่าจะนำเสนอด้วยฟอนต์อะไร ทำให้การแสดงผลในแต่ละ Browser ไม่เหมือนกัน ต่อมาใน HTML2 ได้มีการเพิ่มแท็ก <font> เข้ามา และใน CSS2 ก็อนุญาตให้เราสามารถกำหนดฟอนต์ได้เอง แต่ปัญหาที่เจอคือฟอนต์ที่เราเลือกใช้จะต้องถูกติดตั้งบนเครื่องฝั่งผู้ใช้ด้วย ดังตัวอย่างการกำหนดรูปแบบ font ด้วย CSS2 ดังนี้

    body { font-family: Gill, Helvetica, sans-serif }

    เมื่อ Web Browser อ่านเจอ CSS ดังกล่าว อันดับแรกก็จะดูว่าฟอนต์ที่ชื่อ Gill ถูกติดตั้งไว้ในเครื่องแล้วหรือยัง ถ้าติดตั้งแล้วก็จะแสดงผลเว็บไซต์ด้วยฟอนต์ Gill แต่ถ้ายังไม่ได้ติดตั้ง Browser ก็จะมองหาฟอนต์ตัวถัดไปคือ Helvetica และ sans-serif ตามลำดับ

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

    อะไรๆ ก็ง่ายขึ้นด้วย @font-face

    ถือว่าเป็นข่าวดีของนักพัฒนาเว็บไซต์เป็นอย่างมาก เมื่อ CSS3 ได้กำหนด @font-face ไว้ใน specification ด้วย ทำให้การใช้ฟอนต์บนเว็บไซต์มีความหลากหลายมากยิ่งขึ้น

    @font-face เป็นกลไกที่จะช่วยให้เราสามารถเรียกใช้ฟอนต์ที่ไม่ได้ถูกติดตั้งไว้บนเครื่องฝั่งผู้ใช้ได้ โดยให้ระบุแหล่งที่อยู่ (src) ของไฟล์ฟอนต์ไว้ใน Style Sheet ดังนี้

    @font-face {

    font-family: myFirstFont;

    src: url(‘www.mydomain.com/sansation_light.woff’);

    }

    จากโค้ดเมื่อ Web Browser อ่านเจอก็จะไปโหลดฟอนต์ตามที่อยู่ที่ระบุไว้มาใช้งาน ทำให้เราสามารถกำหนดฟอนต์ได้ตามต้องการ

    ปัญหาต่อมาที่เจอคือแต่ละ Web Browser นั้นรองรับไฟล์ฟอนต์ในรูปแบบ (format) ที่แตกต่างกันออกไป ในโค้ดตัวอย่างใช้รูปแบบ Web Open Font Format (woff) รูปแบบอื่นที่มีการใช้งานกันได้แก่ EOT (Embedded OpenType), TrueType Font (ttf), Open Type Font (otf) และ Scalable Vector Graphics (SVG) เป็นต้น โดยแต่ละ Browser รองรับรูปแบบไฟล์ต่างกันดังรูป

    font-browser-supportที่มา : www.w3schools.com

    แล้วทีนี้เราจะเขียน CSS อย่างไรให้รองรับทุก Browser ล่ะ? คำตอบก็คือ ให้เราระบุแหล่งที่อยู่ของไฟล์ฟอนต์ (src) แต่ละรูปแบบต่อท้ายเข้าไปเลยดังนี้

    @font-face {

    font-family: myFirstFont;

    src: url(‘sansation_light.woff’);

    src: url(‘sansation_light.woff’) format(‘woff’),

    url(‘sansation_light.eot) format(‘embeded-opentype’),

    url(‘sansation_light.ttf) format(‘truetype);

    }

    จากโค้ดในส่วนของ format จะเป็นตัวบอก Browser ว่าไฟล์ที่ระบุตรงกับรูปแบบที่รองรับหรือไม่ ถ้าตรงก็โหลดมาใช้งาน แต่ถ้าไม่ตรงก็จะไม่โหลดลงมาให้เปลือง Banwidth

    แล้วจะหาไฟล์ฟอนต์ได้จากไหน?

    อ่านมาถึงตรงนี้แล้ว หลายคนอาจจะกังวลว่า แล้วจะหาไฟล์ woff, eot, ttf เหล่านี้ได้จากไหน? คำตอบคือให้ทำตามขั้นตอนดังนี้

    1. ดาวน์โหลดฟอนต์ในรูปแบบ ttf ที่ต้องการก่อนครับ แนะนำเว็บไซต์ f0nt.com จะมีฟอนต์ภาษาไทยสวยๆ ให้เลือกมากมาย และที่สำคัญคือสามารถใช้ได้ฟรี ไม่มีค่าลิขสิทธิ์
    2. เข้าเว็บไซต์ http://www.font2com/
    3. ให้อัพโหลดไฟล์ฟอนต์ที่เตรียมไว้ แล้วคลิกปุ่ม Convert & Download ได้เลยครับ จะได้เป็นไฟล์ zip มา ข้างในประกอบด้วยไฟล์ css, demo.html และไฟล์ฟอนต์ต่างๆ ให้เราเอาไปใช้งานได้เลยครับ