業務をしている中で、定期的にバックアップを取りたいことってありますよね。
スプレッドシート(以降スプシ)は版で管理するのもありですが、業務都合で別スプシファイルにしたいケースもあります。
大体はファイルをコピーすれば済むのですが、IMPORTRANGE関数など、データ参照をしている関数を使っている場合はスプシを複製しても関数ごとコピーしてしまいます。
でも必要なのは「バックアップ作成時点の値を保持すること」です。
そこでどう対処すれば良いか検討しました。
目次
複製したスプシに値を上書きするしかなかった
さっそく結論ですが、2022年7月時点で私が調べたところ、スプシを複製した後、IMPORTRANGEの出力データをそのまま値を上書きするという結論に至りました。
この方法で書式等は保持しつつ、関数を出力結果の値にします。
同一スプシであれば他にもやりようはあったのですが、バックアップの別スプシとする場合はこれがベターという結論です。
実際に作成したコード
実際に私が実装した関数を記載しておきます。
あとはこの関数を呼び出す関数を作って、それをトリガーで呼び出すようにしてください。
/**
* backupData
* @param orgSSId: コピー元となるスプレッドシートのID
* @param destination: コピー先となるフォルダのID
*/
function backupData(orgSSId, destination){
// 元スプシのIDからスプレッドシート・ファイルを取得
const orgSS = SpreadSheetApp.openById(orgSSId)
const orgFile = DriveApp.getFileById(orgSSId)
// バックアップの保存先フォルダを取得
const folder = DriveApp.getFolderById(destination)
// 複製ファイルを生成。名前は「yyyy-MM-dd_元ファイル名」の形式
let baFile = orgFile.makeCopy(Utilities.formatDate(new Date(), 'JST', 'yyyy-MM-dd') + '_' + orgFile.getName(), folder)
//ここから現時点の値を上書きする処理
//バックアップのスプシを取得
let baSS = SpreadSheetApp.openById(baFile.getId())
//元・バックアップそれぞれのシート情報を取得
let orgSheets = orgSS.getSheets()
let baSheets = baSS.getSheets()
//シートの数だけ値上書きを繰り返す
for(var i=0; i < orgSheets.length; i++){
let data = orgSheets[i].getDataRange().getValues()
let numColumn = orgSheets[i].getLastColumn()
baSheets[i].getRange(1, 1, data.length, numColumn).setValues(data)
}
}
注意点
値を上書きする際は元シートのデータを参照するようにしましょう。
理由としては以下があげられます
- IMPORTRANGEはアクセス許可しないと参照できない
- flush()等をしないと複製ファイルの値が不安定になっている可能性がある
2は元スプシのデータ量が多いと起きるかもしれません。
まとめ
最終的に原始的なやり方になりましたが、これで無事バックアップが取れるようになりました。
事務作業の多い部署だとこういう作業が必要になることが多いので、同じ境遇にあった方はぜひ参考にしてください。
コメント