web-dev-qa-db-ja.com

Googleフォームの回答シートにデータをインポートする

Googleフォームがいくつかあり、データプレゼンテーション機能(データセットを組み合わせたもの)を活用するために、従来の調査データを回答スプレッドシートにインポートしたいのですが、機能させることができませんでした。

データをインポートしましたが、最後の「ネイティブ」応答の後の行は無視されます。

応答スプレッドシートの最後の応答行の場所に関する隠された情報があるように見えます。

どうすればこれを克服できますか?

5
villares

スプレッドシートは、応答の実際のリポジトリではありません。フォーム自体に関連付けられた応答の「バケット」があります。

データ表示機能は、フォームに接続された応答を使用します。

スクリプトを使用して、Formオブジェクトに追加の応答を追加する必要があります。タイムスタンプは常にフォームに応答を追加するときに使用されるため、元の日付を古い応答とともに保存することはできません。

プロセスは次のように機能します。

   +-------------+
   |Form         |----+
   |-------------|    |
   |Responses    |    |
   |             |    v
   |             |  User
   +-------------+  submits
         ^          form
         |            +
     Saved to         |
         |            |
         |            |
   +--------------+   |
   |   Response   |< -+
   +--------------+
         |
         |
      Copied to
         |
         v
   +-------------+
   |Spreadsheet  |
   |-------------|
   |             |
   |             |
   +-------------+

応答が保存されると、フォームに保存され、スプレッドシートにコピーされます。

別の answer (関連コードを添付)から-フォームに回答を入力するために使用したテスト送信テクニックのようなものを使用できます。スプレッドシートから回答を取得する必要があり、 適切な項目タイプを使用

function testOnSubmit() {
  var answers = [
    ["Sue", "39", "Okay I suppose"],
    ["John", "22", "Great"],
    ["Jane", "45", "yeah no"],
    ["Bob", "33", "Super"]
  ];

  var form = getConnectedForm();
  var items = form.getItems();
  for (var i = 0; i < answers.length; i++) {
    var formResponse = form.createResponse();
    for (var j = 0; j < items.length; j++) {
      var item = items[j];
      var itemResponse = item.asTextItem().createResponse(answers[i][j]);
      formResponse.withItemResponse(itemResponse);
    }
    formResponse.submit();
    Utilities.sleep(500);
  }

}
5
Tom Horwood

これは、履歴データを実際のフォーム応答としてインポートする同様のニーズを解決するために使用できたソリューションです。

コードは最初に作成したフォームを開き、「values」という名前の配列に履歴データを含むスプレッドシートを開きます。 forループは、スプレッドシートの各行を循環し、フォームの各項目に入力してから、完全な応答を送信します。

すべてのデータが1つのタイプである場合、forループを追加してフォームの各項目を追加することにより、コードを簡素化できます。私にとっては、フォームの各アイテムのデータ型が異なっていたため、各アイテムを個別にリストしました。

これはかなり古い記事であることがわかりましたが、私の問題を解決しようとしても何の助けも見つかりませんでした。これが誰かの助けになることを願っています。

function ApendResponses() {
  var form = FormApp.openByUrl('https://docs.google.com/???????');
  var sheet = SpreadsheetApp.openByUrl("https://docs.google.com/???????");
  var rows = sheet.getDataRange();
  var numRows = rows.getNumRows();
  var values = rows.getValues();

  for (var x = 0; x < values.length; x++) {

    var formResponse = form.createResponse();
    var items = form.getItems();

    var row = values[x];

    var formItem = items[0.0].asListItem();   
    var response = formItem.createResponse(row[0]);     
    formResponse.withItemResponse(response);

    var formItem = items[1.0].asListItem();   
    var response = formItem.createResponse(row[1]);     
    formResponse.withItemResponse(response);

    var formItem = items[2.0].asParagraphTextItem();   
    var response = formItem.createResponse(row[2]);     
    formResponse.withItemResponse(response);

    var formItem = items[3.0].asDateTimeItem();   
    var response = formItem.createResponse(row[3]);     
    formResponse.withItemResponse(response);

    var formItem = items[4.0].asDateTimeItem();   
    var response = formItem.createResponse(row[4]);     
    formResponse.withItemResponse(response);

    var formItem = items[5.0].asParagraphTextItem();   
    var response = formItem.createResponse(row[5]);     
    formResponse.withItemResponse(response);

    var formItem = items[6.0].asParagraphTextItem();   
    var response = formItem.createResponse(row[6]);     
    formResponse.withItemResponse(response);

    var formItem = items[7.0].asParagraphTextItem();   
    var response = formItem.createResponse(row[7]);     
    formResponse.withItemResponse(response);

    var formItem = items[8.0].asListItem();   
    var response = formItem.createResponse(row[8]);     
    formResponse.withItemResponse(response);

    var formItem = items[9.0].asParagraphTextItem();   
    var response = formItem.createResponse(row[9]);     
    formResponse.withItemResponse(response);

    formResponse.submit();
    Utilities.sleep(500);

  }

};
5
pasasl

@ Jean-Francoisの回答を Mogsdad と組み合わせて使用​​して、多くの同一のフォームからのデータを1つにマージしました。私のフォームには多くの不要な質問とジャンプセクションがあったため、空の回答にはスキップを追加しました。 30個のアイテムで約1000個の応答を「アップロード」するには、タイムアウトのため、8行目の最初の行を変更するだけで、スクリプトを2回実行する必要がありました。

function FillFormfromSpreadSheet() {
 var ss = SpreadsheetApp.openById('1xxCiWOZSfSWHtIeWA9bEJuI19FwI3TBmGwTlkxxxxxx');//Spreasdsheet ID
 var sheet = ss.getSheetByName("SheetName");
 var form = FormApp.openById('1m1NZ5kB39OqvOvhRKs-BoeU9NWaWAi4Rk40XPxxxxxx');//'Form ID'
 var data = sheet.getDataRange().getValues();  // Data to fill
 var EmptyString = '';
 var items = form.getItems();
  for (var row = 1; row < data.length; row++ ) { //jumps first row, containing headers
    var response = form.createResponse();
    for (var i=0; i<items.length; i++) {//using 'i' to count both data fields and form items
      var resp = data[row][i+1];//jumps first data field containing timestamp
      // Need to treat every type of answer as its specific type.
      if (resp !== EmptyString ) {//jumps the entire procedure for empty datafields, as may occur for non required questions
        switch (items[i].getType()) {//note that data[#][1] corresponds to item[0], as there's no timestamp item!
          case FormApp.ItemType.MULTIPLE_CHOICE:
            item = items[i].asMultipleChoiceItem();
            break;
          case FormApp.ItemType.CHECKBOX:
            item = items[i].asCheckboxItem();
            // In a form submission event, resp is an array, containing CSV strings. Join into 1 string.
            // In spreadsheet, just CSV string. Convert to array of separate choices, ready for createResponse().
            if (typeof resp !== 'string')
              resp = resp.join(',');      // Convert array to CSV
              resp = resp.split(/ *, */);   // Convert CSV to array
              break;
          case FormApp.ItemType.TEXT:
            var item = items[i].asTextItem();
            break;
          case FormApp.ItemType.PARAGRAPH_TEXT: 
            item = items[i].asParagraphTextItem();
            break;
          default:
            item = null;  // Not handling DURATION, GRID, IMAGE, PAGE_BREAK, SCALE, SECTION_HEADER, TIME
            break;
        }
        if (item) {// Add this answer to form
          var respItem = item.createResponse(resp);
          response.withItemResponse(respItem)   
        }
        else Logger.log("Skipping i="+i+", question="+ques+" type:"+type);//skip any other type of response
      }
    }
    response.submit();
    Utilities.sleep(500);
  }
}
4
peppeprof

これは、プロジェクトで使用したスクリプトの提案です。トムがスクリプトを変更して、フィールドに異なる types のデータがある場合(および、私の場合は何もしないセクションヘッダー)を調整するように変更しました。 「スイッチ」と「asタイプアイテム」を使用してトリックを行いますが、誰かがより良い提案を受け取った場合、私はすべて耳です!

@papasiが示唆するように、スプレッドシートからデータを読み取るようにスクリプトを簡単に適合させることもできます。

それが役立つことを願っています。

function testOnSubmit() {
  var answers = [
    ['IT',5,5,4,4,'This is a Comment'],
    ['HR',3,4,5,2,'This is another Comment'],
  ];

  var form = FormApp.openById('1PJ_B.....');
  var items = form.getItems();

  for (var i = 0; i < answers.length; i++) {
    var formResponse = form.createResponse();
    var k=0;
    for (var j = 0; j < items.length; j++) {

      var item;
      switch(items[j].getType()) {
          case FormApp.ItemType.MULTIPLE_CHOICE: item=items[j].asMultipleChoiceItem(); break;
          case FormApp.ItemType.SCALE: item=items[j].asScaleItem(); break;
          case FormApp.ItemType.PARAGRAPH_TEXT: item=items[j].asParagraphTextItem(); break;
         //case FormApp.ItemType.<OTHER_TYPE>: item=items[j].as<OtherType>Item(); break;
          default: 
             Logger.log("#"+(i+1)+":Do nothing for item "+j+" of type "+items[j].getType() ); 
             continue; 
             break;
      }
      Logger.log("#"+(i+1)+": Add answer "+answers[i][k]+" for item "+j+" of type "+items[j].getType());        
      formResponse.withItemResponse(item.createResponse(answers[i][k++]));
    }
    formResponse.submit();

    Utilities.sleep(500);
    }

  }
2

行に追加される情報は、そのフォームがユーザーによって送信された日付と時刻だけだと思います。

おそらく、CSVファイルを作成し、最初の列をある固定日時に設定して、Googleドキュメントにインポートすることができます。

1
Amit Agarwal

さて、手間をかけずにプログラムでGoogleフォームの回答を新しい投稿として送信する方法を作りました。この良い例はどこにも見当たりませんでしたので、必要に応じてサイトにコードを投稿しました。独自の応答を作成したり、スプレッドシートからインポートしたりする必要はありません。

最後のGoogleフォームの応答を新しいフォーム応答として再送信します。ORまた、以前のGoogleフォームの応答をランダムに選択して新しい投稿として再送信する機能も作成しました。面倒なし!

Google Formスクリプトエディタープロジェクトにコピーして貼り付け、デバッガーからいずれかの関数を実行します。楽しい!

これは、このスレッドの元の質問に直接答えるものではありませんが、問題を自分で解決しようとしたときにこの投稿を見つけました。そして、自分でそれを行う方法を考え出そうとするときにこの投稿を頻繁に使用したので、他の人が私と同じようにこの投稿を見つけた場合、ここに私の最終結果を投稿すると役立つと思いました。

http://c2solutions.com.au/submit-response-google-form-using-google-apps-script-made-easy/

// Run this to resubmit your LAST Form response again as a new Form Submission
// You need to go and at least do ONE normal form submission the old school way first :-)
function resubmitLastFormResponseAsNew() {

var [form, loggedTimestamp, thisFormResponses, thisResponse, thisResponseID, thisResponseItems, formEditUrl] = getFormResponsesDetails();

logIt("CALLED resubmitLastFormResponseAsNew");

// Create a form response item
var formResponse = form.createResponse();

// We are going to use just the last response stored in thisResponseItems
// Loop through it and build a form response from the existing form objects
// No fuss required trying to get response types to format them properly
for (var x = 0; x &lt; thisResponseItems.length; x++) {

// Get the last item that was submitted
var response = thisResponseItems[x];

// Respost it back into a the new item
formResponse.withItemResponse(response);
} //END For loop

// Submit the form
formResponse.submit();
}

// Run this to resubmit a random selection from any of your previous form submissions as a new Form Submission
// You need to go and at least do ONE normal form submission the old school way first :-)
// But you are est to go and post a few submission to get a decent selection of randomness
function resubmitRandomFormResponseAsNew() {

var [form, loggedTimestamp, thisFormResponses, thisResponse, thisResponseID, thisResponseItems, formEditUrl] = getFormResponsesDetails();

logIt("CALLED resubmitRandomFormResponseAsNew");

// Pick and random previous submission
var random = randomIntFromInterval(1,thisFormResponses.length);
var thisResponse = thisFormResponses[random];

// Get all the items for this latest response
var thisResponseItems = thisResponse.getItemResponses();

// Create a form response item
var formResponse = form.createResponse();

// We are going to use just the this response stored in thisResponseItems
// Loop through it and build a form response from the existing form objects
// No fuss required trying to get response types to format them properly
for (var x = 0; x &lt; thisResponseItems.length; x++) {

// Get the last item that was submitted
var response = thisResponseItems[x];

// Respost it back into a the new item
formResponse.withItemResponse(response);
} //END For loop

// Submit the form
formResponse.submit();
}

// Generate a random number between 2 numbers
function randomIntFromInterval(min,max)
{
return Math.floor(Math.random()*(max-min+1)+min);
}

// Get the forms response for this submission and its editable URL and return it
function getFormResponsesDetails (formID) {
logIt("CALLED getFormResponsesAndEditableURL WITH " + formID);

var form = FormApp.getActiveForm();
var formID = form.getId();

// Get the form OB
var thisFormOB = FormApp.openById(formID);

// And Array of Objects with all the responses for this form
var thisFormResponses = thisFormOB.getResponses();

// Get an array of all the items (questions and answers and each item details) in the form
//https://developers.google.com/apps-script/reference/forms/item-response#getitem
var thisFormItems = thisFormOB.getItems();

// Get the last response that came through
var thisResponse = thisFormResponses[thisFormResponses.length-1];

// Get the ID for the latest response
var thisResponseID = thisResponse.getId();

// Get all the items for this latest response
var thisResponseItems = thisResponse.getItemResponses();

// get this submitted form's "Timestamp"
var loggedTimestamp = thisResponse.getTimestamp();

// get the url
var formEditUrl = thisResponse.getEditResponseUrl();

return [form, loggedTimestamp, thisFormResponses, thisResponse, thisResponseID, thisResponseItems, formEditUrl];
}
1
Dean Crabb