¿Puedo agregar un campo de autoincremento a una hoja de cálculo de Google basada en un formulario de Google?

20

¿Es posible en Google Forms dar un valor único a cada fila que inserta en la hoja de cálculo y en la marca de tiempo?

Toby Allen
fuente
La marca de tiempo AFAIK se agrega automáticamente cuando crea un formulario. Cuando mira dentro de las columnas de la hoja de cálculo, la primera suele tener una marca de tiempo (a menos que la elimine por alguna razón y realmente no sé qué sucede si hace eso)
Robert Koritnik
Supongo que algo ha cambiado desde que se dio esta respuesta porque después de crear el disparador y agregar el código al script, no sucede nada cuando se envía el formulario. ¿Alguien tiene algún consejo para que las soluciones anteriores funcionen en la nueva versión de Google Sheeth
User3255228

Respuestas:

11

Puede hacerlo agregando un activador de secuencia de comandos.

Supongamos que su formulario actual tiene dos columnas Timestampy la respuesta a una pregunta. Por lo tanto, actualmente tiene las columnas A y B con datos. Supongamos que desea que la columna C tenga su número de incremento automático.

Primero debes ir a Tools > Script Editor

En la ventana Editor de guiones, ingrese el siguiente guión:

function onFormSubmit(e) {

var sheet = SpreadsheetApp.getActiveSheet();
var row =  SpreadsheetApp.getActiveSheet().getLastRow();

sheet.getRange(row,3).setValue(row);


}

Guarde el script y luego vaya al Triggersmenú y seleccioneCurrent script's triggers

Rellene los menús desplegables de la siguiente manera:

Desencadenadores de Google Script

Hacer clic Save

A continuación, guarde y cierre la ventana de Google App Script.

Ahora, cuando se envíe su formulario, completará el número de fila en la columna C junto con los datos que se han enviado a través de su formulario.

Si desea cambiar la columna en la que se guarda el número de fila, debe cambiar esta línea del script:

sheet.getRange(row,3).setValue(row);

y cambie el valor 3 al número de índice de columna correspondiente.

codingbadger
fuente
¿Es posible usar este script pero necesito un número único para que si alguna vez borro o agrego una fila no lo estropeará? Ejemplo: Tengo ID o fila 1, 2, 3, 4, 5, 6 pero elimino manualmente 5 después de que un formulario de envío de ID 6 cambie a la línea 5, por lo que el próximo ID de envío de formulario será 6 nuevamente. Entonces, ¿es posible usar la marca de tiempo y hacer un número único de auto-incremento?
Aún mejor, ahora uso esto para hacer una solicitud de obtención de una url que controlo con todos los datos y ponerla directamente en mi aplicación
Toby Allen
7

Además de la excelente respuesta de Barry, si desea poder eliminar filas y mantener una identificación única, puede tener una celda estática que mantenga un conteo. Luego puede usar este número e incrementarlo en cada nueva entrada a la tabla.

Entonces, la modificación sería mantener un número en algún lugar de su hoja de cálculo ('M1' en el código a continuación) y modificar el código para que se vea así:

function onFormSubmit(e) 
{
   var sheet = SpreadsheetApp.getActiveSheet();
   var row =  SpreadsheetApp.getActiveSheet().getLastRow();

   var bugCount = sheet.getRange("M1").getValue();
   bugCount++;

   sheet.getRange(row,1).setValue(bugCount);
   sheet.getRange("M1").setValue(bugCount);
}

Nuevamente, cambie la segunda última línea para cambiar dónde se ubica su ID.

Danny Parker
fuente
He aplicado esto, pero esto no tiene éxito en el caso de eliminar la fila entre filas de datos. por lo tanto, debe actualizar el valor oculto cada vez que se elimine la fila
No es necesario actualizar el número al eliminarlo si solo se necesitan ID únicos (según la pregunta original). Si disminuye el valor de la eliminación, obtendrá ID duplicados.
Danny Parker
7

Sobre la base de ambas respuestas anteriores (de Barry y Danny):

Suponiendo que la columna ID es la columna A. Elija una celda "Next ID" y configúrela con la siguiente fórmula (suponiendo que esté en "P1"):

=MAX(A:A)+1

Cree una secuencia de comandos con el editor de secuencias de comandos en el menú "Herramientas" y pegue lo siguiente:

function onFormSubmit(e) {
  // Get the active sheet
  var sheet = SpreadsheetApp.getActiveSheet();
  // Get the active row
  var row = sheet.getActiveCell().getRowIndex();
  // Get the next ID value.  NOTE: This cell should be set to: =MAX(A:A)+1
  var id = sheet.getRange("P1").getValue();
  // Check of ID column is empty
  if (sheet.getRange(row, 1).getValue() == "") {
    // Set new ID value
    sheet.getRange(row, 1).setValue(id);
  }
}

Agregue un activador de script utilizando el menú "Activadores" en el editor de script: ingrese la descripción de la imagen aquí

uno mismo
fuente
4

Además de las respuestas anteriores: esta solución no requiere una celda de hoja de cálculo adicional.

Puede usar los controladores de eventos incorporados para enviar el formulario para obtener una identificación única. Debido a que la hoja de cálculo es solo el destino del formulario, eliminar una fila en realidad no elimina la respuesta. Con eso en mente...

EDITAR: se eliminó la necesidad de identificación y se trataron los problemas de formato de fecha.

/**
* This function extracts the relevant properties from the event handler,
* then uses them to get the uniqueID and record the response
* @param {Object} e The event parameter for form submission to a spreadsheet;
*     e has the following properties values, range, namedValues
*/

function onFormSubmit(e) {
  var uniqueID = getUniqueID(e.values);
  recordResponseID(e.range, uniqueID);
}

/**
* Records the unique ID for this response to the correct cell.
* @param  {Object} eventRange Range in which the response is written
* @param  {Integer} uniqueID   Unique id for this range
*/

function recordResponseID(eventRange, uniqueID) {
  var row = eventRange.getRow();
  var column = eventRange.getLastColumn() + 1;
  var sheet = SpreadsheetApp.getActiveSheet();
  sheet.getRange(row, column).setValue(uniqueID);

}
/**
* A shortcut function to get the form that is connected to this spreadsheet
* @return {Form}          The form associated with this spreadsheet.
**/

function getConnectedForm() {
  var formUrl = SpreadsheetApp.getActiveSpreadsheet().getFormUrl();
  var form =  FormApp.openByUrl(formUrl);
  return form;
}

/**
* Returns a unique ID for the response, by finding the actual Response that
* has the same properties.
* @param  {Array} eventValues Array of: Timestamp_string, form_response_value...
* @return {Integer}             The unique id (by 1 based array position) of the Response
*/

function getUniqueID(eventValues) {
  var isMatch = false;
  var eventItems = eventValues.slice(1);

  var responses = getConnectedForm().getResponses();
  //loop backwards through responses (latest is most likely)
  for (var i = responses.length - 1; i > -1; i--) {
    var responseItems = responses[i].getItemResponses();
    //check each value matches

    for (var j = 0; j < responseItems.length; j++) {
      if (responseItems[j].getResponse() !== eventItems[j]) {
        break;
      }
      isMatch = true;
    }
    if (isMatch) {
      return i + 1;
    }
  }
}

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);
  }

}
Tom Horwood
fuente
No entiendo esto. ¿Cómo se llama esto cuando se envía el formulario?
CodyBugstein
@ Imray: creo que esto debe ser un script en la hoja de cálculo. Puede configurar un activador en la hoja de cálculo para ejecutar una función cuando se envía el formulario. Agregaré ese hecho a esta respuesta si funciona (necesito verificarlo).
Gary S.
1
La getUniqueIDfunción se puede simplificar enormemente simplemente devolviendo la longitud de las respuestas hasta la fecha (eso es lo que la lógica de esta función descrita anteriormente está haciendo de una manera bastante complicada). Básicamente, una sola línea en la función:return getConnectedForm().getResponses().length;
Abid H. Mujtaba
2

Esta es una derivada de las otras respuestas, pero podría ser útil para futuros usuarios.

function onEdit(e) 
{
   var sheet = SpreadsheetApp.getActiveSheet();
   var row =  SpreadsheetApp.getActiveSheet().getActiveCell().getRow();

   var bugCount = sheet.getRange("M2").getValue();
   bugCount++;

   if (sheet.getRange(row, 1).getValue() == "") {
      sheet.getRange(row,1).setValue(bugCount);
      sheet.getRange("M2").setValue(bugCount);    
   }

}

La principal diferencia es que actualizará la columna 1 en la fila activa cuando se edite esa fila, pero solo si aún no hay un valor especificado.

Debe configurar el desencadenante como se menciona en otras respuestas en la edición.

establecer disparador en edición

Nacross
fuente
0

Para "¿Es posible en el formulario de Google dar un valor único a cada fila que inserta en la hoja de cálculo y en la marca de tiempo?" al tiempo que permite la eliminación de una fila en la hoja de respuestas del formulario antes de agregar una respuesta adicional sin duplicar valores, esto debería funcionar:

=iferror(ArrayFormula(match(A1:A,A:A,0)),"")
nueces
fuente