pslaboが試したことの記録

はてなダイヤリーからはてなブログに引っ越してきました

この日記は現在実行中の減量記録を含む個人的なメモとして始めましたが、最近はコンピュータやガジェット、ハック、セキュリティネタのほうがメインになっております。

はてなダイヤリー時代はカテゴリ分けが適当だったのですが、これはそのうち直します。


Google Form の回答結果を記録する Google SpreadSheet に、回答結果の再編集用URLを差し込む

Google Form と Google Spreadsheet の連携は非常に便利なのですけど、Form の再編集用URLを Spreadsheet に残しておきたいケースって案外あるような気がします。

たとえば特定の定型データの入力インタフェースとして Google Form を使用しつつ、そのデータの修正も Google Form で行いたい、みたいなケースです。Spreadsheet を直接編集してもよいのですが、これは自由度が高すぎるので本来修正したいデータとは異なるデータを意図せずに改変してしまうリスクがあります。ならば Spreadsheet は原則として全員に閲覧だけの権限を割り振っておき、値の変更は Google Form の再編集用URLから行ってもらうようにしたほうが安全に運用できます。


ですが Google Form の標準の機能では再編集用のURLを Spreadsheet に書き出してはくれません。このため、この機能を代わりに Google Apps Script で実装してみました。

この処理では注意点が1点だけあります。

  • 再編集用のURLはA列に記録するように実装していますので、Form との紐づけがなされたシートに対して、A列に空列を挿入しておく必要があります。Form で入力される項目を増やすと、列の右方向に新しい項目が追加されていきます。そのときに Form 経由の入力値と Form 以外での入力値が混じるのは非常に気持ちが悪いです。だから Form 以外の入力値は、できるだけ左側の列に押し込んでおきたいわけです。このようにすれば、すべてのケースでA列は再編集用URLになるわけですね。


実際に試作した実装は以下のとおりです。これをフォーム送信時のイベントトリガーに割り当てればOKです。

類似の実装はいろいろ試行してみたのですが、たぶんこれが最小の実装ではないかと思います。この実装で唯一美しくないのは getSheetByName にシート名がハードコーディングされていることですね。GAS のリファレンスを一通り見たのですけど、これをハードコーディング以外で取得する方法だけが分からない。何か方法はないものか。。。

// 再編集用URLは A 列( = 1)に差し込む。
var colEditURL = 1; 

/*
 * フォームの送信時に、紐づけ済みのスプレッドシートに対して再編集用のURLを付与する処理。
 */
function onSubmit(e) {
  var response           = e.response;
  var formID             = e.source.getId();
  var destinationSheetID = e.source.getDestinationId();
  var sheet              = SpreadsheetApp.openById(destinationSheetID).getSheetByName('フォームの回答 1');

  // シート最終行の再編集用URLが記入済みならば処理を中断する。
  if ( sheet.getRange( sheet.getLastRow(), colEditURL ).getValue() != "" ) {
    return;
  }
  
  // シートの最終行のA列に再編集用のURLを追加します。
 sheet.getRange( sheet.getLastRow(), colEditURL ).setValue( response.getEditResponseUrl() );
  
  SpreadsheetApp.flush();
}