構造
- 基本はSPA(作ろうと思えば複数ページも作れるが、GASの範疇を超えている気がする)
- application.htmlという共通ページレイアウトを作り、<?!= ?>でコンポーネントを埋め込む
- vueやvuetifyのSDKを詰め込んだhtmlファイルを分離しておくと、他GASプログラム作成時にも転用でき便利
vueコンポーネント
- GASではhtmlとgsしか扱えない(.vueは使えない)
- vue templateを使えば、あたかもvue componentを使っているように作成できる
サーバーとフロントの設計
GASでアプリ操作時に、スプレッドシートに保存したデータを参照する必要があります。
※通常のvueプログラムならaxiosでサーバーにパラメータやクエリを送ってデータを検索しますが、
APIで社内データを取得できるようにしたらシステム部にしばかれると思う。
方法1. フロント側でhtml作成時に、サーバー側から全データを取得する。
概要
- created時にサーバー側にデータを要求
- サーバー側では、スプレッドシートの全データをオブジェクトを詰めた配列に変換し返す
- フロント側では返されたデータをvue dataに格納する
やめた理由
- 20万以上のデータがあるスプレッドシートのデータを引っ張ってくると、フロント側の呼び出しから、データがフロント側に返されるまで時間がかかる (10秒程度)
- データ元のスプレッドシートはきれいなデータ形式ではない(タイトルが入っていたり、ヘッドが複数行あったり) これを整形するスクリプトはサーバー側に書いていたが、メンテナンスが大変(GASプログラムごとに管理する必要がある)
方法2. フロント側から検索ワードを送り、検索結果を返す
概要
- 検索ワードを詰めたオブジェクトをフロント側からサーバー側に送る →サーバー側ではスプレッドシートのデータを全件取得する →(サーバー側)取得したデータから検索ワードに当たるデータをフィルタリングして、フロント側に返す →フロント側では回答をdataに格納して、vueで表示する
- ページを開けたときにデータをダウンロードする必要がないため、ユーザーはすぐに作業に取りかかれます
- サーバー側とフロント側を分離して開発できるため、開発しやすいです。 (検索ワード→結果表示をサーバー側だけでテストできる)
やめた理由
- 検索ワードを送るまで、表は空白。最初に一覧をドーンと見せて、絞り込むような検索をしたい。
- パソコンがネットにつながって無い時は何も検索できない。
方法3. データをローカルストレージに保存する。
- スプレッドシートのデータをローカルストレージに保存する。
- createdでローカルストレージのデータを引っ張ってきて、オブジェクト形式に変換してvue dataに格納(サーバーにデータ一式をリクエストしない) →体感的にはページを開いたら一瞬で画面にデータが表示されます。
- ユーザーは更新ボタンを押したら、スプレッドシートのデータをローカルストレージにダウンロードできる (月イチくらい。ダウンロードは10秒ほど)
工夫点など
- ローカルストレージに保管できる容量は10MB程度なので、データを小さくする工夫が必要
- 品目だけを載せたテーブル、取引先名だけを載せたテーブルなど、小さいテーブルを複数設けることでデータの重複を防ぐ
- ローカルストレージは文字列でデータを保管する必要がある。JSON形式にするとデータ容量が増えるため、テーブル形式(2次元の配列)で保管する
より便利にする小技
スプレッドシートのデータとオブジェクト形式への加工
- getValues()で取得したスプレッドシートのデータは二次元配列
- このままでは扱いにくいので、各行をオブジェクト形式にした一次元配列に変換して使っています。
- mapとreduceを使えば5行で書けます
google.script.runの非同期処理
- google.script.runは非同期処理なので、サーバー側から返されたパラメーターを使って次のスクリプトを実行するにはwithSuccessHandlerに記述します
- 順番がごちゃごちゃでわかりにくいので、Promiseを返すようにし、async/awaitを使ってスクリプトを書くと読みやすくなる
- 複数のスプレッドシートからデータ取得する時は、Promise.allを使うと並列処理できる
google.script.runでサーバー側の関数を実行する
- google.script.run.サーバー側関数()
- いちいち書くのが面倒なので、以下のような書き方をしたい ["関数1()","関数2()","関数3()"].forEach(ele=>google.script.run.ele)
- サーバー側でevalを使えば、関数名と引数を文字形式で指定して実行できます