わたしは食品を買い出しをする際に「買い物リスト」を作ります。今までは物理的なメモ用紙にリストを書いていたのですが、最近はGoogleのSpreadSheetを使うようになりました。スマホ片手にカートを押して買いものをするわけです。
何度かSheetで買い物リストを作成すると、いちいち文字を打つのがめんどくさくなってきました。そこで、チェックボックスをクリックするだけでよいように買い物リストを作るようにしました。
すると、再利用するときに以前のチェックを外さなければいけなくなって、めんどくさく思えました。そこで一気に以前のチェックを外す機能をつけてとりあえず満足のいくようなものになりました。
作成した際に気づいた点などを忘れないうちにまとめておきます
全体像
SpreadSheetのデータをまとめて変更する機能は、GAS/Google App Scriptという言語を使ったスクリプトを作成する必要があるようです。GASはすごく多機能で、SpreadSheetにとどまらず様々なGoogleサービスと連携できるようです。
GASはJavaScriptとすごく良く似た言語仕様を持ちます。私は今でも言語仕様の詳細を知りませんが、JavaScriptだと思えば大体エラーはでません。ビルトインされた各種オブジェクトを呼び出すことで、Googleサービスのデータを操作することができます。例えば現在のシートのセルA5にhello world
と書き込む関数は以下のような感じです:
function sample () {
var r = SpreadsheetApp.getActiveSheet().getRange("A5");
r.setValue("hello world");
}
Googleサービスにアクセスするための SpreadsheetApp
などのオブジェクトの一覧は、Googleのリファレンス を参考にすればよいのですが、量が多いので適当にググったサンプルコードから始めるのがいいのかもしれません。Googleのチュートリアル的なサンプルスクリプト もまた、いきなり読み始めてもそこそこ理解ができます。
さて、GASで定義した関数をSpreadSheetから呼び出すわけですが、スマホアプリではできる機能とできない機能があるようです。例えば、「カスタマイズしたメニューを作成してそこをクリックさせることで関数呼び出しをする」のはブラウザ上からは可能ですが、アプリからは不可能のようです。
そこで、私は「トリガによって関数呼び出しをする」という方法を選びました。前述のスクリーンショットで赤く色づけされたチェックボックスをクリックした時に関数呼び出しをするようにするわけです。トリガに関するリファレンスは、Simple Triggersに記載がありました。編集時にトリガされる関数 onEdit
トリガは、引数としてイベントオブジェクトeを伴い、その e.range
という属性によってどこが変更されたのかがわかります。なので以下のように関数定義をすることで、セルB1のチェックボックスがクリックされたらclearing()を呼び出すことを実現できます:
function onEdit(e) {
var r = e.range;
if (r.getA1Notation() != "B1"){
return;
}
clearing();
}
clearingの実装はまあ、かなりナイーブに作りましたが私の用途ではこれで十分です:
function clearing () {
var dr = SpreadsheetApp.getActiveSheet().getDataRange();
var d = dr.getValues();
for (var i = 0; i < d.length; i++) {
for (var j = 0; j < d[i].length; j++) {
if (d[i][j] === true) {
d[i][j] = false;
}
}
}
dr.setValues(d);
}
以上二つの関数 onEdit, clearing
を実装することで、「特定の箇所のチェックボックスをクリックしたらシート全体のデータを修正する」ことができました。
その他補記
- スクリプトエディタは結構便利でした。構文チェックや補完、デバッグ実行ができるのでWebブラウザ上での開発でも特に苦痛は感じませんでした
- リファレンスのページのHTTPレスポンスが遅すぎてかなりイライラしました
- スマホアプリとWebブラウザでの挙動の違いについて言及したGoogleのドキュメントは見つかりませんでした。適当にググったページで言及していたものの受け売りなので間違ってるかもしれません
- clearing() 実装のなかでトリガ対象であるB1を修正しているので再帰的にトリガが発火するのでは?と思いましたが、スクリプト経由による編集ではトリガは発火しないという仕様があるので大丈夫なようです。