Google apps script 使用“创建的可安装触发器”;ScriptApp.newTrigger“的;必须重新保存才能运行

Google apps script 使用“创建的可安装触发器”;ScriptApp.newTrigger“的;必须重新保存才能运行,google-apps-script,google-sheets,gs-installable-triggers,Google Apps Script,Google Sheets,Gs Installable Triggers,我有一张费用表,我会为我的每个相关用户复制到Google Drive文件夹中。工作表的每个副本都需要一个可安装的触发器,该触发器在编辑最后一行数据时调用函数插入额外的行。这些是使用onEdit事件触发的。手动创建(通过“编辑当前项目的触发器””)时,可安装触发器工作正常 为了简化设置新用户的过程,我编写了创建触发器的脚本。虽然脚本创建了触发器,并且它看起来与手动创建的触发器完全相同,但只有在手动打开触发器、重新选择要触发的函数并重新保存它时,它才起作用 我可以在运行创建脚本时确认我是所有者 我所

我有一张费用表,我会为我的每个相关用户复制到Google Drive文件夹中。工作表的每个副本都需要一个可安装的触发器,该触发器在编辑最后一行数据时调用函数插入额外的行。这些是使用onEdit事件触发的。手动创建(通过“
编辑当前项目的触发器”
”)时,可安装触发器工作正常

为了简化设置新用户的过程,我编写了创建触发器的脚本。虽然脚本创建了触发器,并且它看起来与手动创建的触发器完全相同,但只有在手动打开触发器、重新选择要触发的函数并重新保存它时,它才起作用

我可以在运行创建脚本时确认我是所有者

我所看到的行为向我暗示,我的脚本中的函数名有一些不正确的地方,但在我看来一切都很好。我真的很感激你能帮我

function createInsertRowsTrigger(){
  Logger.log('Id='+ss.getId());
createInstallableTrigger("onEditOfLastRow",ss.getId());
}

function createInstallableTrigger(funcName,ssId) {
      if(!isTrigger(funcName)) {
        ScriptApp.newTrigger(funcName).forSpreadsheet(ssId).onEdit().create();
      }
    }

function isTrigger(funcName){
       Logger.log('In isTrigger');
   var r=false;
   if(funcName){
     Logger.log('Function found');
     var allTriggers=ScriptApp.getProjectTriggers();
     for(var i=0;i<allTriggers.length;i++){
       if(funcName==allTriggers[i].getHandlerFunction()){
         r=true;
         Logger.log('trigger already exists');
         break;
       }
     }
   }
   return r;
 }
函数createInsertRowsTrigger(){ Logger.log('Id='+ss.getId()); createInstallableTrigger(“onEditOfLastRow”,ss.getId()); } 函数createInstallableTrigger(funcName,ssId){ 如果(!isTrigger(funcName)){ ScriptApp.newTrigger(funcName).forSpreadsheet(ssId).OneEdit().create(); } } 函数isTrigger(funcName){ Logger.log('In-isTrigger'); var r=假; 如果(名称){ Logger.log('Function found'); var allTriggers=ScriptApp.getProjectTriggers();
对于(var i=0;iWhy您没有使用
Sheet.appendRow
函数?
onEdit(e)
一次只能处理2次编辑,如果用户“编辑”,则将忽略其余编辑太快了。为什么不直接使用
importrange
?您好@codecamp,我没有使用appendRow函数,因为我的费用表有一些不同的部分,我只是在第一部分插入行。因此,插入而不是追加…为了澄清,我使用的是onEdit事件,这触发了我自己的函数,而不是简单onEdit()功能。我发现的问题是,我的可安装触发器无法工作,除非我重新打开它们,重新选择要触发的功能并重新保存……可安装触发器非常危险,因为它们在gmail帐户下运行。如果你安装它们,通常你需要手动安装它们,因为你有效地授权每张工作表进行pote必须删除所有电子邮件等。因此可能与安装触发器所需的授权有关,不确定。您可以在特定工作表上使用appendRow功能我不确定您为什么需要添加行,但我看到您编辑了您的问题,并希望在用户键入最后一行时有一个新的空行,您可以在键入I时添加行在最后一排。。。
function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('SCLGA Expenses Menu')
      .addItem('Approve Expenses', 'ApproveExpenses')  
      .addToUi();

  resetValidationRules();
 }

//===========================================================================================
// global 
var ss = SpreadsheetApp.getActive();
//===========================================================================================

function onEditofLastRow(e) {
  var value = ss.getActiveSheet().getRange(3, 6).getValue();// row number of the last but one row
  editedCol =e.range.getSheet().getActiveCell().getColumn();
  editedRow =e.range.getSheet().getActiveCell().getRow();

  // if the last cell in the last row is edited...create some more rows...
  if(editedCol==7 && editedRow==  value-1){
       showAlert('Looks like you need some more rows... ');
       insertRows();
  }
}




function createInsertRowsTrigger(){
  Logger.log('Id='+ss.getId());
createInstallableTrigger("onEditOfLastRow",ss.getId());
}


function createInstallableTrigger(funcName,ssId) {
      if(!isTrigger(funcName)) {
        ScriptApp.newTrigger(funcName).forSpreadsheet(ssId).onEdit().create();
      }
    }

function isTrigger(funcName){
       Logger.log('In isTrigger');
   var r=false;
   if(funcName){
     Logger.log('Function found');
     var allTriggers=ScriptApp.getProjectTriggers();
     for(var i=0;i<allTriggers.length;i++){
       if(funcName==allTriggers[i].getHandlerFunction()){
         r=true;
         Logger.log('trigger already exists');
         break;
       }
     }
   }
   return r;
 }
function showAlert(msg) {
  var ui = SpreadsheetApp.getUi(); 
  var result = ui.alert(msg);
}

function insertRows() {
    // this function inserts some new rows and copies relevant formulas and formats


    // this value tells us  where the next data section starts
    var value = ss.getActiveSheet().getRange(3, 6).getValue();
    var rowsToAdd = 5;
    var firstRow = value-rowsToAdd;
    var sh = ss.getActiveSheet();
    var lCol = sh.getLastColumn();
    var range = sh.getRange(firstRow, 1, rowsToAdd, lCol);


    // copy formulas 
    var formulaRange1 = sh.getRange(firstRow, 1, rowsToAdd, 1);
    var formulaRange2 = sh.getRange(firstRow, 8, rowsToAdd, lCol-8);
    var formulas1 = formulaRange1.getFormulasR1C1();
    var formulas2 = formulaRange2.getFormulasR1C1();

    // insert rows
    sh.insertRowsAfter(firstRow+rowsToAdd-1, rowsToAdd);

    // define new range
    newRange1 = sh.getRange(firstRow+rowsToAdd, 1, rowsToAdd, 1);
    newRange2 = sh.getRange(firstRow+rowsToAdd, 8, rowsToAdd, lCol-8);

    // set formulas
    newRange1.setFormulasR1C1(formulas1);
    newRange2.setFormulasR1C1(formulas2);

    // copy formatting for range 2 
    range.copyFormatToRange(sh, 1, lCol-8, firstRow+rowsToAdd, firstRow+rowsToAdd+rowsToAdd-1);


    resetValidationRules();
    resetTransactionUploadFormulas();
}

function resetTransactionUploadFormulas(){
  var sheet = ss.getSheetByName('Transactions to load');
  sourceFormulas = sheet.getRange(2,1,1,12).getFormulasR1C1();
  for (i=3; i<=250; i++)
      newRange=sheet.getRange(i,1,1,12).setFormulasR1C1(sourceFormulas);  

}



function resetValidationRules(){
    var value = ss.getActiveSheet().getRange(3, 6).getValue();
    var firstRow = 5; 
    var sh = ss.getActiveSheet();
    var lCol = sh.getLastColumn();
    var range = sh.getRange(firstRow, 1, 245, lCol);

  // Apply validation rules to all rows
    for(i = 1; i <= 250; i++){
        currentRowNumber = 4+i;
        var cell = SpreadsheetApp.getActive().getRange('F'+currentRowNumber);
        var eventRange = sh.getRange("L"+currentRowNumber+":BB"+currentRowNumber)
        var rule = SpreadsheetApp.newDataValidation().requireValueInRange(eventRange).build();
        if (value != currentRowNumber && value+1 != currentRowNumber)
          cell.setDataValidation(rule);
        }
}