Tag: Google Apps Script

  • เทคนิคการอ่านค่าจากเว็บไซต์ที่มีการเปลี่ยนแปลง (ราคาหุ้น) มาเก็บไว้บน Google Sheets

    มีโจทย์ว่าต้องการคำนวนค่า Indicator ชื่อ RSI ของกองทุนรวมในต่างประเทศ ซึ่งปิดการซื้อขายเวลา 04:00 ของเวลาในประเทศไทย ทางกองทุนจะประกาศราคา (NAV) ในเวลาประมาณ 09:00 แต่ในการตัดสินใจลงทุน จะต้องพิจารณาค่า RSI ซึ่งกองทุนจะคำนวนและประกาศให้ประมาณ 12:00 ซึ่งบางทีก็หลงลืม และไม่ทันการ

    การคำนวนค่า RSI ใช้ค่าการเปลี่ยนแปลงของราคา แบ่งเป็น Gain และ Loss แล้วมาหาค่าเฉลี่ยและเข้าสูตรคำนวน (ไม่ขอกล่าวถึง หากต้องการทราบข้อมูลเพิ่มเติม อ่าน http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:relative_strength_index_rsi)

    สรุปคือ หากต้องการทราบค่า RSI ก่อนที่ทางกองทุนจะประกาศให้ ก็ต้องคำนวนเอง โดยจดค่าการเปลี่ยนแปลงของราคาในแต่ละวันซึ่งเป็นงานที่น่าเบื่อ จึงต้องหาวิธีลดภาระ

    แนวคิดคือ เว็บไซต์ http://www.bloomberg.com/quote/WGHCEPA:ID ซึ่งจะประกาศราคา NAV ในเวลา 09:00 นั้น หากเปิด HTML ดูจะพบว่าข้อมูลที่ต้องการจะอยู่ในรูปแบบของ

    ...
    <meta itemprop="price" content="46.92">
    ...
    <meta itemprop="priceChange" content="0.16">
    ...
    <meta itemprop="priceChangePercent" content="0.34">
    ...
    <meta itemprop="quoteTime" content="2015-05-11T00:59:30-0400">

    จากนั้น สร้าง Function ตามนี้

    function getWGHCEPA(){
     var content=UrlFetchApp.fetch("http://www.bloomberg.com/quote/WGHCEPA:ID");
     //'<meta itemprop="priceChange" content="0.16">';
     var data = content.getContentText().match(/meta itemprop="(.*)" content="(.*)"/mg );
     
     var id="xxxxxxxxxxxxxxxxxxxx Your file ID xxxxxxxxxxxxxx";
     var db=SpreadsheetApp.openById(id);
     var table=db.setActiveSheet(db.getSheetByName("Data"));
     
     var result=[];
     for (var i=0; i<data.length; i++){
     var temp=data[i].match(/meta itemprop="(.*)" content="(.*)"/); 
     result[temp[1]]=temp[2];
     } 
     
     table.appendRow([result["quoteTime"], result["price"], result["priceChange"], result["priceChangePercent"]]);
     
    }

    จากนั้น ตั้ง Trigger ให้ทำงานวันละครั้ง เวลาตั้งแต่ 09:00-10:00 เป็นอันเรียบร้อย

    wghcepa-trigger

    ผลที่ได้

    wghcepa-result

  • เริ่มต้นใช้งาน GAS Editor

    1. เปิด https://drive.google.com แล้ว Login
    2. คลิกปุ่ม New > Google Sheets
    3. ตั้งชื่อไฟล์: GASWS1
    4. เมนู Tools > Script Editor
    5. เลือก Blank Project
    6. ตั้งชื่อโปรเจค : myproject1
    7. เมนู File > New > Script File
    8. ตั้งชื่อ: myscript1
    9. แก้ไข myFunction() ตามนี้
      function myFunction() {
       Logger.log("Hello World");
      }
      
    10. เมนู File > Save หรือ กดปุ่ม Ctrl+s
    11. เมนู Run > myFunction
    12. ดูผลได้ที่ เมนู View > Logs หรือ กดปุ่ม Ctrl+Enter
    13. สร้าง function myForLoop ดังนี้
    14. function myForLoop(){
      for (var i=1; i<=10 ; i++) {
      myFunction();
      }
      }
    15. แล้ว Save ด้วย กดปุ่ม Ctrl+s
    16. เมนู Run > myForLoop
    17. ดูผลได้ที่ เมนู View > Logs หรือ กดปุ่ม Ctrl+Enter
    18. เมนู File > New > Script File
    19. ตั้งชื่อ myscript2
    20. สร้าง function myDate ดังนี้
    21. function myDate() {
      Logger.log(new Date());
      }
    22. แล้ว Save ด้วย กดปุ่ม Ctrl+s
    23. เมนู Resources > All yours triggers
    24. คลิก No triggers set up. Click here to add one now.
    25. ตั้งค่า
      Run = myDate
      Event = Time-driven
      แล้วเลือกเป็น Minutes timers และ Every minute
      จากนั้นคลิกปุ่ม Save
    26. ดูผลได้ที่ เมนู View > Logs หรือ กดปุ่ม Ctrl+Enter

     

  • Case Study: ตรวจสอบ Website Availability ด้วย Google Apps Script

    1. เปิด Google Sheets : GASWS1
    2. สร้าง Sheet ใหม่ ชื่อ “Log”
    3. เมนู Tools > Script Editor…
    4. เมนู File > New > Script File
    5. ตั้งชื่อ: myscript4
    6. เขียนโค๊ดตามนี้
       function check_website(url) { 
       var response = UrlFetchApp.fetch(url, {muteHttpExceptions: true});
       return response.getResponseCode();
      }
      
      function doLog(timestamp, responseCode, timeDiff) {
       
       var ss=SpreadsheetApp.getActiveSpreadsheet();
       var sheet=SpreadsheetApp.setActiveSheet(ss.getSheetByName("Log")); 
       sheet.appendRow([timestamp, responseCode, timeDiff]);
      }
      
      function getTime() {
       var startTime = new Date() ;
       var responseCode=check_website("http://www.psu.ac.th");
       var endTime = new Date() ;
       var timeDiff = endTime-startTime; 
       doLog(Utilities.formatDate(new Date(), "GMT+7", "yyyyMMdd-HHmmss") , responseCode , timeDiff);
      }
    7. เมนู Resources > All yours triggers
      คลิก No triggers set up. Click here to add one now.
      ตั้งค่า
      Run = getTime
      Event = Time-driven
      แล้วเลือกเป็น Minutes timers และ Every minute
      จากนั้นคลิกปุ่ม Save
  • อ่าน/เขียนข้อมูลกับ Google Sheets

    1. เปิด Google Sheets : GASWS1
    2. เมนู Tools > Script Editor…
    3. เมนู File > New > Script File
    4. ตั้งชื่อ: myscript3
    5. สร้าง function insertData1() ตามนี้
      function insertData1() {
       var ss=SpreadsheetApp.getActiveSpreadsheet();
       var sheet=SpreadsheetApp.setActiveSheet(ss.getSheetByName("Sheet1"));
       sheet.getRange(1, 1).setValue("Hello World");
       sheet.getRange("A2").setValue("สวัสดี");
       
       var v1=[ ["ชื่อ","นามสกุล","อายุ"] ];
       var v2=[
       ["สมชาย"]
       ,["Robert"]
       ,["39"]
       ];
       sheet.getRange("A3:C3").setValues(v1);
       sheet.getRange("A4:A6").setValues(v2);
      }
    6. เมนู Run > insertData1
    7. สร้าง function insertData2() ตามนี้
      function insertData2() {
       var ss=SpreadsheetApp.getActiveSpreadsheet();
       var sheet=SpreadsheetApp.setActiveSheet(ss.getSheetByName("Sheet1")); 
       sheet.appendRow([new Date(),"something"]);
      }
    8. เมนู File > Save หรือ กดปุ่ม Ctrl+s
    9. เมนู Run > insertData2
    10. เมนู Resources > All yours triggers
      คลิก No triggers set up. Click here to add one now.
      ตั้งค่า
      Run = insertData2
      Event = Time-driven
      แล้วเลือกเป็น Minutes timers และ Every minute
      จากนั้นคลิกปุ่ม Save
    11. ไปที่ Google Sheets “GASWS1”
    12. สร้าง Sheet ใหม่ ชื่อ “ReadData”
    13. เมนู Tools > Script Editor…
    14. สร้าง function readData1() ตามนี้
      function readData1(){
       var ss=SpreadsheetApp.getActiveSpreadsheet();
       var sheet=SpreadsheetApp.setActiveSheet(ss.getSheetByName("ReadData")); 
      
       var url="https://docs.google.com/spreadsheets/d/1oztRXjC2KJzrqC3LtiRnUPrEgohX4VTYHixylvtCdzY/edit?usp=sharing";
       var db=SpreadsheetApp.openByUrl(url);
       var table=db.setActiveSheet(db.getSheetByName("WGHCEPA"));
       var data=table.getRange("A1:J10").getValues();
       
       for (var i=0; i<data.length;i++){
       sheet.appendRow(data[i]);
       }
       
      }
    15. เมนู File > Save หรือ กดปุ่ม Ctrl+s
    16. เมนู Run > readData1
    17. สร้าง function readData2() ตามนี้
      function readData2(){
       var ss=SpreadsheetApp.getActiveSpreadsheet();
       var sheet=SpreadsheetApp.setActiveSheet(ss.getSheetByName("readData")); 
      
       var id="1oztRXjC2KJzrqC3LtiRnUPrEgohX4VTYHixylvtCdzY";
       var db=SpreadsheetApp.openById(id);
       var table=db.setActiveSheet(db.getSheetByName("WGHCEPA"));
       var data=table.getDataRange().getValues();
       
       for (var i=0; i<data.length;i++){
       sheet.appendRow(data[i]);
       }
       
      }
    18. เมนู File > Save หรือ กดปุ่ม Ctrl+s
    19. เมนู Run > readData2
    20. สร้าง function insertData3() ตามนี้
      function insertData3(){
       var url="https://docs.google.com/a/psu.ac.th/spreadsheets/d/1bQyyQrB3PPyawWVb3afMi0Kgz1KUibIfMblv351BtQI/edit?usp=sharing";
       var db=SpreadsheetApp.openByUrl(url);
       var table=db.setActiveSheet(db.getSheetByName("Sheet1"));
       // เปลี่ยนเป็น ชื่อ นามสกุล และคณะ/หน่วยงานของท่าน
       var mydata=["ชื่อ","นามสกุล","คณะ/หน่วยงาน"];
       
       table.appendRow(mydata);
      }
    21. เมนู File > Save หรือ กดปุ่ม Ctrl+s
    22. เมนู Run > insertData3
  • วิธีใช้ Google Sheets ลบผู้ใช้จำนวนมากบน GAFE

    [บทความนี้ สำหรับผู้ที่มี Admin Privilege ขึ้นไป]

    ต่อจากบทความ วิธีใช้ Google Sheets เปลี่ยนแปลงข้อมูลผู้ใช้จำนวนมากบน GAFE

    เมื่อต้องการลบผู้ใช้จำนวนมาก ก็ทำเหมือนเดิม แต่เปลี่ยน Script นิดหน่อยดังนี้

    1. สร้าง Google Apps Scripts ใน Google Sheets นี้ ด้วยเมนู Tools > Script Editor … จากนั้นเลือก Blank Project แล้วกดปุ่ม Close
    2. ตั้งชื่อโปรเจค UpdateUser แล้วใส่โค๊ดดังนี้ (ปรับค่า firstRow และ lastRow ให้เหมาะสมตามต้องการ)
    3. นอกนั้นเหมือนเดิม

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

  • วิธีใช้ Google Sheets เปลี่ยนแปลงข้อมูลผู้ใช้จำนวนมากบน GAFE

    [บทความนี้ สำหรับผู้ที่มี Admin Privilege ขึ้นไป]

    วิธีใช้ Google Sheets สร้าง Account ใหม่ลงใน Sub Organization ของ GAFE

    เมื่อต้องการแก้ไขข้อมูลของผู้ใช้จำนวนมาก ได้แก่

    • ตั้งรหัสผ่านใหม่
    • ไม่บังคับให้เปลี่ยนรหัสผ่านในครั้งแรกที่เข้าระบบ
    • ย้าย Organization Unit ไปอยู่ภายใต้ /Students

    ใน Admin Console ของ Google Apps จะมีเครื่องมือ Users เพื่อใช้ในการจัดการผู้ใช้

    แต่เครื่องมือที่มีอยู่ มีข้อจำกัด คือ ไม่สามารถเขียนเงื่อนไขในการกรองเอาเฉพาะ Email Address ของผู้ใช้ที่ต้องการได้

    ดังนั้นจึงต้องใช้วิธีการ Download Users ทั้งหมดออกมาก่อน

    เลือก Download all users … แล้วกดปุ่ม OK

    จะได้ไฟล์ UserData-psu.ac.th-20141110.csv (ชื่ออาจจะแตกต่างกันไปในแต่ละโดเมน) ให้ Save ไว้ในเครื่องคอมพิวเตอร์ก่อน แล้ว Upload ไปเก็บไว้บน Google Drive แล้วเปิดด้วย Google Sheets จากนั้นเลือกคอลัมน์ A แล้วคลิกขวาเลือก Copy ไปใส่ใน Google Sheets ใหม่

    ใน Google Sheets ใหม่ ให้ Edit > Paste ข้อมูลมาลงไว้ในคอลัมน์ A เช่นกัน

    จากนั้นในคอลัมน์ B2 ใส่สูตรว่า (นักศึกษาของมหาวิทยาลัยจะใช้ Login เป็นรหัสนักศึกษาซึ่งเป็นตัวเลขทั้งหมด จำนวน 7 หรือ 10 หลัก ตามด้วย @psu.ac.th) ดังนี้

    )

    จากนั้นให้ Copy สูตรดังกล่าวไปในคอลัมน์ B ทั้งหมด จะทำให้ ชื่อบัญชีของนักศึกษาเท่านั้นที่จะมีค่าเป็น Y ส่วนบุคลากรจะมีค่าเป็น N หลังจากนั้นให้ Filter โดยเลือกเฉพาะคอลัมน์ B ที่มีค่าเป็น Y ก็จะได้นักศึกษาทั้งหมด

     แล้วทำการเลือกข้อมูลที่ได้ Copy เอาไว้แล้วสร้าง Google Sheets ใหม่อีกอันหนึ่ง ตั้งชื่อว่า Udate Users แล้วเอาข้อมูลดังกล่าวมาใส่ในคอลัมน์ A จากนั้นสร้าง B เป็น Organization Unit Path ที่ต้องการ แล้วสร้าง C เป็น Password ที่ต้องการตั้ง และ D เป็น Status

    ต่อไป เป็นขั้นตอนการเขียน Google Apps Script

    1. สร้าง Google Apps Scripts ใน Google Sheets นี้ ด้วยเมนู Tools > Script Editor … จากนั้นเลือก Blank Project แล้วกดปุ่ม Close
    2. ตั้งชื่อโปรเจค UpdateUser แล้วใส่โค๊ดดังนี้ (ปรับค่า firstRow และ lastRow ให้เหมาะสมตามต้องการ)
    3. ถ้าลอง Run เลย จะเจอ Error อย่างนี้
      คลิก Continue -> Accept -> Dismiss
      เพราะยังไม่ได้ Enable API ไว้
    4. เนื่องจากการสร้าง Account ต้องใช้สิทธิ์ของ Admin ขึ้นไป และต้องใช้ Admin SDK Directory API ด้วย วิธีการคือใช้เมนู Resources -> Advanced Google Services แล้วเลือก Admin Directory API เป็น On
    5. จากนั้นคลิกที่ Google Developers Consol
      ที่ Admin SDK ให้เปลี่ยน ON
    6. เมื่อ Run ใหม่ ก็จะได้ผลใน Google Sheets ตามภาพ
    7. ผลที่ได้คือสามารถย้ายนักศึกษาลงไปใน OU ที่เหมาะสมได้

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

  • วิธีใช้ Google Sheets สร้าง Account ใหม่ลงใน Sub Organization ของ GAFE

    [บทความนี้ สำหรับผู้ที่มี GAFE Admin Privilege ขึ้นไป]

    ในการสร้างบัญชีผู้ใช้ใหม่บน GAFE นั้นทำได้หลายวิธี ได้แก่

    1. การสร้างทีละคนผ่าน Admin Console
    2. การสร้างทีละหลายๆคนด้วย CSV File
    3. การสร้างทีละหลายๆคนผ่าน Google Apps Directory Sync

    เมื่อต้องการสร้างผู้ใช้จำนวนมาก เช่น 5,500 คน โดยต้องจัดแบ่งผู้ใช้ แยกลงไปในแต่ละ Sub Organization วิธีที่ 1. ทำได้แต่เป็นงานที่หนักมาก วิธีที่ 2. ทำไม่ได้ เพราะการใช้ CSV File ผ่าน Admin Console นั้นจะสร้างผู้ใช้รวมกันที่ Root Organization ไม่สามารถแยกลงไปใน Sub Organization ได้ ส่วนวิธีที่ 3. นั้นทำได้ แต่ต้องเข้าใจกระบวนการทำงานของ LDAP พอสมควร

    ในบทความนี้ จะนำเสนอวิธีการที่ ทำได้ง่ายเหมือนการใช้ CSV แต่สามารถแยกลงไปใน Sub Organization ได้ ด้วย Google Sheets และ Google Apps Script ดังต่อไปนี้ (ขอยกตัวอย่างเพียง 5 Account เพื่อความสะดวก)

    1. สร้าง Google Sheets แล้วใส่ข้อมูล email, firstname, lastname, OU, password, status
    2. สร้าง Google Apps Scripts ใน Google Sheets นี้ ด้วยเมนู Tools > Script Editor … จากนั้นเลือก Blank Project แล้วกดปุ่ม Close
    3. ตั้งชื่อโปรเจค AddMultiAccountToSubOU แล้วใส่โค๊ดดังนี้
    4. ถ้าลอง Run เลย จะเจอ Error อย่างนี้
      คลิก Continue -> Accept -> Dismiss
      เพราะยังงไม่ได้ Enable API ไว้
    5. เนื่องจากการสร้าง Account ต้องใช้สิทธิ์ของ Admin ขึ้นไป และต้องใช้ Admin SDK Directory API ด้วย วิธีการคือใช้เมนู Resources -> Advanced Google Services แล้วเลือก Admin Directory API เป็น On
    6. จากนั้นคลิกที่ Google Developers Consol
      ที่ Admin SDK ให้เปลี่ยน ON
    7. เมื่อ Run ใหม่ ก็จะได้ผลใน Google Sheets ตามภาพ
    8. และจะสามารถสร้างผู้ใช้ได้ตาม Sub Organization ที่ต้องการ

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

  • วิธีการใช้ Google Sheets เป็นระบบเฝ้าระวังเว็บไซต์ (Website Monitoring) จากภายนอกองค์กร

    จาก “วิธีการใช้ Google Sheets เป็นฐานข้อมูล” ซึ่งได้กล่าวถึงพื้นฐานการพัฒนา Google Apps Script เพื่อใช้ต่อยอดความสามารถของ Google Sheets สามารถนำมาประยุกต์ใช้เพื่อเฝ้าระวังบริการเว็บไซต์จากภายนอกระบบเครือข่ายขององค์กรได้ (จาก Google Cloud Infrastructure เลยทีเดียว)

    ขั้นตอนในการทำ

    1. ในโปรเจค ProjectMyDB สร้างไฟล์ monitoring.gs ดังภาพ
    2. ประกอบด้วย 3 ฟังก์ชัน คือ
      function check_website(url) {  
        var response = UrlFetchApp.fetch(url, {muteHttpExceptions: true});
        return response.getResponseCode();
      }
      
      function doLog(timestamp, responseCode, timeDiff) {
        var ss = SpreadsheetApp.openByUrl('https://docs.google.com/a/psu.ac.th/spreadsheets/d/1HJmyqiBYC_AEATmdUWakLgHFyYGqSqeqSA8xEw-8o-c/edit');
        SpreadsheetApp.setActiveSpreadsheet(ss);
        SpreadsheetApp.setActiveSheet(ss.getSheetByName("Log"));
        var activeSheet=ss.getActiveSheet();
        activeSheet.appendRow([timestamp, responseCode, timeDiff]);
      }
      
      function getTime() {
        var startTime = new Date() ;
        var responseCode=check_website("http://www.psu.ac.th");
        var endTime = new Date() ;
        var timeDiff = endTime-startTime;  
        doLog(Utilities.formatDate(new Date(), "GMT+7", "yyyyMMdd-HHmmss") , responseCode , timeDiff);
      }
    • check_website ใช้ UrlFetchApp เพื่อ url ของเว็บไซต์ แล้วรีเทิร์นผล Response Code ของ HTTP Protocol กลับไป
    • doLog ใช้สำหรับเพิ่มค่า timestamp, responseCode และ timeDiff (เวลาในการตอบสนอง) ลงใน Sheet “Log” ใน Google Sheets ที่กำหนดไว้
    • getTime ใช้คำนวนเวลาตั้งแต่เริ่มต้น แล้วเรียกใช้ฟังก์ชั่น check_website และ จับเวลาที่สิ้นสุด จากนั้นคำนวนเป็นเวลาในการตอบสนอง (timeDiff) แล้ว เรียกฟังก์ขัน doLog เพื่อเขียนข้อมูลต่อไป
    1. สร้าง Trigger ด้วยเมนู Resources > Current project’s triggers
    2. เลือกฟังก์ชัน getTime กำหนดเป็น Time-driven ทำงานในหน่วยนาที (Minute timmer) และ ทำงานทุกๆ 5 นาที แล้วกดปุ่ม Save
    3. ผลการทำงาน และการสร้าง Chart ประกอบทำให้สามารถเห็นแนวโน้มได้

    จากตัวอย่างข้างต้น ทำให้เห็นว่า การใช้ Google Apps Script ร่วมกับ Google Sheet สามารถสร้างระบบเฝ้าระวังเว็บไซต์จากภายนอกองค์กรได้อย่างง่ายๆ และไม่มีค่าใช้จ่าย ทำให้เห็นภาพการใช้งานจากภายนอกได้เป็นอย่างดี