Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
36
Help us understand the problem. What is going on with this article?
@tomboyboy

GASで永続化する方法まとめ(設定や処理結果を保存・読み込みしたい時)

More than 1 year has passed since last update.

はじめに

GoogleAppsScriptで、前回呼び出した時の処理結果を再び利用したいような場合があります。
そのためには、前回の処理結果を外部に保存する処理(永続化)が必要です。
本記事では、GASで永続化を行うための方法を、コードの例とともにまとめます。

シチュエーション例

GASで何らかの事象の発生件数を集計したいという状況を考えます。
今日の発生件数と前日までの発生件数を合計した値を、Loggerに出力することにします。
このために、前日までの発生件数を永続化する必要が生まれました。
下記コードにおける、loadCount 関数および saveCount 関数です。

次節からは、この2つの関数を実装する具体的な方法を考えます。

main.gs
function main() {
  var count_before = loadCount(); // 前日までの発生件数を読み込み
  var count_today = getCountToday();
  var count_sum = count_before + count_today;

  Logger.log(count_sum);
  saveCount(count_sum); // 今日までの発生件数を保存
}

function getCountToday() {
  // 今日の発生件数を取得 今回は仮に乱数で決める
  return Math.floor(Math.random() * 10);
}

function loadCount() {
  // 何らかの方法で永続化したデータを読み込みたい
  return count;
}

function saveCount(count) {
  // 何らかの方法でデータを永続化したい
}

方法1. Properties Service を利用

  • Properties Serviceは、GASのAPIとして用意されている、簡単にデータを永続化する仕組み
  • key, value は全て string として保存される
  • データのスコープは、下記3種類を選択可能:
    • 1つのスクリプト内
    • 1人のユーザー内
    • 1つのドキュメント内(Add-onが導入されているGoogleドキュメント)

コード例

var properties = PropertiesService.getScriptProperties();
//var properties = PropertiesService.getUserProperties();
//var properties = PropertiesService.getDocumentProperties();

function loadCount() {
  var count = properties.getProperty("Count");
  if (!count) return 0;
  return parseInt(count, 10);
}

function saveCount(count) {
  properties.setProperty("Count", count);
}
  • 説明

    • まず PropertiesService.getScriptProperties 関数で、Properties クラスのインスタンスを取得する
      • コードに示したように関数を変えることで、データのスコープを変更することができる
    • 値の読み込みは、Properties.getProperty(key) 関数などを使用できる
      • 値は全て string で返戻される
      • キーが存在しない場合は null が返戻される
    • 値の保存は、Properties.setProperty(key, value) 関数などを使用できる
  • Properties クラスのリファレンスはこちら

方法2. スプレッドシートを利用

  • GASのAPIでスプレッドシートのデータを読み書きすることで、永続化する方法
  • 具体的には:
    1. スプレッドシートA列にキー・B列に値を入力しておく
    2. それをGASの実行開始時に読み込んで辞書として格納する
    3. また、GAS終了時に辞書を再度スプレッドシートに書き戻す
  • 方法1と同じく、キー・値ともに string で保存することになる
    • そのため、一度基盤となるコードを用意してしまえば、ユーザー側は方法1と同じように利用可能
  • スプレッドシートの例
    • 保存されているキー・値を表で確認できるので、その点ではProperties serviceよりも便利
    • また、スプレッドシートはセルごとに権限を指定できるので、複数人で設定ファイルを共有する際も役立つ

コード例

抜粋版
var settings = readSettings();

function readSettings() {
  var key = fetchListColumn("Settings", "B");
  var value = fetchListColumn("Settings", "C");
  var settings = {};
  for (var i=0; i<key.length; i++) {
    settings[key[i]] = value[i];
  }
  return settings;
}

function writeSettings(settings) {
  var keys = Object.keys(settings);
  var num = keys.length;
  var values = Array(num);
  for (var i=0; i<num;i++){
    values[i] = settings[keys[i]];
  }
  var content = [keys, values];
  content = transpose(content);

  var range = Utilities.formatString("B1:C%d", num);
  var sheet = ss.getSheetByName("Settings");
  sheet.getRange(range).setValues(content);
}

function loadCount() {
  var value = settings["Count"];
  if (!value) return 0;
  return parseInt(value, 10);
}

function saveCount(count) {
  settings["Count"] = count;
  writeSettings(settings);
}
  • 説明
    • 実行開始時にスプレッドシートからデータを取得し、key-valueペアを settings 辞書に格納する
    • 以後はそれを読み書きすることで、永続化されたデータにアクセスすることが可能
  • スプレッドシートの扱い周りのコードはやや長いので、Gistを参照
  • writeSettings 関数はスプレッドシートにアクセスするという少し重い処理
    • 従って、GAS終了時に1回だけ呼び出すという形も良い

方法3. Google Driveを利用

  • Google Driveにjsonを保存して、それを読み書きする方法
  • JSON.parse を使って値を読み込むので、数値は自動で適当な型に変換されて読み込まれる
    • このため、parseInt などの処理が不要になる
  • ファイルとして保存されるので、ドライブをローカルと同期すれば、さらにgitなどで管理することも可能

コード例

※注意:下記コードは既にドライブに sample.json というファイルが存在した場合、不可逆に上書きします

抜粋版
var jsonName = "sample.json";
var settings = readJson(jsonName);

function readJson() {
  var file = getFile(jsonName);
  var content = file.getBlob().getDataAsString();
  if (!content) return {};
  var json = JSON.parse(content);
  return json;
}

function writeJson() {
  var content = JSON.stringify(settings);
  var file = getFile(jsonName);
  file.setContent(content);
}

function loadCount() {
  var count = settings["Count"];
  if (!count) return 0;
  return count;
}

function saveCount(count) {
  settings["Count"] = count;
  writeJson();
}
  • 説明
    • 実行開始時にドライブからjsonファイルを取得し、key-valueペアを settings 辞書に格納する
    • 以後はそれを読み書きすることで、永続化されたデータにアクセスすることが可能
  • ドライブ周りのコードはGistを参照
  • こちらについても方法2と同じく、writeJson 関数はドライブにアクセスするので、GAS終了時に1回だけ呼び出すという形も良い

まとめ

  • GASで永続化する方法について、3つ紹介しました
  • 各特徴を下表にまとめます
  • それぞれメリット・デメリットを考慮して、ケースバイケースで使い分けると良いでしょう
手軽さ 確認しやすさ 管理しやすさ
Properties Service ×
Spread sheet
Drive
36
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
36
Help us understand the problem. What is going on with this article?