シート上ではQuery関数でSQLを書けますが
スクリプトで実現する方法を探し回ってたどり着いたのが
Google Visualization APIでした
色々試して実現できたコード.gsを書き残しておきます
今回の例で用いたシートのデータ
以下のようなデータが入力されていて
"SELECT A, B"
↑このようなクエリを書いて
[[あいうえお, アイウエオ], [かきくけこ, カキクケコ]]
↑このような配列で取得する
ということを実現するコードの例です
コード.gsvar SS_ID = "SS_ID";
var SH_ID = SH_ID;
var BASE_URL = "https://docs.google.com/spreadsheets/d/";
var URL = BASE_URL + SS_ID + "/gviz/tq?gid=" + SH_ID + "&tqx=out:json&tq=";
SpreadsheetApp.openById(SS_ID);
function get_public_data() {
var options = null;
data_via_gviz(options);
}
function get_private_data() {
var access_token = get_access_token();
var headers = get_headers(access_token);
var options = get_options(headers);
data_via_gviz(options);
}
function get_access_token() {
var access_token = ScriptApp.getOAuthToken();
return access_token;
}
function get_headers(access_token) {
var headers = {
"Authorization": "Bearer " + access_token
}
return headers;
}
function get_options(headers) {
var options = {
"contentType": "application/json",
"headers": headers,
"muteHttpExceptions": true
}
return options;
}
function data_via_gviz(options) {
var query = encodeURIComponent("SELECT A, B");
var response = UrlFetchApp.fetch(URL + query, options);
var jobj = get_jobj(response);
var array = get_array(jobj);
Logger.log([response, array]);
}
function get_jobj(response) {
var data = response.getContentText();
data = data.split("google.visualization.Query.setResponse(")[1];
data = data.substr(0, data.length - 2);
var jobj = JSON.parse(data);
return jobj;
}
function get_array(jobj) {
var rowlen = jobj["table"]["rows"].length;
var collen = jobj["table"]["cols"].length;
var array = [];
for (var i = 0; i < rowlen; i++) {
var values = [];
for (var j = 0; j < collen; j++) {
values.push(jobj["table"]["rows"][i]["c"][j]["v"]);
}
array.push(values);
}
return array;
}
| 意訳スプレッドシートのID 対象のシートのID BASE_URL URLを作る 「Google ドライブのスプレッドシートの表示と管理」の権限を許可しておかないとprivateの場合にUnauthorizedでデータ取得できないので承認フローを入れる この機能がやること 公開されているシートのデータを取得する optionsにnullを入れて data_via_gviz()に渡す この機能がやること 非公開のシートのデータを取得する get_access_token()からaccess_tokenを取得して get_headers()に渡してheadersを取得して get_options()に渡してoptionsを取得して data_via_gviz()に渡す この機能がやること ScriptApp.getOAuthToken()でaccess_tokenを取得して 返す この機能がやること headersを作成して access_tokenを入れて 返す この機能がやること optionsのオブジェクトを作って contentTypeはapplication/jsonにして headersを入れて muteHttpExceptionsをtrueにして(fetchでエラーが出ても例外を投げない) 返す この機能がやること queryを作って URL+queryとoptionsでfetchして get_jobj()にresponseを渡してjobjに入れて get_array()に渡してarrayに入れて ログに出す この機能がやること 渡されたresponseのテキストを取得して 指定した文字列以降を抜き出して 最後の二文字を消して( ); を消す) JSON解析して 返す この機能がやること 行数を取得して 列数を取得して 結果を入れる配列を用意して 一行ずつ以下を繰り返す valuesの配列を用意して 一列ずつ以下を繰り返す セルの値を取得してvaluesに追加する values(一行分のデータ)をarrayに追加する arrayを返す |
補足
responseはこのようになっているので
/*O_o*/
google.visualization.Query.setResponse({
"version": "0.6",
"reqId": "0",
"status": "ok",
"sig": "1103093093",
"table": {
"cols": [{
"id": "A",
"label": "",
"type": "string"
}, {
"id": "B",
"label": "",
"type": "string"
}],
"rows": [{
"c": [{
"v": "あいうえお"
}, {
"v": "アイウエオ"
}]
}, {
"c": [{
"v": "かきくけこ"
}, {
"v": "カキクケコ"
}]
}]
}
});
|
コード.gs内の以下のコードで
google.visualization.Query.setResponse()内の文字列を抜き出しています
- data = data.split("google.visualization.Query.setResponse(")[1];
- data = data.substr(0, data.length - 2);
range.getValues()で取得する場合
シートIDを指定して.getValues()でデータを取得する例も書いておきます
var SS_ID = "SS_ID";
var SH_ID = SH_ID;
function get_values() {
var ss = SpreadsheetApp.openById(SS_ID);
var sh = get_sheet(ss, SH_ID);
var range = sh.getRange("A1:B2");
var values = range.getValues();
Logger.log(values);
}
function get_sheet(ss, sh_id) {
var shs = ss.getSheets();
for (var i = 0; i < shs.length; i++) {
if (shs[i].getSheetId() == sh_id) {
break;
}
}
var sh = ss.getSheets()[i];
return sh;
}
|
PublicシートとPrivateシートの取得
SS_IDとSH_IDを指定してから
Publicシートの場合は get_public_data()
Privateシートの場合は get_private_data()
をそれぞれ実行するとデータを取得できます
Privateシートのデータの取得にはaccess tokenが必要で
ScriptApp.getOAuthToken() で取得しています
- Webに公開されている(Public)シートのデータを取得する場合
- get_public_data()を実行する
- access_tokenの取得は不要なのでoptionsはnullにして
- data_via_gviz(options)を実行する
- 非公開(Private)シートのデータを取得する場合
- get_private_data()を実行する
- get_access_token()でaccess_tokenを取得して
- get_headers(access_token)に渡して
- get_options(headers)でoptionsを作って
- data_via_gviz(options)に渡して実行する
- SpreadsheetApp.openById(SS_ID)で「Google ドライブのスプレッドシートの表示と管理」の権限を許可するフローを入れてやると取得できるようになる
WHEREを使ってみる
上記コード.gsのdata_via_gviz(options){}内にある
var query = encodeURIComponent("SELECT A, B");
を
var query = encodeURIComponent("SELECT A, B WHERE A = 'あいうえお'");
としてやると
A列が あいうえお のA, B列の値を取得できる
参考
Google Charts Authorization
https://developers.google.com/chart/interactive/docs/spreadsheets#Authorization
Query Language Reference
https://developers.google.com/chart/interactive/docs/querylanguage
google/google-visualization-issues
https://github.com/google/google-visualization-issues/issues/1998
getOAuthToken()
https://developers.google.com/apps-script/reference/script/script-app#getOAuthToken()
Google Charts Authorization
https://developers.google.com/chart/interactive/docs/spreadsheets#Authorization
Query Language Reference
https://developers.google.com/chart/interactive/docs/querylanguage
google/google-visualization-issues
https://github.com/google/google-visualization-issues/issues/1998
getOAuthToken()
https://developers.google.com/apps-script/reference/script/script-app#getOAuthToken()

