繁体   English   中英

可安装的触发器因测试加载项而失败

[英]Installable Trigger Failing with Test Add-On

几天来,我一直在努力解决可安装的触发器问题。 我的所有研究表明,附加组件应该允许在电子表格中安装 onEdit() 触发器,但我的尝试不断出错。 我已经稍微简化了我的项目代码来举例说明我的问题。

错误信息:

执行失败:测试加载项尝试执行不允许的操作。

我的代码(列出函数是调用它们的顺序):

   function onOpen() //creates custom menu for the evaluation tool ***FOR ADMININSTRATORS ONLY***
{ 

  var ui = SpreadsheetApp.getUi();

  if(!PropertiesService.getDocumentProperties().getProperty('initialized'))
  {
    ui.createMenu('Evaluation Menu') // Menu Title
      .addItem('Create Installable OnEdit Trigger', 'createInstallableOnEditTrigger')
    .addToUi();
  }
  else
  {
    ui.createMenu('Evaluation Menu') // Menu Title
      .addSubMenu(ui.createMenu('Manage Observations & Evidence')
           .addSubMenu(ui.createMenu('Create New Observation')
               .addItem('Formal', 'createNewFormalObservation')
               .addItem('Informal', 'createNewInformalObservation')
            )          
      .addToUi();    
  }
}


function createInstallableOnEditTrigger() { // installable trigger to create employee look-up listener when user edits the EIN fields on the Documentation Sheet.
  var ss = SpreadsheetApp.getActive();
  ScriptApp.newTrigger('onEditListener')
      .forSpreadsheet(ss)
      .onOpen()
      .create();

  PropertiesService.getDocumentProperties().setProperty('initialized','true');
}

function onEditListener(event) //this function conitnually listens to all edit, but only engages only certain conditions such as when a timestamp is determined to be needed or the Documentation Sheet needs to be auto-populated
{
  //Determine whether or not the conditions are correct for continuing this function
  var sheetName = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName(); //determines the name of the currently active sheet

  if (sheetName.indexOf("Evidence") > -1) // if the active sheet is an evidence collection sheet, a timestamp may be needed
  {
    populateEvidenceTimeStamp(event, sheetName);
  }
  else if (sheetName == "Documentation Sheet") //if the active sheet is the "Documentation Sheet" than auto-population and EIN lookups may be needed
  {
    employeeLookup(event, sheetName);
  }
}

我错过了什么? 任何帮助是极大的赞赏!!

以下代码已根据@Mogsdad 的要求添加。

populateEvidenceTimeStamp() 依赖于 generateTimeStamp() ,它也包括在下面:

function populateEvidenceTimeStamp(event, sheetName)
{
  var evidenceColumnName = "Evidence"; 
  var timeStampColumnName = "Timestamp";
  var sheet = event.source.getSheetByName(sheetName);

  var actRng = event.source.getActiveRange();
  var indexOfColumnBeingEdited = actRng.getColumn();
  var indexOfRowBeingEdited = actRng.getRowIndex();
  var columnHeadersArr = sheet.getRange(3, 1, 1, sheet.getLastColumn()).getValues(); // grabs the column headers found in the 3rd row of the evidence sheet

  var timeStampColumnIndex = columnHeadersArr[0].indexOf(timeStampColumnName); //determines the index of the Timestamp column based on its title
  var evidenceColumnIndex = columnHeadersArr[0].indexOf(evidenceColumnName); evidenceColumnIndex = evidenceColumnIndex+1; //determines the index of the evidence column based on its title
  var cell = sheet.getRange(indexOfRowBeingEdited, timeStampColumnIndex + 1); //determines the individual timestap cell that will be updated

  if (timeStampColumnIndex > -1 && indexOfRowBeingEdited > 3 && indexOfColumnBeingEdited == evidenceColumnIndex && cell.getValue() == "") // only create a timestamp if 1) the timeStampColumn exists, 2) you are not actually editing the row containing the column headers and 3) there isn't already a timestamp in the Timestamp column for that row
  {
    cell.setValue(generateTimeStamp());
  }
}

function generateTimeStamp()
{
  var timezone = "GMT-7"; // Arizona's time zone
  var timestamp_format = "MM.dd.yyyy  hh:mm:ss a"; // timestamp format based on the Java SE SimpleDateFormat class. http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html 
  var currTimeStamp = Utilities.formatDate(new Date(), timezone, timestamp_format);  
  return currTimeStamp;  
}

下面是依赖于lookupEIN()的employeeLookup()函数

function employeeLookup(event, sheetName)
{
  if(sheetName == "Documentation Sheet" && !PropertiesService.getDocumentProperties().getProperty('initialized')) // if the activeSheet is "Documentation Sheet" and the sheet has not yet been initialized
  {
    var actRng = event.source.getActiveRange();
    Logger.log("employeeLookup(): actRng: "+actRng.getRow()+" , "+actRng.getColumn());
    if(actRng.getRow() == 4 && actRng.getColumn() == 9 && event.source.getActiveRange().getValue() != "") //if the "Teacher EIN" cell is the active range and it's not empty
    { 
      var ein = actRng.getValue();
      clearDocumentationSheetTeacherProfile(); //first clear the teacher profile information to avoid the possibility of EIN/Teacher Info mismatch if previous search did not yield results
      var teacherDataArr = lookupEIN(ein, "Teachers");
      if(teacherDataArr)
      {
        //write retrieved teacher data to Documentation Spreadsheet
        var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Documentation Sheet");
        sheet.getRange(5, 9, 1, 1).setValue(teacherDataArr[1]); // Teacher First Name
        sheet.getRange(6, 9, 1, 1).setValue(teacherDataArr[2]); // Teacher Last Name
        sheet.getRange(7, 9, 1, 1).setValue(teacherDataArr[3]); // Teacher Email 

        sheet.getRange(11, 9, 1, 1).setValue(teacherDataArr[4]); // School Name
        sheet.getRange(11, 39, 1, 1).setValue(teacherDataArr[5]); // Site Code
        sheet.getRange(10, 30, 1, 1).setValue(calculateSchoolYear()); //School Year
      }
      else
      {
        Logger.log("employeeLookup(): type:Teachers 'died. lookupEIN() did not return a valid array'"); //alert message already sent by lookUpEIN
      }
    }
    else if (actRng.getRow() == 4 && actRng.getColumn() == 30 && actRng.getValue() != "" && !PropertiesService.getDocumentProperties().getProperty('initialized')) //if the "Observer EIN" cell is the active range
    {
      Logger.log("employeeLookup(): 'active range is Observer EIN'");
      var ein = actRng.getValue();
      clearDocumentationSheetObserverProfile(); //first clear the teacher profile information to avoid the possibility of EIN/Observer Info mismatch if previous search did not yield results
      var observerDataArr = lookupEIN(ein, "Observers");
      if(observerDataArr)
      {
        //write retrieved observer data to Documentation Spreadsheet
        var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Documentation Sheet");
        sheet.getRange(5, 30, 1, 1).setValue(observerDataArr[1]); // Observer First Name
        sheet.getRange(6, 30, 1, 1).setValue(observerDataArr[2]); // Observer Last Name
        sheet.getRange(7, 30, 1, 1).setValue(observerDataArr[3]); // Observer Email 
      }
      else
      {
        Logger.log("employeeLookup(): type:Observers 'died. lookupEIN() did not return a valid array'"); //alert message already sent by lookUpEIN
      }
    }
    else
    {
      Logger.log("employeeLookup(): 'active range is not a trigger'");
      //do nothing (not the right cell)
    }
  }
  else
  {
    //Observer log has already been initialized and documentation cannot be altered. notify user
    Logger.log("employeeLookup(): 'log already saved.... alerting user'");
    logAlreadyInitializedDialogue();
    restoreDocumentationSheetData();
  }
}

function lookupEIN(ein, type)
{
  Logger.log ("lookUpEIN(): 'engaged'");
  var ss = SpreadsheetApp.openById(teacherObserverIndex_GID);
  var sheet = ss.getSheetByName(type); //lookup type aligns with the individual sheet names on the teacherObserverIndex_GID document
  var values = sheet.getDataRange().getValues();
  var val = sheet.getDataRange();

  for (var i = 1; i < values.length; i++)
  {
     if(values[i][0] == ein)
    {
      Logger.log ("lookUpEIN(): values[i]: "+values[i]);
      return values[i];
    }
    else
    { 
      Logger.log ("lookUpEIN(): 'no match found'");
    }
  }
  //a match could not be found 
  Logger.log("An EIN match could not be found"); // create a feedback pop-up
  einNotFoundDialogue(type); //alert user that there is a problem with the provided ein
}

将脚本作为测试作为附加组件运行时,无法创建触发器。

https://developers.google.com/apps-script/add-ons/test

在测试附加组件时,需要牢记以下几点:

  • 测试时当前不支持可安装触发器。 依赖于可安装触发器的功能将无法测试。

一些可能的解决方法

  • 对于 on open 和 on edit 可安装触发器,临时添加简单触发器来调用可安装触发器的功能。 这可能仅在 的执行时间小于简单触发器限制时才有效。
  • 从创建模拟相应事件对象的对象的函数调用可安装触发器中的函数
  • 不要使用独立项目,而是使用有界项目。 您可以使用CLASPGoogle Apps Script GitHub Assistant Chrome 扩展程序等扩展程序,以便更轻松地将代码从独立项目复制到有界项目。

有关的

根据我的经验,onEdit() 不能作为附加组件进行测试。

我同意文档不清楚,它似乎仅指“可安装触发器”,但我认为它适用于所有触发器,除了“onInstall”触发器在您开始测试时立即运行。 (有关更多详细信息,请参阅: 测试 Google Sheet Addon 触发器

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM