【问题标题】:Create Trigger to Run Script Only When New Row is Added to Spreadsheet仅在将新行添加到电子表格时创建触发器以运行脚本
【发布时间】:2021-08-11 22:23:46
【问题描述】:

我有一个看似相对简单的任务,但似乎无法弄清楚。我编写了一个脚本,在提交表单时创建一个日历事件。我们将不再使用表单(改为移至 AppSheet),因此,我需要触发器仅在添加新行时触发。我相信“onChange”是解决这个问题的方法,但我只希望脚本在添加一行时运行,而不是在编辑、删除或以任何其他方式更改时运行。有什么建议吗?

// Create Calendar Event From Spreadsheet

var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var lastRow = sheet.getLastRow();
var lastColumn = sheet.getLastColumn();

// Calendar to output requests
var calendar = CalendarApp.getCalendarById('youremail@gmail.com');

// Creates an object from the last row
function getSubmission() {
  this.timestamp = sheet.getRange(lastRow, 1).getValue();
  this.accountNumber = sheet.getRange(lastRow, 2).getValue();
  this.contactLastName = sheet.getRange(lastRow, 3).getValue();
  this.contactFirstName = sheet.getRange(lastRow, 4).getValue();
  this.contactPhoneNumber = sheet.getRange(lastRow, 5).getValue();
  this.contactEmail = sheet.getRange(lastRow, 6).getValue();
  this.userLastName = sheet.getRange(lastRow, 7).getValue();
  this.userFirstName = sheet.getRange(lastRow, 8).getValue();
  this.userPhoneNumber = sheet.getRange(lastRow, 9).getValue();
  this.userEmail = sheet.getRange(lastRow, 10).getValue();
  this.streetAddress = sheet.getRange(lastRow, 11).getValue();
  this.city = sheet.getRange(lastRow, 12).getValue();
  this.state = sheet.getRange(lastRow, 13).getValue();
  this.zipCode = sheet.getRange(lastRow, 14).getValue();
  this.type = sheet.getRange(lastRow, 15).getValue();
  this.equipment = sheet.getRange(lastRow, 16).getValue();
  this.typeOfLead = sheet.getRange(lastRow, 17).getValue();
  this.sourceOfLead = sheet.getRange(lastRow, 18).getValue();
  this.notes = sheet.getRange(lastRow, 19).getValue();
  this.date = new Date(sheet.getRange(lastRow, 20).getValue());
  this.appointmentStart = sheet.getRange(lastRow, 21).getValue();
  this.appointmentEnd = sheet.getRange(lastRow, 22).getValue();
  this.direction = sheet.getRange(lastRow, 23).getValue();
  this.callOnWay = sheet.getRange(lastRow, 24).getValue();
  return this;
}

//  Creates a calendar event using the last row
function updateCalendar(request) {
  request.date.setHours(request.appointmentStart.getHours());
  request.date.setMinutes(request.appointmentStart.getMinutes());
  var endTime = new Date(request.date);
  endTime.setHours(request.appointmentEnd.getHours());
  endTime.setMinutes(request.appointmentEnd.getMinutes())
  var event = calendar.createEvent(
    request.state + " " + request.direction + " EST " + request.contactLastName + ", " + request.contactFirstName + " " + request.callOnWay,
    request.date,
    endTime
  )
  .setLocation(request.streetAddress + " " + request.city + ", " + request.state + " " + request.zipCode
  )
  .setDescription("Account # " + request.accountNumber + "\n" + "\n" + request.contactFirstName + " " + request.contactLastName + "\n" + request.contactPhoneNumber + "\n" + request.contactEmail + "\n" + "\n" + "Notes: " + request.type + " - " + request.equipment + ". " + request.notes + ".\n" + "Lead: " + request.typeOfLead + " - " + request.sourceOfLead + "." + "\n" + "\n" + "Jim: Scanned:____    " + "Inv. Adj:____    " + "QB:____    " + "Est. SL:____" + "\n" + "\n" + "Tracy: QB:____" + "    Scan:____" + "    Letter:____" + "    Lead Sheet:____" + "    Ref. Check #:____"
  )
}

// --------------Main--------------
function main() {
  var request = getSubmission();
  updateCalendar(request);
}

【问题讨论】:

  • 如果是谷歌表单,你应该使用onFormSubmit而不是onChange。如果您使用的是自定义 HTML 表单,最好在之后立即创建事件
  • ArtiBucco,我使用的是 onFormSubmit,但现在不再使用了,因为不会通过谷歌表单接收提交。我只需要在添加新行时触发脚本。

标签: google-apps-script triggers


【解决方案1】:

将 onChange 与 changeType = "INSERT_ROW" 一起使用

如果您使用一个 getValues();,您的代码可能会快十倍;

我只是将列号与名称与数组和对象相关联。

我不会真的这样做。我将把它作为练习留给读者。

顺便说一句,使用 lastRow 提交表单是个坏主意。您应该使用事件对象值或命名值。如果您同时收到大量提交,您的代码就会出现问题。

函数 getSubmission(e) { if(e.changeType == "INSERT_ROW") { //这里放代码 } }

【讨论】:

  • 感谢库珀的建议。我对编写应用程序脚本很陌生。我假设我需要运行以下代码来创建触发器。如何实现 changeType = "INSERT_ROW" ?我所有的实现尝试都导致“无法读取属性‘changeType’。” function createTrigger(){ var sheet = SpreadsheetApp.getActive(); ScriptApp.newTrigger("notify") .forSpreadsheet(sheet) .onChange() .create(); }
  • 感谢您的编辑,现在似乎更接近工作了,但对于被识别为“INSERT_ROW”的内容存在问题。请看我提交的答案。
  • 触发器仅由用户操作激活。其他脚本或公式操作不会生成触发器。
  • 插入行触发器仅在用户实际插入新行而不是类型到已经存在的行时发生。
  • 这就是我害怕的。我确实想出了一个让它工作的方法。我确信这样做不是正确的方法,但是设置changeType == "OTHER" 允许脚本在通过AppSheet 提交数据时按需要运行。同样,这不是正确的方法,而是暂时的解决方法。我们使用表格和脚本来收集我们(3 名员工)通过应用表格输入的潜在客户,并在谷歌日历中为他们的估计约会创建一个日历事件。我们始终会验证事件是否显示在 gcal 上,因此一旦出现任何问题应立即通知。
【解决方案2】:

似乎 INSERT_ROW 仅在手动插入行时注册(右键单击,在上方或下方插入行)。当通过 AppSheet、表单或输入数据添加数据时,它不会运行。下面是我在脚本中添加的代码,当手动插入一行时,它的行为与预期一致。当数据通过外部源输入到新行或输入到行中时,有什么方法可以运行脚本?

function runMain(e) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
    if (e.changeType == "INSERT_ROW") {
    main();
    }
}

这是一个简单的独立测试脚本,我一直在使用它来检查表单中的哪些输入会触发脚本。

function notify(e) {
    MailApp.sendEmail("youremail@gmail.com.com", "Row Added", "A row was added to your sheet.");
}

function runNotify(e) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
    if (e.changeType == "INSERT_ROW") {
    notify(e);
    }
}

【讨论】:

    猜你喜欢
    • 2011-06-16
    • 2015-05-16
    • 1970-01-01
    • 2020-09-08
    • 1970-01-01
    • 1970-01-01
    • 2015-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多