【问题标题】:Trigger script only on first instance of Form Submission仅在表单提交的第一个实例上触发脚本
【发布时间】:2017-01-28 10:00:55
【问题描述】:

我们的寄宿学校使用 Google 表格让学生在抵达和离开时登录和退出。 我有一个函数 -dailyRecord() - 每天晚上记录哪些学生当晚登机。 有两个自定义菜单,一个用于在半学期和 exeats(周末外出)清除表单响应,另一个用于在每个学期结束时清空登机夜记录。

目前清除表单响应也会禁用 dailyRecord() 功能(无论如何,我们不想在学校没有学生的情况下进行记录)。 我试图创建一个脚本,在下次提交表单响应时重新启用 dailyRecord() 函数(即学生在周末/半学期后再次开始登录)。问题是每次提交表单时它都在运行,这意味着每晚都会制作多条记录而不是一条。我只需要在休息后第一次提交表单时重新启用该功能。 任何想法任何人

//ONOPEN - Menu allowing user to choose to delete previous form submissions//
function onOpen() {
  var ui = SpreadsheetApp.getUi();
  // Or DocumentApp or FormApp.
  ui.createMenu('Clear Data')
  .addItem('Exeat & HT - Purge Form reponses', 'responsesAlert')
  .addItem('End of Term - Empty History Sheets', 'historyAlert')
      .addToUi();
}

//DELETETRIGGER - Stand alone function to delete 'dailyRecord' Trigger (stop recording nightly register)// 
function deleteTrigger() {
  var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() === 'dailyRecord') {
  ScriptApp.deleteTrigger(triggers[i]);
}
}}

//RESPONSESALERT - Alert box deleting previous form submissions 'YES', doing nothing if not//
function responsesAlert() {
  var ui = SpreadsheetApp.getUi();
  var result = ui.alert(
     'This will remove previous form responses - The nightly record (History Sheet) will remain intact',
     'Are you sure you want to continue?',
      ui.ButtonSet.YES_NO);
  // Process the user's response.
  if (result == ui.Button.YES) {
  //Empty 'Form Responses 1' Sheet of data
  var ui = SpreadsheetApp.getUi();
  var source = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Form Responses 1");
  var lastRow = source.getLastRow()
  source.deleteRows(2, lastRow)}
  //Empty the Google Form of all Responses
  var form, urlForm = SpreadsheetApp.getActiveSpreadsheet().getFormUrl();
  if (urlForm) {}
    form = FormApp.openByUrl(urlForm);
    if (form) form.deleteAllResponses();
  //Delete 'dailyRecord' Trigger (stop recording nightly register)
  var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() === 'dailyRecord') {
  ScriptApp.deleteTrigger(triggers[i]);
}
}}

//HISTORYALERT - Alert box deleting previous form submissions 'YES', doing nothing if not//
function historyAlert() {
  var ui = SpreadsheetApp.getUi();
  var result = ui.alert(
     'This will clear all daily records from the History Sheet',
     'Are you sure you want to continue?',
      ui.ButtonSet.YES_NO);
  // Process the user's response.
  if (result == ui.Button.YES) {
  //Empty 'History' Sheet of data
  var ui = SpreadsheetApp.getUi();
  var source = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("History");
  var lastColumn = source.getLastColumn()
  source.deleteColumns(4, lastColumn-3)}
}


//DAILYTRIGGER - Trigger running record-keeping function c.10pm each night//
function dailyTrigger() {
  ScriptApp.newTrigger('dailyRecord')
  .timeBased()
  .atHour(22)
  .everyDays(1)
  .create();
}

//DAILYRECORD - Record-keeping function, copy/value-pasting record into next clear column//
function dailyRecord() {
    var ss = SpreadsheetApp.getActive()
        .getSheetByName('History'),
        lastColumn = ss.getLastColumn(),
        colC = ss.getRange("C:C")
            .getValues();
    ss.getRange(1, lastColumn + 1, colC.length, 1)
        .setValues(colC);
}

【问题讨论】:

  • HTML/JavaScript/CSS sn-p 应该只用于可以直接在这个站点上运行的代码,所以我删除了它。另一方面,这在我看来就像XY Problem。我认为如果您避免从表单中删除所有回复,您将不需要 dailyRecord 功能。
  • 谢谢Rubén,对此相当陌生,对XY问题也很模糊,只是想分享我想要实现的目标以及我是如何尝试实现它的。你说得对,不删除表格回复会有所帮助,但是,所有学生整天都在签到和签出,我担心电子表格会开始变得过于笨拙。感谢您的回复!

标签: google-apps-script google-sheets google-apps google-forms


【解决方案1】:

下面的代码为提交表单时调用的 firstSubmission 函数设置了一个 onFormSubmit 触发器,该函数删除了自己的触发器,本质上成为一次性触发器或第一次提交触发器。

在你的 reponseAlert 函数结束时调用这个函数 像这样:

function responsesAlert() {
  var ui = SpreadsheetApp.getUi();
  ....
  var form, urlForm = SpreadsheetApp.getActiveSpreadsheet().getFormUrl();
  if (urlForm) {}
  form = FormApp.openByUrl(urlForm);
  ....
  var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() === 'dailyRecord') {
  ScriptApp.deleteTrigger(triggers[i]);
}
}
firstSubmissionTrigger(form)
}

function firstSubmissionTrigger(form){
    ScriptApp.newTrigger('firstSubmission').forForm(form).onFormSubmit().create()
// Sets trigger to call firstSubmission to be called when the submission is made
}

function firstSubmission(){
 dailyTrigger()
// Starts the dailyTrigger
// Below code deletes the triggers that calls firstSubmission function 
// Essentially making it a one time trigger or First submission trigger      
 var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() === 'firstSubmission') {
  ScriptApp.deleteTrigger(triggers[i]);
}

}
}

【讨论】:

  • 对此非常感激 - 我将实施并测试它。对此有点陌生,4个点(....)只是指原始元素保持不变?
  • 是的,我把 ( ...) 指的是保持不变的原始元素。这样我就可以更容易地突出我修改代码的地方
  • 谢谢您 - 刚开始第一个周末休息,因为做了更改 - 周末后会通知您。
【解决方案2】:

感谢所有 cmets 和对此的帮助。我最终变得尽可能简单......脚本设置在脚本编辑器中设置每日触发器,并编写脚本以在多个表单条目时运行。每个周末和半学期都会清空表格。

//RECORDTRIGGER
 function recordTrigger() {
  var responses = FormApp.openByUrl('formurl.com').getResponses().length
  if (responses > 1) {
      var ss = SpreadsheetApp.getActive().getSheetByName('History'),
        lastColumn = ss.getLastColumn(),
        colC = ss.getRange("C:C").getValues();
    ss.getRange(1, lastColumn + 1, colC.length, 1).setValues(colC);
}}

经过测试似乎可以工作 - 非常感谢支持。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-29
    • 1970-01-01
    • 1970-01-01
    • 2018-08-25
    • 1970-01-01
    • 2021-06-30
    相关资源
    最近更新 更多