(圖片出處: pixabay.com)
一、使用 GAS 搜尋試算表的方案
1. 試算表內建函數
很不幸的,試算表沒有內建任何跟搜尋有關的 GAS 函數,我想這無可厚非,畢竟是免費的服務,如果把搜尋功能做得太強,那會把 Google 自己的伺服器搞得累死,還沒有錢賺。
不得已,關於利用 GAS 來搜尋試算表的資料,就要看個人的功力了,多半只能每次都讀取整個試算表的資料,然後慢慢篩出自己要的資訊來。
2. BigQuery
另外一個選擇是引用 Google 提供的「BigQuery API」,那麼就可以使用 SQL 語法來查詢試算表資料,程式寫起來比較方便。
不過 BigQuery 在免費使用下是有每日配額限制的,可參考官網「Quota Policy」,可以想成每日免費查詢 1000 次(細節以官網為準)。
在使用量不大的情況下,引用 BigQuery API 是 ok 的,那麼可參考這篇「Big Query And Google Spreadsheet Integration」的教學來操作。
如果使用量非常大的話,那麼我相信你的服務是可以賺錢的,花點錢提升 Google 的配額限制,是應該的、且划算的。
二、使用 GAS 讀取試算表
本篇在免費的前提下,未採用 BigQuery 的查詢方式(避免偶爾的流量爆衝而導致網頁程式失效),改為提供一個簡易的查詢範例。
1. read_data 函數
上一篇的 GAS 程式碼範例,寫了兩個函數:doPost 及 write_data。我們可以接在原本的程式碼後面,新增一個 read_data 函數,內容如下:
function read_data(para) {
var query = para.query,
rowLength = sheet1.getLastRow() - 1, // 列數
columnLength = sheet1.getLastColumn(), // 欄數
allData = sheet1.getRange(2, 1, rowLength, columnLength).getValues(), // 取得所有儲存格資料
queryData, queryMessage, i;
for (i in allData) {
if (allData[i].indexOf(query) > -1) {
queryData = allData[i];
break;
}
}
queryMessage = "稱謂:" + queryData[1] + " 性別:" + queryData[2] + " 註解:" + queryData[3]; // 回傳字串
return ContentService.createTextOutput(queryMessage);
}
簡單說明一下運作方式:
- 利用試算表內建函數找出儲存格的欄數、列數
- 撈出所有儲存格資料
- 逐列比對,如果某列包含了要搜尋的字串,取出該列所有資料
- 返回處理過的字串,包含該列儲存格資料
- 字串要怎麼處理,請自行修改程式碼
- ContentService.createTextOutput() 的使用方法,後面會說明。
2. 呼叫 read_data
接著是呼叫 read_data 這個函數,以下是修改後的 doPost 函數內容:
function doPost(e) {
var para = e.parameter, // 存放 post 所有傳送的參數
method = para.method;
if (method == "write") {
write_data(para);
}
if (method == "read") {
return read_data(para);
}
}
其實就是新增紅字這一行就可以了,這行程式碼會回應 post 請求,送出查詢結果的字串,返回網頁端。
接下來的步驟請參考「上一篇」→「四、部署為網路應用程式」的流程,將新的 GAS 版本發佈為網路應用程式。
三、用 jQuery 送出 post 請求
以下範例程式碼,用 jQuery 的 Ajax 方法來傳送 post 請求,查詢範例試算表中,包含儲存格有 "Mary" 字串這一列的資料:
<script src='//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js'></script>
<script>
$.ajax({
type: "post",
data: {
"method": "read",
"query": "Mary"
},
url: "https://script.google.com/macros/s/AKfycbxN6sBikcLtDNxzZU1-hrylbGUzJ1qD2yXjZjmiw9ra7hPHPgo/exec", // 填入網路應用程式網址
success: function (e) {
alert(e);
}
});
</script>
以上 url 參數紅色網址字串,請改為自己的網路應用程式網址。
method、query 等參數名稱,需要與 GAS 的設定一樣。
想要測試效果,直接執行以上程式碼即可,查詢成功時,瀏覽器會 alert 訊息,也就是前面 GAS 所設定返回的字串訊息,就像下面這個範例試算表中,"Mary" 那一行的資料。
四、讀取的資料型態
現在來說明 ContentService.createTextOutput() 這個內建函數要如何使用。
1. 回傳字串:回傳的資料如果需要是 "字串" 型態的話,使用預設的語法 ContentService.createTextOutput(字串) 來處理即可。
2. 回傳其他型態的資料:實際上,大部分會需要回傳的資料型態,往往不是字串這麼簡單。官網的說明文件「Content Service」提供了很詳細的操作說明,例如 RSS、JSONP 等。
如果是 JSON 物件,對應的回傳語法為:
ContentService.createTextOutput(JSON.stringify(這裡是整理好的 JSON 物件)).setMimeType(ContentService.MimeType.JSON)
如果處理 JSONP,對應的回傳語法為:
ContentService.createTextOutput("回呼函數字串(" + JSON.stringify(這裡是整理好的 JSON 物件) + ")")
.setMimeType(ContentService.MimeType.JAVASCRIPT)
以上 GAS 最重要的讀取、搜尋、寫入功能,都已說明完畢,下一篇會說明其他處理試算表要注意的地方。
用 Google Apps Script 操作試算表系列文章:
大大您好,請問如何是要用bigQuery,要如何從GAS將試算表的內容寫入bigQuery呢?
回覆刪除爬了很多文章,都是只有介紹從bigQuery讀出,而且好像國外的文章比較多說明,
嗚嗚,我的破英文XD
請問如果只想query,第一個column該如何改呢?我這樣改if (allData[i][0].indexOf(query) > -1) 後是只針對第一個column沒錯,但是變成Mary,只要其中一個字母符合,就會抓到那個row
回覆刪除請問若符合比對的資料有2筆(例有2個Mary的資料),我測試結果只顯示第1筆的資料而已,請問程式需要修改嗎?謝謝!
回覆刪除您好我照您的步驟從“(1)製作資料庫 + 寫入資料” 到 “(2)讀取、儲存資料庫__更新”重新寫一個 google app script 然後發布成網路應用程式設成以(1)網路使用者的名義執行(2)任何人可以使用,另外jquery,ajax那邊我是直接用.html用chrome開啟,可是我會在console.log那邊得到401跨網域禁止,但是用您的app卻是可以使用,請問您有做額外的設定嗎?
回覆刪除