1. ホーム
  2. google-apps-script

googleスプレッドシートのデータを使って、googleフォームに「プリフィル」することは可能でしょうか?

2023-11-21 16:48:22

質問

Google スプレッドシートからの特定のデータで Google フォームを「事前入力」する方法を探しています。フォームには全員に対して同じ「標準」の質問がありますが、最初の2つの質問のデータは、既存のgoogleスプレッドシートから固有のデータで「事前充填」されます。このデータは、既存のスプレッドシート内の電子メールアドレスに基づいて一意になります。

ソーススプレッドシートの例

Col 1       Col 2        Col 3 
email       name         birthday  
@mike       Mike Jones   May 9th 1975  
@jim        Jim Smith    April 19th 1985


フォーム例1

質問1 - データがあらかじめ入力されている (マイク・ジョーンズ) googleスプレッドシートからのデータです。

質問2 - データを事前に入力する (1975年5月9日) をgoogleスプレッドシートから取得しました。

質問3 - 空白 (ユーザーの回答待ち)

質問4 - 空白 (ユーザーの回答待ち)


フォーム例2

質問1 - データがあらかじめ入力されている (ジム・スミス) googleスプレッドシートからのデータです。

質問2 - データを事前に入力する (1985年4月19日) をgoogleスプレッドシートから取得しました。

質問3 - 空白 (ユーザーの回答待ち)

質問4 - 空白 (ユーザーの回答待ち)


これが可能かどうか、誰か知っていますか?もしそうなら、どんな助けや指示でも大いに感謝します。

事前にありがとうございます。

トッド

どのように解決するのですか?

で説明したように、フォームエディタ内からあらかじめ入力されたフォームの URL を作成することができます。 のドキュメントを参照してください。 . 例えばこのようなURLができあがります。

https://docs.google.com/forms/d/--form-id--/viewform?entry.726721210=Mike+Jones&entry.787184751=1975-05-09&entry.1381372492&entry.960923899

buildUrls()

この例では、質問1、"Name"は、IDが 726721210 であり、質問2、誕生日、は 787184751 . 質問3と4は空白です。

UIを通じて提供されるものをテンプレート化することで、このように事前入力されたURLを生成することができます。

function buildUrls() {
  var template = "https://docs.google.com/forms/d/--form-id--/viewform?entry.726721210=##Name##&entry.787184751=##Birthday##&entry.1381372492&entry.960923899";
  var ss = SpreadsheetApp.getActive().getSheetByName("Sheet1");  // Email, Name, Birthday
  var data = ss.getDataRange().getValues();

  // Skip headers, then build URLs for each row in Sheet1.
  for (var i = 1; i < data.length; i++ ) {
    var url = template.replace('##Name##',escape(data[i][1]))
                      .replace('##Birthday##',data[i][2].yyyymmdd());  // see yyyymmdd below
    Logger.log(url);  // You could do something more useful here.
  }
};

これは十分に効果的です。あらかじめ入力されたURLを各人にメールで送れば、いくつかの質問がすでに入力されているはずです。

betterBuildUrls()

力技でテンプレートを作成する代わりに、プログラム的にそれを組み合わせることができます。これは、テンプレートを変更することを忘れることなく、コードを再利用できるという利点があります。

フォームの各質問は項目です。この例では、フォームにはあなたが説明したように4つの質問しかないと仮定します。項目 [0] は "Name"です。 [1] は"Birthday"といった具合になります。

フォームの応答を作成することができますが、これは送信しません。その代わりに、フォームを部分的に完成させて、事前に入力されたフォームの URL を取得するだけにします。Forms APIは各項目のデータ型を理解するので、日付や他の型の文字列フォーマットの操作を避けることができ、コードをいくらか簡略化することができます。

( EDITです。 には、より一般的なバージョンとして Google フォームのチェックボックスをプリフィルする方法は? )

/**
 * Use Form API to generate pre-filled form URLs
 */
function betterBuildUrls() {
  var ss = SpreadsheetApp.getActive();
  var sheet = ss.getSheetByName("Sheet1");
  var data = ss.getDataRange().getValues();  // Data for pre-fill

  var formUrl = ss.getFormUrl();             // Use form attached to sheet
  var form = FormApp.openByUrl(formUrl);
  var items = form.getItems();

  // Skip headers, then build URLs for each row in Sheet1.
  for (var i = 1; i < data.length; i++ ) {
    // Create a form response object, and prefill it
    var formResponse = form.createResponse();

    // Prefill Name
    var formItem = items[0].asTextItem();
    var response = formItem.createResponse(data[i][1]);
    formResponse.withItemResponse(response);

    // Prefill Birthday
    formItem = items[1].asDateItem();
    response = formItem.createResponse(data[i][2]);
    formResponse.withItemResponse(response);

    // Get prefilled form URL
    var url = formResponse.toPrefilledUrl();
    Logger.log(url);  // You could do something more useful here.
  }
};


yymmdd 機能

プレフィルドフォームのURLの日付項目は、このフォーマットであることが期待されます。 yyyy-mm-dd . このヘルパー関数は、変換を処理するための新しいメソッドでDateオブジェクトを拡張します。

スプレッドシートから日付を読み込む場合、データのフォーマットが日付として認識できる限り、最終的にはjavascriptのDateオブジェクトを使用することになります。(あなたの例は認識できないので、代わりに May 9th 1975 の代わりに 5/9/1975 .)

// From http://blog.justin.kelly.org.au/simple-javascript-function-to-format-the-date-as-yyyy-mm-dd/
Date.prototype.yyyymmdd = function() {
  var yyyy = this.getFullYear().toString();                                    
  var mm = (this.getMonth()+1).toString(); // getMonth() is zero-based         
  var dd  = this.getDate().toString();             

  return yyyy + '-' + (mm[1]?mm:"0"+mm[0]) + '-' + (dd[1]?dd:"0"+dd[0]);
};