2014年3月19日 星期三

Google Apps Script使用心得

之前就有聽過google apps script能夠讓你自行撰寫程式碼,然後在google的次服器上執行,有人拿他來做監測伺服器運作是否正常的工具,有人拿來架設簡易的Web Server

前陣子我弄了一個google表單,要統計一些數據,我希望有人回覆表單的時候我能收到mail通知,所以就研究了一下FormEmailer,他可以幫我達到這個功能。

然後手上剛好接到一個案子,要寫一個盤點系統,因為有一些需求,所以我決定用google drive的試算表+google apps script來完成,會採用這種架構的主要原因是跨平台+省去UI開發,而且不用伺服器24小時運作。整個系統完成的時間大概花我一個半月吧,弄完之後有點小心得跟大家分享。

  1. 語法方面:基於javascript上的script語法,寫起來跟寫javascript沒啥差別,一切javascript的function都可以用,不過官方編輯器會有比較嚴謹的要求,例如:變數必須先宣告。
  2. 速度方面:這就是非常重要的一點了,google apps script跑起來,非常慢...,慢到什麼程度? 複製一個試算表,再改點權限,寫幾個值進去該表,可能要花10秒鐘左右。10秒鐘聽起來還好,不過檔案一多時間就變超久了,而且他有每次最大執行時間6分鐘的限制,執行超過6分鐘的function會被強制中斷,我怎麼知道我的程式跑起來會不會超過6分鐘? 被中斷之後你就知道了 XD
  3. 除錯方面:官方的編輯器有點難用,雖然提供了簡單的function提醒功能,也有debug功能,但是他的debug功能速度慢也就算了,居然沒辦法debug UI的event function,我google之後有人說善用Logger,但是Log根本沒辦法紀錄全部的東西啊...
  4. Log方面:說到log,我們當然希望他越詳盡越好,但是他的log只會提供最後一次的執行log,有時候根本不敷使用,我最後自己寫了一個log系統,把要紀錄的東西另外塞到別的試算表內...
  5. 穩定性方面:別懷疑,執行程式時的穩定性不好,這一個半月下來,大概2~3天會接到一次通知程式執行失敗的mail,所以你的程式要設計的非常有容錯能力,要可以檢查上次是否執行成功,如果失敗了要接下去跑,然後把執行次數多設幾次這樣才能確保程式都有跑完
  6. 計算額度方面:google apps script有提供每天的免費計算額度,例如:個人用戶1天1小時的計算時間,每天可以發出的200封Mail...等,可是他沒有一個介面讓你知道你今天的扣打剩多少了,只說會在接近上限時通知你,這有點麻煩,最後我還是自己寫了一個表,自動統計所有的function到底運算多少時間。
  7. API支援方面:開發這個系統時我用到大量的試算表,google drive有非常完善的權限控管功能,可以透過API任意新增或減少使用者,試算表也有類似的功能可以設定保護工作表,但是,保護儲存格範圍目前沒有相關的API,所以沒辦法用API去設定保護儲存格!!!!!,最後我的解法是把所有重要的資料都集中到某個工作表,然後保護該工作表....
  8. ImportRange功能:ImportRange可以讓你載入某個檔案的某部份資料進來,非常好用,但是如果import的層數一多,例如:載入A檔案的B資料,再用B資料去載入C資料,再用C資料去載入D資料,這樣一連串的載入之後速度就會變得非常慢....,大概超過3層以上的載入有時還會失敗,我的解法是把已經固定下來的載入資料直接寫入檔案,不讓他再去載入,這樣速度會快很多。
  9. 驗證資料功能:千萬別開啟驗證資料失敗後拒絕輸入的功能,請開顯示警告,你然你會發現,應該可以寫入的數值被莫名其妙的拒絕了,這一開始困擾我很久,還以為是我寫錯了,後來證實是他的bug...
  10. OnOpen function不執行的問題:所有script專案都會掛一個OnOpen的event,不過有時候他就是莫名其妙不會執行,答案是,你所有運算都要包在function裡面,不然就會造成這個錯誤,例如:
    
    var a = new Date();
    function OnOpen(){
        ...
    }
    

    這樣就會出錯了,建議解法是不要使用全域變數,或是自己再掛一個OnOpen的event上去就可以了
  11. 使用者資料讀取問題:剛剛提到google drive的權限控管很好用,他提供addEditor(emailAddress)、removeEditor(emailAddress)、getEmail()等function,讓你可以使用對方的email就可以快速刪改權限,爸特!,就是這個getEmail(),他有陷阱存在,他是去抓google plus的資料,所以如果對方沒有開放google plus的資料給人家看,那你就永遠抓不到他的email,會陷入可以用email加權限但是你不知道要怎樣砍他權限的問題...,解法是...乖乖開放你的email給朋友讀取吧....
  12. 讀取資料問題:一次讀取某個範圍的資料跟一次讀取一格資料所需的時間差不多,所以可以的話就一次讀出一堆資料再來處理,寫入也是一樣,反正記憶體不算在使用額度內 XD
綜合以上幾點,要用google apps script開發中小型軟體系統,最好考慮到未來擴充性的問題,因為每個帳號每天有扣打限制,所以要設計的有平行處理的功能,因為穩定性問題,要考慮接續上一次處理進度的問題,這樣才能避免程式運作不順利。

一次寫了這麼多好像都在抱怨google apps script的缺點 XD,不過這都是我開發過程中的心得,事實上,使用google apps script開發這個專案幫我省下了UI開發時間、權限控管問題,安全性問題,跨平台問題,資料同步問題,重要的是還不必有一台伺服器24小時運作。

希望大家開發google apps script順利 :)

2014年1月29日 星期三

Android抓不到WiFi SSID

之前把一台用不到的無線AP架在我房間內,想讓手機跟iPad都可以無線上網,但是很奇怪的事情發生了,我的Android手機居然抓不到WiFi的SSID,但是iPad跟iPhone都可以,google也找不到原因,後來就懶得理他了,反正我的手機有3G吃到飽。

但是最近忽然心血來潮把那台AP刷了最新版的dd-wrt,就抓的到了,可是我做了一些調整之後,又發現抓不到了!!!居然是設定的問題,所以我就開始檢查到底是什麼設定出問題,結果發現,是頻率不能調自動,我把頻率固定在頻道6就能夠抓到了~~~

使用jQuery的attr注意事項

這篇其實是寫給自己看的,最近在做一個階層式選單,所有資料都是使用ajax拿回來的,連第一層也是。所以頁面一打開,他會去讀第一層的資料,點第二層之後去拿第三層,點第三層去拿第四層....

但是為了避免資源浪費,所以拿過的資料不要重複拿,不要看的時候就把他隱藏起來,要看再打開讓他看,這時需要2個控制變數,一個判斷是否有拿過資料,一個判斷是否要打開或隱藏這個元素

所以我很自然的 取了 data, open 當做變數名稱放在html tag裡面使用,但是open在html5裡面居然是一個keyword,雖然使用$(this).attr('open', 'true')可以正確設置open='true',但是使用$(this).attr('open')取回值,他一律回open!!!!!!!

又不是歐噴醬,幹嘛一直回我歐噴!!!!!!
所以以後最好避免使用open當做tag的名稱...切記...

本次重點整理

  1. 要使用attr取得tag的內容,最好初始的html就有該tag名稱,不然他一律回undefined,直到你用attr設定了該tag的值
  2. html tag一律為字串,所以設定$(this).attr('data', true)跟$(this).attr('data', 'true')之後,取回內容一律為字串的true,建議一開始寫入就寫字串,比較不會混淆
  3. 千萬別用open當做tag名稱,不然他會變歐噴醬。
  4. 使用attr設定tag值為false時會使得該tag消失,下次想用attr取回時會回傳undefined,要非常注意,解決方式是設置字串的false就好

使用jQuery在表格中任一插入一列

最近再做一個表格,要能在表格中任意插入一列,google了幾個方法都是教你用eq(x),就能在某一行後面插入balabala...

阿我就是不知道要在哪行後面插入啊!!!!!,掯,這不是廢話嗎?

爆氣之後決定自己想辦法,以下就是source code。

要注意的是一般我們插入元件都會用append加到後面,但是append這個指令其實是會把要加入的內容放在該元素的最後面,而不是這個元素的後面。意思就是,新加入的內容還是算在該元素的頭上,不會自成一個元素。

在加入一般的元素或許沒什麼問題,但是要加入表格就會造成版面亂掉,
所以這邊加入要使用after或是before,這2個指令才會把加進去的內容放在原本的元素外面。


$(document).on('click', '.tr', function(){
    $(this).after("<tr class='tr'><td>data</td></tr>"); //要放在前面就把after換成before
});