2015年11月4日水曜日

Google Spreadsheet - 数式の差分管理

Google App Script のトリガーを使って、Google Drive 上で定期バックアップ


function dump_formulas(gridID, sheetName) {

  // 座標の配列を生成する関数群
  var zip = function(a, b) {
    return a.map(function(x,i){ return [x, b[i]]; });
  };
  var product = function(a, b) {
    return a.map(function(x){ return b.map(function(y){ return y+x; }); });
  };
  var flatten = function(xs) {
    return xs.reduce(function(x,y){ return x.concat(y); }, []);
  };
  var num_range = function(n) {
    return Array(n).join(0).split(0).map(function(_,i){ return i+1; })
  };
  var alpha_range = function(n) {
    var xs = "ZABCDEFGHIJKLMNOPQRSTUVWXY";
    return num_range(n).map(function(x){
      var mod = x % 26,
          pow = x / 26 - (mod ? 0 : 1) | 0;
      return (pow ? xs[pow] : '') + xs[mod];
    });
  };

  // 数式を所得
  var ss = SpreadsheetApp.openById(gridID),
      sheet = ss.getSheetByName(sheetName),
      formulas = sheet.getDataRange().getFormulas();
  
  // 数式に座標を添え、出力形式を整える
  var address = product(num_range(formulas.length), alpha_range(formulas[0].length)),
      source = zip(flatten(address), flatten(formulas)) // [座標, 数式] のペアの配列を生成
        .filter(function(xs){ return xs[1]; }) // 数式のないセルは無視
        .map(function(xs){
          return "// " + xs[0] + "\n\n" + xs[1];
        }).join("\n\n====\n"); // 区切り線で連結

  // 生成日時を行頭へ築城
  var timestamp = Utilities.formatDate(new Date(), 'JST', 'yyyy-MM-dd HH:mm:ss'),
      header = "// " + timestamp + "\n";
  
  return header + source;
}


function backup_formulas() {
  var content = dump_formulas("XXXXXXXX", "Sheet01");

  // ファイル名
  var date = Utilities.formatDate(new Date(), 'JST', 'yyyyMMdd_hhmmss'),
      path = "dump_" + date + ".txt";
  
  // Backupフォルダ内へファイル出力 ※ Backupフォルダが2つ以上ある場合は注意
  var folders = DriveApp.getFoldersByName("Backup");
  if (folders.hasNext()) {
    folders.next().createFile(path, content);
  }
}


  • シートのID/シート名/ファイル・フォルダ名は適宜変更
  • フォルダは予め生成しておきます
  • トリガーに backup_formulas 関数を登録して、定期的な自動バックアップ

実装上の制限

  • alpha_range関数を3桁に対応させてない為、列は A..ZZ までしか扱えません。

0 件のコメント:

コメントを投稿