2
votes

Shouldn't FormResponse have a remove or delete response method? https://developers.google.com/apps-script/reference/forms/form-response

Is it there and I'm just missing it in the docs?

I'm talking about Responses here not Items.

4

4 Answers

4
votes

Nope, not there. And no external API to fill the gap.

So here's a crazy idea.

You could write a script that gets all the responses, calls deleteAllResponses(), then writes back all but the one(s) you want deleted. You'd then have summary info that reflects the responses you care about, but you'd have lost the submission dates (...which you could add as non-form data in a spreadsheet), and submitter UserID (in Apps Domains only, and again you could retain it outside the form).

Whether or not the compromises are acceptable depend on what your intended use of the form data is.

Code

This is a forms-contained script with a simple menu & UI, which will delete indicated responses. The content of deleted responses are logged.

/**
 * Adds a custom menu to the active form, containing a single menu item for
 * invoking deleteResponsesUI() specified below.
 */
function onOpen() {
  FormApp.getUi()
      .createMenu('My Menu')
      .addItem('Delete response(s)', 'deleteResponsesUI')
      .addToUi();
}

/**
 * UI for Forms function, deleteResponses().
 */
function deleteResponsesUI() {
  var ui = FormApp.getUi();
  var response = ui.prompt("Delete Response(s)",
                           "List of resonse #s to delete, separated by commas",
                           ui.ButtonSet.OK_CANCEL);
  if (response.getSelectedButton() == ui.Button.OK) {
    var deleteCSV = response.getResponseText();
    var numDeleted = deleteResponses(deleteCSV.split(/ *, */));
    ui.alert("Deleted "+numDeleted+" responses.", ui.ButtonSet.OK);
  }
}

/**
 * Deletes the indicated response(s) from the form.
 * CAVEAT: Timestamps for all remaining responses will be changed.
 * Deleted responses are logged, but cannot be recovered.
 *
 * @parameter {Number or Number[]}   Reponse(s) to be deleted, 0-indexed.
 *
 * @returns {Number}                 Number of responses that were deleted.
 */
function deleteResponses(trash) {
  if (!trash) throw new Error( "Missing parameter(s)" );
  Logger.log(JSON.stringify(trash))
  if (!Array.isArray(trash)) trash = [trash];    // If we didn't get an array, fix it

  var form = FormApp.getActiveForm();
  var responses = form.getResponses();

  // Really feels like we should ask "ARE YOU REALLY, REALLY SURE?"
  form.deleteAllResponses();

  var numDeleted = 0;
  for (var i = 0; i < responses.length; i++) {
    if ( trash.indexOf(i.toString()) !== -1 ) {
      // This response to be deleted
      Logger.log( "Deleted response: " + JSON.stringify(itemizeResponse(responses[i] )) )
      numDeleted++
    }
    else {
      // This response to be kept
      var newResponse = form.createResponse();
      var itemResponses = responses[i].getItemResponses();
      for (var j = 0; j < itemResponses.length; j++) {
        newResponse.withItemResponse(itemResponses[j]);
      }
      newResponse.submit();
    }
  }
  return numDeleted
}

/**
 * Returns item responses as a javascript object (name/value pairs).
 *
 * @param {Response}     Form Response object
 *
 * @returns              Simple object with all item responses + timestamp
 */
function itemizeResponse(response) {
  if (!response) throw new Error( "Missing parameter(s)" );

  var itemResponses = response.getItemResponses();
  var itemizedResponse = {"Timestamp":response.getTimestamp()};

  for (var j = 0; j < itemResponses.length; j++) {
    itemizedResponse[itemResponses[j].getItem().getTitle()] = itemResponses[j].getResponse();
  }
  return itemizedResponse;
}
3
votes

@james-ferreira

New Google Forms allows you to delete even individual responses from within a Google Form itself without the need of a script.
The answer that this wasn't possible by @mogsdad and @john was true until very recently.

--This is now possible on the New Google Forms--

Google announcement on the 10th of February 2016. (New Google Forms is now the default option)

Delete ALL of the responses: Delete ALL responses

Delete individual responses: Delete Individual

To delete individual responses you click on the "Responses" tab and choose "Individual". You locate the record you wish to delete and click on the trash can icon to delete that individual response.
Make a note however that the response/s will NOT be deleted from the connected to the form spreadsheet.

3
votes

It is now possible by script:

To delete a response you need the id of the response you wish to delete:

FormApp.getActiveForm().deleteResponse(responseId) 

note: you may also get the form with openById

FormApp.openById(form_id).deleteResponse(responseId) 

ref: https://developers.google.com/apps-script/reference/forms/form#deleteresponseresponseid

note: the response is permanently removed from both the summary and individual responses.

1
votes

You can delete all responses from a form using deleteAllResponses(), but not individual responses. You can't even delete individual responses manually. If your form responses are directed to a spreadsheet, you use the Spreadsheet Service to select and delete individual responses there.