开发者问题收集

在 Google App Script 中运行已安装的触发器时出现问题

2020-08-04
169

对应用程序脚本相当陌生,所以请耐心等待。 编写了这个庞大的脚本,然后将其设置为时间触发器,但它就是拒绝运行。我尽可能地向前追溯,至少让一些东西工作,但我甚至无法让一个基本的提示以一分钟的间隔出现。

这是我构建的脚本,我直接运行它来启用触发器:

function createTriggers() {
  
  ScriptApp.newTrigger('testTime')
      .timeBased()
      .everyMinutes(1)
      .create();
};

它调用的函数非常简单,我经常使用它,也经常更改它:

var gSS = SpreadsheetApp.openById("this_1s/the.1d")

function testTime() {
  var d = new Date()
  var Start = d.getTime();
  
  gSS.toast(Start, "Testing", 30)
};

所以它应该如何工作,如果我直接调用“testTime”函数,它就会在相关电子表格上弹出一个小提示,并保持可见 30 秒。 当我运行触发器函数“createTriggers”时,什么也没发生..

请帮忙!如果我不能让它自己运行,那么我写的所有代码都是毫无意义的。:(

***** 编辑 - 08/04/20 - 根据评论*****

这可能是一个 XY 示例,我尝试运行原始代码的一小部分,当我直接运行它时它可以工作,但它在这里也不起作用.. 这个代码片段没有任何面向 UI 的函数,所以它不应该是问题.. 我所做的就是采用上面的触发函数并将名称更改为“testClear”,它调用以下函数:

function testClear(){
  sheetVars(1)
  clearSheetData(sheetSPChange)
};

function sheetVars(numSprints) {
  // returns the global vars for this script
  
  try {
    sheetNameSprints = "Name of Sprint Sheet"
    sheetNameSPChange = "Name of Story Point Change Sheet"
    sheetSprints = gSS.getSheetByName(sheetNameSprints)
    sheetSPChange = gSS.getSheetByName(sheetNameSPChange)
    arraySprints = iterateColumn(sheetSprints,"sprintIDSorted", 1, numSprints)
  }
  catch(err) {
    Logger.log(err)
  };
};

function iterateColumn(sheet, header, columnNum, numRows) {
  // Create an array of first column values to iterate through
  // numRows is an int, except for the string "all"
  
  var gData = sheet.getDataRange();
  var gVals = gData.getValues();
  var gLastR = ""
  var gArray = []
  
  
  // check how many rows to iterate
  
  if (numRows == "all") {
    gLastR = gData.getLastRow();
  }
  else {
    gLastR = numRows
  };
  
  // Iterate through each row of columnNum column
  
  for (i = 1; i < gLastR; i++){
    // iterate through
    
    if(gVals[i][columnNum] !== "" && gVals[i][columnNum] !== header){
      // push to array
      
      gArray.push(gVals[i][columnNum]);
    }
    else if (gVals[i][columnNum] == "") {
      break
    };
  };
  
  return gArray
};

function clearSheetData(sheet) {
  // Delete all rows with data in them in a sheet
    
  try {
    if (!sheet.getRange(sheet.getLastRow(),1).isBlank()){
      sheet.getRange(2, 1, sheet.getLastRow()-1, sheet.getLastColumn()-1).clearContent()
      Logger.log("Sheet cleared from old data.")
    }
    else {
      sheet.deleteRows(2, sheet.getLastRow()-1)
      Logger.log("Sheet rows deleted from old data.")
    };
  }
  catch(err){
    Logger.log(err)
    emailLogs()
  };
};

“emailLogs”函数是一个基本的 MailApp,因此我会收到有关脚本问题的通知:

function emailLogs() {
  // Email Nikita the loggs of the script on error
  
  var email = "my work email@jobbie"
  var subject = "Error in Sheet: " + gSS.getName()
  var message = Logger.getLog()
  MailApp.sendEmail(email, subject, message)
};

感谢评论,我现在发现了执行页面!!:D 这是编辑的错误脚本。

Aug 4, 2020, 10:48:18 AM Error Exception: Cannot call SpreadsheetApp.getUi() from this context. at unknown function

2个回答

若要每隔特定“时间”(每 n 次迭代)显示一次提示消息,请将其添加到 for 循环中

if (!((i+1) % n)) spreadsheet.toast("Working...")

来自问题

Aug 4, 2020, 10:48:18 AM Error Exception: Cannot call SpreadsheetApp.getUi() from this context. at unknown function

上述错误意味着您的时间驱动脚本正在调用一种只能在用户在 Web 浏览器中打开电子表格时执行的方法。

换句话说, toast 不能用于时间驱动触发器。解决方案是使用客户端代码每分钟显示该消息。为此,您可以使用侧边栏和执行 setTimeout

参考

Wicket
2020-08-04

根据所有评论以及我从中学到的新知识:

我一直在为我的 onOpen 函数调用一个全局变量:

var gUI = SpreadsheetApp.getUi();

尽管我没有将它用作触发器,但由于它是全局变量,因此它尝试运行但失败了。

我将 gUI 的实际定义移到了 onOpen 函数中,然后再次尝试,结果成功了。 感谢大家的支持!

nikooters
2020-08-04