0
votes

I have a spreadsheet in which I have the form response sheets from a large number of forms (quizzes). As all the forms contain the same format, number and order of questions I want to collect them all into one sheet.

I know this can be done using the query({sheet1!range,sheet2!range...}) But the size of this query would be huge (have over 25 forms!) and it would require me to fiddle around with this formula every time I add a new form.

What i initially investigated was creating a list of sheets in a range and then tried to get arrayformula query to run through that list using indirect. This however did not work and after asking on this forum have been told that that cannot be done.

I was advised to look into scripts and have spent all weekend trying to find a script that can do this. I have however failed.

I need the script to copy the last row of a form response sheet to the bottom of a master sheet. I would like the script to do this to all response sheets (I have a naming format for sheets that would allow the script to easily see which sheets to incorporate). I would imagine I need to use the onSubmit() function but not sure.

1
What have you tried so far? Can you post your code? Check this How to create a Minimal, Complete, and Verifiable example to help you better with your issue.abielita

1 Answers

1
votes

Overview

I don't think that using a on submit trigger is a good idea because there are several forms involved and a large number of responses. By the other hand could be conflicts if several responses are submitted very close. IMHO a better approach is to run the script by demand (manually) or by using a time-driven trigger.

As Google Apps Script execution time should not exceed six minutes1, instead of checking each sheet for new responses I think that a better approach is to clear the master sheet and append all the sheet responses at once. This could work if there will no be notes, comments, custom formats, data validations or data changes applied directly on the master sheet.

Script

Below is a script that joins the content of form responses sheets that are in the same spreadsheet to a sheet named 'Master'. It could be easily adapted, I think.

It's assumed that the spreadsheet only contains form responses sheets and the 'Master' sheet.

/**
 * Joins the data from form responses sheets on a master responses sheet.
 * Assumes that the master sheet has the form response headers and 
 * that there aren't extra columns.
 */

function joinSheetsData() {
  // Initialize loop variables
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheets = ss.getSheets();
  var masterName = 'Master';                             // Change this.
  var masterSheet = ss.getSheetByName(masterName);
  var headers = [masterSheet.getDataRange().getValues()[0]];
  var masterdata = [];

  // Loop to append form responses from all response sheets to one array. 
  for(var i = 0; i < sheets.length; i++){ 
    if(sheets[i].getName() != masterSheet.getName()){
      var data = sheets[i].getDataRange().getValues();
      data.splice(0,1);
      masterdata = append(masterdata,data);
    }
  }
  // Clear the master sheet.
  masterSheet.clear();
  // Add the headers to the master sheet.
  var masterheadersRow = masterSheet.getRange(1, 1, 1,
    masterdata[0].length);
  masterheadersRow.setValues(headers);
  // Send the resulting array to the master sheet.
  var masterdataRange = masterSheet.getRange(2, 1, masterdata.length,
    masterdata[0].length);
  masterdataRange.setValues(masterdata);
}

/*
 * Auxiliary function to append 2D arrays.
 */
function append(a,b){
  for(var i = 0; i<b.length; i++){
    a.push(b[i]);
  }
  return a;
}