Search code examples
google-apps-scriptgoogle-sheetsgoogle-forms

Google form to create two rows based on a question response


I am creating a google form to capture data from multiple users. This form has 13 fields. 3 of the form fields are drop down which are populating data from a sheet. This part of the code is completed. But I got struck with the following scenario.

One of the fields captures instance details (production, UAT) and has checkbox option. I thought I would be able to create two rows in the response sheet when instance field has select on two check boxes but learnt that’s not how google form works. So I am looking for a scripting option to do the following.

  1. When the user select PRD and UAT for the instance, two rows to be created in the form response sheet on when the form is created.
  2. The data for the new rows created in #1 will remain the same for the two rows expect for the column instance which will adopt the checkbox value from the form in the respective rows.
  3. If only one option is selected then only one row is added to the response sheet

My experience in google app scripting or Java is very limited. With my limited knowledge I was able to get the responses from the form but not sure how to create an additional row when the condition is met (as mentioned above). Taking one step at a time to understand the form architecture

Code 1: This is to get the title, index and type of the fields in the form. So I know some information of the form (still learning)

function testgetFormDetails() 
{
  var form = FormApp.getActiveForm();
  var items = form.getItems();
  for (var i in items) 
  { 
    Logger.log(items[i].getTitle() +', ID - '+ 
               items[i].getId() +', Type - ' + 
               items[i].getType() +' , Form Index - '+ 
               items[i].getIndex());
  }
} 

Following is the execution log

**Execution log**
5:49:38 PM  Notice  Execution started
5:49:39 PM  Info    Business Group, ID - 286404828, Type - CHECKBOX , Form Index - 0
5:49:39 PM  Info    Instance, ID - 1043278952, Type - CHECKBOX , Form Index - 1
5:49:40 PM  Notice  Execution completed

Code 2: Get responses for the questions (small progress)

function getResponseForInstance() 
{
  var formResponses = FormApp.getActiveForm().getResponses();
  Logger.log(formResponses.length);
  for (var i = 0; i < formResponses.length; i++) 
  {
    var formResponse = formResponses[i];
    var itemResponses = formResponse.getItemResponses();
    for (var j = 0; j < itemResponses.length; j++) 
      {
        var itemResponse = itemResponses[j];
        var lookfor = 'UAT,PRD'
          if(itemResponse.getResponse() == lookfor )
            {
              Logger.log('Question:' + itemResponse.getItem().getTitle() + ' Response:' + itemResponse.getResponse() ) 
            }
      }
  }
}

The execution log shows me the row number, question and the response

**Execution log**
8:22:18 PM  Info    Question:Instance Response:UAT,PRD
8:22:18 PM  Info    Question:Instance Response:UAT,PRD

Now I have to marry both to create an additional row in the response spreadsheet and have been racking my brains on this. All I know atm is the **Logger.Log()** line will be replaced by additional code to add 2 rows when the condition is met.

Any help on this will be very much appreciated.

Look forward to your support and guidance.

Adding example screenshots per @Jose Vasquez Sample Form

enter image description here

Actual Form Response enter image description here

Expected Response - row two has been split into 2 row with column data in C2 is parsed into PRD and UAT per row and the reminder of the data remains the same for line 2 and line 3

Expected Response'

OnFormSubmit Function results enter image description here

Thanks Al


Solution

  • You can split into different rows by filtering afterwards

    Here's my approach (No triggers, only run and process all the current responses):

    function processResponses() {
      var ss = SpreadsheetApp.openById("SPREADSHEET_ID");
      var sheet = ss.getSheetByName("SHEET_NAME");
      const formResponses = FormApp.getActiveForm().getResponses();
    
      for (var i = 0; i < formResponses.length; i++) {
        var formResponse = formResponses[i];
        var itemResponses = formResponse.getItemResponses();
        
        // Add responses comma-separated included
        var rowData = itemResponses.map(item => item.getResponse().toString());
        rowData.splice(0, 0, formResponse.getTimestamp()); // Timestamp
    
        // Split into different rows afterwards
        if (rowData[2].includes(',')) {
          rowData[2].split(',').forEach(instanceName => {
            let tmpRow = rowData.map(data => data);
            tmpRow[2] = instanceName;
            sheet.appendRow(tmpRow); // Append to the sheet
          });
        } else {
          sheet.appendRow(rowData); // Append to the sheet
        }
      }
    }
    

    First of all open the Spreadsheet where you'll store your responses. Having done that, iterate through your responses as you were already doing and then add all of your responses including the timestamp for each form response.

    After adding the response data into rowData you can evaluate if the Instance Column (column 2 or Column C) includes a comma. If so, simply split this field by this character and then iterate through this data in order to append a new row into your sheet for each "instance".

    On Form Submit trigger (keep in mind that you have to install it)

    Retrieve the response from the Event Object.

    function onFormSubmit(e) {
      var ss = SpreadsheetApp.openById("SPREADSHEET_ID");
      var sheet = ss.getSheetByName("SHEET_NAME");
      // Form Response retrieved from the event object
      const formResponse = e.response;
      var itemResponses = formResponse.getItemResponses();
      
      // Add responses comma-separated included
      var rowData = itemResponses.map(item => item.getResponse().toString());
      rowData.splice(0, 0, formResponse.getTimestamp());
    
      // Split into different rows afterwards
      if (rowData[2].includes(',')) {
        rowData[2].split(',').forEach(instanceName => {
          let tmpRow = rowData.map(data => data);
          tmpRow[2] = instanceName;
          sheet.appendRow(tmpRow); // Append to the sheet
        });
      } else {
        sheet.appendRow(rowData); // Append to the sheet
      }
    }
    

    References