web-dev-qa-db-fra.com

Importation de données dans une feuille de réponses Google Forms

J'ai quelques formulaires Google et j'aimerais importer des données d'enquêtes traditionnelles dans le tableur de réponses, afin de tirer parti des fonctionnalités de présentation des données (ensemble de données combinées), mais je n'ai pas réussi à le faire fonctionner.

J'ai importé les données, mais les lignes après la dernière réponse "native" sont simplement ignorées.

Il semble y avoir des informations cachées sur l'emplacement de la dernière ligne de réponse dans la feuille de calcul des réponses.

Comment puis-je surmonter cela?

5
villares

La feuille de calcul n'est pas le référentiel réel des réponses. Il y a un "seau" de réponses qui est connecté au formulaire lui-même.

Les fonctionnalités de présentation des données utilisent les réponses liées au formulaire.

Vous devez utiliser un script pour ajouter les réponses supplémentaires à l'objet Form. Vous ne pourrez pas enregistrer les dates d'origine avec les anciennes réponses, car l'horodatage est toujours utilisé lorsque vous ajoutez une réponse au formulaire.

Le processus fonctionne comme ceci:

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

Lorsque la réponse est enregistrée, elle est enregistrée dans le formulaire et copiée dans la feuille de calcul.

D'un autre réponse (code pertinent joint) - vous pouvez utiliser quelque chose comme la technique de soumission de test que j'ai utilisée pour remplir le formulaire avec les réponses. Vous devez obtenir vos réponses à partir de la feuille de calcul et tilisez le type d'élément approprié .

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

Voici la solution que j'ai pu utiliser pour résoudre un besoin similaire d'importer des données historiques sous forme de réponses à des formulaires.

le code ouvre d'abord le formulaire que j'ai créé et la feuille de calcul avec les données historiques du tableau nommé "valeurs". La boucle for parcourt chaque ligne de la feuille de calcul, en remplissant chaque élément du formulaire, puis en soumettant chaque réponse complète.

Si toutes vos données sont d'un seul type, vous pouvez simplifier le code en ajoutant une boucle for pour ajouter chaque élément du formulaire. Pour moi, les types de données pour chaque élément du formulaire étaient différents, j'ai donc répertorié chaque élément séparément.

Je me rends compte que c'est un article assez ancien, mais en essayant de résoudre mon problème, je n'ai trouvé aucune aide. J'espère que cela aidera quelqu'un.

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

J'ai utilisé @ Jean-François answer avec Mogsdad pour accomplir ma tâche: fusionner des données provenant de nombreux formulaires identiques en un seul. J'ai ajouté un saut pour les réponses vides, car mon formulaire comportait de nombreuses questions non obligatoires et sections sautantes. Pour "envoyer" environ 1000 réponses avec 30 éléments, j'ai dû exécuter deux fois le script à cause du délai d'attente, simplement en modifiant la ligne initiale à la ligne 8.

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

Voici ma suggestion pour le script que j'ai utilisé pour mon projet. J'ai modifié le script par Tom pour qu'il s'ajuste lorsque les champs ont différents types de données (et dans mon cas, En-têtes de section où nous ne devrions rien faire). J'ai utilisé un "commutateur" et un "commeTypeItem "pour faire le tour, mais si quelqu'un a une meilleure suggestion, je suis tout ouïe!

Nous pouvons également facilement adapter le script pour lire les données d'une feuille de calcul, comme le suggère @papasi.

J'espère que ça peut aider.

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
Jean-Francois T.

Je pense que la seule information ajoutée à la ligne est la date et l'heure de l'envoi de ce formulaire par l'utilisateur.

Vous pouvez probablement créer un fichier CSV, définir la première colonne à une date précise et l'importer dans Google Docs.

1
Amit Agarwal

D'accord, j'ai créé un moyen de soumettre une réponse à un formulaire Google par programme, en tant que nouvelle publication sans tracas. Je n'ai vu aucun bon exemple de cela nulle part, alors j'ai posté le code sur mon site si vous le voulez. Il n'est pas nécessaire de construire votre propre réponse ou de les importer depuis une feuille de calcul.

Elle soumettra à nouveau votre dernière réponse à Google Form sous forme de nouvelle réponse, OR J'ai également créé une fonction qui sélectionne de manière aléatoire l'une de vos réponses précédentes à Google Form et la soumet à nouveau. Sans tracas!

Il vous suffit de copier et coller dans votre projet d’éditeur de script Google Form et d’exécuter l’une des fonctions de votre débogueur. Prendre plaisir!

Je devrais ajouter que cela ne répond pas directement à la question initiale dans ce fil de discussion, mais j'ai trouvé ce post en essayant de résoudre le problème moi-même. AND a beaucoup utilisé ce message pour trouver un moyen de le faire moi-même; j'ai donc pensé qu'il serait utile pour les autres de poster mon résultat final ici s'ils trouvent ce message aussi, comme je l'ai fait.

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